SlideShare a Scribd company logo
1 of 67
Download to read offline
Write a Facebook
messenger bot in Python3
Jim
Outline
Some basic knowledges and some
requirements
Setup server with FB
Write an echo bot
Further configuration
Communicate with FB
FB Server
To react with FB, we need a
web api server which accept
FB’s message and response to it.
Response to a message
FB Server
Response to a message
FB Server
Response to a message
FB Server My Server
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
Web server
To finish a web request, you need
An IP address
A Server
Accept HTTP Protocol
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)
Request and Response
My ServerGET /index.html
HTML Content
Try with command line
$ telnet www.google.com 80
GET / HTTP/1.1
(enter)
Methods
GET (Usually used for get web page)
POST (Usually used for submit a form)
Others (PUT, DELETE, OPTION)

(Won’t mention today)
Parameters
Query string (on the url link)
Form submit body
Raw body <— We will use today
Headers
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…
API
Application Programming Interface
A way to offer resources
Could be a server or a library
Sample codes
https://github.com/lemonlatte/
myCurrencyBot
Write you own API server
Flask
Flask is a simple but flexible and
powerful web framework
Strong community support
Setup a local environment
$ virtualenv -p python3 .venv
$ . .venv/bin/activate
exit
Before this, we need to setup your python
environment
$ pip3 install flask
First web server
#!/usr/bin/env python
from flask import Flask
from flask import abort
from flask import request
app = 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)
Try telnet to your web
server
$ telnet localhost 11123
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /version HTTP/1.1
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 3
Server: Werkzeug/0.12.1 Python/3.5.2
Date: Sun, 16 Apr 2017 15:54:35 GMT
0.1Connection closed by foreign host.
(enter)
Start building a bot
Now, we need a web
server
FB Server My Server
What we have to do?
Set up you account on Facebook
Write a web server
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)
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)
Echo Bot
A web call accept requests from FB
Parse data from FB
Return a text response to FB
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
Get messages
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:
. . .
Test - talk to your bot
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"
}
}
]
}
]
}
Send messages
Install an additional requirement:
$ pip3 install requests
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)
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 ""
Test - talk to you bot again
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
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
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":"嗨,我會幫你查匯率"
}
]
}'
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"
}
}'
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.
Payload
{
"object": "page",
"entry": [
{
"id": "708403975999401",
"time": 1492364568758,
"messaging": [
{
"recipient": {
"id": "708403975999401"
},
"timestamp": 1492364568758,
"sender": {
"id": "1433303610077218"
},
"postback": {
"payload": "GET_STARTED"
}
}
]
}
]
}
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 ""
Send More
Generic Template
Generic template is some FB predefined
rich message format.
Lists, Images, Buttons
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"
}
]
}
}
}
}
Image
{
"title": "BTC - USD",
"image_url": "<image url>",
"subtitle": "The currency between BTC and USD"
}
Send Template Function
def 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)
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:
. . .
Button Types
web_url - an url link
postback - some customized events
Etc.
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“
}
]
}
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:
. . .
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"
}
]
}
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!')
. . .
Ask a question
FB can also send some quick answers for
a user to select
This is called: quick-replies
Quick Replies
"message":{
"text":"Query currency?”,
"quick_replies":[
{
"content_type":"text",
"title":"Yes",
"payload":"YES"
},
{
"content_type":"text",
"title":"No", 

"payload":"NO",
}
]
}
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)
. . .
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"
}
])
. . .
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"
}
}
]
}
]
}
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":
. . .
Review
Go back to developer page
Submit a review
Make a video
Not mentioned
Location
Persistent menu
Lots of advanced features
Reference
http://flask.pocoo.org/
https://developers.facebook.com/docs/
messenger-platform
http://docs.python-requests.org/en/
master/
Q & A

More Related Content

What's hot

Sps mad2019 es el momento, empieza a desarrollar para microsoft teams
Sps mad2019   es el momento, empieza a desarrollar para microsoft teams Sps mad2019   es el momento, empieza a desarrollar para microsoft teams
Sps mad2019 es el momento, empieza a desarrollar para microsoft teams Ruben Ramos
 
Introduction to Google API - Focusky
Introduction to Google API - FocuskyIntroduction to Google API - Focusky
Introduction to Google API - FocuskyFocusky Presentation
 
Common Gateway Interface
Common Gateway InterfaceCommon Gateway Interface
Common Gateway InterfaceBalu Masulkar
 
Class 6 - PHP Web Programming
Class 6 - PHP Web ProgrammingClass 6 - PHP Web Programming
Class 6 - PHP Web ProgrammingAhmed Swilam
 
Web Development Course: PHP lecture 3
Web Development Course: PHP lecture 3Web Development Course: PHP lecture 3
Web Development Course: PHP lecture 3Gheyath M. Othman
 
PHP and MySQL PHP Written as a set of CGI binaries in C in ...
PHP and MySQL PHP Written as a set of CGI binaries in C in ...PHP and MySQL PHP Written as a set of CGI binaries in C in ...
PHP and MySQL PHP Written as a set of CGI binaries in C in ...webhostingguy
 
Services web RESTful
Services web RESTfulServices web RESTful
Services web RESTfulgoldoraf
 
Handle complex POST/PATCH requests in RESTful API
Handle complex POST/PATCH requests in RESTful APIHandle complex POST/PATCH requests in RESTful API
Handle complex POST/PATCH requests in RESTful APIfightmaster
 
Sending E-mail that reaches the destination using PHP
Sending E-mail that reaches the destination using PHPSending E-mail that reaches the destination using PHP
Sending E-mail that reaches the destination using PHPManuel Lemos
 
Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1Gheyath M. Othman
 
Build PHP Search Engine
Build PHP Search EngineBuild PHP Search Engine
Build PHP Search EngineKiril Iliev
 
Webservice for android ppt
Webservice for android pptWebservice for android ppt
Webservice for android pptsantosh lamba
 
Php file upload, cookies & session
Php file upload, cookies & sessionPhp file upload, cookies & session
Php file upload, cookies & sessionJamshid Hashimi
 
Php Tutorial | Introduction Demo | Basics
 Php Tutorial | Introduction Demo | Basics Php Tutorial | Introduction Demo | Basics
Php Tutorial | Introduction Demo | BasicsShubham Kumar Singh
 
JSON-RPC Proxy Generation with PHP 5
JSON-RPC Proxy Generation with PHP 5JSON-RPC Proxy Generation with PHP 5
JSON-RPC Proxy Generation with PHP 5Stephan Schmidt
 

What's hot (19)

Sps mad2019 es el momento, empieza a desarrollar para microsoft teams
Sps mad2019   es el momento, empieza a desarrollar para microsoft teams Sps mad2019   es el momento, empieza a desarrollar para microsoft teams
Sps mad2019 es el momento, empieza a desarrollar para microsoft teams
 
Introduction to Google API - Focusky
Introduction to Google API - FocuskyIntroduction to Google API - Focusky
Introduction to Google API - Focusky
 
Common Gateway Interface
Common Gateway InterfaceCommon Gateway Interface
Common Gateway Interface
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
Web Scraping with PHP
Web Scraping with PHPWeb Scraping with PHP
Web Scraping with PHP
 
Class 6 - PHP Web Programming
Class 6 - PHP Web ProgrammingClass 6 - PHP Web Programming
Class 6 - PHP Web Programming
 
Web Development Course: PHP lecture 3
Web Development Course: PHP lecture 3Web Development Course: PHP lecture 3
Web Development Course: PHP lecture 3
 
PHP and MySQL PHP Written as a set of CGI binaries in C in ...
PHP and MySQL PHP Written as a set of CGI binaries in C in ...PHP and MySQL PHP Written as a set of CGI binaries in C in ...
PHP and MySQL PHP Written as a set of CGI binaries in C in ...
 
Services web RESTful
Services web RESTfulServices web RESTful
Services web RESTful
 
Handle complex POST/PATCH requests in RESTful API
Handle complex POST/PATCH requests in RESTful APIHandle complex POST/PATCH requests in RESTful API
Handle complex POST/PATCH requests in RESTful API
 
MWLUG 2017 - Elementary!
MWLUG 2017 - Elementary!MWLUG 2017 - Elementary!
MWLUG 2017 - Elementary!
 
Sending E-mail that reaches the destination using PHP
Sending E-mail that reaches the destination using PHPSending E-mail that reaches the destination using PHP
Sending E-mail that reaches the destination using PHP
 
File Upload
File UploadFile Upload
File Upload
 
Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1Web Development Course: PHP lecture 1
Web Development Course: PHP lecture 1
 
Build PHP Search Engine
Build PHP Search EngineBuild PHP Search Engine
Build PHP Search Engine
 
Webservice for android ppt
Webservice for android pptWebservice for android ppt
Webservice for android ppt
 
Php file upload, cookies & session
Php file upload, cookies & sessionPhp file upload, cookies & session
Php file upload, cookies & session
 
Php Tutorial | Introduction Demo | Basics
 Php Tutorial | Introduction Demo | Basics Php Tutorial | Introduction Demo | Basics
Php Tutorial | Introduction Demo | Basics
 
JSON-RPC Proxy Generation with PHP 5
JSON-RPC Proxy Generation with PHP 5JSON-RPC Proxy Generation with PHP 5
JSON-RPC Proxy Generation with PHP 5
 

Similar to Write FB Bot in Python3

Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4DEVCON
 
Rpi python web
Rpi python webRpi python web
Rpi python websewoo lee
 
CHATBOT using Facebook Messenger
CHATBOT using Facebook MessengerCHATBOT using Facebook Messenger
CHATBOT using Facebook MessengerNavjyotsinh Jadeja
 
Python Google Cloud Function with CORS
Python Google Cloud Function with CORSPython Google Cloud Function with CORS
Python Google Cloud Function with CORSRapidValue
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代Shengyou Fan
 
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + BallerinaWSO2
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4DEVCON
 
The Django Book - Chapter 7 forms
The Django Book - Chapter 7 formsThe Django Book - Chapter 7 forms
The Django Book - Chapter 7 formsVincent Chien
 
PSR-7 - HTTP message interfaces
PSR-7 - HTTP message interfacesPSR-7 - HTTP message interfaces
PSR-7 - HTTP message interfacesThe Software House
 
[2019 south bay meetup] Building more contextual message with Block Kit
[2019 south bay meetup] Building more contextual message with Block Kit[2019 south bay meetup] Building more contextual message with Block Kit
[2019 south bay meetup] Building more contextual message with Block KitTomomi Imura
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersAaron Patterson
 
Creating Chatbots with Botman - English
Creating Chatbots with Botman - EnglishCreating Chatbots with Botman - English
Creating Chatbots with Botman - EnglishLaravel Poland MeetUp
 
Laravel Poznań Meetup #2 - Creating chatbots with BotMan
Laravel Poznań Meetup #2 - Creating chatbots with BotManLaravel Poznań Meetup #2 - Creating chatbots with BotMan
Laravel Poznań Meetup #2 - Creating chatbots with BotManHighSolutions Sp. z o.o.
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.jsAdrien Guéret
 
HTTP fundamentals for developers
HTTP fundamentals for developersHTTP fundamentals for developers
HTTP fundamentals for developersMario Cardinal
 
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés RianchoCODE BLUE
 

Similar to Write FB Bot in Python3 (20)

Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4Python Code Camp for Professionals 4/4
Python Code Camp for Professionals 4/4
 
Rpi python web
Rpi python webRpi python web
Rpi python web
 
CHATBOT using Facebook Messenger
CHATBOT using Facebook MessengerCHATBOT using Facebook Messenger
CHATBOT using Facebook Messenger
 
Pyramid REST
Pyramid RESTPyramid REST
Pyramid REST
 
Python Google Cloud Function with CORS
Python Google Cloud Function with CORSPython Google Cloud Function with CORS
Python Google Cloud Function with CORS
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
 
Web 11 | AJAX + JSON + PHP
Web 11 | AJAX + JSON + PHPWeb 11 | AJAX + JSON + PHP
Web 11 | AJAX + JSON + PHP
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
 
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 
The Django Book - Chapter 7 forms
The Django Book - Chapter 7 formsThe Django Book - Chapter 7 forms
The Django Book - Chapter 7 forms
 
Flask-Python
Flask-PythonFlask-Python
Flask-Python
 
PSR-7 - HTTP message interfaces
PSR-7 - HTTP message interfacesPSR-7 - HTTP message interfaces
PSR-7 - HTTP message interfaces
 
[2019 south bay meetup] Building more contextual message with Block Kit
[2019 south bay meetup] Building more contextual message with Block Kit[2019 south bay meetup] Building more contextual message with Block Kit
[2019 south bay meetup] Building more contextual message with Block Kit
 
Ruby on Rails: Tasty Burgers
Ruby on Rails: Tasty BurgersRuby on Rails: Tasty Burgers
Ruby on Rails: Tasty Burgers
 
Creating Chatbots with Botman - English
Creating Chatbots with Botman - EnglishCreating Chatbots with Botman - English
Creating Chatbots with Botman - English
 
Laravel Poznań Meetup #2 - Creating chatbots with BotMan
Laravel Poznań Meetup #2 - Creating chatbots with BotManLaravel Poznań Meetup #2 - Creating chatbots with BotMan
Laravel Poznań Meetup #2 - Creating chatbots with BotMan
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.js
 
HTTP fundamentals for developers
HTTP fundamentals for developersHTTP fundamentals for developers
HTTP fundamentals for developers
 
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
 

More from Jim Yeh

Introduction openstack horizon
Introduction openstack horizonIntroduction openstack horizon
Introduction openstack horizonJim Yeh
 
Web develop in flask
Web develop in flaskWeb develop in flask
Web develop in flaskJim Yeh
 
Git tutorial II
Git tutorial IIGit tutorial II
Git tutorial IIJim Yeh
 
Git Tutorial I
Git Tutorial IGit Tutorial I
Git Tutorial IJim Yeh
 
Introduction to docker
Introduction to dockerIntroduction to docker
Introduction to dockerJim Yeh
 
Dive into Python Class
Dive into Python ClassDive into Python Class
Dive into Python ClassJim Yeh
 

More from Jim Yeh (6)

Introduction openstack horizon
Introduction openstack horizonIntroduction openstack horizon
Introduction openstack horizon
 
Web develop in flask
Web develop in flaskWeb develop in flask
Web develop in flask
 
Git tutorial II
Git tutorial IIGit tutorial II
Git tutorial II
 
Git Tutorial I
Git Tutorial IGit Tutorial I
Git Tutorial I
 
Introduction to docker
Introduction to dockerIntroduction to docker
Introduction to docker
 
Dive into Python Class
Dive into Python ClassDive into Python Class
Dive into Python Class
 

Recently uploaded

High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxthe ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxhumanexperienceaaa
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)Suman Mia
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escortsranjana rawat
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...ranjana rawat
 
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVRajaP95
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxAsutosh Ranjan
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxpurnimasatapathy1234
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingrknatarajan
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Dr.Costas Sachpazis
 
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...Call girls in Ahmedabad High profile
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxupamatechverse
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSSIVASHANKAR N
 

Recently uploaded (20)

★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
★ CALL US 9953330565 ( HOT Young Call Girls In Badarpur delhi NCR
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptxthe ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
the ladakh protest in leh ladakh 2024 sonam wangchuk.pptx
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptx
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
 
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
High Profile Call Girls Dahisar Arpita 9907093804 Independent Escort Service ...
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptx
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 

Write FB Bot in Python3

  • 1. Write a Facebook messenger bot in Python3 Jim
  • 2. Outline Some basic knowledges and some requirements Setup server with FB Write an echo bot Further configuration
  • 4. To react with FB, we need a web api server which accept FB’s message and response to it.
  • 5. Response to a message FB Server
  • 6. Response to a message FB Server
  • 7. Response to a message FB Server My Server
  • 8. 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
  • 9. Web server To finish a web request, you need An IP address A Server Accept HTTP Protocol
  • 10. 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)
  • 11. Request and Response My ServerGET /index.html HTML Content
  • 12. Try with command line $ telnet www.google.com 80 GET / HTTP/1.1 (enter)
  • 13. Methods GET (Usually used for get web page) POST (Usually used for submit a form) Others (PUT, DELETE, OPTION)
 (Won’t mention today)
  • 14. Parameters Query string (on the url link) Form submit body Raw body <— We will use today Headers
  • 15. 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…
  • 16. API Application Programming Interface A way to offer resources Could be a server or a library
  • 18. Write you own API server
  • 19. Flask Flask is a simple but flexible and powerful web framework Strong community support
  • 20. Setup a local environment $ virtualenv -p python3 .venv $ . .venv/bin/activate
  • 21. exit Before this, we need to setup your python environment $ pip3 install flask
  • 22. First web server #!/usr/bin/env python from flask import Flask from flask import abort from flask import request app = 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)
  • 23. Try telnet to your web server $ telnet localhost 11123 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET /version HTTP/1.1 HTTP/1.0 200 OK Content-Type: text/html; charset=utf-8 Content-Length: 3 Server: Werkzeug/0.12.1 Python/3.5.2 Date: Sun, 16 Apr 2017 15:54:35 GMT 0.1Connection closed by foreign host. (enter)
  • 25. Now, we need a web server FB Server My Server
  • 26. What we have to do? Set up you account on Facebook Write a web server
  • 27. 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)
  • 28. 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)
  • 29. Echo Bot A web call accept requests from FB Parse data from FB Return a text response to FB
  • 30. 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
  • 32. 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: . . .
  • 33. Test - talk to your bot
  • 34. 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" } } ] } ] }
  • 36. Install an additional requirement: $ pip3 install requests
  • 37. 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)
  • 38. 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 ""
  • 39. Test - talk to you bot again
  • 40. 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
  • 42. 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":"嗨,我會幫你查匯率" } ] }'
  • 43. 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" } }'
  • 44. 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.
  • 45. Payload { "object": "page", "entry": [ { "id": "708403975999401", "time": 1492364568758, "messaging": [ { "recipient": { "id": "708403975999401" }, "timestamp": 1492364568758, "sender": { "id": "1433303610077218" }, "postback": { "payload": "GET_STARTED" } } ] } ] }
  • 46. 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 ""
  • 48. Generic Template Generic template is some FB predefined rich message format. Lists, Images, Buttons
  • 49. 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" } ] } } } }
  • 50. Image { "title": "BTC - USD", "image_url": "<image url>", "subtitle": "The currency between BTC and USD" }
  • 51. Send Template Function def 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)
  • 52. 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: . . .
  • 53. Button Types web_url - an url link postback - some customized events Etc.
  • 54. 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“ } ] }
  • 55. 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: . . .
  • 56. 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" } ] }
  • 57. 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!') . . .
  • 58. Ask a question FB can also send some quick answers for a user to select This is called: quick-replies
  • 60. 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) . . .
  • 61. 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" } ]) . . .
  • 62. 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" } } ] } ] }
  • 63. 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": . . .
  • 64. Review Go back to developer page Submit a review Make a video
  • 67. Q & A