Вебхуки

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

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

В этом разделе:

Настройка вебхука

Важно

Для создания вебхука необходимы права администратора.

Примечание

Для того чтобы использовать вебхуки, обязательно укажите по крайней мере один из параметров SERVICE_EXTERNAL_ADDRESS/EXTERNAL_ADDRESS в файле /etc/ffsecurity/config.py.

Для создания вебхука выполните следующие действия:

  1. Перейдите на вкладку Настройки. Выберите Вебхуки.

  2. Нажмите +.

    create_webhook_ru

  3. Введите имя вебхука.

    webhook_ru

  4. Укажите адрес, на который будут отправляться оповещения.

  5. Вы можете отправлять уведомления в пакетном режиме. Укажите максимальное количество уведомлений в пакете. Фактическое количество может быть меньшим.

  6. Укажите максимальное количество попыток отправить уведомление. Интервал между попытками увеличивается экспоненциально с максимумом 100 секунд.

  7. FindFace Security будет автоматически отправлять оповещения о событиях, эпизодах и показаниях счетчика, удовлетворяющих заданным фильтрам. Фильтровать события можно по следующим параметрам:

    События:

    • allowed_bs_types: режим отслеживания лиц на видео, возможные значения: overall, realtime.
    • camera_group_in: id группы камер, число.
    • camera_in: id камеры, число.
    • matched_lists_in: id списка наблюдения, число.
    • matched_dossier_in: id совпавшего досье, число.
    • matched: статус события совпадение (true или false), логический.
    • confidence_gte: минимальное значение уверенности алгоритма, число.

    Эпизоды:

    • allowed_types: статус эпизода, возможные значения: открытие эпизода (episode_open), добавление нового события в эпизод (episode_event), закрытие эпизода (episode_close).
    • camera_group_in: id группы камер, число.
    • camera_in: id камеры, число.
    • matched_lists_in: id списка наблюдения, число.
    • matched: статус события совпадение (true или false), логический.
    • events_count_gte: минимальное количество событий в эпизоде, число.
    • events_count_lte: максимальное количество событий в эпизоде, число.

    Счетчики:

    • counter_in: id счетчика, число.
    • camera_group_in: id группы камер, число.
    • camera_in: id камеры, число.
    • faces_gte: минимальное количество лиц в записи счетчика, число.
    • faces_lte: максимальное количество лиц в записи счетчика, число.
    • silhouettes_gte: минимальное количество силуэтов в записи счетчика, число.
    • silhouettes_lte: максимальное количество силуэтов в записи счетчика, число.
    {
            "events": {
                    "allowed_bs_types": [
                            "overall",
                            "realtime"
                    ],
                    "camera_group_in": [],
                    "camera_in": [],
                    "matched_lists_in": [],
                    "matched_dossier_in": [],
                    "matched": true,
                    "confidence_gte": 0.75
            },
            "episodes": {
                    "allowed_types": [
                            "episode_open",
                            "episode_event",
                            "episode_close"
                    ],
                    "camera_group_in": [],
                    "camera_in": [],
                    "matched_lists_in": [],
                    "matched": true,
                    "events_count_gte": 0,
                    "events_count_lte": 999
            },
            "counters": {
                    "counter_in": [],
                    "camera_group_in": [],
                    "camera_in": [],
                    "faces_gte": 0,
                    "faces_lte": 0,
                    "silhouettes_gte": 0,
                    "silhouettes_lte": 0
            }
    }
    

    Важно

    Используйте только фильтры, соответствующие цели поиска. Для выключения фильтра удалите его из вебхука. Не оставляйте фильтр пустым ([]), поскольку в этом случае фильтр вернет пустой результат.

    Примечание

    Для получения всех оповещений передайте скобки без вложенных фильтров:

    {}
    

    Совет

    Пример №1. Получение оповещений обо всех событиях:

    { "events": {} }
    

    Пример №2. Получение оповещений об открытии эпизодов с совпадениями в досье:

    { "episodes": { "allowed_types": ["episode_open"], "matched": true }} - отправлять только события создания эпизода, которое сматчилось с досье.
    

    Примечание

    Вы можете задать несколько значений в фильтрах с квадратными скобками. В этом случае вебхук будет активироваться при совпадении одного из значений фильтра. В примере ниже вы будете оповещены о событии с группы камер 1 или 3, если совпало досье с id 12 или 25.

    {
            "events": {
                    "camera_group_in": [1, 3],
                    "matched_dossier_in": [12, 25],
            },
    }
    
  8. Поставьте флажок Активный.

  9. Нажмите Сохранить.

Как работает вебхук

Для тестирования работы вебхука можно использовать следующий простой веб-сервер на Python, обеспечивающий захват отправленных вебхуком оповещений о событиях:

from pprint import pprint
from aiohttp import web


async def handle(request):
    pprint(await request.json())
    return web.Response(status=200)


app = web.Application()
# for aiohttp v 3.x
# app.add_routes([web.post('/', handle)])

# for aiohttp v 2.x
app.router.add_post('/', handle)

web.run_app(app, port=8888)

Важно

Используемый вами сервер-ловушка оповещений по вебхуку должен возвращать ответ HTTP 200 после получения вебхука от FindFace Security, по аналогии с примером выше.

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

Событие

[{'acknowledged': True,
  'acknowledged_by': None,
  'acknowledged_date': '2020-05-18T15:08:38+00:00',
  'acknowledged_reaction': '',
  'bs_type': 'overall',
  'camera': None,
  'camera_group': 1,
  'confidence': 0.0,
  'created_date': '2020-05-18T15:08:38+00:00',
  'episode': None,
  'event_type': 'event_created',
  'face': 'http://172.17.46.134/uploads/2020/05/18/event/150842_face_AgohWm.jpg',
  'features': {'age': None,
               'beard': None,
               'emotions': None,
               'gender': None,
               'glasses': None,
               'liveness': None,
               'medmask': None,
               'race': None},
  'frame': 'http://172.17.46.134/uploads/2020/05/18/event/150842_full_frame_Y3vtGe.jpg',
  'frame_coords_bottom': 320,
  'frame_coords_left': 117,
  'frame_coords_right': 170,
  'frame_coords_top': 242,
  'id': '4267625862518432158',
  'looks_like_confidence': None,
  'matched': False,
  'matched_dossier': None,
  'matched_face': '',
  'matched_lists': [-1],
  'quality': -0.000766,
  'scores': {'liveness_score': None,
             'quality': -0.000766480341553,
             'track': {'first_timestamp': '2020-05-18T15:08:38',
                       'id': '43277e17b1c2-44',
                       'last_timestamp': '2020-05-18T15:08:39'},
             'track_duration_seconds': 2.502499999999997},
  'video_source': 1,
  'webhook_type': 'events'}]

Открытие эпизода

[{'acknowledged': True,
  'acknowledged_by': None,
  'acknowledged_date': None,
  'acknowledged_reaction': '',
  'best_event': '4267637154774219594',
  'camera_groups': [1],
  'cameras': [],
  'closed_date': None,
  'created_date': '2020-05-18T16:18:49.111880Z',
  'event_type': 'episode_open',
  'events_count': 1,
  'features': None,
  'id': 2118,
  'last_event': {'acknowledged': True,
                 'acknowledged_by': None,
                 'acknowledged_date': '2020-05-18T16:18:46+00:00',
                 'acknowledged_reaction': '',
                 'camera': None,
                 'camera_group': 1,
                 'confidence': 0.0,
                 'created_date': '2020-05-18T16:18:46+00:00',
                 'episode': 2118,
                 'face': 'http://172.17.46.134/uploads/2020/05/18/event/161849_face_j2TQwk.jpg',
                 'features': {'age': None,
                              'beard': None,
                              'emotions': None,
                              'gender': None,
                              'glasses': None,
                              'liveness': None,
                              'medmask': None,
                              'race': None},
                 'frame': 'http://172.17.46.134/uploads/2020/05/18/event/161849_full_frame_vTfuH9.jpg',
                 'frame_coords_bottom': 327,
                 'frame_coords_left': 778,
                 'frame_coords_right': 901,
                 'frame_coords_top': 161,
                 'id': '4267637154774219594',
                 'looks_like_confidence': None,
                 'matched': False,
                 'matched_dossier': None,
                 'matched_face': '',
                 'matched_lists': [-1],
                 'quality': -0.000311,
                 'scores': {'liveness_score': None,
                            'quality': -0.000311948591843,
                            'track': {'first_timestamp': '2020-05-18T16:18:46',
                                      'id': '1ee9a3612af3-9',
                                      'last_timestamp': '2020-05-18T16:18:47'},
                            'track_duration_seconds': 2.039999999999999},
                 'video_source': 2},
  'matched_event': None,
  'matched_lists': [-1],
  'open': True,
  'webhook_type': 'episodes'}]

Закрытие эпизода

[{'acknowledged': True,
  'acknowledged_by': None,
  'acknowledged_date': None,
  'acknowledged_reaction': '',
  'best_event': {'acknowledged': True,
                 'acknowledged_by': None,
                 'acknowledged_date': '2020-05-18T15:09:57+00:00',
                 'acknowledged_reaction': '',
                 'camera': None,
                 'camera_group': 1,
                 'confidence': 0.0,
                 'created_date': '2020-05-18T15:09:57+00:00',
                 'episode': 518,
                 'face': 'http://172.17.46.134/uploads/2020/05/18/event/151012_face_5LlHQL.jpg',
                 'features': {'age': None,
                              'beard': None,
                              'emotions': None,
                              'gender': None,
                              'glasses': None,
                              'liveness': None,
                              'medmask': None,
                              'race': None},
                 'frame': 'http://172.17.46.134/uploads/2020/05/18/event/151012_full_frame_CdNn2N.jpg',
                 'frame_coords_bottom': 299,
                 'frame_coords_left': 917,
                 'frame_coords_right': 1005,
                 'frame_coords_top': 179,
                 'id': '4267626103667833809',
                 'looks_like_confidence': None,
                 'matched': False,
                 'matched_dossier': None,
                 'matched_face': '',
                 'matched_lists': [-1],
                 'quality': -0.653877,
                 'scores': {'liveness_score': None,
                            'quality': -0.653877139091491,
                            'track': {'first_timestamp': '2020-05-18T15:09:57',
                                      'id': '43277e17b1c2-231',
                                      'last_timestamp': '2020-05-18T15:09:57'},
                            'track_duration_seconds': 0.250255555555554},
                 'video_source': 1},
  'camera_groups': [1],
  'cameras': [],
  'closed_date': '2020-05-18T15:10:42.870851Z',
  'created_date': '2020-05-18T15:10:12.201230Z',
  'event_type': 'episode_close',
  'events_count': 1,
  'features': None,
  'id': 518,
  'last_event': {'acknowledged': True,
                 'acknowledged_by': None,
                 'acknowledged_date': '2020-05-18T15:09:57+00:00',
                 'acknowledged_reaction': '',
                 'camera': None,
                 'camera_group': 1,
                 'confidence': 0.0,
                 'created_date': '2020-05-18T15:09:57+00:00',
                 'episode': 518,
                 'face': 'http://172.17.46.134/uploads/2020/05/18/event/151012_face_5LlHQL.jpg',
                 'features': {'age': None,
                              'beard': None,
                              'emotions': None,
                              'gender': None,
                              'glasses': None,
                              'liveness': None,
                              'medmask': None,
                              'race': None},
                 'frame': 'http://172.17.46.134/uploads/2020/05/18/event/151012_full_frame_CdNn2N.jpg',
                 'frame_coords_bottom': 299,
                 'frame_coords_left': 917,
                 'frame_coords_right': 1005,
                 'frame_coords_top': 179,
                 'id': '4267626103667833809',
                 'looks_like_confidence': None,
                 'matched': False,
                 'matched_dossier': None,
                 'matched_face': '',
                 'matched_lists': [-1],
                 'quality': -0.653877,
                 'scores': {'liveness_score': None,
                            'quality': -0.653877139091491,
                            'track': {'first_timestamp': '2020-05-18T15:09:57',
                                      'id': '43277e17b1c2-231',
                                      'last_timestamp': '2020-05-18T15:09:57'},
                            'track_duration_seconds': 0.250255555555554},
                 'video_source': 1},
  'matched_event': None,
  'matched_lists': [-1],
  'open': False,
  'webhook_type': 'episodes'}]

Запись счетчика

[{'camera': 3,
  'camera_group': 1,
  'counter': 2,
  'counter_name': 'smosh',
  'created_date': '2020-05-18T16:15:06.679592Z',
  'event_type': 'counter_record',
  'faces_bbox': [[[700, 210], [894, 210], [894, 464], [700, 464]],
                 [[160, 190], [304, 190], [304, 394], [160, 394]]],
  'faces_count': 2,
  'fullframe': 'http://172.17.46.134/uploads/2020/05/18/counters/161506_fullframe_7Z8n7X.jpg',
  'id': 16,
  'silhouettes_bbox': [[[15, 135], [584, 135], [584, 709], [15, 709]],
                       [[585, 80], [1194, 80], [1194, 684], [585, 684]],
                       [[0, 380], [69, 380], [69, 714], [0, 714]]],
  'silhouettes_count': 3,
  'thumbnail': 'http://172.17.46.134/uploads/2020/05/18/counters/161506_thumb_XLMFwE.jpg',
  'webhook_type': 'counters'}]

Для просмотра статуса отправки вебхука в FindFace Security, выполните следующую команду:

sudo journalctl -u findface-security.service | grep 'WebhooksManager'

Ответ в случае успеха:

May 18 21:21:38 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] Updating "events" workers for webhooks: {2}
May 18 21:21:52 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:9KHqkQg7-VW:aa3af58f] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.002617
May 18 21:21:52 qa-2 ffsecurity[17851]: INFO     [WebhooksManager:2] <queue:  0> Webhook worker(id-2, type-"events") sent batch(len-1, type-"events"): ['4267685965791894192']
May 18 21:21:53 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:v59UsC1V-VW:75c4a9ec] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.002386
May 18 21:21:53 qa-2 ffsecurity[17851]: INFO     [WebhooksManager:2] <queue:  0> Webhook worker(id-2, type-"events") sent batch(len-1, type-"events"): ['4267685968207813297']
May 18 21:21:53 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:vKNlXiIn-VW:c0219d31] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.004499
May 18 21:21:53 qa-2 ffsecurity[17851]: INFO     [WebhooksManager:2] <queue:  0> Webhook worker(id-2, type-"events") sent batch(len-1, type-"events"): ['4267685968837561053']
May 18 21:21:55 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:zZO8v4LJ-VW:feff75dd] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.001905
May 18 21:21:55 qa-2 ffsecurity[17851]: INFO     [WebhooksManager:2] <queue:  0> Webhook worker(id-2, type-"events") sent batch(len-1, type-"events"): ['4267685973269790230']
May 18 21:21:57 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:EbpDel24-VW:083688e2] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.002017
May 18 21:21:57 qa-2 ffsecurity[17851]: INFO     [WebhooksManager:2] <queue:  0> Webhook worker(id-2, type-"events") sent batch(len-1, type-"events"): ['4267685977917324748']
May 18 21:21:57 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:L5XoQTdq-VW:6f1e397f] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.009237
May 18 21:21:57 qa-2 ffsecurity[17851]: INFO     [WebhooksManager:2] <queue:  0> Webhook worker(id-2, type-"events") sent batch(len-1, type-"events"): ['4267685979796372941']
May 18 21:21:58 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:ZZ33mwuv-VW:a4cad3a2] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.008542
May 18 21:21:58 qa-2 ffsecurity[17851]: INFO     [WebhooksManager:2] <queue:  0> Webhook worker(id-2, type-"events") sent batch(len-1, type-"events"): ['4267685980899116054']
May 18 21:21:58 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:BfAQRgp0-VW:4c19b207] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.003183
May 18 21:21:58 qa-2 ffsecurity[17851]: INFO     [WebhooksManager:2] <queue:  0> Webhook worker(id-2, type-"events") sent batch(len-1, type-"events"): ['4267685982215838395']

Ответ, если попытка была неудачной:

May 18 21:29:09 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:jrGdiC7e-VW:2def51cf] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.003909
May 18 21:29:09 qa-2 ffsecurity[17851]: WARNING  [WebhooksManager:2] <queue:  1> Webhook worker(id-2, type-"events") Error sending webhook: 405, message='Not Allowed'. Attempt 2 out of 10. Next attempt in 0.729 seconds.
May 18 21:29:10 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:jgqLszI7-VW:6a7fea19] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.002402
May 18 21:29:10 qa-2 ffsecurity[17851]: WARNING  [WebhooksManager:2] <queue:  2> Webhook worker(id-2, type-"events") Error sending webhook: 405, message='Not Allowed'. Attempt 3 out of 10. Next attempt in 1.968 seconds.
May 18 21:29:10 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:LLGB1RRR-VW:053d7c7d] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.003794
May 18 21:29:11 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:4Vl23NQD-VW:a4640479] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.037162
May 18 21:29:11 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:QKY577ed-VW:41cd531a] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.005274
May 18 21:29:12 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:SVSrlj1n-VW:973ae0dd] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.004273
May 18 21:29:12 qa-2 ffsecurity[17851]: WARNING  [WebhooksManager:2] <queue:  6> Webhook worker(id-2, type-"events") Error sending webhook: 405, message='Not Allowed'. Attempt 4 out of 10. Next attempt in 5.314 seconds.
May 18 21:29:12 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:phoO3HFd-VW:9c6812d1] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.019604
May 18 21:29:13 qa-2 ffsecurity[17851]: INFO     [WebhooksManager] [SC:WDMmZ5MO-VW:842b3397] Webhook updater processing message(type-"events:event_created"). Consumer reception delta: 0.231164