Создаем структуру простого мультиплатформенного бота

На самом деле мы сделали два бота. Зачем мы их создали, как один помогает другому и что такое платформонезависимые абстракции — в материале на Хабре.



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

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

Давайте познакомимся с нашим ботом. Его можно найти в Telegram, VK, FB, где он обслуживает одновременно до нескольких тысяч человек (как бывает на крупных мероприятиях). Кстати, о том, кто мы и чем занимаемся, можно узнать из нашей первой статьи. Если кратко, оперируем огромной сетью бесплатных коворкингов и пространств для презентаций по всей России и одновременно поддерживаем коммуникационную платформу Leader-ID, являющуюся ядром всей системы. И бот играет во всей этой истории немаловажную роль.

Double gun — double fun

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



Второй бот — по сути интерфейс для операторов поддержки. Работают боты в связке, но базы и интерфейсы у них разнесены.

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

Структура самого простого бота

В базовом варианте бот будет состоять из одного лишь сервиса, отправляющего и принимающего сообщения через API нужного нам мессенджера (платформы), например Telegram.

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



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

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

Организуем общение коннекторов и ядра (поллинг БД, или Как делать не надо)

Итак, перед нами стоит задача организовать обмен данными между коннекторами и ядром. Первый вариант — передавать новые сообщения через БД. Мы с этого начинали. Соответственно, в нашей схеме появляется сама БД, а структура становится вот такой: ядро, написанное на Python, плюс база на MongoDB (причины такого выбора исключительно исторические), плюс коннекторы.



Эта схема проработала у нас относительно недолго. Когда количество сообщений перевалило за 700 тыс., а частота в пиках достигала до 120 обращений в секунду, индексы стали тяжелее, поллинг БД стал ощутимо дороже. Пришлось подключить сюда брокер RabbitMQ. Основная его роль – генерить уведомления, что компоненту (ядру/коннектору) следует обработать сообщение с конкретным айдишником. Эти айдишники и передаются через него. RabbitMQ разгрузил нам базу и компоненты, которым теперь не нужно все время проверять БД на наличие новой информации для обработки.

В итоге наша базовая структура стала выглядеть так:



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

Добавляем администраторов

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



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

Сам интерфейс для администраторов у нас выглядит так:

Подключаем операторов через второго бота

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

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

Фраза «Тестовый вопрос» на скриншоте является текстом вопроса для техподдержки

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



Также у него своя БД. Но общение с конечным пользователем идет через ядро основного бота, которое управляет общим потоком сообщений.

Вот как выглядит диалог оператора с ботом поддержки, который переадресовывает сообщения пользователей:



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

Что еще умеет наш бот

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

Обмен контактами

Осуществляется он через сканирование и распознавание личных QR-кодов из бота. Для этого в ядро добавляется дефолтный обработчик картинок. Пересылкой изображений занимаются коннекторы, которые сохраняют их в БД вместе с сообщением.

Распознавание QR-кодов также используется для выдачи пользователю дополнительной информации или файлов с семинаров. Выглядит это так:

Рассылка уведомлений



Через панель управления в модуле web мы можем рассылать уведомления участникам тех или иных мероприятий.

Проведение опросов

Аналогичным образом проводятся опросы во время лекций. Но для них мы пока вручную формируем JSON-файл с логикой, который подгружаем в web.

Вопросы могут быть как с вариантами ответов, так и открытые. А структура опроса может меняться в зависимости от ответов.

Автоматические ответы

Бот может самостоятельно подбирать ответы на часто задаваемые вопросы.



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

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

Другие материалы на Хабре: