Build a Facebook Messenger Bot in Scala

In this tutorial, we will go through all the steps to make your own Facebook Messenger Bot that echoes back messages it receives. We will use Scala and Akka HTTP , library to create REST API.

Let’s first define dependencies

1

2

3

4

5

6

7

8

libraryDependencies++=Seq(

"commons-codec"%"commons-codec"%"1.10",

"com.typesafe.akka"%%"akka-actor"%"2.4.14",

"com.typesafe.scala-logging"%%"scala-logging"%"3.1.0",

"com.typesafe.akka"%"akka-slf4j_2.11"%"2.4.8",

"com.typesafe.akka"%%"akka-http"%"10.0.0",

"com.typesafe.akka"%%"akka-http-spray-json"%"10.0.0"

)

Model

In this simple scenario, the model is just set of case classes to receive and send messages to Facebook.Link to official documentation, where you can find a detailed description of each field.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

caseclassPayload(url:String)

caseclassAttachment(`type`:String,payload:Payload)

caseclassFBMessage(mid:Option[String]=None,

seq:Option[Long]=None,

text:Option[String]=None,

metadata:Option[String]=None,

attachment:Option[Attachment]=None)

caseclassFBSender(id:String)

caseclassFBRecipient(id:String)

caseclassFBMessageEventIn(sender:FBSender,

recipient:FBRecipient,

timestamp:Long,

message:FBMessage)

caseclassFBMessageEventOut(recipient:FBRecipient,

message:FBMessage)

caseclassFBEntry(id:String,

time:Long,messaging:

List[FBMessageEventIn])

caseclassFBPObject(`object`:String,entry:List[FBEntry])

Routes

GET /webhook is used by Facebook for verification during subscription.POST /webhook is used for handling messages.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

traitFBRouteextendsDirectiveswithLazyLoggingwithRouteSupport{

protectedimplicitdefactorSystem:ActorSystem

protectedimplicitdefec:ExecutionContext

protectedimplicitvalmaterializer:ActorMaterializer

privatevalfbService=FBService

valfbRoute={

extractRequest{request:HttpRequest=>

get{

path("webhook"){

parameters("hub.verify_token","hub.mode","hub.challenge"){

(token,mode,challenge)=>

complete{

fbService.verifyToken(token,mode,challenge)

}

}

}

}~

post{

verifyPayload(request)(materializer,ec){

path("webhook"){

entity(as[FBPObject]){fbObject=>

complete{

fbService.handleMessage(fbObject)

}

}

}

}

}

}

}

}

Service layer

FBService consist of two methods:verifyToken: is used during subscription to verify token, send by Facebook, and sends back challenge token, otherwise Forbidden Http Code must be returned.handleMessage: after we receive a message, we create response payload messages with response text which is an echo of the message which we received. In order to send our newly created messages back, we need to make POST call to Facebook’s Graph API, we doing it in an asynchronous way using helper method HttpClient. We need to send 200 status code to confirm that we receive the message.

Security

To protect from unauthorized calls, HTTP requests coming from Facebook include header X-Hub-Signature which is the SHA1 hash of the payload in method verifyPayload we verify it using the App Secret key.

Configuration

In application.conf we need to define verifyToken, which is some random string you will create during subscription, to setup your webhooks, pageAccessToken and appSecret will be provided by Facebook during integration phase.

1

2

3

4

5

6

fb{

appSecret:""

pageAccessToken:""

verifyToken:""

responseUri="https://graph.facebook.com/v2.6/me/messages"

}

Starting the server

BotApp starts an Http server which listens on port 8080.DebuggingDirectives.logRequestResult enables to log all incoming requests and outgoing responses, which is very helpful during the integration phase.

HTTPS

Facebook requires HTTPS to setup webooks. You can get free HTTPS certificates from Let’s Encrypt.

Integration with Facebook

You will need to create Facebook App and Facebook Page, setup webhooks, get Page Access Token and App Secret. All these steps are describe in official Facebook guide.

Deployment

Here I will give you few hints how I go about deployment. I added sbt-assembly to the project, running sbt assembly command will lets you package the whole project into single jar. I use Nginx as the reverse proxy, here is a link tutorial about setting up SSL with Nginx and Let’s Encrypt.

Summary

Assuming that this bot only echoes messages back to the sender, quite substantial amount of code was written, definitely, a lot has to do with the security but we got here clean, easy to extend solution to help you build cool stuff using Facebook messenger platform.