QuBot: 4. Общение ботов


Введение

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


Клиентский бот и бот-админка

Пусть есть бот под названием ping. Его пользователи совершают некоторые действия, результаты которых должны оперативно попадать в другой бот pong, который просматривает администратор бота ping. События пользователей в боте ping будут двух видов - заказ еды и заполнение анкеты в HR-разделе. Кроме этого, из административного бота pong можно будет посылать в бот ping уведомления о новостях компании и при необходимости их редактировать.

Создадим два файла ping.yml и pong.yml, которые разместим в одной папке. Чтобы боты могли обмениваться сообщениями, в разделе bot в свойстве senders перечислиим ботов от которых могут быть приняты сообщения:

# ping.yml
bot:
    senders: [ pong ] # получаем от pong-а
# pong.yml
bot:
    senders: [ ping ] # получаем от ping-а


Посылка сообщений

Предположим, что в разделе HR была собрана информация о соискателе, которая помещена в слоты HR_NAME (имя соискателя), HR_DESCR (информация о соискателе) и HR_PHONE (телефон соискателя). После совершения собеседования, пошлём в бот pong сообщение при помощи действия ACTION_MESSAGE_SEND:

# ping.yml
states:
    RUN_SEND_MESSAGE:
      - action: ACTION_MESSAGE_SEND    # послать сообщение
        bots: [ pong ]                 # список ботов-получателей
        group: hr                      # к какой группе относится сообщение
        content:                       # содержание сообщения
          - text: |
                  $HR_NAME: $HR_DESCR
                  phone: $HR_PHONE"
          - image:  im/girl.png
            caption: "Это я!"

В аргументе действия bots перечисляется список названий ботов которым адресовано сообщение. Необязательный аргумент group - это строка обозначающая группу сообщений, которая может анализироваться получателем (например, показывая сообщения только из данной группы). Наконец, аргумент content содержит собственно сообщение и состоит из списка визуальных объектов text и при необходимости image.


Приём сообщений

Пришедшие сообщения находятся во встроенном слоте MESSAGES типа list. Сделаем, например, на главном экране кнопку "📪 Наши новости" в которую добавим длину списка MESSAGES (функция len):

# ping.yml
    SCR_MAIN:
      - block:
            clear: 0
    
      - text: "Приветствую Вас в лучшем ресторане на побережье!"
    
      - buttons:
          - button: "🍹 Заказ на вынос"                        
            state: SCR_RESTORAN
            
          - button: "👫 Работа у нас"                        
            state: SCR_JOB
            
          - button: "📪 Наши новости ({len($MESSAGES))"            
            state: SCR_SHOW_NEWS
    
      - message:

Приход сообщения, это такое же событие как нажатие кнопки (button) или ввод текста (input). Ему соответствует объект message, список объектов которого запустится при приходе сообщения. Выше этот список пустой. Пусть бот находится в состоянии SCR_MAIN и приходит сообщение. Так как внутри message нет state, произойдёт повторный показ состояния SCR_MAIN и на кнопке "📪 Наши новости (1) появится единица (общее число сообщений).


Показ сообщений

Выведем список сообщений по нажатию кнопки "📪 Наши новости", перейдя в состояние SCR_SHOW_NEWS. Так как слот MESSAGES имеет тип list, можно воспользоваться действием ACTION_LIST_SHOW:

# ping.yml
    SCR_SHOW_NEWS:
      - block:
            clear: -1                   # очищаем ленту бота
    
      - action: ACTION_LIST_SHOW        # выводим список,
        list:   MESSAGES                # хранящийся в слоте MESSAGES
        result:
            empty:                      # что показать, если сообщений нет
              - text: "Пока новостей нет"          
              
            item:                       # каждое сообщение 
              - block:                  # выводим в отдельной "плашке"
              - text: "$LIST_ITEM_INDEX. $_DATE $_TIME\n"
                p: false
              - show: $_CONTENT
              
      - buttons:
          - button: "↻ Назад"
            state: PREV_STATE    

MESSAGES является списком объектов которые могут содержать достаточно много ключей. Среди них обязательно присутствует _DATE (дата посылки сообщения) и _TIME (время посылки), которые сначала выводятся в разделе item. Содержимое сообщения находится в поле _CONTENT. Так как это список визуальных компонент, для его отображения нужно вызвать объект show.

Аналогично можно фильтровать сообщения по ключу _GROUP. Так, в административном боте pong, если нужно показать только сообщения из группы hr, надо в ACTION_LIST_SHOW добавить аргумент equal:

# pong.yml
      #...
      - action: ACTION_LIST_SHOW        
        list:   MESSAGES                
        equal:  { _GROUP: hr }          # покажем только сообщения из этой группы
        result:            
            item:                       
              - block:                  
              - text: "$LIST_ITEM_INDEX. $_DATE $_TIME\n"
                p: false
              - show: $_CONTENT

Удаление сообщений

Список сообщений MESSAGES можно очистить, как обычно, при помощи действия ACTION_LIST_CLEAR. Иногда требуется очистить список сообщений (весь или последние) в другом боте. Например, из административного бота pong можно очистить новости в боте ping. Для этого сообщение посылается с аргументом clear:

# pong.yml
    SCR_CLEAR_ALL_CLIENTS_MESSAGES:
    
      - text: "Вы уверены? Все сообщения вашим клиентам будут удалены."
      - state: SCR_SEND_MESSAGE
      
      - buttons:
          - row:
              - button: "👌 Да"
                actions:
                  - action: ACTION_MESSAGE_SEND
                    bots: [ ping ]                      
                    clear: -1                                    
                    
              - button: "❌ Нет"
Если clear равно -1, то удаляются все сообщения. Если clear равно n > 0 - удаляется n последних сообщений у всех пользователей бота ping.

Отправка конкретным пользователям

В QuBot доступны два встроенных слота:


Раздел default


Выполнение действий в другом боте