31  /  36

Механизм оффлайн-событий

Просмотров: 1650 (Статистика ведётся с 06.02.2017)

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

Механизм оффлайн события используется для работы со сторонними информационными системами, например, с 1С. Выпуск планируется на начало-середину марта.

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

Внимание! Все методы работы с событиями, будь то установка/удаление обработчиков или чтение очереди, требуют наличия административных прав и доступны для выполнения только с авторизацией приложения. То есть вебхуки с этими методами работать не будут.

Записи в очереди аккумулируются по данным событий. Например, если в очереди уже ожидает событие ONCRMLEADUPDATE для лида с ID=10, то следующее обновление лида 10 не добавит новую запись, а только изменит дату существующей.

Установка обработчика события

Используется метод /rest/event.bind со значением event_type=offline. В этом случае параметр handler становится не обязательным, а параметр auth_type - бессмысленным.

Пример вызова:

https://myportal.bitrix24.com/rest/event.bind
  ?auth=0534845a0000cd7a0000cd5d00000001000003bc52a2dde6b58915beb0a09fcc57ed36
  &event=ONCRMLEADUPDATE
  &event_type=offline

HTTP/1.1 200 OK

{
    "result": true 
}

После вызова установки обработчика метод /rest/event.get выдает нам вот такую картину (обычный обработчик события добавил для сравнения):

https://myportal.bitrix24.com/rest/event.get
  ?auth=0534845a0000cd7a0000cd5d00000001000003bc52a2dde6b58915beb0a09fcc57ed36

HTTP/1.1 200 OK

{
    "result": [
        {
            "connector_id": "", 
            "event": "ONCRMLEADUPDATE", 
            "offline": 1
        }, 
        {
            "auth_type": "0", 
            "event": "ONCRMLEADUPDATE", 
            "handler": "http://apphost.com/handler/", 
            "offline": 0
        }
    ]
}

Для отписки от события используется тот же самый метод /rest/event.unbind, вызываемый с теми же параметрами, что и event.bind.

Далее происходит разбор очереди событий.

Простая схема

Если приложение вызывает метод /rest/event.offline.get, то портал отдаст первые 50 событий, удовлетворяющих фильтру и в заданном порядке сортировки, и сразу вычистит их из базы.

https://myportal.bitrix24.com/rest/event.offline.get
  ?auth=0534845a0000cd7a0000cd5d00000001000003bc52a2dde6b58915beb0a09fcc57ed36

HTTP/1.1 200 OK

{
    "result": {
        "events": [
            {
                "EVENT_ADDITIONAL": {
                    "user_id": "1"
                }, 
                "EVENT_DATA": {
                    "FIELDS": {
                        "ID": 28
                    }
                }, 
                "EVENT_NAME": "ONCRMLEADUPDATE", 
                "ID": "40", 
                "MESSAGE_ID": "438d4ec3d329464c4bb9909db4c7a19b", 
                "TIMESTAMP_X": "2018-02-14T14:20:19+02:00"
            }
        ], 
        "process_id": null
    }
}

Поля записей массива events
ID Идентификатор записи очереди событий
TIMESTAMP_X Дата последнего срабатывания события
EVENT_NAME Имя события
EVENT_DATA Данные события
EVENT_ADDITIONAL Дополнительные параметры события. Пока содержит единственный параметр - ID пользователя, спровоцировавшего последнее срабатывание события.
MESSAGE_ID Уникальные идентификатор "срабатывания" события. Представляет собой хэш от типа события и данных события. То есть, все события ONCRMLEADUPDATE с данными {FIELDS:{ID:28}} будут иметь один и тот же MESSAGE_ID, и по нему будут объединены в одну запись. Используется в контроле ошибок по усложнённой схеме

Метод event.offline.get поддерживает многопоточный разбор. То есть допускается несколько параллельных запросов к методу (с соблюдением ограничений на количество запросов в единицу времени), и каждый из них получит разные наборы записей.

Усложнённая схема

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


Получение записей

Включается эта схема добавлением параметра clear=0 к вызову event.offline.get.

https://myportal.bitrix24.com/rest/event.offline.get
  ?auth=0534845a0000cd7a0000cd5d00000001000003bc52a2dde6b58915beb0a09fcc57ed36
  &clear=0

HTTP/1.1 200 OK

{
    "result": {
        "events": [
            {
                "EVENT_ADDITIONAL": {
                    "user_id": "1"
                }, 
                "EVENT_DATA": {
                    "FIELDS": {
                        "ID": 28
                    }
                }, 
                "EVENT_NAME": "ONCRMLEADUPDATE", 
                "ID": "45", 
                "MESSAGE_ID": "438d4ec3d329464c4bb9909db4c7a19b", 
                "TIMESTAMP_X": "2018-02-14T14:43:13+02:00"
            }
        ], 
        "process_id": "5xcvetmo5zm5li73qxnj8qu72e2qrxw8"
    }
}

Обратите внимание на поле process_id в ответе. После такого вызова записи остаются в базе, но помечаются как обрабатываемые процессом с этим идентификатором. И далее не учитываются ни при каких последующих выборках и при добавлении новых событий.

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


Очистка записей

Очистка производится вызовом метода /rest/event.offline.clear, который принимает на вход process_id и массив идентификаторов записей, которые нужно удалить.

https://myportal.bitrix24.com/rest/event.offline.clear
  ?auth=0534845a0000cd7a0000cd5d00000001000003bc52a2dde6b58915beb0a09fcc57ed36
  &process_id=5xcvetmo5zm5li73qxnj8qu72e2qrxw8

HTTP/1.1 200 OK

{
    "result": true
}
Внимание! В параметре id ожидается массив идентификаторов записей из очереди событий, а не, например, идентификаторов лидов CRM. То есть, в примере выше, result.events[].ID, а не result.events[].EVENT_DATA.FIELDS.ID.

Обработка ошибок

При создании сложных интеграций, для которых и предназначена усложнённая схема, вполне возможна ситуация, когда возникает конфликт данных различных систем. В этом случает требуется человеческий контроль или использование какого-то другого способа разрешения конфликтов. Чтобы при этом не стопорить процесс и не копить ошибки, некоторые записи о событиях можно оставлять в базе с пометкой об их ошибочности. Для этого используется метод /rest/event.offline.error.

https://myportal.bitrix24.com/rest/event.offline.error
  ?auth=4742845a0000cd7a0000cd5d0000000100000386a97f24a7f515e9ec5e242fed727af4
  &process_id=cal3dm2qg31gb3g8uatca6huqjdtdn6u
  &message_id[]=438d4ec3d329464c4bb9909db4c7a19b

HTTP/1.1 200 OK

{
    "result": true
}

После выставления флага об ошибке помеченные записи перестанут отдаваться приложению при вызове event.offline.get. Перестают отдаваться как сама помеченная запись, так и все последующие срабатывания события с этими данными. Иными словами, изменения этой сущности на стороне Битрикс24 перестанут передаваться в приложение, пока приложение не даст разрешение на передачу. Также, запись отвяжется от текущего процесса, и не будет удалена при вызове event.offline.clear. Если за время обработки были срабатывания события с такими данными, они также передаются приложению, даже если уже были захвачены другим процессом.


Разрешение ошибок

Чтобы снять пометку об ошибке с записи, нужно вычистить ее из базы при помощи event.offline.get с указанием параметра error=1. И, при необходимости, с дополнительным фильтром, если нужно обработать только часть ошибок. Сразу после вызова ошибочные записи будут вычищены из базы (если указать clear=1), либо помечены как обрабатываемые (если указать clear=0). В обоих случаях новые события с такими данными снова начнут регистрироваться и отдаваться приложению.


Простое получение состояния очереди

Иногда может потребоваться считать текущую очередь, не внося изменений в ее состояние, как это делает event.offline.get, и не завися от сложной логики пометки ошибочных событий или раскидывания событий по процессам. Для этого сделан простой списочный метод /rest/event.offline.list:

https://myportal.bitrix24.com/rest/event.offline.list
  ?auth=4742845a0000cd7a0000cd5d0000000100000386a97f24a7f515e9ec5e242fed727af4

HTTP/1.1 200 OK

{
    "result": [
        {
            "ERROR": "0", 
            "EVENT_ADDITIONAL": {
                "user_id": "1"
            }, 
            "EVENT_DATA": {
                "FIELDS": {
                    "ID": 28
                }
            }, 
            "EVENT_NAME": "ONCRMLEADUPDATE", 
            "ID": "60", 
            "MESSAGE_ID": "438d4ec3d329464c4bb9909db4c7a19b", 
            "PROCESS_ID": "", 
            "TIMESTAMP_X": "2018-02-14T15:34:34+02:00"
        }, 
        {
            "ERROR": "0", 
            "EVENT_ADDITIONAL": {
                "user_id": "1"
            }, 
            "EVENT_DATA": {
                "FIELDS": {
                    "ID": 27
                }
            }, 
            "EVENT_NAME": "ONCRMLEADUPDATE", 
            "ID": "65", 
            "MESSAGE_ID": "7bf367ea2e4c9b6a8c3adac4a416627c", 
            "PROCESS_ID": "", 
            "TIMESTAMP_X": "2018-02-14T15:34:55+02:00"
        }
    ]
}


26
Курсы разработаны в компании «1С-Битрикс»

Если вы нашли неточность в тексте, непонятное объяснение, пожалуйста, сообщите нам об этом в комментариях.
Развернуть комментарии