Serializable scala models for the Webhook and Send API of the Facebook Messenger Platform. This repo follows the SemVer Specification.
- Current version: 1.0.0
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:
- A server validated by facebook to receive webhook events (e.g. Akka HTTP).
- Usage of
io.circe.decode
and the webhook models to interpret the webhook events. - Pattern matching to identify message types (text, attachments, fallback, etc).
- Process the messages (e.g. ML, expert model, business logic).
- Build the response using the Send models.
- Send the response using
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
- Akka HTTP
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.