Статьи

Создание чата на Facebook с Node и Heroku

Создание бота в чате Facebook с Node и Heroku было рецензировано Джоан Инь и Камило Рейесом . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Мужчина и его бот-чат из Facebook сидят на диване и смотрят «Метрополис»

На прошлогодней конференции f8 Facebook запустил платформу Messenger , предоставив разработчикам возможность создавать ботов, которые могли бы общаться с людьми в Messenger или со страницы Facebook. С помощью ботов владельцы приложений могут лучше взаимодействовать со своими пользователями, обеспечивая персонализированное и интерактивное общение, которое может масштабироваться для масс. С момента запуска компании и владельцы приложений проявили большой интерес к чат-ботам. Всего через три месяца после объявления на платформе было построено около 11 000 ботов .

Компании и владельцы приложений не единственные, кто получает выгоду от чат-ботов. Пользователи этих ботов могут пользоваться множеством услуг, таких как:

В настоящее время интерес к чат-ботам и их привлекательность очевидны, и по мере совершенствования технологии искусственного интеллекта боты будут лучше взаимодействовать с пользователями.

В этой статье мы рассмотрим, как создать чат-бота Facebook, который может взаимодействовать с пользователями через Messenger от имени страницы Facebook. Мы создадим бота, который предоставит пользователю различные детали относительно фильма, который он указал.

Нужно ли знать ИИ, чтобы построить бота?

Навык в искусстве ИИ, безусловно, поможет, особенно в создании сложных ботов, но это не обязательно. Конечно, вы можете построить бот, не зная машинного обучения.

Есть два типа ботов, которые вы можете построить. Один основан на наборе правил, а другой использует машинное обучение. Первый ограничен во взаимодействиях, которые он может предложить. Он может отвечать только на конкретные команды. Это тот тип бота, который мы будем строить.

С ботами, которые используют машинное обучение, вы получаете лучшее взаимодействие с пользователем. Пользователь может взаимодействовать с ботом более естественным образом, как при взаимодействии человека с человеком, а не просто с помощью команд. Бот также становится умнее, поскольку он учится на разговорах с людьми. Мы оставим создание этого типа бота для будущей статьи. Тем не менее, знание машинного обучения не потребуется. К счастью для нас, есть такие сервисы, как wit.ai и Api.ai, которые позволяют разработчикам интегрировать машинное обучение (в частности, Natural Language Processing — NLP) в свои приложения.

Начиная

Вы можете скачать код для готового демо-приложения здесь .

Чтобы ваш чат-бот общался с пользователями Facebook, нам нужно настроить сервер, который будет принимать, обрабатывать и отправлять сообщения. Для этого сервер будет использовать API Graph Facebook. Graph API — это основной способ получения данных с платформы Facebook. На сервере должен быть URL-адрес конечной точки, доступный с серверов Facebook, поэтому развертывание веб-приложения на локальном компьютере не будет работать, его необходимо подключить к сети. Кроме того, начиная с версии 2.5 Graph API, новые подписки на службу должны использовать защищенный URL-адрес обратного вызова HTTPS. В этом руководстве мы развернем приложение на Heroku, поскольку все домены appname.herokuapp.com умолчанию уже поддерживают SSL. Мы будем использовать Node.js для создания веб-приложения.

Для начала убедитесь, что Node установлен на вашем компьютере. Вы можете проверить это, набрав node -v в Терминале. Если установлено, будет выведен номер версии. Затем установите интерфейс командной строки Heroku (CLI). Мы будем использовать это позже, чтобы отправить приложение в Heroku. Используйте heroku --version чтобы убедиться, что CLI установлен.

Создайте каталог проекта и инициализируйте файл package.json с помощью следующих команд.

 $ mkdir spbot $ cd spbot $ npm init 

Следуйте инструкциям, чтобы установить свои предпочтения для проекта.

После того как файл package.json создан, откройте его и добавьте свойство start к объекту scripts . Это позволяет Heroku знать, какую команду выполнить для запуска приложения. Во время настройки проекта я определил app.js как точку входа в приложение, поэтому я использую node app.js в качестве значения start . Измените это в соответствии с настройками вашего проекта.

 { "name": "spbot", "version": "1.0.0", "description": "SPBot Server", "main": "app.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node app.js" }, "author": , "license": "ISC" } 

Установите следующие пакеты Node.

 $ npm install express request body-parser mongoose --save 

Создайте файл .gitignore в корневом каталоге вашего проекта и node_modules папку node_modules , чтобы предотвратить его node_modules .

 node_modules 

В корневом каталоге вашего проекта создайте файл с app.js (или index.js , если вы index.js имя по умолчанию). Измените это как показано:

 var express = require("express"); var request = require("request"); var bodyParser = require("body-parser"); var app = express(); app.use(bodyParser.urlencoded({extended: false})); app.use(bodyParser.json()); app.listen((process.env.PORT || 5000)); // Server index page app.get("/", function (req, res) { res.send("Deployed!"); }); // Facebook Webhook // Used for verification app.get("/webhook", function (req, res) { if (req.query["hub.verify_token"] === "this_is_my_token") { console.log("Verified webhook"); res.status(200).send(req.query["hub.challenge"]); } else { console.error("Verification failed. The tokens do not match."); res.sendStatus(403); } }); 

Первый обработчик GET предназначен для нашего собственного тестирования — чтобы узнать, было ли приложение успешно развернуто. Второй обработчик GET — это конечная точка, которую Facebook будет использовать для проверки приложения. Код должен искать verify_token и отвечать запросом, отправленным в запросе проверки.

Вы можете вставить свой собственный токен в код. Такие данные лучше всего сохранять в переменной среды , что мы сделаем вскоре после создания проекта в Heroku.

Развертывание в Heroku

Для того чтобы платформа Facebook могла подключиться к нашему бэкэнд-приложению, нам нужно сначала подключить его к сети.

Создайте Git-репозиторий и зафиксируйте файлы проекта с помощью следующих команд:

 $ git init $ git add . $ git commit -m "Initial commit" 

Зарегистрируйте бесплатную учетную запись Heroku, если у вас ее еще нет.

С вашего терминала войдите в Heroku и создайте приложение.

 $ heroku login $ heroku create $ git push heroku master $ heroku open 

При запуске команды heroku open в браузере по умолчанию будет открыта ссылка на запущенное приложение. Если все прошло хорошо, вы получите страницу с текстом Deployed! в теме.

Создание переменных среды

Прежде чем мы продолжим, давайте создадим переменную среды в Heroku для хранения токена проверки приложения.

Откройте панель управления Heroku и выберите приложение, которое вы только что развернули. Перейдите в настройки приложения и нажмите кнопку « Показать настройки» . Введите VERIFICATION_TOKEN в качестве ключа и свой токен в качестве значения и нажмите кнопку Добавить .

Создать Heroku Config Var

В своем коде измените строку токена ( "this_is_my_token" ) на process.env.VERIFICATION_TOKEN . Зафиксируйте свои изменения и отправьте их в Heroku.

Создать страницу Facebook и приложение

После запуска и запуска сервера мы создадим приложение Facebook и страницу, с которой он будет связан. Вы можете создать новую страницу или использовать существующую.

Чтобы создать страницу Facebook, войдите в Facebook и перейдите на страницу «Создание страницы» . Выберите тип страницы из предложенных вариантов. Я выбрал Развлечения .

Снимок экрана параметров "Создать страницу", показывающий шесть различных типов страниц

Затем выберите категорию и имя для страницы.

Снимок экрана

После нажатия кнопки «Начать» будет создана страница, и вам будет предложено узнать больше информации о вашем приложении (описание, веб-сайт, изображение профиля, целевая аудитория и т. Д.). Вы можете пропустить эти шаги настройки сейчас.

скриншот недавно созданной страницы Facebook

Чтобы создать приложение Facebook, перейдите на страницу « Добавить новое приложение» и нажмите ссылку базовой настройки под другими вариантами платформы.

Снимок экрана страницы "Добавить новое приложение" с предложением выбрать платформу

Заполните необходимые детали. Выберите Приложения для страниц в качестве категории.

Снимок экрана формы "Создать новый идентификатор приложения"

При нажатии кнопки « Создать идентификатор приложения» откроется панель приложения.

Снимок экрана: панель инструментов приложения

В разделе « Настройка продукта» справа нажмите « Начало работы» в разделе « Messenger ». После этого вы попадете на страницу настроек Messenger, показанную ниже.

Снимок экрана со страницей настроек Facebook Messenger

Чтобы получать сообщения и другие события, отправленные пользователями Messenger, приложение должно включать интеграцию с веб-крючками. Мы сделаем это дальше. Webhooks (ранее обновления в реальном времени ) позволяют подписываться на изменения, которые вы хотите отслеживать, и получать обновления в режиме реального времени без необходимости вызова API.

В разделе Webhooks нажмите Setup Webhooks

Введите URL-адрес обратного вызова, на который будут отправляться обновления (URL-адрес конечной точки, определенный в бэкэнд-приложении, т. <your-app-url>/webhook ), введите <your-app-url>/webhook (токен, используемый в бэкэнд-приложении, то есть значение, сохраненное в process.env.VERIFICATION_TOKEN ) и установите все флажки. Они определяют, на какие события будет подписано приложение. Мы увидим, что они делают чуть позже.

Настройки Webhook

При успешном включении веб-хука вы должны увидеть « Завершено» в разделе «Веб-хуки» и список событий, на которые подписаны. Если вы получили сообщение об ошибке, убедитесь, что вы ввели правильный URL-адрес для конечной точки webhook (оканчивающийся на /webhook ), а также убедитесь, что используемый здесь токен тот же, который вы использовали в приложении Node.

Панель Webhooks с сообщением «завершено»

В разделе Token Generation выберите свою страницу из выпадающего меню. После аутентификации для вас будет сгенерирован токен доступа к странице.

Раздел создания токенов, отображающий токен доступа к странице

Создайте в Heroku еще одну переменную среды и установите для ее ключа значение PAGE_ACCESS_TOKEN а сгенерированный токен — в качестве значения . Обратите внимание, что сгенерированный токен не будет сохранен на текущей странице, на которой он отображается в Facebook. Каждый раз, когда вы переходите на эту веб-страницу, поле «Токен доступа к странице» будет пустым, и при выборе страницы «Facebook» в раскрывающемся меню «Страница» будет сгенерирован новый токен. Однако все предыдущие созданные токены будут продолжать работать. Поэтому убедитесь, что вы скопировали токен перед закрытием веб-страницы.

Чтобы ваш webhook мог получать события для определенной страницы, вы должны подписать свое приложение на эту страницу. В разделе Webhooks выберите страницу для подписки.

Подписаться Webhook на страницу событий

Экран приветствия

Когда пользователь начинает новый разговор с вашим ботом, первое, что он увидит, это экран приветствия. Этот экран покажет название вашей страницы, описание, изображение профиля и фотографию обложки. Вы можете настроить экран, установив текст приветствия, который будет использоваться вместо описания страницы. Вы можете использовать это, чтобы установить вводное сообщение, которое сообщит пользователю, чего ожидать от вашего бота.

По умолчанию, чтобы начать разговор, именно пользователь отправляет первое сообщение вашему боту. Однако вы можете включить кнопку «Начать», которая позволит вашему боту отправлять начальное сообщение. Кнопка отправит на ваш сервер событие, на которое вы сможете ответить.

Чтобы установить текст приветствия, откройте страницу и перейдите к ее настройкам .

Настройки страницы

Выберите « Сообщения» на левой панели, а затем включите « Показать приветствие Messenger» на правой панели. Установите сообщение по своему вкусу.

Настроить текст приветствия

Чтобы активировать кнопку «Начало работы», замените строку PAGE_ACCESS_TOKEN в следующей инструкции токеном и вставьте команду в Терминал.

 curl -X POST -H "Content-Type: application/json" -d '{ "setting_type":"call_to_actions", "thread_state":"new_thread", "call_to_actions":[ { "payload":"Greeting" } ] }' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=PAGE_ACCESS_TOKEN" 

Выше делается запрос к API Graph Facebook. Если запрос выполнен успешно, кнопка «Начало работы» появится на экране приветствия нового разговора. Пользователь, нажав на кнопку, активирует ответный обратный вызов. Ваш бот может ответить на этот постбэк.

Обратная передача может быть инициирована различными типами компонентов — кнопкой обратной передачи, кнопкой «Начало работы», постоянным меню или структурированным сообщением. Вы можете установить любую строку в качестве payload . На сервере мы будем использовать эту строку для идентификации обратной передачи, отправленной в результате нажатия кнопки «Начать». Чтобы получать сообщения обратной передачи, ваше приложение должно быть подписано на обратную передачу в вашем веб-крюке. Мы сделали это ранее, установив флажок messaging_postbacks при настройке webhook.

Если кнопка Get Started успешно установлена, вы получите следующий ответ.

 { "result": "Successfully added new_thread's CTAs" } 

Помните, что экран приветствия и кнопка « Начало работы» отображаются только для новых разговоров. При кодировании и тестировании вашего бота вы можете начать новый разговор, удалив текущий.

Чтобы обработать сообщение обратной передачи, вставьте следующее в свое приложение Node.

 // All callbacks for Messenger will be POST-ed here app.post("/webhook", function (req, res) { // Make sure this is a page subscription if (req.body.object == "page") { // Iterate over each entry // There may be multiple entries if batched req.body.entry.forEach(function(entry) { // Iterate over each messaging event entry.messaging.forEach(function(event) { if (event.postback) { processPostback(event); } }); }); res.sendStatus(200); } }); function processPostback(event) { var senderId = event.sender.id; var payload = event.postback.payload; if (payload === "Greeting") { // Get user's first name from the User Profile API // and include it in the greeting request({ url: "https://graph.facebook.com/v2.6/" + senderId, qs: { access_token: process.env.PAGE_ACCESS_TOKEN, fields: "first_name" }, method: "GET" }, function(error, response, body) { var greeting = ""; if (error) { console.log("Error getting user's name: " + error); } else { var bodyObj = JSON.parse(body); name = bodyObj.first_name; greeting = "Hi " + name + ". "; } var message = greeting + "My name is SP Movie Bot. I can tell you various details regarding movies. What movie would you like to know about?"; sendMessage(senderId, {text: message}); }); } } // sends message to user function sendMessage(recipientId, message) { request({ url: "https://graph.facebook.com/v2.6/me/messages", qs: {access_token: process.env.PAGE_ACCESS_TOKEN}, method: "POST", json: { recipient: {id: recipientId}, message: message, } }, function(error, response, body) { if (error) { console.log("Error sending message: " + response.error); } }); } 

Всякий раз, когда кто-то взаимодействует с вашим ботом или отправляет на вашу страницу сообщение, через вашу интеграцию с Webhook будет отправлено обновление. Чтобы получать сообщения, вы должны прослушивать POST-звонки на своем веб-крюке. Все обратные вызовы будут сделаны для этого webhook.

В описанном выше обработчике POST мы перебираем записи сообщений, отправляемых в приложение. Иногда сообщения группируются и отправляются вместе, поэтому запись может содержать несколько объектов. Затем мы перебираем событие сообщения каждой записи и проверяем его тип. Ниже показаны различные сообщения обратного вызова, которые можно отправить в приложение.

  • Сообщение получено обратным вызовом — сообщение получено обратным вызовом отправляется, когда человек отправляет вашему боту сообщение. Вы должны были подписаться на событие messages при настройке вашего webhook.
  • Обратный вызов принятого ответаОбратный вызов принятого ответа отправляется, когда человек нажимает на кнопку, которая была настроена для отправки вам обратной передачи. Чтобы получить обратный вызов от постбэка, вы должны были подписаться на событие messaging_postbacks при настройке вашего webhook.
  • Message Delivered callback — этот обратный вызов происходит, когда доставлено сообщение, отправленное страницей. Вы должны были подписаться на событие message_deliveries при настройке вашего webhook.
  • Аутентификационный обратный вызов — этот обратный вызов произойдет, если подключаемый модуль Send-to-Messenger был нажат. Вы должны были подписаться на событие messaging_optins при настройке вашего webhook.
  • Обратный вызов чтения сообщения — этот обратный вызов происходит, когда сообщение, отправленное отправленной страницей, было прочитано пользователем. Вы должны были подписаться на событие message_reads при настройке вашего webhook.
  • Message Echo callback — этот обратный вызов будет происходить, когда сообщение было отправлено вашей страницей. Вы можете получать текстовые сообщения или сообщения с вложениями (изображение, видео, аудио, шаблон или запасной вариант). Вы должны были подписаться на событие message_echoes при настройке вашего webhook.
  • Checkout Update callback (BETA) — этот обратный вызов будет происходить при использовании кнопки «Купить» с транзакцией с гибкой суммой. Это позволяет обновлять цены на основе адреса доставки человека. Вы должны были подписаться на событие messaging_checkout_updates при настройке вашего webhook. На данный момент, это не доступно за пределами США.
  • Платежный обратный вызов (БЕТА) — этот обратный вызов происходит, когда человек нажимает кнопку оплаты в диалоговом окне оформления заказа, отображаемом кнопкой «Купить». Вы должны были подписаться на событие messaging_payments при настройке вашего webhook. На данный момент, это не доступно за пределами США.

Если событие является Postback, мы вызываем processPostback() где мы проверяем значение payload . Помните, что мы установили Greeting в качестве полезной нагрузки кнопки Get Started, поэтому здесь мы сначала проверяем, было ли отправлено событие обмена сообщениями в результате нажатия этой кнопки. Если это так, мы используем API профиля пользователя, чтобы получить имя пользователя, и используем его для персонализации сообщения, которое будет отправлено ему обратно. Из API вы можете получить их имя, фамилию, изображение профиля, локаль, часовой пояс и пол.

Затем сообщение отправляется в sendMessage() которая отправляет его в Messenger Platform. Вернувшись в обработчик POST Webhook, мы возвращаем HTTP-ответ 200 OK.

Важно вернуть ответ 200 как можно быстрее. Facebook будет ждать 200, прежде чем отправить вам следующее сообщение. У ботов с большими объемами задержка возврата 200 может привести к значительным задержкам в доставке сообщений на ваш веб-крючок в Facebook.

Если ваш webhook возвращает ошибку (т.е. не в состоянии 2XX) или истекает время ожидания (т. Е. Для ответа требуется более 20 секунд), и он продолжает это делать более 15 минут, вы получите предупреждение.

Если веб-крючок продолжает выходить из строя в течение 8 часов, то Facebook отправит вам предупреждение, сообщающее, что веб-крючок отключен, тогда ваше приложение будет отписано. После того, как вы исправите проблемы, вы должны снова добавить свой веб-крючок и повторно подписать приложение на страницу.

Зафиксируйте изменения и отправьте их в Heroku.

Чтобы протестировать бота, вы можете начать беседу со своей страницей либо через facebook.com, мобильное приложение facebook, либо с помощью короткого URL-адреса Messenger https://m.me/PAGE_USERNAME (вскоре мы увидим, как создать имя пользователя) ,

В Facebook и мессенджере вы можете найти страницу, выполнив поиск по названию страницы.

Поиск страницы

Как видно из вышесказанного, вы не всегда можете гарантировать, что имя страницы будет уникальным. Ваши пользователи могут выбрать не ту страницу. Чтобы предотвратить это, вы можете установить уникальное имя пользователя для страницы. Для этого перейдите на домашнюю страницу своей страницы и выберите « Изменить информацию о странице» в раскрывающемся меню «Дополнительно».

Более выпадающее меню

Затем установите имя пользователя.

Задать имя пользователя страницы

Теперь, если вы @page_username вы получите правильную страницу. Вы также можете перейти на https://m.me/PAGE_USERNAME чтобы начать взаимодействие.

Ниже вы можете увидеть текст приветствия, который мы установили для экрана приветствия, а также кнопку « Начало работы» .

Экран приветствия вашего чата на Facebook

При нажатии на кнопку вы должны увидеть сообщение, отправленное с сервера.

Начальное сообщение

Если вы введете какой-либо текст, вы не получите ответ. Мы позаботимся об этом дальше.

Настройка базы данных

Когда пользователь вводит название фильма, бот использует API-интерфейс Open Movie Database для получения подробной информации о фильме. Запрос API, который мы будем использовать, будет извлекать только первый соответствующий результат, поэтому возвращаемый фильм может не всегда соответствовать желаемому пользователю. Из-за этого бот сначала подтвердит пользователю, правильно ли он посмотрел фильм, и после этого пользователь может получить такие детали, как сюжет фильма, актеры, рейтинг IMDB и т. Д. Они также могут ввести другое название фильма и получить его детали вместо.

Вследствие этого бот должен запоминать текущую запись фильма пользователя. Facebook не держит сеанс открытым с вашим веб-крюком, поэтому любые данные, которые вы сохраняете в объекте сеанса, будут потеряны при следующем запросе. Вместо этого мы сохраним эти данные в базе данных — точнее, MongoDB. Мы будем использовать дополнение mlab на Heroku.

mLab — это база данных как услуга для MongoDB. На Heroku, хотя вы можете использовать бесплатный план mlab для песочницы, вам потребуется сохранить кредитную карту на Heroku для проверки. Если вы не хотите предоставлять данные своей карты, вы можете зарегистрировать учетную запись на веб-сайте mLab, создать там бесплатную базу данных песочницы и сослаться на нее из своего кода (подробнее об этом позже).

Чтобы использовать дополнение к Heroku, перейдите на панель инструментов приложения и выберите вкладку Ресурсы . Найдите mlab и выберите результат. В появившемся диалоговом окне выберите план « Sandbox - Free из выпадающего меню и нажмите « Предоставление» . Вы должны увидеть подтверждение выбранного дополнения.

MLab Add On

Если вы проверите переменные окружения в Heroku, вы увидите переменную с уже установленным URI вашего MongoDB.

Переменная среда MONGO DB

Настройка базы данных через веб-сайт mLab

Если вы предпочитаете настроить базу данных MongoDB на веб-сайте mLab, зарегистрируйте там учетную запись и перейдите на страницу создания нового развертывания . Измените параметр « План» на « Один узел», а затем выберите « Песочницу» в разделе « Стандартная линия ».

mlab Создать базу данных

Задайте имя для своей базы данных и завершите процесс, нажав кнопку Создать новое развертывание MongoDB .

mlab Создать базу данных

На следующей странице выберите базу данных, которую вы только что создали, из отображаемой таблицы. Откроется страница с инструкциями по доступу к базе данных.

Выберите вкладку « Пользователи » и нажмите кнопку « Добавить пользователя базы данных» . Введите имя пользователя и пароль и нажмите « Создать» . Это создает новый набор учетных данных, которые вы можете использовать, чтобы разрешить вашему приложению доступ к БД.

В верхней половине страницы найдите и скопируйте URI базы данных — он будет выглядеть следующим mongodb://<dbuser>:<dbpassword>@dsxxxxxx.mlab.com:55087/spbot . Вставьте имя и пароль dbuser который вы только что создали. В Heroku создайте переменную среды с именем MONGODB_URI и вставьте в ее значение URI базы данных.

Определение класса модели

Вернувшись в приложение Node, создайте файл с названием movie.js и сохраните его в папке с названием models . Вставьте следующее в файл:

 var mongoose = require("mongoose"); var Schema = mongoose.Schema; var MovieSchema = new Schema({ user_id: {type: String}, title: {type: String}, plot: {type: String}, date: {type: String}, runtime: {type: String}, director: {type: String}, cast: {type: String}, rating: {type: String}, poster_url: {type: String} }); module.exports = mongoose.model("Movie", MovieSchema); 

Выше создается модель базы данных фильмов. user_id будет идентификатором пользователя, полученным из платформы Messenger, в то время как другие поля будут получены из API фильмов. Мы будем хранить только последний просмотренный фильм пользователя, поэтому в базе данных будет только одна запись на пользователя.

Мы могли бы опустить поле user_id и просто использовать идентификатор пользователя в качестве _id каждой созданной записи. Это сработало бы, поскольку идентификаторы пользователей уникальны для страницы Facebook. Если вы собираетесь это сделать, вы должны знать, что идентификаторы пользователей имеют объем страницы. Это означает, что идентификаторы пользователей являются уникальными для данной страницы, но пользователь может иметь разные идентификаторы для разных страниц.

Вам нужно знать об этом, только если ваш бот обслуживает разные страницы (да, бот может обслуживать несколько страниц ). Таким образом, если ваш бот обслуживает несколько страниц, возможно, будет неправильно идентифицировать пользователей только по их идентификаторам, а также будет неправильно использовать идентификатор пользователя для поля _id записи, поскольку это должно быть уникальным, и вы не будете в состоянии гарантировать эту уникальность на всех страницах.

Собираем все вместе

Теперь, когда база данных и модель настроены, мы можем завершить чат-бота. Код будет представлен по частям, но если вы хотите вставить весь код в свой проект, вот ссылка на файл app.js

Начните с настройки соединения с базой данных. Mongoose уже должен был быть установлен ранее с другими модулями.

 var mongoose = require("mongoose"); var db = mongoose.connect(process.env.MONGODB_URI); var Movie = require("./models/movie"); 

Измените обработчик POST webhook, как показано на рисунке.

 // All callbacks for Messenger will be POST-ed here app.post("/webhook", function (req, res) { // Make sure this is a page subscription if (req.body.object == "page") { // Iterate over each entry // There may be multiple entries if batched req.body.entry.forEach(function(entry) { // Iterate over each messaging event entry.messaging.forEach(function(event) { if (event.postback) { processPostback(event); } else if (event.message) { processMessage(event); } }); }); res.sendStatus(200); } }); 

Мы добавили проверку событий типа message , передав их в функцию processMessage() .

 function processMessage(event) { if (!event.message.is_echo) { var message = event.message; var senderId = event.sender.id; console.log("Received message from senderId: " + senderId); console.log("Message is: " + JSON.stringify(message)); // You may get a text or attachment but not both if (message.text) { var formattedMsg = message.text.toLowerCase().trim(); // If we receive a text message, check to see if it matches any special // keywords and send back the corresponding movie detail. // Otherwise, search for new movie. switch (formattedMsg) { case "plot": case "date": case "runtime": case "director": case "cast": case "rating": getMovieDetail(senderId, formattedMsg); break; default: findMovie(senderId, formattedMsg); } } else if (message.attachments) { sendMessage(senderId, {text: "Sorry, I don't understand your request."}); } } } 

Здесь мы сначала проверяем, было ли сообщение отправлено с помощью функции обратного вызова. Этот обратный вызов произойдет, когда ваша страница отправит сообщение. Например, первое сообщение, которое мы отправили пользователю (приветствие), будет отправлено обратно в наш Webhook. Мы не хотим обрабатывать какие-либо наши собственные сообщения, поэтому мы ставим проверку для этого.

Затем мы проверяем, является ли сообщение текстом или вложением (изображение, видео, аудио). В случае последнего мы отправляем сообщение об ошибке пользователю. Для текстовых сообщений мы проверяем, соответствует ли ввод определенным ключевым словам, которые укажут, какие детали фильма хочет пользователь. На данный момент пользователь уже сделал запрос фильма, и фильм будет сохранен в базе данных. Функция getMovieDetail() запрашивает базу данных и возвращает конкретную запись.

 function getMovieDetail(userId, field) { Movie.findOne({user_id: userId}, function(err, movie) { if(err) { sendMessage(userId, {text: "Something went wrong. Try again"}); } else { sendMessage(userId, {text: movie[field]}); } }); } 

Если пользовательский запрос не соответствует ни одному из заданных ключевых слов, бот предполагает, что входные данные предназначены для запроса фильма, поэтому он передается функции findMovie() которая вызывает API-интерфейс Open Movie Database с входными findMovie() .

 function findMovie(userId, movieTitle) { request("http://www.omdbapi.com/?type=movie&amp;t=" + movieTitle, function (error, response, body) { if (!error &amp;&amp; response.statusCode === 200) { var movieObj = JSON.parse(body); if (movieObj.Response === "True") { var query = {user_id: userId}; var update = { user_id: userId, title: movieObj.Title, plot: movieObj.Plot, date: movieObj.Released, runtime: movieObj.Runtime, director: movieObj.Director, cast: movieObj.Actors, rating: movieObj.imdbRating, poster_url:movieObj.Poster }; var options = {upsert: true}; Movie.findOneAndUpdate(query, update, options, function(err, mov) { if (err) { console.log("Database error: " + err); } else { message = { attachment: { type: "template", payload: { template_type: "generic", elements: [{ title: movieObj.Title, subtitle: "Is this the movie you are looking for?", image_url: movieObj.Poster === "N/A" ? "http://placehold.it/350x150" : movieObj.Poster, buttons: [{ type: "postback", title: "Yes", payload: "Correct" }, { type: "postback", title: "No", payload: "Incorrect" }] }] } } }; sendMessage(userId, message); } }); } else { console.log(movieObj.Error); sendMessage(userId, {text: movieObj.Error}); } } else { sendMessage(userId, {text: "Something went wrong. Try again."}); } }); } 

Если фильм найден, его данные сохраняются вместе с идентификатором пользователя. Если запись с таким идентификатором пользователя была создана ранее, она будет обновлена. Затем мы создаем структурированное сообщение и отправляем его пользователю.

Помимо текста, Messenger Platform позволяет отправлять обратно изображения, видео, аудио, файлы и структурированные сообщения. Структурированные сообщения — это шаблоны, которые поддерживают различные варианты использования. Шаблон кнопки позволяет отправлять текст и кнопки. Общий шаблон позволяет определять изображение, заголовок, подзаголовок и кнопки. В нашем приложении мы используем общий шаблон.

Измените processPostback() как показано.

 function processPostback(event) { var senderId = event.sender.id; var payload = event.postback.payload; if (payload === "Greeting") { // Get user's first name from the User Profile API // and include it in the greeting request({ url: "https://graph.facebook.com/v2.6/" + senderId, qs: { access_token: process.env.PAGE_ACCESS_TOKEN, fields: "first_name" }, method: "GET" }, function(error, response, body) { var greeting = ""; if (error) { console.log("Error getting user's name: " + error); } else { var bodyObj = JSON.parse(body); name = bodyObj.first_name; greeting = "Hi " + name + ". "; } var message = greeting + "My name is SP Movie Bot. I can tell you various details regarding movies. What movie would you like to know about?"; sendMessage(senderId, {text: message}); }); } else if (payload === "Correct") { sendMessage(senderId, {text: "Awesome! What would you like to find out? Enter 'plot', 'date', 'runtime', 'director', 'cast' or 'rating' for the various details."}); } else if (payload === "Incorrect") { sendMessage(senderId, {text: "Oops! Sorry about that. Try using the exact title of the movie"}); } } 

Здесь мы добавляем две проверки для Correct и Incorrect сообщений полезной нагрузки. Они будут прикреплены к кнопкам, которые пользователь будет использовать, чтобы сообщить боту, представил ли он правильный фильм.

Зафиксируйте свой код и отправьте его в Heroku, затем попробуйте отправить сообщения боту.

Когда вы отправляете запрос боту, если он находит фильм, он отправляет обратно структурированное сообщение, которое проверяет, был ли выбран правильный фильм.

Пример структурированного сообщения от чата Facebook

В Интернете (и iOS) это выглядит немного иначе.

Пример вывода структурированного сообщения на iOS

Структурированные сообщения могут иметь разные типы кнопок, как показано:

  • Кнопка URL : открыть URL в браузере приложения
  • Кнопка обратной передачи : отправьте обратную запись вашему веб-крюку, если вы хотите отправить действие своему боту
  • Кнопка вызова : вызов телефонного номера
  • Кнопка «Поделиться» : откройте диалоговое окно «Поделиться», чтобы сообщения могли быть переданы друзьям.
  • Кнопка «Купить» : открыть диалоговое окно оформления покупки

В нашем примере мы используем две кнопки обратной передачи и устанавливаем для их значений полезной нагрузки значения « Correct и « Incorrect . Если вы посмотрите на processPostback() , вы увидите проверки для этих двух полезных нагрузок. Если нажать кнопку « Нет» , будет возвращено следующее сообщение:

Неправильная полезная нагрузка отправлена

Затем пользователь может сделать еще один запрос.

Поиск фильма

И после подтверждения, что это правильный фильм, они получат дальнейшие инструкции от бота о том, как действовать дальше.

Детали фильма

Помните, что мы проверяем эти ключевые слова в processMessage() .

Вы должны убедиться, что структурированное сообщение, которое вы отправляете, правильно сформировано, иначе оно не будет показано пользователю. В демонстрационном приложении я заметил, что некоторые API возвращают фильмы, в которых отсутствуют некоторые детали в некоторых областях. В таких случаях значение поля N/A В нашем структурированном сообщении мы используем два поля из объекта, возвращаемого API — заголовок и постер (URL для постера фильма). Если фильм найден, у него всегда будет заголовок, поэтому нет необходимости подтверждать это, но если у фильма нет постера и вы не предоставите альтернативный URL для этого, структурированное сообщение не сможет быть показано. Поэтому убедитесь, что атрибуты в ваших структурированных сообщениях всегда имеют значения.

В нашем случае мы ссылаемся на изображение-заполнитель, если ни один не был возвращен

Фильм без постера

Фильм с постером

Если по запросу пользователя не найдено ни одного фильма, бот сообщает об этом.

Фильм не найден

Живи с твоим Facebook Chat Bot

Когда вы будете готовы опубликовать свое приложение для общественности, оно должно пройти процедуру одобрения. До утверждения приложения только вы и приглашенные вами тестеры смогут взаимодействовать с ним. Процесс отправки в группу обзора выходит за рамки данного руководства, но это руководство расскажет вам, что вам нужно сделать.

Вывод

В этом уроке мы создали простой чат-бот Facebook, который способен получать запросы от пользователей в Messenger и отвечать на них. Однако бот далеко не совершенен. Когда пользователь взаимодействует с ним, он ограничен строгим набором команд. Это не то, как люди разговаривают друг с другом. Бот может быть улучшен таким образом, чтобы пользователи могли взаимодействовать с ним более естественным образом, чем при общении между людьми, а не просто с помощью команд. Это может быть сделано путем интеграции обработки естественного языка в бот. Для этого вы можете создать свой собственный механизм NLP или использовать сервис, такой как wit.ai, который позволяет вам добавлять NLP в ваши приложения. wit.ai принадлежит Facebook и может свободно использоваться как для личных, так и для коммерческих проектов.

Что вы думаете о чат-ботах и ​​их возрастающем использовании? Если у вас есть страница в Facebook, подумаете ли вы о том, чтобы бот разрешил взаимодействие с вашими пользователями? Дайте мне знать, что вы думаете в комментариях.

Хотите узнать больше о ботах? Ознакомьтесь с нашим новым Премиум курсом по созданию бота Skype с помощью Microsoft Bot Framework !