write fb bot in python3

67
Write a Facebook messenger bot in Python3 Jim

Upload: jim-yeh

Post on 21-Apr-2017

198 views

Category:

Engineering


2 download

TRANSCRIPT

Page 1: Write FB Bot in Python3

Write a Facebook messenger bot in Python3

Jim

Page 2: Write FB Bot in Python3

Outline

Some basic knowledges and some requirements

Setup server with FB

Write an echo bot

Further configuration

Page 3: Write FB Bot in Python3

Communicate with FB

FB Server

Page 4: Write FB Bot in Python3

To react with FB, we need a web api server which accept

FB’s message and response to it.

Page 5: Write FB Bot in Python3

Response to a message

FB Server

Page 6: Write FB Bot in Python3

Response to a message

FB Server

Page 7: Write FB Bot in Python3

Response to a message

FB Server My Server

Page 8: Write FB Bot in Python3

Recall

How we get a web page?

We type an url address (ip address) onto the location bar

Chrome sends a request to the server

Server responses us with corresponded return

Page 9: Write FB Bot in Python3

Web server

To finish a web request, you need

An IP address

A Server

Accept HTTP Protocol

Page 10: Write FB Bot in Python3

HTTP

A way to communicate with server

A general way to exchange information

Ask for resources from server (request)

Server returns if a request is valid (response)

Page 11: Write FB Bot in Python3

Request and Response

My ServerGET /index.html

HTML Content

Page 12: Write FB Bot in Python3

Try with command line

$ telnet www.google.com 80

GET / HTTP/1.1

(enter)

Page 13: Write FB Bot in Python3

Methods

GET (Usually used for get web page)

POST (Usually used for submit a form)

Others (PUT, DELETE, OPTION) (Won’t mention today)

Page 14: Write FB Bot in Python3

Parameters

Query string (on the url link)

Form submit body

Raw body <— We will use today

Headers

Page 15: Write FB Bot in Python3

HTTPS

What is HTTPS? HTTP with Secure

Why HTTPS

Make you info secure

Create a security tunnel before data transfer

How to setup it? It’s complicated…

Page 16: Write FB Bot in Python3

API

Application Programming Interface

A way to offer resources

Could be a server or a library

Page 17: Write FB Bot in Python3

Sample codes

https://github.com/lemonlatte/myCurrencyBot

Page 18: Write FB Bot in Python3

Write you own API server

Page 19: Write FB Bot in Python3

Flask

Flask is a simple but flexible and powerful web framework

Strong community support

Page 20: Write FB Bot in Python3

Setup a local environment

$ virtualenv -p python3 .venv

$ . .venv/bin/activate

Page 21: Write FB Bot in Python3

exit

Before this, we need to setup your python environment

$ pip3 install flask

Page 22: Write FB Bot in Python3

First web server

#!/usr/bin/env python

from flask import Flaskfrom flask import abortfrom flask import requestapp = Flask(__name__)

@app.route("/version", methods=['GET'])def version(): if request.method == 'GET': return "0.1" else: abort(404)

if __name__ == "__main__": app.run(port=11123)

Page 23: Write FB Bot in Python3

Try telnet to your web server

$ telnet localhost 11123Trying ::1...Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.GET /version HTTP/1.1

HTTP/1.0 200 OKContent-Type: text/html; charset=utf-8Content-Length: 3Server: Werkzeug/0.12.1 Python/3.5.2Date: Sun, 16 Apr 2017 15:54:35 GMT

0.1Connection closed by foreign host.(enter)

Page 24: Write FB Bot in Python3

Start building a bot

Page 25: Write FB Bot in Python3

Now, we need a web server

FB Server My Server

Page 26: Write FB Bot in Python3

What we have to do?

Set up you account on Facebook

Write a web server

Page 27: Write FB Bot in Python3

1. Go https://developers.facebook.com

2. My Apps —> Add a New App

3. Add Product —> Messenger —> Get Started

4. Setup Webhooks, you need

a. A callback url (require HTTPS)

b. A random string as the token

5. Subscription Fields: messages, messaging_postbacks

How to setup a bot (I)

Page 28: Write FB Bot in Python3

Setup Webhooks

BOT_TOKEN = "your-random-string"

@app.route("/fbCallback", methods=['GET', 'POST'])def fb_cb_handler(): if request.method == 'GET': token = request.args.get('hub.verify_token') if token == BOT_TOKEN: return request.args.get('hub.challenge') else: abort(403) else: abort(405)

Page 29: Write FB Bot in Python3

Echo Bot

A web call accept requests from FB

Parse data from FB

Return a text response to FB

Page 30: Write FB Bot in Python3

How to setup a bot (II)

1. Create a fan page

2. Create a new App in “facebook developers” page

a. Category : Brand or Product / App Page

3. Back to developer page:

a. Generate page access token

b. Subscribe messages from your page

Page 31: Write FB Bot in Python3

Get messages

Page 32: Write FB Bot in Python3

def fb_post_handler(req): print(req.get_data()) resp_body = req.get_json() return ""

@app.route("/fbCallback", methods=['GET', 'POST'])def fb_cb_handler(): if request.method == 'GET': . . . elif request.method == 'POST': return fb_post_handler(request) else: . . .

Page 33: Write FB Bot in Python3

Test - talk to your bot

Page 34: Write FB Bot in Python3

Payload{ "object": "page", "entry": [ { "id": "708403975999401", "time": 1492008179540, "messaging": [ { "sender": { "id": "1433303610077218" }, "recipient": { "id": "708403975999401" }, "timestamp": 1492008179350, "message": { "mid": "mid.$cAAKEShkF7FJhk-NellbYp4VzAIdE", "seq": 105605, "text": "hahaha" } } ] } ]}

Page 35: Write FB Bot in Python3

Send messages

Page 36: Write FB Bot in Python3

Install an additional requirement:

$ pip3 install requests

Page 37: Write FB Bot in Python3

Send text function

import requests

PAGE_TOKEN = "your-page-access-token"FB_MESSENGER_URI = "https://graph.facebook.com/v2.6/me/messages?access_token=" + PAGE_TOKEN

def send_text(reply_token, text): data = { "recipient": {"id": reply_token}, "message": {"text": text} } r = requests.post(FB_MESSENGER_URI, json=data) if r.status_code != requests.codes.ok: print(r.content)

Page 38: Write FB Bot in Python3

Return messages to a user

def fb_post_handler(req): print req.get_data() resp_body = req.get_json()

for entry in resp_body["entry"]: for msg in entry["messaging"]: sender = msg['sender']['id'] if 'message' in msg: if msg['message'].get('is_echo'): return "" if 'text' not in msg[‘message']: return "" text = msg['message']['text'] send_text(sender, text) return ""

Page 39: Write FB Bot in Python3

Test - talk to you bot again

Page 40: Write FB Bot in Python3

Messenger Profile

Facebook provides some API call for us to configure the BOT environment

•Greeting - A help message to show a user what the purpose of the bot is

•Get Started - Setup the postback message when a user is first login

•Persistent Menu

Page 41: Write FB Bot in Python3

Messenger Profile API

POST

https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<your-page-access-token>

A JSON body for the configurations

Page 42: Write FB Bot in Python3

Greeting

curl -X POST \ 'https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<your-page-access-token>' \ -H 'content-type: application/json' \ -d '{ "greeting":[ { "locale":"default", "text":"嗨,我會幫你查匯率"

} ] }'

Page 43: Write FB Bot in Python3

Get Started

curl -X POST \ 'https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<your-page-access-token>' \ -H 'content-type: application/json' \ -d '{ "get_started":{ "payload":"GET_STARTED" }}'

Page 44: Write FB Bot in Python3

POSTBACK

Some user-defined words which represents some kinds of events have been triggered.

For example, once a new user starts chatting with the bot, a predefined postback message will sent to your server.

Page 45: Write FB Bot in Python3

Payload{ "object": "page", "entry": [ { "id": "708403975999401", "time": 1492364568758, "messaging": [ { "recipient": { "id": "708403975999401" }, "timestamp": 1492364568758, "sender": { "id": "1433303610077218" }, "postback": { "payload": "GET_STARTED" } } ] } ]}

Page 46: Write FB Bot in Python3

Handle the POSTBACK

def fb_post_handler(req): print req.get_data() resp_body = req.get_json()

for entry in resp_body["entry"]: for msg in entry["messaging"]: sender = msg['sender']['id'] if 'message' in msg: if msg['message'].get('is_echo'): return "" text = msg['message']['text'] send_text(sender, text) elif 'postback' in msg: if msg['postback']['payload'] == "GET_STARTED": send_text(sender, 'welcome') return ""

Page 47: Write FB Bot in Python3

Send More

Page 48: Write FB Bot in Python3

Generic Template

Generic template is some FB predefined rich message format.

Lists, Images, Buttons

Page 49: Write FB Bot in Python3

Generic Template{ "message": { "attachment": { "type": "template", "payload": { "template_type": "generic", "elements": [ { "title": "BTC - USD", "image_url": "<image url>", "subtitle": "The currency between BTC and USD" } ] } } }}

Page 50: Write FB Bot in Python3

Image

{ "title": "BTC - USD", "image_url": "<image url>", "subtitle": "The currency between BTC and USD"}

Page 51: Write FB Bot in Python3

Send Template Functiondef send_template_message(user_id, elements): data = { "recipient":{ "id": user_id }, "message":{ "attachment": { "type":"template", "payload":{ "template_type":"generic", "elements": elements } } } }

r = requests.post(FB_MESSENGER_URI, json=data) if r.status_code != requests.codes.ok: print(r.content)

Page 52: Write FB Bot in Python3

def fb_post_handler(req): . . . for entry in resp_body["entry"]: for msg in entry["messaging"]: sender = msg['sender']['id'] if 'message' in msg: . . . text = msg['message']['text'] if text == "btcusd": element = [{ "title":"<title>", "image_url":"<url>", "subtitle":"<sub title>" }] send_template_message(sender, element) else: send_text(sender, text) elif 'postback' in msg: . . .

Page 53: Write FB Bot in Python3

Button Types

web_url - an url link

postback - some customized events

Etc.

Page 54: Write FB Bot in Python3

Image with URL Button{ "title": "BTC - USD", "image_url": "<image url>", "subtitle": "The currency between BTC and USD", "buttons": [ { "type": "web_url", "url": "https://btc-e.com/exchange/btc_usd", "title": "View in BTC-E“ } ]}

Page 55: Write FB Bot in Python3

if 'message' in msg: . . . text = msg['message']['text'] if text == "btcusd": element = [{ "title":"<title>", "image_url":"<url>", "subtitle":"<sub title>", "buttons": [ {"type": "web_url", "url": "https://btc-e.com/exchange/btc_usd", "title": "View in BTC-E" } ] }] send_template_message(sender, element) else: send_text(sender, text) elif 'postback' in msg: . . .

Page 56: Write FB Bot in Python3

Image with POSTBACK Button

{ "title": "BTC - USD", "image_url": "<image url>", "subtitle": "The currency between BTC and USD", "buttons": [ { "type": "postback", "payload": "HAHAHA", "title": "Laugh" } ]}

Page 57: Write FB Bot in Python3

def fb_post_handler(req): . . . element = [{ . . . "buttons": [ {"type": "web_url", "url": "", "title": "View in BTC-E" }, {"type": "postback", "payload": "HAHAHA", "title": "Laugh" } ] }] . . . if msg['postback']['payload'] == "GET_STARTED": send_text(sender, 'welcome') elif msg['postback']['payload'] == "HAHAHA": send_text(sender, 'hahaha!') . . .

Page 58: Write FB Bot in Python3

Ask a question

FB can also send some quick answers for a user to select

This is called: quick-replies

Page 59: Write FB Bot in Python3

Quick Replies

"message":{ "text":"Query currency?”, "quick_replies":[ { "content_type":"text", "title":"Yes", "payload":"YES" }, { "content_type":"text", "title":"No", "payload":"NO", } ]}

Page 60: Write FB Bot in Python3

Extend our send_text function

def send_text(reply_token, text, answers): data = { "recipient": {"id": reply_token}, "message": {"text": text} } if answers: data["message"]["quick_replies"] = answers r = requests.post(FB_MESSENGER_URI, json=data) if r.status_code != requests.codes.ok: print(r.content)

def fb_post_handler(req): . . .

send_text(sender, text, None) . . .

Page 61: Write FB Bot in Python3

Send quick replies

. . .elif text == "btcusd": . . .

elif text == "Btc": send_text(sender, "Query currency?", [ {"content_type":"text", "title":"Yes", "payload":"QUERY_CURRENCY" }, {"content_type":"text", "title":"No", "payload":"CANCEL" } ]) . . .

Page 62: Write FB Bot in Python3

Payload{ "object": "page", "entry": [ { "id": "708403975999401", "time": 1492411242498, "messaging": [ { "sender": { "id": "1433303610077218" }, "recipient": { "id": "708403975999401" }, "timestamp": 1492411242366, "message": { "quick_reply": { "payload": "CANCEL" }, "mid": "mid.$cAAKEShkF7FJhq-mfflbeqRWhUtKd", "seq": 106589, "text": "No" } } ] } ]}

Page 63: Write FB Bot in Python3

Handle quick replies response

. . .

if 'message' in msg: if msg['message'].get('is_echo'): return "" if 'text' not in msg['message']: return "" if 'quick_reply' in msg['message']: reply = msg["message"]["quick_reply"] if reply['payload'] == "QUERY_CURRENCY": send_text(sender, "This function is not worked yet.", None) elif reply['payload'] == "CANCEL": send_text(sender, "No problem.", None) return "" text = msg['message']['text'] if text == “btcusd":

. . .

Page 64: Write FB Bot in Python3

Review

Go back to developer page

Submit a review

Make a video

Page 65: Write FB Bot in Python3

Not mentioned

Location

Persistent menu

Lots of advanced features

Page 66: Write FB Bot in Python3

Reference

http://flask.pocoo.org/

https://developers.facebook.com/docs/messenger-platform

http://docs.python-requests.org/en/master/

Page 67: Write FB Bot in Python3

Q & A