В этой статье я хочу описать простой пример работы мультипротокольного бота через Microsoft Bot Connector API — v3.0. На тему skype подобных ботов уже есть статьи на Хабре: «Как создать своего бота для Skype. Что не написано в документации» от and7ey и «Hello, Bot! Чат-боты – следующее поколение приложений?» от shwars. Но в первой идёт речь про работу через apis.skype и описанный там вариант не мультипротокольный, а во второй описана реализация через C#, а я в него не умею.

Кому и зачем нужна эта статья


Во-первых, «тому парню», который хочет сделать своего бота, но не умеет в C#, а умеет в REST.

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

Авторизация


В полной мере (на сколько я смог оценить) рассмотрена в статье, которую я упомянул выше — в этой. Делаем как описано, получаем token и начало положено — мы «на первой базе» (это не общепринятая аналогия про базы, где на третьей нам дадут жмакнуть сиську, нет, это не она).

Получение сообщений


У бота должен быть endpoint, куда будут приходить запросы с json-телом. Например, отправленное для бота сообщение через skype с текстом «привет, бот» придет таким:

json
{  
   "type":"message",
   "id":"1q80QckzCi3wL6zg",
   "timestamp":"2016-08-16T12:56:16.49Z",
   "serviceUrl":"https://skype.botframework.com",
   "channelId":"skype",
   "from":{  
      "id":"29:1Phe2HAxz6CD9uc1O_PVl_Zih6doxIe_KuyrQ9eANUbs",
      "name":"avvero"
   },
   "conversation":{  
      "id":"29:1Phe2HAxz6CD9uc1O_PVl_Zih6doxIe_KuyrQ9eANUbs"
   },
   "recipient":{  
      "id":"28:300cbb48-78e0-4998-8e85-4f4c7ccb5aee",
      "name":"notify_bot"
   },
   "text":"привет, бот",
   "entities":[  

   ]

}

Что нам особенно важно в этом запросе:

  • conversation.id — идентификатор беседы
  • channelId — идентификатор канала

Эти два параметра особенно важны, потому что на основе их определяется url для отправки запросов в botframework. При этом, роль conversationId упомянута в описании API (swagger), а вот с channelId не все так очевидно, точнее нифига (технический термин) не очевидно. Например, сообщения от бота для канала skype должны пойти сюда:

https://skype.botframework.com/v3/conversations/{conversationId}/activities,

А для telegram сюда:

https://telegram.botframework.com/v3/conversations/{conversationId}/activities.

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

Отправка сообщений


Для skype минимальное тело запроса будет таким:

json
{  
   "type":"message",
   "text":"hello"
}


А для telegram таким (нужен объект from):

json
{  
   "type":"message",
   "from":{  
      "id":"avvero_notify_bot",
      "name":"avvero"
   },
   "text":"hello"
}

Карточки


Не текстами едиными. Можно отправлять и карточки (здесь приведен пример сообщения для telegram, для skype можно без from):

json
{ 
   "type":"message",
   "from":{ 
      "id":"avvero_notify_bot",
      "name":"avvero"
   },
   "text":"hello",
   "attachments":[ 
      { 
         "contentType":"application/vnd.microsoft.card.hero",
         "content":{ 
            "title":"title",
            "subtitle":"subtitle",
            "text":"text",
            "images":[ 
               { 
                  "url":"https://pp.vk.me/c7011/v7011856/3160d/HVELORSo5KM.jpg",
                  "alt":"hello thumb"
               }
            ],
            "buttons":[ 
               { 
                  "type":"imBack",
                  "title":"Да",
                  "value":"yes <context offer=\"...\"/>"
               },
               { 
                  "type":"imBack",
                  "title":"Нет",
                  "value":"no"
               },
               { 
                  "type":"openUrl",
                  "title":"Загуглить",
                  "value":"https://disney.radisson.com"
               }
            ]
         }
      }
   ]
}

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



В telegram так:



Конец


Ну вот в принципе и все, что я хотел рассказать. Стоит упомянуть проблемы при использовании такого бота.

Для skype:

  • нужна свежая версия клиента (на linux совсем старая и боты там не пойдут)
  • одного бота я добавил как простой контакт — через поиск, второго бота так добавить не получилось, получилось только через ссылку типа такой join.skype.com/bot/6877d5c8-dc4f-4eda-9aac-29b19e1761f0

Для telegram:

  • Не получается обращаться к боту в группе через знак @, сообщения боту не идут, сообщения идут боту если перед сообщением ставить знак /, т.е. так "/привет бот"

Спасибо за внимание!
Поделиться с друзьями
-->

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


  1. lair
    18.08.2016 13:42

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

    В документации написано, что сообщения должны идти на serviceUrl. channelId тут не важен.


    "NOTE: Even though ServiceUrl values may seem stable bots should not rely on that and instead always use the ServiceUrl value "


    1. Avvero
      18.08.2016 13:49

      Получается, что мне повезло в том, что channelId совпал с префиксом доменного имени. Странно, что этот момент не отражен в разделе описания REST API. Спасибо.


  1. may-cat
    18.08.2016 18:41

    Пробовал вести разработку на их платформе — не смог добавить бота в группу.


    1. Avvero
      19.08.2016 03:25

      А Вы включали «Group messaging» в настройках skype канала тут — https://skype.botframework.com/Dev/?botId={имя_бота}?


      1. may-cat
        19.08.2016 11:10

        Включал.
        Но при попытке «перетащить» бота в группу или добавить его через интерфейсы скайпа — ничего не происходит. Скайп будто игнорирует эти действия. Проверено на веб-версии и Skype for desktop 7.26


    1. lair
      19.08.2016 11:23

      На самом деле, это зависит от того, какая у вас группа — "старая" или "новая" (да, они разные). В старые добавить не получится никак. И это к платформе отношения не имеет, это проблема любого скайп-бота.


      1. may-cat
        19.08.2016 11:24

        Пробовал и в те и в те. Увы.


  1. Don_Peredon
    20.08.2016 14:45

    Может кто подскажет, есть такая проблема. После того как я выложил на Heroku своего бота(node.js) он работает, но после часа он идет спать и после этого он не отвечает. Приходиться в ручную будить или через браузер переходить на свай проект тогда просыпается. Но через Telegram будить не хочет.


    1. Avvero
      20.08.2016 14:51

      А какой у вас план подписки? Если free, то контейнер «засыпает» после 30-и минут не активности. Он вроде должен просыпаться, когда на endpoint что-то приходит, но не факт, что пробуждающий запрос будет правильно обработан.


      1. Don_Peredon
        20.08.2016 23:32

        Спасибо за ответ. Все решилось при использование WebHook, а я пытался через long polling)) т.e его работа заключается в опросе чата Telegram, и он не может сделать запрос на сервер что бы разбудить Heroku. А WebHook при каждом изменений в чате отправляет POST, и в случаи спячки, будит его)