Создаем своего мессенджер-бота, взаимодействующего с бэкэндом WordPress

Дата публикации:Июль 19, 2017

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

Знакомимся с WPFBBotKit

Платформа Messenger Platform – это JSON API, и, как в случае со многими другими API, я обнаружил, что в ней используется довольно много шаблонного кода – цифровой эквивалент рукопожатий и приветствий. Таким образом, вместо того чтобы знакомить вас со всем этим, я решил создать свой собственный WordPress плагин, WPFBBotKit, который поможет вашему WP-боту быстрее начать общение.

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

Настройка

Для начала нам нужен будет WordPress-сайт с поддержкой SSL, поскольку Messenger Platform требует HTTPS URL для конечных точек webhook. Если у вас пока нет сайта с настроенным SSL, вы можете создать и запустить его локально на MAMP, создав туннель с помощью Ngrok (либо используя Local от Flywheel для автоматического создания туннеля Ngrok).

Теперь вы можете установить плагин WPFBBotKit, скачав zip-архив. Активируйте плагин и перейдите на страницу с его настройками, выбрав WPFBBotKit в меню Settings панели администратора.

На странице WPFBBotKit вы увидите Webhook URL и Verification String, а также текстовую область для Page Access Token. Оставьте страницу открытой, мы будем использовать эту информацию.

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

В вашем приложении вы настраиваете интеграцию. Вернитесь к списку приложений и перейдите к вашему только что созданному приложению, после чего щелкните по Add Products и выберите Set Up в разделе Messenger.

На странице Messenger Setup, прокрутите вниз до Token Generation и выберите Select a Page, после чего задайте вашу страницу. У вас может появиться всплывающее окно Facebook с просьбой авторизовать ваше приложение для управления страницей. Предоставьте ему такие полномочия. Далее щелкните по Page Access Token для копирования токена – перейдите обратно к странице настроек WPFBBotKit в панели администратора вашего WP сайта и вставьте токен в поле Page Access Token, после чего нажмите Save.

Переходим обратно к странице Messenger Setup. Вы можете выбрать Setup Webhooks и скопировать ваш Webhook URL со страницы настроек WPFBBotKit, вставив в поле Callback URL (обязательно используйте https и замените  url сайта на Ngrok url, если вы используете туннель), а также скопировать Verification String и вставить в поле Verify Token. Выберите пункты messages и messaging_postbacks в Subscription Fields, после чего щелкните по Verify and Save. Вы должны увидеть индикатор, после чего модальное окно пропадет. Если возникнут какие-либо проблемы, вы увидите красный крестик в поле URL, и, наведя курсор на него, вы сможете получить подробную информацию о возникшей ошибке.

Наконец, вы можете выбрать свое приложение из раскрывающегося списка «Select a page to subscribe your webhook to the page events». Щелкните по Subscribe.

Ознакомьтесь с руководством по началу работы Messenger Platform для получения информации о правильной настройке вашей страницы, приложения и webhook.

Загружаем бота

Далее вам нужно будет где-то проверить работоспособность вашего бота. Для этого создаем новый плагин, либо новый файл в папке mu-plugins. Также вы можете поместить код и прямо в свой файл functions.php (опасный способ, но все же рабочий). WPFBBK предлагает действие wpfbbk_message_received, которое будет срабатывать всякий раз, когда ваш бот получит сообщение, потому давайте подцепим функцию к этому действию.


add_action( 'wpfbbk_message_received', 'my_cool_bot' );
function my_cool_bot( $M ) {
    // message processing and response goes here
    exit( 0 );
}

Пока что код не делает ничего, кроме выхода из скрипта, поэтому Facebook не будет повторно пересылать запрос webhook. В идеале вы должны ставить все ответы в очередь, т.к. Facebook дает вам 20 секунд на то, чтобы вернуть код ответа 200/OK, прежде чем он попытается повторно отправить сообщение вам. Если вы не можете это сделать, то в таком случае лучше всего ограничить количество отправляемых ответов, и покинуть программу (exit) как можно быстрее.

Действие wpfbbk_message_received передаст экземпляр класса WPFBBK_Messaging, содержащий read-only свойства, включая $text и $postback, которые будут заполнены, если кто-либо отправит вашему боту сообщение или щелкнет по кнопке обратной передачи (postback). Он также предлагает метод reply( $message ), который позволит вам отправить ответ на текущее сообщение с данными, отформатированными вручную, а также некоторые другие вспомогательные методы: reply_with_text( $text ), reply_with_image_url( $url ) и reply_with_buttons( $text, $buttons ). Давайте воспользуемся методами reply_with_text и reply_with_image для отправки ответа на любое сообщение без обратной передачи:


add_action( 'wpfbbk_message_received', 'my_cool_bot' );
function my_cool_bot( $M ) {
    if( ! $M->postback ) {
        $M->reply_with_text( 'Hi There!' );
        $M->reply_with_image_url( 'https://media.giphy.com/media/eHpWHuEUxHIre/giphy.gif' );
    }
    exit( 0 );
}

Теперь мы можем перейти в Facebook Messenger и начать новый чат с вашим ботом – он будет примерно следующим:

Chatting with Bindey bot

Отправка ответов на Facebook сообщения через WordPress-сайт выглядит привлекательно и удобно, но давайте посмотрим, можем ли мы предложить людям что-то большее, чем просто отправку GIF. Поскольку мы работаем с WP, который когда-то был платформой для блогов, мы можем предоставить пользователям что-либо полезное для чтения. Вместо GIF мы передадим пользователям набор кнопок, которые помогут пользователям рассказать вашему боту, что именно они хотят почитать. Мы можем использовать WPFBBK_Messaging::reply_with_buttons() для отправки этого; обратитесь к Postback Button документации для получения информации по поводу того, как надо отформатировать массив, описывающий ваши кнопки.

Мы передаем в reply_with_buttons() немного текста, а также массив массивов, который описывает postback кнопки. Каждая кнопка имеет тип postback, а также title, который будет отображаться на кнопке, и payload – то, что мы получим обратно в качестве их ответа, если они щелкнули по кнопке. Теперь я заменю GIF, который мы отправили ранее, на ответы с кнопками, и протестирую это в мессенджере:

Bindey sends me buttons

Давайте обработаем эти ответы. Во-первых, нам нужно перехватить postback и настроить ответы для каждой опции, которую мы предлагаем. Реализуем мы это путем добавления else блока после if, который будет проверять, был ли postback, а также перехода к нужной ветви с помощью switch:


$M->reply_with_buttons( 'Looking for something to read?', array(
		array(
			'type'  => 'postback',
			'title' => '👀  Something new.',
			'payload' => 'GET_LATEST_POST', 
		),
		array(
			'type'  => 'postback',
			'title' => '👍  Vintage post, B!',
			'payload' => 'GET_ARCHIVE_POST', 
		),
		array(
			'type'  => 'postback',
			'title' => '🤓  I\'m all caught up!',
			'payload' => 'GET_GIF', 
		),
	));

Теперь нам нужно просто добавить #code для каждого случая. Давайте начнем с отрицательного ответа: когда пользователь щелкает по кнопке «I’m all caught up!». В таком случае мы передадим им быстрый ответ и GIF. Мы можем воспользоваться Tenor GIF API в ограниченном виде без отдельного ключа, потому мы применим wp_remote_get() для получения и кэширования списка GIF, а затем применим WPFBBK_Messaging::reply_with_image_url() для отправки выбранного случайным образом изображения:


case 'GET_GIF':
    // get and cache some gifs
    if( ! $gifs = get_site_transient( 'schwifty_gifs' ) ){
        $gifsearch = 'rick morty';
        $gifs = json_decode( wp_remote_get( 'https://api.tenor.com/v1/search?tag=' . urlencode( $gifsearch ) . '&safesearch=strict&limit=50&key=LIVDSRZULELA' )['body'] )->results;
        set_site_transient( 'schwifty_gifs', $gifs );
    }

    //choose a random GIF from the results
    $gif = $gifs[ rand( 0, count( $gifs ) - 1 ) ]->media[0]->gif->url;

    // reply with text and a schwifty GIF for the road
    $M->reply_with_text( 'Sounds good. Keep it Schwifty!', true );
    $M->reply_with_image_url( $gif );
    break;

От GET_GIF мы переходим к GET_ARCHIVE_POST. Мы воспользуемся get_posts для поиска первого опубликованного поста, после чего применим WPFBBK_Messaging::reply_with_generic_template_link() для отправки пользователю красиво оформленной ссылки на статью с помощью Messenger API Generic шаблона:


case 'GET_ARCHIVE_POST':
    // get the oldest published post
    $posts = get_posts( array(
        'posts_per_page'   => 1,
        'orderby'          => 'date',
        'order'            => 'DESC',
    ) );

    // populate fields required for generic template
    $title = $posts[0]->post_title;
    $image = str_replace( 'http://', 'https://', wp_get_attachment_image_src( get_post_thumbnail_id( $posts[0]->ID ), 'large' )[0] );
    $url = get_permalink( $posts[0]->ID );
    $subtitle = strip_tags( $posts[0]->post_content );

    // trim post content to subtitle length
    if( 70 > strlen( $subtitle ) ) {
        $subtitle = substr( $subtitle, 0, 67 ) . '...';
    }

    // send generic template link card
    $M->reply_with_generic_template_link( $title, $subtitle, $image, $url );
    break; 

Наконец, мы можем использовать практически тот же самый код для GET_LATEST_POST. Мы изменим лишь параметр order, который мы передаем в get_posts(), с DESC на ASC. Давайте посмотрим, как это работает:

Our completed chatbot interaction

FAQ

Почему изображения не загружаются в Messenger?

Если ваши изображения не загружаются в Messenger, то это, скорее всего, вызвано жесткими требованиями Facebook к SSL: изображения должны передаваться по HTTPS с доверенным SSL сертификатом. У меня были проблемы с этим во время использования Ngrok, потому я решил воспользоваться WP Offload S3 для передачи моих изображений напрямую из S3 по HTTPS, что прекрасно сработало.

Почему мой бот отвечает два/три/n раз?

Messenger автоматически пересылает запросы на ваш webhook, если он не получил ответа в течение примерно 20 секунд. Каждый ответ, который вы отправляете, останавливает ваш сервер от закрытия соединения. Таким образом, если вы отправляете множество отдельных сообщений или соединяетесь с другими API (к примеру, Tenor GIF API), то в таком случае очень легко не вписаться в этот 20-секундный лимит. Кроме того, если у вас имеются ошибки в коде, которые не позволяют WordPress передать 200 ответ, Messenger будет постоянно дергать ваш webhook с тем же самым запросом (хотя и с возрастающими интервалами), потому убедитесь, что ваш код правильный; также советуем вам держать ваш журнал ошибок открытым, чтобы отслеживать разные ошибки по мере их появления.

Если вы хотите создать высокоинтеллектуального бота, то в таком случае вам обязательно захочется реализовать сервер очереди. Это возможно с помощью хука WPFBBotKit wpfbbk_before_send_request, который позволяет вам обрабатывать запрос самостоятельно (поставить его в очередь), вместо того чтобы передавать запрос классу WP’s Requests.

Почему WPFBBK не делает X?

Честно говоря, я сделал WPFBBK, поскольку без него эта статья была бы в три раза длиннее. Это новый проект. Если он вам понравился, вы всегда можете внести в него свой вклад.

Источник: deliciousbrains.com

Поделиться

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.