Как создать бота для Facebook Messenger на Python Flask

Как создать бота для Facebook Messenger на Python Flask
Сейчас каждый строит своего бота и сегодня мы расскажем как написать бота на Python/Flask. Исходники можно взять здесь.

Мы будем использовать следующие технологии:

  • На бэкенде: Flask
  • Безопасное туннелирование к localhost: Ngrok
  • Платформа обработки естественного языка: API AI
  • Развёртываем в Facebook Messenger
  • Python wrapper для OpenWeatherMap API для погоды


Мы сделаем следующую штуку: запрашиваем у чат-бота погоду в заданном месте, а он отвечает погодной сводкой.

Пример:

Вопрос: What is the current weather of New Delhi? (Какая погода в Нью-Дели?)
Ответ: Current weather report of New Delhi : max temp: 42.0 min temp: 40.0 current temp: 40.95 wind speed :2.6 humidity 20{33d8302486bd10b0fde64d2037652320e6f176a736d71849c0427b0d7398501a} (Погода в Нью-Дели: макс. темп: 42.0 мин. темп: 40.0 текущая темп: 40.95 скорость ветра :2.6 влажность 20{33d8302486bd10b0fde64d2037652320e6f176a736d71849c0427b0d7398501a})

Как создать бота для Facebook Messenger на Python Flask

1. Настраиваем API AI

API AI это платформа для построения приложений, основанных на общении. Зарегистрируйтесь там и создайте агента для доступа к тестовой консоли. Перейдите в настройки агента и получите Client Access Token.

Как создать бота для Facebook Messenger на Python Flask

Создаём intent

Intent (намерение) это связка пользовательского запроса и желаемого ответа. Мы добавим его со следующим пользовательским запросом: «What’s the weather in Singapore?» («Какова погода в Сингапуре?»)

Как создать бота для Facebook Messenger на Python Flask
где Singapore задан как сущность типа @sys.geo-city. Т.е. этот параметр принимает любые запросы в диалоге для построения корректного ответа.

И мы добавим такой ответ на этот запрос: «Current weather report of $geo-city :»

Как создать бота для Facebook Messenger на Python Flask

Python клиент к API AI

Мы будем использовать python SDK API AI для обработки естественного языка.

2. Настраиваем Open Weather Map

У Open Weather Map есть хороший API для доступа к погодным условиям в любой точке планеты. И также есть отличная обёртка на python для этого API. Регистрируйтесь на OWM и получайте свой API ключ для доступа к API погоды.

owm = pyowm.OWM('your_open_weather_map_api_key') # You MUST provide a valid API key

forecast = owm.daily_forecast(input_city)

observation = owm.weather_at_place(input_city)
w = observation.get_weather()
print(w)
print(w.get_wind())
print(w.get_humidity())
max_temp = str(w.get_temperature('celsius')['temp_max'])
min_temp = str(w.get_temperature('celsius')['temp_min'])
current_temp = str(w.get_temperature('celsius')['temp'])
wind_speed = str(w.get_wind()['speed'])
humidity = str(w.get_humidity())

Если же у вас есть PRO-подписка, запрос будет немного другим:

owm = pyowm.OWM(API_key='your-API-key', subscription_type='pro')

3. Создаём Flask Server

import apiai
Добавляем все токены и верифицируем их:

CLIENT_ACCESS_TOKEN = 'your_client_access_token_from_api_ai'
PAGE_ACCESS_TOKEN = 'your_facebook_page_access_token'
VERIFY_TOKEN = 'verification_token_for_facebook_chatbot_using_python'

ai = apiai.ApiAI(CLIENT_ACCESS_TOKEN)
Теперь нужно отправить запрос к Facebook webhook от приложения с проверкой корректности токена, заданного в приложении facebook:

@app.route('/', methods=['GET'])
def handle_verification():
if (request.args.get('hub.verify_token', '') == VERIFY_TOKEN):
print("Verified")
return request.args.get('hub.challenge', '')
else:
print("Wrong token")
return "Error, wrong validation token"

Приложение будет обрабатывать все сообщения от facebook messenger

@app.route('/', methods=['POST'])
def handle_message():
'''
Handle messages sent by facebook messenger to the applicaiton
'''
data = request.get_json()

if data["object"] == "page":
for entry in data["entry"]:
for messaging_event in entry["messaging"]:
if messaging_event.get("message"):

sender_id = messaging_event["sender"]["id"]
recipient_id = messaging_event["recipient"]["id"]
message_text = messaging_event["message"]["text"]
send_message_response(sender_id, parse_natural_text(message_text))

return "ok"
Вызовем facebook Graph API с помощью библиотеки python requests для отправки сообщения пользователю facebook

def send_message(sender_id, message_text):
'''
Sending response back to the user using facebook graph API
'''
r = requests.post("https://graph.facebook.com/v2.6/me/messages",

params={"access_token": PAGE_ACCESS_TOKEN},

headers={"Content-Type": "application/json"},

data=json.dumps({
"recipient": {"id": sender_id},
"message": {"text": message_text}
}))

Используем API AI для разбора сообщения от пользователя, получим ответ боту от API AI. Затем получаем погодные данные от open weather map и добавляем их к ответу бота

def parse_user_text(user_text):

'''
Send the message to API AI which invokes an intent
and sends the response accordingly
The bot response is appened with weaher data fetched from
open weather map client
'''

request = ai.text_request()
request.query = user_text

response = json.loads(request.getresponse().read().decode('utf-8'))
responseStatus = response['status']['code']
if (responseStatus == 200):
print("Bot response", response['result']['fulfillment']['speech'])

weather_report = ''

input_city = response['result']['parameters']['geo-city']

#Fetching weather data
owm = pyowm.OWM('edd197717da7951b85f8f6936fc27b13') # You MUST provide a valid API key

forecast = owm.daily_forecast(input_city)

observation = owm.weather_at_place(input_city)
w = observation.get_weather()
print(w)
print(w.get_wind())
print(w.get_humidity())
max_temp = str(w.get_temperature('celsius')['temp_max'])
min_temp = str(w.get_temperature('celsius')['temp_min'])
current_temp = str(w.get_temperature('celsius')['temp'])
wind_speed = str(w.get_wind()['speed'])
humidity = str(w.get_humidity())
weather_report = ' max temp: ' + max_temp + ' min temp: ' + min_temp + ' current temp: ' + current_temp + ' wind speed :' + wind_speed + ' humidity ' + humidity + '{33d8302486bd10b0fde64d2037652320e6f176a736d71849c0427b0d7398501a}'
print("Weather report ", weather_report)
return (response['result']['fulfillment']['speech'] + weather_report)
else:
return ("Please try again")

def send_message_response(sender_id, message_text):
sentenceDelimiter = ". "
messages = message_text.split(sentenceDelimiter)

for message in messages:
send_message(sender_id, message)

if __name__ == '__main__':
app.run()

Активируйте виртуальную среду, установите необходимые пакеты

pip install -r requirements.txt
Запустите скрипт

python fb-chatbot.py

Настраиваем теннелирование к localhost

Для вывода локального сервера в интернет мы воспользуемся утилитой ngrok, с помощью которой к нему можно будет достучаться через webhook от приложения facebook

sudo apt-get update
sudo apt-get install ngrok-client

Запустим клиента

./ngrok http -bind-tls=true 5000
Помните, что secure callback URL (https) нужен для верификации.

Настраиваем facebook messenger

Создайте страницу facebook и приложение facebook. Добавьте Webhook к приложению.

Как создать бота для Facebook Messenger на Python Flask
Получите ID приложения и обновите его в скрипте.

Добавьте Messenger к приложению и создайте token для страницы, которую будете использовать для чата.

Как создать бота для Facebook Messenger на Python Flask
Включите интеграцию webhook с callback URL и верифицируйте token

Как создать бота для Facebook Messenger на Python Flask
Задайте события в подписке на странице

Как создать бота для Facebook Messenger на Python Flask
Перезапустите сервер и чатбот готов. Также Facebook предоставляет дополнительные элементы пользовательского интерфейса, потестировать их можно здесь.

По материалам «How to Create a Facebook Messenger Bot with Python Flask»

Leave a Comment