0 0
Read Time:10 Minute, 24 Second

How to create a bot for Messenger from scratch

Currently there are many tools to create chatbots, without the need to program them. Some tools are good and some are not. This is primarily determined by ease of use, and the various scenarios they cover.

But what if we want to develop our own chatbot from scratch , without relying on third-party tools?

Is that possible? Can we really build a chatbot that is useful to us? The answer is Yes. It is possible, and today we will see how to do it.

  • We are going to create a bot for Facebook Messenger
  • We are going to develop this bot using Python
  • And we will have it hosted for free thanks to the Google App Engine service

Why develop our own chatbot instead of using a tool?

There are applications, which have a graphical user interface, and which allow us to create our own bots. Why do we have to develop one from scratch?

We have 3 main reasons:

  • It’s free. The App Engine Free Tier is very generous, so it is highly unlikely that we will exceed the limit. This would only happen if we have several thousand users communicating with our bot continuously. If that is the case, our success would far exceed our investment in hosting.
  • To learn. Are you really not curious to see how a chatbot develops from scratch?
  • Go further. The tools for creating chatbots can be very interesting, but we are really limited to what they offer. Developing our own chatbot will allow us to be original, and develop what we want. We could even develop our own platform for creating chatbots.

Choosing a channel for our chatbot

We can build a bot for different channels. Among the most popular channels we have Facebook Messenger, Slack, Twitter and Telegram.

In this article we are going to talk specifically about the development of chatbots for Facebook Messenger.

Why? Mainly because Messenger is the most popular platform for chatbots. Almost all the tools for building chatbots focus on Messenger, and some even only support Messenger. And there is a good reason for this: it has 2,167 million active users per month (data corresponding to the beginning of 2018).

Another reason Messenger tends to be prioritized: quick-response buttons.

There are buttons that our chatbot can offer users as a shortcut and save them having to type it. This not only makes the bot more attractive (who likes to have to type from mobile?), It also makes our job as chatbot developers much easier.

If we offer buttons to users, then they will use them. This means that we should not worry about “parsing” arbitrary queries, which a user could write (in natural language and probably out of context).

Guiding our users is good for them, but it is also good for us.

The magical tree of nodes

We are going to design our bot based on a tree of nodes.

The possible states of the bot are determined based on this tree.

The nodes represent:

  • The messages sent by the bot
  • The possible answers that the user can give

The root node specifies the first message that the bot sends to the user. In this case the initial message is “Hello. How can I help you?”, And according to the user’s response, the conversation with the bot flows.

What do we need to start developing our bot?

To develop our bot, we first have to configure a couple of things on Facebook.

Official instructions can be found here , but in summary, we are going to need:

  • A page on Facebook – each bot needs a different page.
  • A developer account, which will allow us to register our app on Facebook.
  • An app on Facebook to get access to one secret access token(we’ll need it later).

Bots for Facebook work through webhooks, which are URLs that we define and that Facebook Messenger will use to interact with our bot.

To publish our webhook we will use Google App Engine . The advantage of this is that it is free for low volumes of traffic, and it scales automatically if we need more. We will also use Python as a programming language, but in reality it can also be achieved with any other language.

We are going to need to download the Python SDK and create a Google Cloud project if we don’t already have one.

Creating our Webhook

The first mission of our webhook is to allow Facebook to verify that it really is a genuine webhook. For this we simply have to manage a GET request, which contains a verification token (it is a secret and random string, which we must define in Facebook).

Verification is possible using the following code:

class MainPage(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        mode = self.request.get("hub.mode")
        if mode == "subscribe":
            challenge = self.request.get("hub.challenge")
            verify_token = self.request.get("hub.verify_token")
            if verify_token == VERIFY_TOKEN:
                self.response.write(challenge)
        else:
            self.response.write("Ok")
 

This is how we define a class to handle requests (using the framework webapp2).

Although it is not shown in the previous fragment, this class also has a constructor that is responsible for initializing our bot class.

Managing user messages

We need to interpret the messages that users write. For this we first need to capture these messages.

These are sent by Facebook to our webhook, through POST requests.

def post(self):
    logging.info("Data obtained from Messenger: %s", self.request.body)
    data = json.loads(self.request.body)

    if data["object"] == "page":
        for entry in data["entry"]:

            for messaging_event in entry["messaging"]:
                sender_id = messaging_event["sender"]["id"]
                recipient_id = messaging_event["recipient"]["id"]

                if messaging_event.get("message"):

                if messaging_event.get("postback"):

Here we “parse” the information we receive in JSON format from Facebook, so that it can be analyzed and processed later.

Basically Facebook Messenger allows us to subscribe to events of 2 types: events message(when the user types) and events postback(which are sent when a user clicks on a reply button).

So we iterate over messaging events in general, and depending on the type we decide how to act.

After receiving the information that Facebook sends us and identifying the messages, we invoke the method handleso that our Bot class takes care of its processing.

The above fragment only shows the general structure.

Sending messages to users

When we instantiate our Bot class, we send the function send_messageto the constructor.

This function allows our bot to return reply messages to users. And its definition is the following:

def send_message(recipient_id, message_text, possible_answers):
    headers = {
        "Content-Type": "application/json"
    }

    message = get_postback_buttons_message(message_text, possible_answers)
    if message is None:
        message = {"text": message_text}

    raw_data = {
        "recipient": {
            "id": recipient_id
        },
        "message": message
    }
    data = json.dumps(raw_data)

    logging.info("Sending message to %r: %s", recipient_id, message_text)

    r = urlfetch.fetch("https://graph.facebook.com/v2.6/me/messages?access_token=%s" % ACCESS_TOKEN,
                       method=urlfetch.POST, headers=headers, payload=data)
    if r.status_code != 200:
        logging.error("Error %r Sending message: %s", r.status_code, r.content)
 

The variable recipient_idthat this function receives corresponds to the identifier of the user to whom we are going to respond. Along with this variable we have as parameters: the text to send, and some quick response buttons (which the user can press).

First we make sure that our request headers specify the format to use (JSON), and then we add our postback buttons as part of the message.

These buttons will not always be present, only in some cases, depending on what is defined in our tree. In any case, for the cases in which they are present, the function get_postback_buttons_messageis in charge of giving these buttons the appropriate format (as required by Facebook).

Finally we make our request to the Facebook Graph API, sending the one access token thatthat Facebook gave us when we registered our app.

Running our bot

The final code of our main file contains the following, which is necessary to build the main class and execute the webhook that will represent our bot:

app = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)
 

Brain of our bot

And now we come to an interesting point.

How does the bot know what to say? The brain of our bot corresponds to the file bot.py.

class Bot(object):
    def __init__(self, send_callback, users_dao, tree):
        self.send_callback = send_callback
        self.users_dao = users_dao
        self.tree = tree

    def handle(self, user_id, user_message, is_admin=False):

The class is initialized with 3 parameters:

  • a callback function (which has already been defined before) to return messages to users,
  • an object that provides access to data (to save the history of conversations), and
  • the tree containing the possible conversation flows (obtained from the YAML shown above).

As it should be noted, the class handleis the one that contains the main logic of the bot.

The above code only shows a fragment of the method. But in summary here:

  • First we record the message received from the user, and we obtain the history of messages exchanged with said user, using our instance DAOdata access object).
  • This will allow us to reproduce the actions of the user, to discover where we are according to the tree.
  • A message and buttons are defined by default, which will be returned in case the user says something that the bot does not understand.
  • And likewise, a variable is defined to determine if the user wants to restart the conversation with the bot.

Message history is very important. These messages save the texts sent by both the user and the bot.

Finally, after going through all the history, we write our response (in a log and in our own database), and send the response message to the user.

The last piece of the puzzle

The last but not least is the definition of a data access objectand a model that represents the events reported by Messenger.

Together, these classes allow us to manage all the information related to the exchanged messages (considering 3 actors: users, bot and administrator).

class UserEvent(ndb.Model):
    user_id = ndb.StringProperty()
    author = ndb.StringProperty()
    message = ndb.StringProperty()
    date = ndb.DateTimeProperty(auto_now_add=True)

class UserEventsDao(object):
    def add_user_event(self, user_id, author, message):
        event = UserEvent()
        event.user_id = user_id
        event.author = author
        event.message = message
        event.put()
        logging.info("Registered event: %r", event)

    def get_user_events(self, user_id):
        events = UserEvent.query(UserEvent.user_id == user_id).order(UserEvent.date)
        return [(event.message, event.author) for event in events]

    def remove_user_events(self, user_id):
        events = UserEvent.query(UserEvent.user_id == user_id)
        quantity = events.count()
        for event in events:
            event.key.delete()
        logging.info("Events were removed", quantity)

    def admin_messages_exist(self, user_id):
        events = UserEvent.query(UserEvent.user_id == user_id, UserEvent.author == 'admin')
        return events.count() > 0
 

Our DAO makes use of the Google Datastore . And the Python API makes using Datastore a breeze.

In the snippet above:

  • We first create a model class UserEvent, which specifies the fields and their types. In our case, the user ID, the author of the message, and the message itself are String, and finally the date of the event is of type DateTime.
  • To create and store a new user event, we simply instantiate this class, set the properties, and call the method put()from the object.
  • To obtain the events of a user, we call the function query()and use the user ID. Here we sort the events by date, and return a list of tuples.

Deployment (bot deployment)

We have taken a look at the code that makes up our bot! Now it is time to carry out the deployment process, to finally connect it with Messenger.

To deploy our application on App Engine, we use the command gcloudthat comes with the App Engine SDK:

gcloud app deploy

Once the deployment process is complete, the URL of our webhook will be:

http://[PROJECT_ID].appspot.com/

So we update our Facebook app with this webhook URL and we are good to go!

The world of chatbots has no limits

Remember that you can develop all kinds of bots based on what you have learned in this article / course.

About Post Author

Indian Cyber Troops

Indian Cyber Work For Nation's Wellness And Nation's Security We Share new and unique things with you Jai Hind Jai Shri Ram
Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %