Views: 4835
Last Modified: 14.08.2020

Offline events

Sometimes an application cannot receive events. It can be hidden by firewalls, or be located in an internal network and etc. In this case, offline events mechanism is used. In this case the app subscribes to events, but does not indicate handler's URL. Instead, this app indicates that events are to be stored in the database, until it accesses them. Offline mechanism is used for handling third-party data systems as well.

There are two ways how such mechanism operates - simplified and complex. In case of simplified operation, the app just subscribes to events and when required, "picks up" first event at the head of queue. The more complex way consists of managed selection from the queue, individual separation of events into already processed and those events requiring conflict resolution and etc.

Attention! All event handling methods, be it installation/deletion of event handlers or queue reading, require administration access permissions and can be executed with authenticated application. It means that webhooks won't be work with these methods.

Queued entries accumulate by event data. For example, when the event ONCRMLEADUPDATE is already active for the lead with ID=10, the next lead 10 update won't add a new entry, but only update the existing entry date.

Event handler setup

The method /rest/event.bind is used with value event_type=offline. In this case the parameter handler becomes optional, and the parameter auth_type - absolute.

Call example:

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

HTTP/1.1 200 OK

{
    "result": true 
}

After called handler is installed, the method /rest/event.get prints the following image (standard event handler added for comparison):

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
        }
    ]
}

Use the same method to unsubscribe from event /rest/event.unbind, called with the same parameters as the event event.bind.

Next, event queue is processed.

Simplified operation

When application calls the method /rest/event.offline.get, the account will send first 50 events satisfying filter in the specified sorting order, clearing them out the database immediately.

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
    }
}

Fields for events array
ID Queued event ID
TIMESTAMP_X Date of the last triggered event
EVENT_NAME Event name
EVENT_DATA Event data
EVENT_ADDITIONAL Additional event parameters. Presently, contains only one parameter - user ID, who triggered the last event.
MESSAGE_ID Unique identifier for "triggered" event. It contains event type hash and event data. It means all events ONCRMLEADUPDATE with data {FIELDS:{ID:28}} will have the same MESSAGE_ID, and use it to merge into a single entry. This parameter is used for debugging in a complex event operation

The method event.offline.get supports multi-thread parsing. It means that only several parallel requests to methods are permitted (with complying to limits on number of requests per unit of time), and each of them gets different sets of entries.

Complex operation

When offline events complex operation main difference: selected entries are not deleted from the database, but marked as processed. They will continue to remain in the database until the app notification informs you that their processing is complete. If new triggered events occur during the processing, such events are added into the queue as usual, even if an entity for such event already exists among processed events. Other processing thread will receive notification of such update.


Entry

This operation is enabled by adding a parameter clear=0 to the call 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"
    }
}

Pay special attention to the field process_id in the response. After calling an event, entries remain in the database, but marked as processed by the process having such ID. Such entries will not be included in further results and new events.

After all entries are selected, marked as processed and passed to the application, the application can delete some of them, mark some as erroneous, leave some for later processing.


Entry cleanup

Cleanup is perfumed by calling the method /rest/event.offline.clear, that receives process_id as well as entry ID array to be deleted.

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

HTTP/1.1 200 OK

{
    "result": true
}
Attention! The ID parameter must receive array of entry IDs from event queue, not the CRM lead IDs for example. Meaning the example above indicates result.events[].ID, not the result.events[].EVENT_DATA.FIELDS.ID.

Error processing

Sometimes, when creating complex integrations that require complex event operation, a conflict between various system data occurs. Such case requires human control or using some other method of conflict resolution. To avoid interrupting the process and avoid accumulating errors, some event entries can be left in the database marked as erroneous. /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
}

After marking event as erroneous, marked entries won't be passed to the app when calling event.offline.get. Both marked entry and subsequent triggered event containing such entry data will no longer be passed. In other words, an updated Bitrix24 entity won't be sent to the app until the app grants a permission. Also, an entry will de-associate from the current process and won't be deleted when calling event.offline.clear. In cases, when events containing this data were triggered during the processing, they are also passed to the app, even if they are captured by another process.


Error resolution

Removing an error mark is done by removing the entry from the database via event.offline.get with parameter error=1, as well as with additional filter, when only portion of errors must be processed. When calling this method, erroneous entries will be removed from the database (when indicating clear=1), or marked as processed (when indicating clear=0). In both cases new events with such data will begin to register again and passed to the app.


Simplified retrieval of queue status

Sometime current queue must be read without updating its status, as done via event.offline.get, independently from complex logic for marking erroneous events or distributing events to processes. Simply retrieving the status is done via the list method /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"
        }
    ]
}




Courses developed by Bitrix24