Моя предыдущая статья про разработку чат-бота для Facebook Messenger показала что тема интересна обитателям Хабра, поэтому я продолжаю.
Сегодня у нас будет разработка бота для Битрикс24 мессенджера. Язык разработки тот же — PHP.

Общая информация


Платформа для чат-ботов Битркис24 появилась в конце марта этого года.
На момент написания бота, в GitHub не было библиотеки на PHP, поэтому я написал свою — github.com/pimax/bitrix24-bot-php

Пишем код


Самый простой вариант, выполнить клонирование репозитория github.com/pimax/bitrix24-bot-php-example

git clone https://github.com/pimax/bitrix24-bot-php-example.git .
composer install
cp config_example.php config.php

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

Поясню подробнее основную часть демо-бота.
Всего, Битрикс24 передает 4 типа событий на webhook:

ONAPPINSTALL — Установка бота на портал


$bot->install(new Bot(
    $config['alias'],
    $config['type'],
    $config['url_message_add'],
    $config['url_welcome_message'],
    $config['url_bot_delete'],
    $config['data']
));

Здесь все элементарно — берем данные из конфига нашего приложения и регистрируем бота на портале.
Этот код вряд ли будет меняться у вас.

ONIMBOTDELETE — Удаление бота


$bot->uninstall();

Удаляем бота с портала.
Аналогично предыдущему, меняться вряд ли будет.

ONIMBOTJOINCHAT — Приглашение бота в чат


$bot->send(new Message("Hello", $_REQUEST['data']['PARAMS']['DIALOG_ID'], [
    new Message('[send=/command1]Command 1[/send]'),
    new Message('[send=/command2]Command 2[/send]'),
    new Message('[send=/command3]Command 3[/send]'),
]));

Вот здесь уже возможны варианты. Хорошим тоном является поведение, при котором в первом сообщении бот сообщит свои команды пользователю. Чтобы пользователь не вводил команды вручную, в Битрикс24 предусмотрели код [send], отправляющий сообщение боту при клике на ссылку.

Вот так это выглядит:



ONIMBOTMESSAGEADD — Получение сообщения от пользователя


Основной тип для нас.
В нем мы должны понять, что хочет пользователь от бота, подготовить ответ, и отправить ответ пользователю.

switch ($_REQUEST['data']['PARAMS']['MESSAGE'])
{
    case '/command1':
        $bot->send(new Message("Command 1 response", $_REQUEST['data']['PARAMS']['DIALOG_ID']));
    break;
    case '/command2':
        $bot->send(new Message("Command 2 response", $_REQUEST['data']['PARAMS']['DIALOG_ID']));
    break;
    case '/command3':
        $bot->send(new Message("Command 3 response", $_REQUEST['data']['PARAMS']['DIALOG_ID']));
    break;
    default:
        $bot->send(new Message("Hello", $_REQUEST['data']['PARAMS']['DIALOG_ID'], [
            new Message('[send=/command1]Command 1[/send]'),
            new Message('[send=/command2]Command 2[/send]'),
            new Message('[send=/command3]Command 3[/send]'),
        ]));
}

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

Размещение приложения


Переходим в раздел Приложения > Добавить приложение своего портала.

Указываем название приложения, отмечаем галочку «Приложение использует только API».
В правах доступа отмечаем «Создание и управление Чат-ботами».
В поля Укажите ссылку и укажите callback-ссылку для события установки указываем ссылку на нашего бота, например: example.com/apps/bitrix24
Нажимаем кнопку сохранить.

Реальный пример Бота для фриланс-биржи Job4Joy


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

Итак, наша цель, реализовать бота, который по нашему запросу будет выдавать новые проекты в соответствующей категории.
Данные будем получать по RSS, используя picoFeed — github.com/fguillot/picoFeed
И github.com/SebastianM/GooglShortener для сокращения ссылок.

Выполняем

git clone https://github.com/pimax/bitrix24-bot-php-example.git .
composer install
cp config_example.php config.php

Далее, правим config.php и добавляем список фидов и токен для goo.gl:

'google_token' => '',

'feeds' => [
    '/all' => [
        'Title' => 'All jobs',
        'Feed' => 'https://job4joy.com/marketplace/rss/'
    ],
    '/webdev' => [
        'Title' => 'Web Development',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=3'
    ],
    '/software' => [
        'Title' => 'Software Development & IT',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=5'
    ],
    '/design' => [
        'Title' => 'Design & Multimedia',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=2'
    ],
    '/mobile' => [
        'Title' => 'Mobile Application',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=7'
    ],
    '/server' => [
        'Title' => 'Host & Server Management',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=6'
    ],
    '/writing' => [
        'Title' => 'Writing',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=8'
    ],
    '/customer' => [
        'Title' => 'Customer Service',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=10'
    ],
    '/marketing' => [
        'Title' => 'Marketing',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=11'
    ],
    '/business' => [
        'Title' => 'Business Services',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=12'
    ],
    '/translations' => [
        'Title' => 'Translation & Languages',
        'Feed' => 'https://job4joy.com/marketplace/rss/?id=14'
    ]
]

Создаем файл messages/ru.php, со следующим содержимым:

<?php
return [
    'Hello! I can help you with IT projects.' => 'Привет! Я помогу с проектами в сфере ИТ.',
    'find work & hire freelancers' => 'Работа в сфере ИТ',
    'All jobs' => 'Все проекты',
    'Web Development' => 'Веб-разработка',
    'Software Development & IT' => 'Разработка ПО',
    'Design & Multimedia' => 'Дизайн и мультимедиа',
    'Mobile Application' => 'Мобильные приложения',
    'Host & Server Management' => 'Хостинг и сервера',
    'Writing' => 'Тексты',
    'Customer Service' => 'Поддержка клиентов',
    'Marketing' => 'Маркетинг',
    'Business Services' => 'Бизнес услуги',
    'Translation & Languages' => 'Переводы',
    'New projects not a found!' => 'Новые проекты не найдены!'
];

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

В index.php добавляем подключение библиотеки GoogleShortener:

require_once (dirname(__FILE__) .'/GooglShortener.php');
$googl = new GooglShortener($config['google_token']);

Напишем сразу функцию логирования:

/**
 * Log
 *
 * @param mixed $data Data
 * @param string $title Title
 * @return bool
 */
function writeToLog($data, $title = '')
{
    $log = "\n------------------------\n";
    $log .= date("Y.m.d G:i:s") . "\n";
    $log .= (strlen($title) > 0 ? $title : 'DEBUG') . "\n";
    $log .= print_r($data, 1);
    $log .= "\n------------------------\n";

    file_put_contents(__DIR__ . '/imbot.log', $log, FILE_APPEND);

    return true;
}

Далее пишем функцию приветственного сообщения бота:

/**
 * Send Help Message
 *
 * @param $bot Bot instance
 * @return bool
 */
function sendHelpMessage($bot)
{
    global $config;
    $attach = [];
    foreach ($config['feeds'] as $com => $feed)
    {
        $attach[] = new Message('[send='.$com.']'.$bot->t($feed['Title']).'[/send]');
    }
    $bot->send(new Message($bot->t('Hello! I can help you with IT projects.'), $_REQUEST['data']['PARAMS']['DIALOG_ID'], $attach));
    return true;
}

Дальше, напишем функцию, для получения списка проектов по конкретному фиду и отправку сообщений пользователю:

/**
 * Get Feed Data
 *
 * @param $feed Feed data
 * @param $bot Bot instance
 * @return bool
 */
function getFeed($feed, $bot)
{
    global $googl;
    try {
        $reader = new Reader;
        $resource = $reader->download($feed['Feed']);
        $parser = $reader->getParser(
            $resource->getUrl(),
            $resource->getContent(),
            $resource->getEncoding()
        );
        $feed = $parser->execute();
        $items = array_reverse($feed->getItems());
        if (count($items)) {
            foreach ($items as $itm)
            {
                $url = $googl->shorten($itm->getUrl());
                $message = substr(strip_tags($itm->getContent()), 0, 150);
                $bot->send(new Message("[B]".$itm->getTitle() . "[/B]\n" . $message . "\n", $_REQUEST['data']['PARAMS']['DIALOG_ID']), [
                    new Link($url->id, $url->id)
                ]);
            }
        } else {
            $bot->send(new Message($bot->t('New projects not a found!'), $_REQUEST['data']['PARAMS']['DIALOG_ID']));
        }
    }
    catch (Exception $e) {
        writeToLog($e->getMessage(), 'Exception');
    }
    return true;
}

Вот и все. Полный код выложен на GitHub — github.com/pimax/job4joy_bitrix24bot

Публикация в каталоге для всех


Сейчас приложение доступно только для пользователей вашего портала.
Для того, чтобы опубликовать приложения в каталоге для всех, необходимо стать партнером 1С-Битрикс.
Подробная информация по этому процессу приведена здесь — www.bitrix24.ru/apps/dev.php

Заключение


В целом платформа производит достаточно приятные впечатления, не смотря на свой молодой возраст.
Самый большой минус для разработчиков — это довольно продолжительное время модерации. Счёт может идти на недели без преувеличения. Возможно, это из-за большой нагрузки на модераторов и они не успевают. На сегодня, проблема характерна для многих мессенджеров.

Полезные ссылки


  1. Статья на сайте 1С-Битрикс про платфору для чат-ботов — dev.1c-bitrix.ru/community/blogs/marketplace_apps24/we-present-a-platform-for-chatbots-for-bitrix24.php
  2. Bitrix24 Bot PHP SDK — github.com/pimax/bitrix24-bot-php
  3. Bitrix24 Bot PHP SDK Example — github.com/pimax/bitrix24-bot-php-example
  4. Job4Joy Bot PHP Sources — github.com/pimax/job4joy_bitrix24bot

Комментарии (4)


  1. Suvitruf
    21.04.2016 11:23

    catch (Exception $e) {}
    

    не надо так


    1. pimax
      21.04.2016 11:29

      Это же пример. Можете обработать исключение как считаете нужным.


      1. Fesor
        21.04.2016 16:47

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


        1. pimax
          21.04.2016 16:55

          Добавил логирование исключительных ситуаций, как и в статье про Facebook messenger.