Перейти к основному контенту

Metabot 101: Создание простого бота с использованием REST API

Создание

Уважаемые разработчики! В этом уроке вы познакомитесь с основами разработки приложений с помощью платформы Metabot. Вместе мы создадим простой бот, который будет присылать в мессенджер по запросу изображение с сайта Pexels.com.

Обращаясь к сторонним веб-сервисам с помощью REST API, мы создадим простой диалоговый сценарий, запрашивающий ключевое слово, по которому вы хотели бы найти изображение. Затем бот обращается к сервису API и возвращает найденное изображение. Далее мы добавим кнопку "Прислать следующее изображение". Таким образом, через бота длявы просмотрасможете фотопосмотреть поочерёдно все изображения, найденные на Pexels.comсервисе.

В ходе урока вы узнаете:

1. Как разрабатывается REST API интеграция с помощью вызова точек интеграции, называемых "endpoints".
2. Как использовать JavaScript для обращения к сторонним ресурсам.
3. Как работать с данными, которые хранятся в лиде (lead) и во временной памяти (memory).
4. Как работать с режимом отладки кода, который позволит вам получать уведомления об ошибках выполнения вашего кода.

Приятного обучения!

ПервыеСоздание шагипервого скрипта бота

После регистрации на платформе METABOT,Metabot, у бизнеса имеется один пользователь административной панели, который может подключать дополнительных пользователей, создавать новых метаботовботов и администрировать их.

image.png

Первым делом требуется создать скрипт-приветствие и добавить в него скриптсообщение с приветствием и меню.

Как это сделать вы можете узнать из урока "Hello Humans: ваше руководство по быстрому старту"

Для нашего бота в начальном скрипте понадобится только команда отправки текста. Примерное содержимое команды может быть таким: "Приветствую! Это бот для просмотра фотографий на сервисе Pexels.com".

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

Подключение каналов

В данном боте будет создано два канала: Telegram и Metabot Widget

Создание

1. каналаСоздадим Telegramканал Telegram.

Как это сделать вы можете узнать из инструкции "Интеграция канала Telegram с платформой Metabot24"Metabot"

Создание

2. каналаСоздадим Widgetканал Metabot Widget.

Как это сделать вы можете узнать из инструкции "Metabot Widget"

Подключение маршрутов

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

Как это сделать вы можете узнать из инструкции "Маршруты"

Запускаем первую версию бота

1. Находим бот в Telegram и запускаем /start.

image.png

2. В справочнике каналов открываем канал «Metabot Widget» и в справочнике каналов последовательно нажимаем на кнопки «Загрузить|Предварительный просмотр».

image.png

После этого возможно включить режим отладки для обоих созданных лидов бота.

Включение режима отладки

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

1. Для включения отладки следует зайти в меню "Лиды" и нажать на кнопку переключения отладчика.

image.png

2. Затем нужно выбрать уровень отладки. В данном случае выбирайте уровень "editor".

image.png

Если режим отладки включен, в мессенджер или виджет (в зависимости от канала, с которым связан лид), то в случае ошибок в JS-коде, будут выдаваться сообщения об ошибках. Если лид, под которым выполнялась отладка используется на продуктовом сервере, после завершения разработки отладчик следует отключить.

image.png

Расширяем скрипт с приветствием и меню

1. Добавляем пункты меню "Выбрать тему" и "Следующее фото" в стартовый скрипт.

Как это сделать вы можете узнать из инструкции "Создание меню"

Если при создании пункта меню не указывать скрипт, то будет автоматически создан пустой скрипт с тем же именем, что и подпись кнопки.

2. Следующим шагом отредактируем свойства автоматически созданных скриптов, а точнее их имя и JS-код. Это делается при помощи кнопки редактирования в меню скриптов.

image.png

    Название - это имя скрипта, которое может содержать в себе любые символы. Скриптам связанные с интеграциями, которые содержат большой объем JavaScript команд, рекомендуется присваивать англоязычные имена.имена, Этотак как это область работы JS программистов. Код - это дополнительный уникальный идентификатор. Используется для поиска скрипта, например, в JavaScript функциях, а также для поиска и запуска скрипта через NLP. Он всегда обозначается одним словом без пробелов.

    image.png

    Для скрипта выбора темы вводим в поля название и код значение select_theme_photo, а в скрипт переключения на следующее фото значение show_next_photo.

    В итоге получаем следующие скрипты после изменения свойств:

    image.png

    Кнопки в боте появятся, но реакция на их нажатие отсутствует, так как созданные скрипты пока пустые. МыИх наполнением мы займёмся чуть позже.

    Теперь мы готовы выполнить интеграцию с сервисом Pixels.com.

    Подключаемся к API Pixels.com

    Для начала получим токен к API Pixels.com.

    1. Переходим к документации API Pixels.com по ссылке: https://www.pexels.com/api/documentation/

    2. Регистрируемся на платформе. Переходим в раздел "Авторизация" и переходим по ссылке "запросить ключ API".

    image.png

    3. Затем заполняем информацию о том для чего будет использован ключ и как результат получаем API Key:

    image.png

    4. В «Настройки бота» меню «Атрибуты» создаем системный атрибут sys_sysAapi_piHheaderseaders и присваиваем ему значение:

    {"Accept":"application/json",  "Authorization": "Bearer <ваш скопированный токен>"}

    Внимание! Между Bearer и токеном должен быть ровно один пробел!

    Подробнее про атрибуты вы можете узнать из инструкции image.pngАтрибуты

    image.png

    Иcследуем endpoints API Pixels.com

    1. На главной странице документации в правом верхнем углу находим базовый URL для работы с фото.

    image.png

    2. Аналогично предыдущему пункту, в «Настройки бота» меню «Атрибуты» заносим системный атрибут sys_api_http_client_configsysApiHttpClientConfig  и присваиваем значение: {"base_uri":"https://api.pexels.com/v1/"}

    В итоге имеем в нашем боте следующие атрибуты:

    image.pngimage.png

    Подробнее про работу с API на платформе Metabot вы можете узнать из инструкции Конструктор API

    Заполняем скрипт SELECT_THEME_PHOTOselect_theme_photo

    Данный скрипт запрашивает тему фото, выполняет restREST запрос к сервису и выводит первую выбранную фотографию.

    1. Для реализации данного функционала создадим команду "Запросить значение". Зададим команде параметр "Имя переменной" = photo_themephotoTheme. Именно в этом атрибуте будет храниться результат запроса.

    Подробнее о команде "Запросить значение" вы можете узнать из соответствующей инструкции.

    2. Следующей командой будет "Выполнить JavaScript". Она будет содержать JS код для доступа к API.

    // раздел 1: подготовка параметров restREST запроса
    
    var photo_themephotoTheme = lead.getAttr('photo_theme'photoTheme');
    var url = "search?query=" + photo_themephotoTheme + '&per_page=1';
    var jsonBody = {};
    var headers = {};
    
    //--------------------------------------------------------
    
    // раздел 2: подготовка вспомогательной переменной и начальная установка атрибутов Лидалида
    
    var total_results = 0;
    lead.setAttr('url', url);
    memory.setAttr('rsps.next_page'nextPage', '');
    lead.setAttr('rsps.total_results'totalResults', 0);
    memory.setAttr('rsps.photographer', '');
    memory.setAttr('rsps.original', '');
    memory.setAttr('rsps.medium', '');
    lead.setAttr('photo_theme_index'photoThemeIndex', 1);
    
    //--------------------------------------------------------

    В разделе 1 выбирается из атрибутов Лидалида введенная ранее пользователем тема PHOTO_photoThemeTHEME и подготавливаются параметры restREST запроса.

    В разделе 2 присваиваем начальные значения атрибутов:

    • url - restREST запрос.
    • total_results – всего фото по заданной теме
    • photo_theme_found - признак, что запрос вернул фото
    • next_page - следующая страница
    • photographer – фотограф
    • original - cсылка на оригинальное фото
    • medium – ссылка на уменьшенную копию medium
    • photo_theme_index - текущиее фото в теме

    При этом одни переменные сохраняются в атрибутах Лидалида (в lead), а другие во временном хранилище в памяти (в memory). 

    Примечание: Переменные, которые необходимы для выполнения алгоритма скрипта лучше сохранять в memory, чтобы не засорять атрибуты Лидалида ненужными данными. В тоже время необходимо помнить, что при запуске нового скрипта по кнопке, по намерению NLP или по маршруту memory очищается, а lead очистить можно только принудительно командой. Поэтому переменные, которые используются в различных скриптах, сохранять в memory не нужно. В тоже время скрипт, который запускается из некоторого скрипта командой запустить скрипт имеет доступ к переменным в memory скрипта, который его запустил и всех остальных его запустивших.

    Примечание: для отладки удобно временно сохранять переменную в lead вместо memory, так как переменные lead можно просматривать в справочнике атрибутов Лидов.лидов.

    Используются некоторые параметры из jsonJSON объекта, который возвращает restREST запрос.

    Ниже подробно расписаны все атрибуты запроса:

    Атрибут Тип Описание
    query

    string | required

    Поисковой запрос. ПодробноНапример: форматОкеан, запросаТигры, Груши и структурут.д.
    orientation

    string | optional

    Желаемая ориентация фотографии. Текущие поддерживаемые ориентации: landscape, portrait or square.
    size

    string | optional

    Минимальный размер фото. В настоящее время поддерживаются следующие размеры: large(24MP), medium(12MP) or small(4MP).
    color

    string | optional

    Желаемый цвет фото. Поддерживаемые цвета: red, orange, yellow, green, turquoise, blue, violet, pink, brown, black, gray, white или любой шестнадцатеричный код цвета (например, #ffffff).
    locale

    string | optional

    Регион поиска, из которого вы делаете запрос. Текущие поддерживаемые регионы: 'en-US' 'pt-BR' 'es-ES' 'ca-ES' 'de-DE' 'it-IT' 'fr-FR' 'sv-SE' 'id-ID' 'pl-PL' 'ja-JP' 'zh-TW' 'zh-CN' 'ko-KR' 'th-TH' 'nl-NL' 'hu-HU' 'vi-VN' 'cs-CZ' 'da-DK' 'fi-FI' 'uk-UA' 'el-GR' 'ro-RO' 'nb-NO' 'sk-SK' 'tr-TR' 'ru-RU'.
    page

    integer | optional

    Номер страницы, которую вы запрашиваете. По умолчанию: 1.
    per_page
    integer | optional Количество результатов, которые вы запрашиваете на странице. По умолчанию: 15 Макс.: 80.

    Все атрибуты ответа:

    можно
    изучить Атрибут Тип Описание
    photos

    array of Photo

    Массив объектов Photo.
    page

    integer

    Номер текущей страницы.
    per_page

    integer

    Количество фото на текущей странице.
    total_results

    integer

    Общее количество результатов по адресу:запросу. https://www.pexels.com/ru-ru/api/documentation/#photos-search
    prev_page
    string | optional URL-адрес предыдущей страницы, если она есть.
    next_page
    string | optional URL-адрес следующей страницы, если она есть.

    3. Продолжаем разрабатывать скрипт в той же команде.

    // раздел 3: выполнение restREST запроса
    
    memory.setAttr('photo_theme_found'photoThemeFound', 0);
    jsonResponse = api.getJson(url, jsonBody, headers);
    if (jsonResponse) {
    
    //------------------------------------------------
      
    // раздел 4: сохранение результата запроса в атрибутах Лидалида
      
      var rsps = jsonResponse;
      total_resultstotalResults = rsps['total_results'] * 1;
      if (total_results > 0) {
        memory.setAttr('photo_theme_found'photoThemeFound', 1);
        lead.setAttr('rsps.total_results'totalResults', total_results)totalResults);
        memory.setAttr('rsps.photographer', rsps['photos'][0]['photographer']);
        memory.setAttr('rsps.original', rsps['photos'][0]['src'][ 'original' ]);
        memory.setAttr('rsps.medium', rsps['photos'][0]['src'][ 'medium' ]);
        memory.setAttr('rsps.next_page'nextPage', rsps['next_page']);
      }
      
    //------------------------------------------------
    
    // раздел 5
      
      memory.setJsonAttr("lastHttpResponse", api.getLastResponseContent());
      memory.setAttr("lastHttpResponseCode", api.getLastResponseCode());
    }
    
    //------------------------------------------------

    В разделе 3 выполняется restREST запрос к сервису и проверяется что запрос выполнился.

    В разделе 4 проверяется что в данной теме имеются фото и переносятся необходимые параметры restREST запроса в атрибуты Лида.лида.

    В разделе 5 для удобства отладки запоминаем в атрибуте Лидалида полный ответ ** и код ответа сервиса.

    **

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

    4. Далее выводим ответ в канал, используя данные, сохраненные в атрибутах Лида.лида. Для этого используем две команды вывода текста с условием. Одна срабатывает когда атрибут photo_theme_foundphotoThemeFound равен 1, вторая, наоборот, он не равен 1.

    image.pngimage.png

    Так выглядят данные команды после создания:

    image.pngimage.png

    Условие выполнения Текст команды return (lead.getAttr("photoThemeFound") == 1); "{{$photoTheme}}": {{$rsps.totalResults}} / {{$photoThemeIndex}}
    Фотограф: {{$rsps.photographer}}
    Изображение: {{$rsps.medium}}
    Высокое разрешение: {{$rsps.original}} return !(lead.getAttr("photoThemeFound") == 1); Фото по теме "{{$photoTheme}}" не найдены.

    Заполняем скрипт SHOW_NEXT_PHOTOshow_next_photo

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

      1 извлечение из Лидалида параметров запроса,запроса; 2 выполнение запроса и заполнение атрибутов в memory и lead,lead; 3 сохранение переменных для отладки. 

      Команда запроса темы не нужна, так как она определена в скрипте выбора темы и сохранена в атрибуте photo_themephotoTheme.

      // раздел 1: подготовка параметров restREST запроса
      
      var photo_themephotoTheme = lead.getAttr('photo_theme'photoTheme');
      var photo_theme_indexphotoThemeIndex = lead.getAttr('photo_theme_index'photoThemeIndex') * 1;
      photo_theme_indexphotoThemeIndex = photo_theme_indexphotoThemeIndex + 1;
      var url = "search?query=" + photo_themephotoTheme + "&page=" + photo_theme_indexphotoThemeIndex + "&per_page=1"
      var jsonBody = {};
      var headers = {};
      
      //----------------------------------------------------------
      
      // раздел 2
      
      lead.setAttr('url', url);
      memory.setAttr('photo_theme_found'photoThemeFound', 0);
      jsonResponse = api.getJson(url, jsonBody, headers);
      if (jsonResponse) {
        var rsps = jsonResponse;
        total_resultstotalResults = rsps['total_results'] * 1;
        if (total_resultstotalResults > 0 && photo_theme_indexphotoThemeIndex <= total_results)totalResults) {
          memory.setAttr('photo_theme_found'photoThemeFound', 1);
          lead.setAttr('rsps.total_results'totalResults', total_results)totalResults);
          lead.setAttr('photo_theme'photoTheme', photo_theme)photoTheme);
          lead.setAttr('photo_theme_index'photoThemeIndex', photo_theme_index)photoThemeIndex);
          memory.setAttr('rsps.photographer', rsps['photos'][0]['photographer']);
          memory.setAttr('rsps.original', rsps['photos'][0]['src'][ 'original' ]);
          memory.setAttr('rsps.medium', rsps['photos'][0]['src'][ 'medium' ]);
          memory.setAttr('rsps.next_page'nextPage', rsps['next_page']);
        }
        
      //----------------------------------------------------------
        
      // раздел 3
        
        memory.setJsonAttr("lastHttpResponse", api.getLastResponseContent());
        memory.setAttr("lastHttpResponseCode", api.getLastResponseCode());
      }
      
      //----------------------------------------------------------

      2. Аналогично создаем две команды вывода данных с условиями для отправки в канал необходимых атрибутов Лида.лида. Одна срабатывает в случае успешной выборки фото, другая в противоположном случае.

      image.pngimage.png

      Условие выполнения Текст команды return (memory.getAttr("photoThemeFound") == 1); "{{$photoTheme}}": {{$rsps.totalResults}} / {{$photoThemeIndex}}
      Фотограф: {{$rsps.photographer}}
      Изображение: {{$rsps.medium}}
      Высокое разрешение: {{$rsps.original}} return !(memory.getAttr("photoThemeFound") == 1); Фото не найдено.

      Запускаем бот!

      В

      1. Запускаем в канале TelegramTelegram.

      image.png

      В

      2. Запускаем в канале виджета MetabotMetabot.

      image.png

      Поздравляем с успешным созданием бота! Рекомендуем так же ознакомиться с остальными нашими уроками по созданию ботов.