Scala chatbot utils for fb-messenger platform.
Serializable scala models for the Webhook and Send API of the Facebook Messenger Platform.
This repo follows the SemVer Specification.
The original objective was to provide the models for the webhook and send APIs to facilitate the development
of chatbots in the facebook messenger platform.
A chatbot project written in Scala might look something like this:
io.circe.decode
and the webhook models to interpret the webhook events.io.circe.syntax
for json encoding and a client http to send the post request. A more advanced implementation involves streaming technologies, natural language processing, reinforced learning
and complex business logic.
The webhook API is needed when a message is send to a facebook page.
You may receive text messages, attachments or fallback.
For a precise definition of these elements see the messenger platform official documentation for webhook events.
Usage example:
import io.circe.parser.decode
import com.rhdzmota.fbmessenger.webhook.model.Event
import com.rhdzmota.fbmessenger.webhook.model.implicits.Decoders._
// This is a facebook callback (payload a post request from fb representing an event)
val eventJsonString: String = ???
// We can use our implicit decoders with circe to get the event object.
val result = decode[Event](eventJsonString)
result match {
case Left(error) => println("There was an error decoding the eventJsonString: " + error.toString)
case Right(event) => println("We have an event.")
}
Event json example:
{
"object":"page",
"entry":[
{
"id":"<PAGE_ID>",
"time":0,
"messaging":[
{
"sender":{
"id":"<PSID>"
},
"recipient":{
"id":"<PAGE_ID>"
},
"timestamp":0,
"message":{
"mid":"<MID>",
"seq":0,
"attachments":[
{
"title":"<TITLE>",
"url":"<URL>",
"type":"location",
"payload":{
"coordinates":{
"lat":0,
"long":0
}
}
}
]
}
}
]
}
]
}
The send API is needed in order to send a message from a facebook page to a user. For a complete decription of the API see the messenger platform official documentation to send requests.
Usage example:
import io.circe.syntax._
import com.rhdzmota.fbmessenger.send.model.reply._
import com.rhdzmota.fbmessenger.send.model.message._
import com.rhdzmota.fbmessenger.send.model.message.quickreply._
import com.rhdzmota.fbmessenger.send.model.implicits.Encoders._
val recipient = Recipient("<PSID>") // Message recipient (user)
val quickReply = Text("text", "<TITLE>", "<PAYLOAD>", None) // Quick reply buttons (create none or many)
val withText = WithText("<TEXT-1>", Some(List(quickReply))) // Create text message with quick reply list (a message can be withText or withAttachment)
val withMessage = Reply.withDefaultConfigMessage(recipient, withText) // Define reply element (a reply can be done with a message or with an action)
// You can use the implicit encoders and circe syntax to serialize to json
withMessage.asJson
Send request message example:
{
"messaging_type": "RESPONSE",
"recipient": {
"id": "<PSID>"
},
"message": {
"text": "<TEXT-1>",
"quick_replies": [
{
"content_type": "text",
"title": "<TITLE>",
"payload": "<PAYLOAD>"
}
]
},
"notification_type": "REGULAR"
}
This repository only contains the models to interact with the facebook messenger API. If you are using the Send API models, you will need to figure out a way of sending the
request to fb messenger. In this section we present a suggestion for sending the requests using akka http async client library.
Dependencies
Create the required implicit variables for the Actor Model.
import akka.actor.ActorSystem
import akka.stream.{ActorMaterializer, Materializer}
import scala.concurrent.ExecutionContext
trait Context {
implicit val actorSystem: ActorSystem = ActorSystem()
implicit val executionContext = actorSystem.dispatcher
implicit val materializer: Materializer = ActorMaterializer()
}
Create a Client Http object or trait with the post method.
object ClientHttp extends Context{
def postRequest(targetUrl: String)(data: String): Future[HttpResponse] =
Http(actorSystem).singleRequest(
HttpRequest(
HttpMethods.POST,
targetUrl,
entity = HttpEntity(ContentTypes.`application/json`, data)
))
}
Now we can send a request to the Facebook Messenger.
def send(data: String, apiKey: String): Unit =
ClientHttp.postRequest(Settings.Facebook.sendUri + apiKey)(data).onComplete {
case Failure(e) => println(s"- Failed to post:\n$data\n- Reason:\n$e")
case Success(response) => println(s"- Server responded with:\n$response")
}
Feel free to create a PR or raise an issue. For more information, contact the developers of this repo:
To be defined.