The story of implementing the popular Facebook Messenger Bot with python

Have you read TechCrunch's article? Didn't you read? Then this? Also here or here / facebook-messenger-ai /) or here or [here](http://qiita.com/naoyashiga / items / 6c663f6e773490934312). Articles are increasing rapidly. This is all articles from 4/13. If you haven't read it, please read it. And if you don't know it, you can be impressed. ** You can now turn Facebook Messenger into a bot. ** ** You can do it in no time with a little tweaking of the Facebook API.

スクリーンショット 2016-04-22 14.01.49.png

how can I do?

If you read here, everything is written, but if you read English, it will be explained appropriately for people who have urticaria. I will. That said, there is little to do. So I could understand too. By the way, this time it is implemented with python × Tornado.

  1. Make a Facebook App and Facebook page as you like.
  2. Authenticate the URL used by the webhook
  3. Write a program to receive and send messages

Let's look at them in order

1. Make a Facebook App and Facebook page as you like.

I made it really properly. This time it's a bot trial. App category? I think WWW is fine. After making it, the setting screen of the application? Please go to. スクリーンショット 2016-04-22 16.27.17.png Second from the bottom. Messenger-> Start スクリーンショット 2016-04-22 17.04.35.png

There is a place to select a Facebook page, so set the page you created earlier. You will get an access token for the page.

2. Authenticate the URL used by the webhook

What is a webhook? Did you not know it, it seems that it is a function that allows you to hit an arbitrary URL when something changes (http://blog.manaten.net/entry/573) When a message comes to the messenger who turned into a bot, it seems to post to the set URL. So, first you have to authenticate the URL.

For the time being, I wrote a program that processes authentication first. Use Tornado with python. Apparently there are many 5000 ports, so 5000. FB official had a process for js, so I fixed it to python.

server.py


# -*- coding: utf-8 -*-
import tornado.ioloop
import tornado.web
import json

verify_token = <VERIFY_TOKEN>

class WebHookHandler(tornado.web.RequestHandler):
    def get(self):
        if self.get_argument("hub.verify_token", "") == verify_token:
            self.write(self.get_argument("hub.challenge", ""));
        else:
            self.write('Error, wrong validation token');


application = tornado.web.Application([
    (r"/webhook", WebHookHandler)
])


if __name__ == "__main__":
    application.listen(5000)
    tornado.ioloop.IOLoop.instance().start()

Write up to this point and confirm that it starts up on port 5000. Let's set the URL for the webhook.

In the URL [http: // localhost: 5000 / webhook](http: // localhost: 5000 / webhook), the token is for authentication, so anything is fine, but make it the same value as \ <VERIFY_TOKEN> used in the python variable. please. This time I chose "test_fb". Check and save the follow input field as you like ... スクリーンショット 2016-04-22 17.12.42.png ···can not. It is said to be the https one.

What to do now

What should I do? I just want to use it for a while, but it's tedious to give it to the server. [https: // localhost: 5000](https: // localhost: 5000) doesn't work (it didn't work).

Conclusion

There is a super useful application called ngrok in the world. The great thing is that you can temporarily expose one port of your localhost to the outside world. Moreover, it also issues an https URL. Great. Mac users can enter with brew install ngrok. I entered, but I didn't go well, so I obediently dropped it from ngrok official. The usage is sure to follow → here. Official strongest. ./ngrok http 5000 Hit スクリーンショット 2016-04-22 17.15.08.png If such a thing comes out, you win. The address to be forwarded (ca27a10a part) is assigned differently every time, but if you just try it for the time being, there should be no problem. Set the https address assigned to the URL of the webhook earlier. You should be able to save this time.

3. Write a program to receive and send messages

It seems that authentication is required before sending and receiving. curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=<PAGE_ACCESS_TOKEN> \ <PAGE_ACCESS_TOKEN> is an access token for facebook page. {"success":true} This is what comes out. Ready when it comes out ok

FB Official has sample code for js. As you can see, when a message comes, the post will fly to the URL of the webhook. On the other hand, when sending a message, post it to https://graph.facebook.com/v2.6/me/messages. If you get here, all you have to do is write the code. I will post the code I wrote for the time being. \ <VERIFY_TOKEN> is the URL for webhook authentication. This time "test_fb". \ <PAGE_ACCESS_TOKEN> is an access token for facebook page as above.

server.py


#!/bin/env python
# -*- coding: utf-8 -*-
import tornado.ioloop
import tornado.web
import json
import requests

verify_token = <VERIFY_TOKEN>
token = <PAGE_ACCESS_TOKEN>

def sendTextMessage(sender, text):
  if len(text) <= 0:
      return
  url = 'https://graph.facebook.com/v2.6/me/messages'
  headers = {'content-type': 'application/json'}
  data = {
        "recipient": {
            "id":sender
        },
        "message":  {
          "text":"echo: " + text
        }
  }
  params = {"access_token":token}

  r = requests.post(url, params=params, data=json.dumps(data), headers=headers)
  #print r.text

class WebHookHandler(tornado.web.RequestHandler):
    def get(self):
        if self.get_argument("hub.verify_token", "") == verify_token:
            self.write(self.get_argument("hub.challenge", ""));
        else:
            self.write('Error, wrong validation token');
    def post(self):
        print "receive!"
        data = json.loads(self.request.body)
        print data
        messaging_events = data["entry"][0]["messaging"]
        text = ""
        for event in messaging_events:
            sender = event["sender"]["id"];
            if ("message" in event and "text" in event["message"]):
                text = event["message"]["text"];
                sendTextMessage(sender, text)


application = tornado.web.Application([
    (r"/webhook", WebHookHandler)
])

if __name__ == "__main__":
    application.listen(5000)
    tornado.ioloop.IOLoop.instance().start()

The content of the program is extremely simple. When a message flies, add "echo:" to it and return it. that's all. With this alone (for the time being), you can create a bot. I just get back what I hit. But it's fun.

that's all. Thank you for your hard work. Please send us a fun Bot Life.

Recommended Posts

The story of implementing the popular Facebook Messenger Bot with python
The story of making a university 100 yen breakfast LINE bot with Python
The story of Python and the story of NaN
The story of rubyist struggling with python :: Dict data with pycall
The story of making a question box bot with discord.py
March 14th is Pi Day. The story of calculating pi with python
The story of making a standard driver for db with python.
The story of visualizing popular Qiita tags with Bar Chart Race
The story of making a module that skips mail with python
The story of making Python an exe
Check the existence of the file with python
The story of manipulating python global variables
The story of blackjack A processing (python)
The story of creating a bot that displays active members in a specific channel of slack with python
The story of doing deep learning with TPU
Prepare the execution environment of Python3 with Docker
2016 The University of Tokyo Mathematics Solved with Python
[Note] Export the html of the site with python.
Calculate the total number of combinations with python
Check the date of the flag duty with Python
Image processing? The story of starting Python for
The story of reading HSPICE data in Python
Convert the character code of the file with Python3
[Python] Determine the type of iris with SVM
the zen of Python
The story of sys.path.append ()
Extract the table of image files with OneDrive & Python
The story of Python without increment and decrement operators.
The story of stopping the production service with the hostname command
Learn Nim with Python (from the beginning of the year).
The story of replacing Nvidia GTX 1650 with Linux Mint 20.1.
The story of sharing the pyenv environment with multiple users
Destroy the intermediate expression of the sweep method with Python
Visualize the range of interpolation and extrapolation with python
The story of FileNotFound in Python open () mode ='w'
Calculate the regression coefficient of simple regression analysis with python
Summary of the basic flow of machine learning with Python
Get the operation status of JR West with Python
The story of automatic language conversion of TypeScript / JavaScript / Python
Extract the band information of raster data with python
I tried to find the entropy of the image with python
Try scraping the data of COVID-19 in Tokyo with Python
I tried "gamma correction" of the image with Python + OpenCV
The story of building Zabbix 4.4
A note about hitting the Facebook API with the Python SDK
Towards the retirement of Python2
Unify the environment of the Python development team starting with Poetry
Visualize the results of decision trees performed with Python scikit-learn
[Apache] The story of prefork
The story of how the Python bottle worked on Sakura Internet
Calculate the square root of 2 in millions of digits with python
The story of introducing jedi (python auto-completion package) to emacs
I wrote the basic grammar of Python with Jupyter Lab
Let's execute the command on time with the bot of discord
Tank game made with python About the behavior of tanks
Run the intellisense of your own python library with VScode.
About the ease of Python
I evaluated the strategy of stock system trading with Python.
Check the scope of local variables with the Python locals function.
Let's touch the API of Netatmo Weather Station with Python. #Python #Netatmo
Stumble story with Python array