Skip to content

Developing with FB BotMill

Alvin Reyes edited this page Jan 3, 2017 · 14 revisions

Welcome! We're glad that you chose to try out our framework that we passionately built. We will try to update our source and documentations as much as we can. It is extremely recommended that you go through Facebook Platform overview to get an understanding on how does facebook manage inputs and output. It'll make much more sense to understand our framework when you get how facebook manages responses from chat user input.

Pre-requisites:

  • Our framework is entirely written in Java. We're assuming that you know and understand Java Programming Language and a bit of a background on the basic J2EE components.
  • Any IDE will do as long as you're comfortable with it.
  • Any build tool will do as long as you can create a Java Web Application with it. We do recommend Maven (or Gradle) so that you can just plug it in as dependency on your project.
  • Any hosting services will do but keep in mind that Facebook mandates all callback urls to be accessible via SSL (HTTPS). Digital Ocean or Heroku has free starter packages that automatically gives your a domain that is accessible as such.

Further reading: It is important that you understand the mechanism behind, please feel free to check more details about facebook messenger platform.

Let's Begin!

Table of Contents

Environment Setup

First, we need to create the configuration in Facebook. You need to follow the steps specified at facebook messenger platform quick guide to create the necessary configuration.

Nutshell - how does it work? Whenever a user tries to communicate with your bot, Facebook will send a POST request to your callback url with all the necessary details of the user input (this includes, sender id, type of text, payload, attachments etc). To respond to it, facebook exposed a different set of endpoint APIs that developers can call to create response payload that in turn renders into the users facebook chat window.

So when user enter "Hi" with your bot, facebook calls the callback URL with this message. The callback url (our app) use this information to create a response via facebook graph api.

To understand more about this process, you can review the product overview here.

What happens when a request is sent to the callback URL and how do we create the response? Every input and output is an API call and this is where FB-BotMill comes in. The framework allow developers to catch those messages, convert them to events and create the custom response using its collection of object response factories (buttons, list, sliders, text, attachments etc). The framework only needs the page access token and the webhook verification code in order for it to catch the response.

Let's dive in how we can do a simple response from a callback url post from facebook.

Your first Facebook ChatBot App

  1. Create a Java Web Application and name it MyFirstBotApp and import the fb-botmill library. PLease take note of the latest stable version.

    co.aurasphere.botmill fb-botmill 1.x.x

This will be the application that will handle all the callback post sent by facebook whenever user enters a text. In our Java Web application, specify the framework servlet and the bot-definition-class. The bot-definition-class will be our behaviour class which we will create on the next step.

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <display-name>thubbot</display-name>
    <servlet>
        <servlet-name>myfirstbotservlet</servlet-name>
        <servlet-class>co.aurasphere.botmill.fb.FbBotMillServlet</servlet-class>
        <init-param>
            <param-name>bot-definition-class</param-name>
            <param-value>my.package.MyFirstFbotMillAppBehaviour</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>myfirstbotservlet</servlet-name>
        <url-pattern>/myfirstbotservlet</url-pattern>
    </servlet-mapping>
</web-app>

Things to note

  • Specify the FbBotMillServlet
  • Double check your bot-definition-class value
  • Take note of your servlet mapping (/myfirstbotservlet)
  1. Create your first behaviour class, create a class named: MyFirstFbotMillAppBehaviour and extend AbstractBehaviour. Extending this abstract class will required your concrete class to implement a single method called defineBehaviour().

    public class ThubBotDefinition extends AbstractFbBot { public void defineBehavior() { } }

This is where we will put all our Event and Response Handlers of our Bot App.

  1. Create your first Event handler and Reply. Paste the code below:

    public class ThubBotDefinition extends AbstractFbBot { public void defineBehavior() { // Setting my tokens from Facebook (page token and validation token for webhook). FbBotMillContext.java.getInstance().setup("myFacebookPageToken", "myFacebookWebhookValidationToken"); // Defining a bot which will reply with "Hello World!" as soon as I write "Hi" addActionFrame(new MessageEvent("Hi"),new MessageAutoReply("Hello World!")); } }

  2. Replace the myFacebookPageToken with your page token and myFacebookWebhookValidationToken with your choice of verification Token.

  3. Deploy your app.

In order to complete the process of creating a WebHook, we need to deploy our application. The Servlet url will be the callback url we will specify on the webhook. All Callback URLs should be accessible via HTTPS only. Facebook has mandated this for obvious security reasons.

TIP
The fastest way to do this is to just deploy it via Heroku. Heroku is an infrastructure as a service company that simplifies the creation of JVM Container instance. Not only it provides an easy way to deploy your app, it also automatically uses SSL on it's free personal application domain.

Deploy

Once your application is deployed, check the URL and append the servlet url. Try accessing it via your browser. It should return a 403 error. Note that having a 403 error doesn't mean there's something wrong, the application is just not accepting our request since it's expecting a POST request

  1. Go back to your Facebook App Page and paste the CallBack URL. Put the verification number you used on the app to the Verify Token field.

  2. Subscribe your Webhook to your Facebook Page and Test it out!

Now that you've manage to get your first bot application running, let's dive into other ways of sending and receiving a message.

Sending Messages

Now that you're all set up, let's play around with your bot! The core of our framework plays around using builder patterns. When sending a message, it is important to keep in mind that whenever we receive a response from the user, we need to build a response object for it.

Here is an example of how you can create a text message response given a user input.

public FbBotMillResponse createResponse(MessageEnvelope envelope) {
	String greetingMessage = "Hey There! ";
	return ReplyFactory.addTextMessageOnly(greetingMessage).build(envelope);
}

Aside from sending a simple text, you can also respond differently, let say a generic template!

public FbBotMillResponse createResponse(MessageEnvelope envelope) {
	return ReplyFactory.addGenericTemplate().addElement("Welcome to TechnoWebHub")
		.addUrlButton("Go to Our Website", "http://www.technowebhub.com")
		.setImage("https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTCau2xKug5qTlyXnwQDubIJDeBWvFy0YXPJmobXnMNwInJLDbj")
		.addPostbackButton("Start Chatting", "chat")
		.addShareButton()
		.setSubtitle("Systems Development Company, How would like to check our services?")
		.endElement().build(envelope);
}

 

Go to our snippets page for the complete list of Reply/Response type.

Receiving Messages

Either it's rule based or ml-based, receiving a message will be match to a configured Event.

There are different types of Events that can be use to catch a user input. The most basic one would be to match it against a specific string.

addActionFrame(new MessageEvent("text message"), new MessageAutoReply("simple text message"));

You can also match it against a Regular Expression.

addActionFrame(new PostbackPatternEvent(Pattern.compile("(?i:chat)")), 
    new AutoReply() {
        @Override
        public FbBotMillResponse createResponse(MessageEnvelope envelope) {
            return ReplyFactory.addTextMessageOnly("Sure!").build(envelope);
        }
    });

 

A postback that returns a list.

addActionFrame(new PostbackPatternEvent(Pattern.compile("(?i:services)")), 
    new AutoReply() {
	@Override
	public FbBotMillResponse createResponse(MessageEnvelope envelope) {
		return ReplyFactory.addTextMessageOnly("Services it is! Here you go!").build(envelope);
	}
},new AutoReply() {
		@Override
		public FbBotMillResponse createResponse(MessageEnvelope envelope) {
			return ReplyFactory.addGenericTemplate()
					.addElement("Systems Development")
						.setSubtitle("Custom Software Development with the latest cutting edge Technology")
						.setImage("https://cdn3.iconfinder.com/data/icons/illustricon-tech/512/development.desktop-512.png")
						.addPostbackButton("Inquire", "inquire_softdev")
					.endElement()
					.addElement("Infrastructure")
					.setSubtitle("AWS Infrastructure Management with Certified Professionals")
						.setImage("https://cdn3.iconfinder.com/data/icons/illustricon-tech/512/development.gears-512.png")
						.addPostbackButton("Inquire", "inquire_aws")
					.endElement()
					.addElement("Web Hosting")
					.setSubtitle("Professional Web Hosting/Domain Solutions for your Personal and Business Needs")
						.setImage("https://cdn3.iconfinder.com/data/icons/illustricon-tech/512/structure.hierarchy-512.png")
						.addPostbackButton("Inquire", "inquire_webhosting")
					.endElement()
					.build(envelope);
		}
	});

 

a postback handler response ("inquire_softdev" > payload).

addActionFrame(new PostbackEvent("inquire_softdev", false), new AutoReply() {
	@Override
	public FbBotMillResponse createResponse(MessageEnvelope envelope) {
		return ReplyFactory.addTextMessageOnly("Hold on tight, One of our Sales Development will be with you shortly!")
			.build(envelope);
	}
});

 

And even a catch all event.

addActionFrame(new AnyEvent(), new AutoReply() {
	@Override
	public FbBotMillResponse createResponse(MessageEnvelope envelope) {
		if(safeGetMessage(envelope).equals("")) {return null;}
		return ReplyFactory.addTextMessageOnly("I didn't get that, you can type in: products, service or bot demo").build(envelope);
	}
});

 

#ActionFrame, Event and Reply

Action Frame

The FB-BotMill framework architecture is based on ActionFrames. An ActionFrame is a made up by an Event (Facebook's Messenger Platform callbacks) and and an AutoReply (developer-defined replies to that event).

Basically, an Event tells when the FaceBot should reply, an AutoReply tells how the FB-BotMill should reply and the ActionFrame wraps all this together, adding the possibility of implementing extra logic before and after the reply is sent.

Event

An Event defines wheter the FB-BotMill should reply to an incoming callback or not. Each Event implements the FBBotMillEvent interface. This interface is defined as follow:

public interface FBBotMillEvent {

/**
 * A method which evaluates whether the event is verified or not.
 * 
 * @param envelope
 *            the callback message.
 * @return true if the event is verified, false otherwise.
 */
public boolean verifyEventCondition(MessageEnvelope envelope);

}

The verifyEventCondition method takes as an input the incoming callback from Facebook Messenger Platform and returns a boolean that indicates wheter the callback should be handled or not.

If you want to know more about callbacks, you can read the official Facebook documentation.

AutoReply

An AutoReply incapsulates the logic which creates a reply from a FB-BotMill to a user. Each AutoReply extends the abstract class AutoReply. This class contains an abstract method createResponse which you will override. The method is defined as follows:

/**
 * Method which defines the response to send back as a response to the
 * current message.
 * 
 * @param envelope
 *            the current message.
 * @return a {@link FBBotMillResponse} which contains the response to the
 *         current message.
 */
public abstract FBBotMillResponse createResponse(MessageEnvelope envelope);

It takes as argument the incoming callback and returns a FBBotMillResponse object which represents the response that the FBBotMill will return back to the user. It's recommended to use the ReplyFactory facility to produce the response to return, since it's designed to make easier to build a valid and well-formed response and also adds supports for testing. However, this is not compulsory since FBBotMill gives the possibility to create your own response object with the provided model classes.

For the complete list of our code snippets, you can view them all via our snippets page.

For more information on other callbacks, framework features or how to create a different kind of reply, check out the official wiki.

Contribution

Contribution Guide

Examples