Потоки событий (WebHooks)

Мегаплан может уведомлять об изменениях сущностей по HTTP (WebHooks).

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

../_images/app_edit.png

Приложение на скриншоте будет подписано на изменения таких сущностей как клиенты, задачи и проекты.

В данный момент, доступны следующие опциональные потоки:

  • клиенты (contractors)

  • сделки (deals)

  • события (events)

  • задачи (tasks)

  • проекты (projects)

  • сотрудники (employees)

  • счета (invoices)

  • финансовые операции (operations)

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

События будут приходить на указанный URL(в приведённом примере это https://example.com), в виде HTTPS POST-запросов, в теле которых будут содержаться данные о сущности.

Важно! Самоподписанные сертификаты не поддерживаются.

Пример структуры события

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

{
    "data": {
        "id": "43",
        "name": "№1",
        "price": {
            "value": 188,
            "currency": "RUB",
            "contentType": "Money"
        },
        "manager": {
            "id": "1000001",
            "age": null,
            "uid": 1000075,
            "name": "User Name",
            "avatar": null,
            "birthday": null,
            "lastName": "Name",
            "position": "Директор",
            "firstName": "User",
            "middleName": "",
            "contactInfo": [
                {
                    "type": "email",
                    "value": "[email protected]",
                    "comment": "",
                    "contentType": "ContactInfo"
                },
                {
                    "type": "mobile",
                    "number": "0000000",
                    "comment": "",
                    "areaCode": "910",
                    "contentType": "Phone",
                    "countryCode": 7
                }
            ],
            "contentType": "Employee"
        },
        "invoices": [],
        "positions": [
            {
                "id": "85",
                "name": "То",
                "count": 1,
                "contentType": "DealPosition"
            },
            {
                "id": "94",
                "name": "Это",
                "count": 2,
                "contentType": "DealPosition"
            }
        ],
        "contractor": {
            "id": "1000251",
            "type": {
                "id": "1",
                "name": "Клиент",
                "type": "client",
                "contentType": "ContractorType"
            },
            "avatar": null,
            "gender": "male",
            "status": null,
            "company": null,
            "birthday": null,
            "lastName": "Какой-то",
            "position": "",
            "firstName": "клиент",
            "canSeeFull": true,
            "isFavorite": false,
            "middleName": "",
            "contactInfo": [],
            "contentType": "ContractorHuman",
            "description": "",
            "responsibles": [
                {
                    "id": "1000001",
                    "age": null,
                    "uid": 1000075,
                    "name": "User Name",
                    "avatar": null,
                    "birthday": null,
                    "lastName": "Name",
                    "position": "Директор",
                    "firstName": "User",
                    "middleName": "",
                    "contactInfo": [
                        {
                            "type": "email",
                            "value": "[email protected]",
                            "comment": "",
                            "contentType": "ContactInfo"
                        },
                        {
                            "type": "mobile",
                            "number": "0000000",
                            "comment": "",
                            "areaCode": "910",
                            "contentType": "Phone",
                            "countryCode": 7
                        }
                    ],
                    "contentType": "Employee"
                }
            ],
            "possibleActions": [
                "act_edit",
                "message",
                "task",
                "add_item",
                "add_deal"
            ],
            "preferTransport": "",
            "unreadNewsCount": 0,
            "availableActions": [],
            "dateLastReadNews": null
        },
        "isFavorite": false,
        "contentType": "Deal",
        "description": "Нам бы того и этого",
        "timeCreated": {
            "value": "2016-10-24T11:01:03+00:00",
            "contentType": "DateTime"
        },
        "currentState": {
            "id": "94",
            "name": "Сделка",
            "result": "active",
            "contentType": "DealState"
        },
        "positionsCount": 2,
        "shortDescription": "Сделка №1 с Какой-то клиент"
    },
    "uuid": "44b95294-1fcf-4f9f-bd57-a05ab3a68615",
    "event": "on_after_update",
    "model": "Deal",
    "accountId": "yourAccount.megaplan.ru",
    "fullEventName": "BumsTradeM_Deal.on_after_update",
    "integrationUuid": "4897ba31-28ec-48fb-a581-85cf8844a7d1",
    "accountInfo": {
        "id": "299",
        "accountName": "yourAccount.megaplan.ru",
        "contentType": "AccountInfo",
        "productName": "Совместная работа",
        "buildVersion": "r1802.20173.41",
        "permanentHost": "yourAccount.megaplan.ru"
    }
}

Рассмотрим подробнее, какая информация находится в теле события.

В приведённом примере можно увидеть блок "data". Он содержит в себе информацию о конкретной сущности, с которой связано событие.

Помимо этого блока, в теле события есть следующие поля:

  • "integrationUuid" - уникальный идентификатор приложения, по подписке которого было отправлено событие;

  • "uuid" - уникальный идентификатор события, по которому можно отфильтровать продублированное событие;

  • "model" - тип сущности, с которой связано событие;

  • "event" - тип события.

Возможные типы событий (значения поля "event"):

  • "on_after_create" - соответствует событию создания нового экземпляра сущности;

  • "on_after_update" - соответствует событию обновления/редактирования экземпляра сущности;

  • "on_after_drop" - соответствует событию удаления экземпляра сущности.

Для однозначной идентификации аккаунта Мегаплана, с которого пришло событие, можно использовать данные из блока "accountInfo":

  • "accountName" - доменное имя аккаунта;

  • "productName" - название подключенного тарифа;

  • "buildVersion" - версия продукта;

  • "permanentHost" - уникальный адрес аккаунта, присваивается при его создании и не меняется, если даже аккаунту изменяют доменное имя.

  • "uniqueAccountId" - это уникальный числовой идентификатор аккаунта. Он закреплен за аккаунтом даже после перевода оного на коробочную версию. И после смены имени аккаунта. Этот id отлично подходит в качестве ключа для хранения настроек аккаунта Мегаплана на стороне разработчика приложения.

Таким образом, событие с типом "on_after_create" из потока «deals» будет свидетельствовать о создании новой сделки в Мегаплане.

Необходимо отметить, что события типа "on_after_drop", в общем случае, не будут содержать полной информации в поле "data". Это связано с тем, что сущность уже удалена в Мегаплане на момент отправки события. Однако, всегда будет доступно поле "id", по значению которого можно однозначно идентифицировать сущность.

Важно! Приложение должно быть готово к тому, что ему придет больше 1 запроса, с одним и тем же событием. Для отсеивания дубликатов, в событии присутствует параметр "uuid", уникальный для события.

Событие считается успешно доставленным, если запрос уложился в 20 секунд и HTTP-статус ответа - 200 OK. Если попытка завершилась неудачей, то следующие попытки отправить событие будут осуществлены спустя некоторое время. При этом последующие события будут отправлены только после успешной обработки «проблемного» события.

События, связанные с приложением

Помимо вышеописанных потоков по сущностям Мегаплана, существуют события, связанные с самим приложением. Каждое приложение будет в обязательном порядке подписано на события своего изменения и удаления, включения и выключения, на события своих внутренних виджетов, при условии, что в настройках приложения заполнено поле «URL принимающий события».

Общая структура таких событий ничем не отличается. Событие обновления приложения, например, имеет следующую структуру:

{
    "data": {
        "name": "App for test",
        "uuid": "babf410e-53da-4b52-9be8-efa685bef725",
        "pageUri": "",
        "version": 1,
        "widgets": [],
        "isEnabled": true,
        "streamUri": "https://www.example.com",
        "identifier": "testing_app",
        "contentType": "Integration",
        "preferencesUri": "",
        "subscribedStreams": []
    },
    "uuid": "bf36262d-d057-4dba-8049-c345e9d321c6",
    "event": "on_after_update",
    "model": "Integration",
    "accountId": "yourAccount.megaplan.ru",
    "fullEventName": "bums\\integration\\m\\Integration.on_after_update",
    "integrationUuid": "babf410e-53da-4b52-9be8-efa685bef725"
}

Иногда необходимо отследить выключение или обратное включение приложения. Для этого необходимо проверить значение поля "isEnabled". Если значение true - приложение находится во включённом состоянии.

События создания, редактирования и удаления виджета приложения в поле "data" будут содержать информацию о самом виджете.

Если приложение устанавливается из каталога расширений Мегаплана, после установки, на «URL принимающий события» будет отправлено событие с типом "on_install":

{
    "data": {
        "name": "Testing",
        "uuid": "babf410e-53da-4b52-9be8-efa685bef725",
        "token": "YmVmODExOGZlOTZhMzg4YTQ1ZjJmODljMmJkOGU1YmQxYTBkNjM0ODE4NTRlODVhNTAzNzdiN2JjZWI0ZjA5NQ",
        "pageUri": "",
        "version": 1,
        "widgets": [],
        "isEnabled": true,
        "streamUri": "https:\/\/requestb.in\/sznzpwsz",
        "identifier": "testing_foo",
        "contentType": "Integration",
        "preferencesUri": "",
        "subscribedStreams": []
    },
    "uuid": "bf36262d-d057-4dba-8049-c345e9d321c6",
    "event": "on_install",
    "model": "Integration",
    "accountId": "yourAccount.megaplan.ru",
    "fullEventName": "bums\\integration\\Model\\Integration.on_install",
    "integrationUuid": "babf410e-53da-4b52-9be8-efa685bef725"
}

Cобытие установки приложения из каталога расширений Мегаплана содержит в себе токен-ключ приложения. Как видно из примера, значение токена хранится в одноименном поле("token"), внутри блока "data".

Установка приложения сопряжена с созданием нового приложения в Мегаплане, поэтому вместе с событием установки будет отправлено и событие создания.

Пример обработки событий на PHP есть в библиотеке.