0  /  48

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

Просмотров: 10488
Дата последнего изменения: 24.09.2021
Сложность урока:
4 уровень - сложно, требуется сосредоточится, внимание деталям и точному следованию инструкции.
1
2
3
4
5

Офлайн события

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

Механизм офлайн события используется для работы со сторонними информационными системами. Например, текущая интеграция продукта с целиком построена на офлайн событиях.

Преимущества офлайн событий:

  1. Простота использования - работа механизм очень проста;
  2. Надежность - при необходимости можно дополнительно контролировать факт получения и обработки данных во внешних системах;
  3. Универсальность - подходит для любой внешней системы или сервиса (не только для 1С);
  4. Возможность получения данных в режиме реального времени.

Отличительная особенность офлайн событий от обычных: если событие ещё не обработано, то его копии не создаются. Например: сделка изменена 5 раз. При использовании обычных событий - вызов обработчика выполнится 5 раз, а офлайн событий - оставит 1 запись в журнале об изменении сделки.

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

Схема работы

В общем виде работы схемы очень проста. Офлайн событие попадает в очередь офлайн событий. Потом внешняя система забирает их из очереди и обрабатывает.

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

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

Внимание! Офлайн события доступны на действующих тарифах:
  • Базовый
  • Стандартный
  • Профессиональный
  • NFR Специальная лицензия для партнёров

Полезные видеоматериалы:

Технологический поток 21.05.2021: Преимущества офлайн-событий, или как использовать REST правильно

Регистрация офлайн события

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

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

https://myportal.bitrix24.com/rest/event.bind
  ?auth=0534845a0000cd7a0000cd5d00000001000003bc52a2dde6b58915beb0a09fcc57ed36 // ключ авторизации
  &event=ONCRMLEADUPDATE // название события
  &event_type=offline // тип события
  &auth_connector=OneC // ключ источника

HTTP/1.1 200 OK

{
    "result": true 
}
Все основные параметры описаны в документации метода /rest/event.bind. На параметре &auth_connector остановимся немного подробнее.

Параметр &auth_connector

&auth_connector=OneC - ключ источника. Этот важный параметр отличает офлайн события от онлайн, т.к. позволяет исключать ложные срабатывания событий.

Что такое ложное срабатывание события?. Рассмотрим на примере:

Пусть у нас есть Битрикс24 и 1С. В Битрикс24 зарегистрировано 2 события:

  • событие на добавление компании;
  • событие на обновление компании.

Создали компанию. Сработало событие, по которому компания попала в 1С. Затем в 1С компания была изменена посредством Rest и изменения попали в Битрикс24. В теории, должно сработать офлайн событие на обновление компании и снова попасть в 1С, что нелогично.

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

Таким образом это обязательный параметр для rest запросов из внешних систем:

Правильно

https://my.bitrix24.ru/rest/crm.company.add?auth=123456&auth_connector-OneC&fields[TITLE]=Test

Неправильно

https://my.bitrix24.ru/rest/crm.company.add?auth=123456&fields[TITLE]=Test

Список событий

После вызова установки обработчика метод /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"
        }
    ]
}


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

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