Крок вебхука

Мова: Українська
Цю статтю перекладено з англійської за допомогою ШІ, тому вона може містити помилки. Ваші відгуки допоможуть нам її покращити.

Крок вебхука надсилає HTTP-запит до зовнішньої системи щоразу, коли потік досягає його. Вебхуки є мостом між ActivityInfo та іншими інструментами: платформами робочих процесів, такими як Power Automate, Zapier, n8n або Pipedream, чат-інструментами, такими як Google Chat або Slack, або вашими власними сервісами.

Конфігурація

| Налаштування | Опис ||---------|-------------|| Назва | Назва кроку, що відображається в потоці та в історії запусків. | | URL вебхука | URL-адреса, на яку надсилається запит. Це має бути URL-адреса https://. | | Формат корисного навантаження | Форма тексту запиту: Сумісний з ActivityInfo 4.0, Стандартний або Налаштування. | | Секретний ключ підпису | Необов'язково. Після створення кожен запит підписується, щоб одержувач міг його перевірити. Див. Підписання. |

Доставка

Запит — це HTTP POST з Content-type: application/json. Час очікування з'єднання та читання становить 15 секунд, а перенаправлення не виконуються. Відповідь з кодом статусу 2xx позначає крок як успішний; будь-яка інша відповідь або збій з'єднання призводить до повторної спроби доставки.

Усі запити містять ці заголовки, відповідно до конвенції standard-webhooks:

| Заголовок | Значення ||--------|-------|| webhook-id | Унікальний ідентифікатор події, наприклад, msg_cfbin3msbq939jk. Повторні спроби тієї ж події мають той самий ідентифікатор, тому одержувачі можуть усунути дублікати. | | webhook-timestamp | Час відправлення, в секундах з початку епохи. | | webhook-signature | Присутній, коли згенеровано секретний ключ підпису. Див. Підписання. |

Підписання

Створення секретного ключа підпису дозволяє системі-одержувачу перевірити, що запит дійсно надійшов від ActivityInfo і не був підроблений. Підпис відповідає симетричній схемі standard-webhooks:

webhook-signature: v1,<base64 HMAC-SHA256 of "{webhook-id}.{webhook-timestamp}.{body}">

Підпис обчислюється на основі точних байтів тексту запиту, незалежно від формату корисного навантаження. Секретний ключ відображається один раз при генерації — скопіюйте його в систему-одержувач у цей момент. Зміна URL вебхука видаляє секретний ключ; спочатку збережіть новий URL, а потім згенеруйте для нього новий секретний ключ.

Формати корисного навантаження

Наведені нижче приклади походять з однієї події: запис у формі Реєстрація пацієнта було відредаговано, змінивши поле Статус з "На лікуванні" на "Відновлено". Поля форми мають коди (NAME, AGE, STATUS, ...) — ми наполегливо рекомендуємо призначати коди вашим полям, оскільки вони ідентифікують поля в корисних навантаженнях і шаблонах нижче набагато зрозуміліше, ніж ідентифікатори полів, і зберігаються при зміні назв.

Форма має по одному полю кожного поширеного типу: серійний номер (NUMBER), текст (NAME), кількість (AGE), дата (REGDATE), місяць (MONTH), тиждень (WEEK), одиночний вибір (STATUS), множинний вибір (SYMPTOMS), посилання на форму Клініка (CLINIC), множинне посилання (NEARBY), географічна точка (LOCATION) та обчислюване поле (ADULT).

Сумісний з ActivityInfo 4.0

Точний формат корисного навантаження вебхуків ActivityInfo 4.0, збережений для інтеграцій, створених на його основі, — включаючи конектор Power Automate. Автоматизації, перенесені з версії 4.0, та з'єднання, створені через Power Automate, використовують цей формат; нові кроки вебхуків за замовчуванням використовують Стандартний. Для отримання додаткової інформації див. Від вебхуків ActivityInfo 4.0 до автоматизації.

Текст листа описує подію: data.update містить лише поля, змінені подією (усі поля для доданого запису), тоді як data.previous — присутній для редагувань та видалень — це повний збережений стан запису до зміни. Поля ідентифікуються за кодом (або ідентифікатором поля, якщо поле не має коду). Тип події type — record.added, record.edited або record.deleted.

Оскільки текст листа створюється на основі збережених значень запису, обчислювані поля не включаються — вони обчислюються під час читання, а не зберігаються, тому вони ніколи не з'являються в цьому форматі. Споживач, якому потрібне обчислене значення, повинен або перерахувати його, або використовувати Стандартний чи Налаштування формат, які обробляють обчислювані поля як будь-які інші.

{
  "type": "record.edited",
  "timestamp": "2026-08-02 13:30:00 +0200",
  "id": "cfbin3msbq939jk",
  "data": {
    "update": {
      "formId": "cabwlbemsbq938l5",
      "formLabel": "Реєстрація пацієнта",
      "recordId": "cuusah2msbq938xi",
      "parent": null,
      "deleted": false,
      "time": "2026-08-02 13:30:00 +0200",
      "fields": {
        "STATUS": "Відновлено"
      }
    },
    "previous": {
      "formId": "cabwlbemsbq938l5",
      "formLabel": "Реєстрація пацієнта",
      "recordId": "cuusah2msbq938xi",
      "parent": null,
      "time": "2026-07-30 11:00:00 +0200",
      "fields": {
        "NAME": "Аміна Юсуф",
        "AGE": 34,
        "REGDATE": "2026-07-30",
        "MONTH": "2026-07",
        "WEEK": "2026W31",
        "STATUS": "На лікуванні",
        "SYMPTOMS": ["Лихоманка", "Кашель"],
        "CLINIC": {
          "reference": {
            "recordId": "cfw5r5dmsbq938vh",
            "formId": "cprk1xdmsbq93893"
          }
        },
        "LOCATION": {
          "latitude": 0.9432,
          "longitude": 29.2154
        }
      }
    },
    "user": {
      "userName": "Амара Діалло",
      "userEmail": "amara.diallo@example.org",
      "userId": "ci5dxvbkq1v6ueg2"
    }
  }
}

Значення полів у цьому форматі:

| Тип поля | Значення ||-----------|-------|| Текст, серійний номер, штрих-код | Текст | | Кількість | Число | | Дата, тиждень, місяць | Текст, напр. "2026-07-30", "2026W31", "2026-07" | | Одиночний вибір | Код опції, якщо він є, інакше її назва | | Множинний вибір | Масив кодів/назв опцій, у порядку опцій форми | | Довідка | {"reference": {"recordId": ..., "formId": ...}} | | Множинне посилання | Масив рядків "formId:recordId" | | Географічна точка | {"latitude": ..., "longitude": ...} | | Вкладення | Масив {"filename": ..., "mimetype": ..., "url": ...} з URL-адресою для завантаження | | Обчислено | Не включено — обчислювані поля обчислюються під час читання, а не зберігаються |

Для видалення (record.deleted), update.deleted має значення true, update.fields є пустим, а previous містить останній стан запису. Записи підформ містять об'єкт parent з parentRecordId, parentFormId та parentFormLabel замість null.

Стандартний

Дані кроку тригера, серіалізовані як JSON — той самий єдиний рядок, представлений точно так, як його бачать формули. Кожне поле форми присутнє в кожній події (пусті поля як null, тому форма корисного навантаження є стабільною), з ключем за кодом поля (або назвою, якщо поле не має коду). Структури _previous, _user та _trigger з'являються під тими ж зарезервованими іменами, які використовують формули.

{
  "_id": "cuusah2msbq938xi",
  "NUMBER": null,
  "NAME": "Аміна Юсуф",
  "AGE": 34,
  "REGDATE": "2026-07-30",
  "MONTH": "2026-07",
  "WEEK": "2026W31",
  "STATUS": {
    "_id": "s2",
    "label": "Відновлено"
  },
  "SYMPTOMS": [
    { "_id": "y1", "label": "Лихоманка" },
    { "_id": "y2", "label": "Кашель" }
  ],
  "CLINIC": {
    "_id": "cfw5r5dmsbq938vh",
    "label": "Медичний пункт Мангіна"
  },
  "NEARBY": [
    { "_id": "cfw5r5dmsbq938vh", "label": "Медичний пункт Мангіна" },
    { "_id": "c7ptg4xmsbq938wj", "label": "Референтна лікарня Бені" }
  ],
  "LOCATION": {
    "LATITUDE": 0.9432,
    "LONGITUDE": 29.2154,
    "ACCURACY": null
  },
  "ADULT": true,
  "_lastEditTime": "2026-08-02T11:30:00Z",
  "_previous": {
    "_id": "cuusah2msbq938xi",
    "NUMBER": null,
    "NAME": "Аміна Юсуф",
    "AGE": 34,
    "REGDATE": "2026-07-30",
    "MONTH": "2026-07",
    "WEEK": "2026W31",
    "STATUS": {
      "_id": "s1",
      "label": "На лікуванні"
    },
    "SYMPTOMS": [
      { "_id": "y1", "label": "Лихоманка" },
      { "_id": "y2", "label": "Кашель" }
    ],
    "CLINIC": {
      "_id": "cfw5r5dmsbq938vh",
      "label": "Медичний пункт Мангіна"
    },
    "NEARBY": [
      { "_id": "cfw5r5dmsbq938vh", "label": "Медичний пункт Мангіна" },
      { "_id": "c7ptg4xmsbq938wj", "label": "Референтна лікарня Бені" }
    ],
    "LOCATION": {
      "LATITUDE": 0.9432,
      "LONGITUDE": 29.2154,
      "ACCURACY": null
    },
    "ADULT": true,
    "_lastEditTime": "2026-07-30T09:00:00Z"
  },
  "_user": {
    "name": "Амара Діалло",
    "email": "amara.diallo@example.org",
    "id": "ci5dxvbkq1v6ueg2"
  },
  "_trigger": {
    "type": "RECORD_EDITED",
    "time": "2026-08-02T11:30:00Z"
  }
}

Значення полів у цьому форматі:

| Тип поля | Значення ||-----------|-------|| Текст, серійний номер, штрих-код | Текст, null якщо пусте | | Кількість | Число | | Дата, тиждень, місяць | Текст, напр. "2026-07-30", "2026W31", "2026-07" | | Одиночний вибір | {"_id": <ідентифікатор опції>, "label": <назва опції>} | | Множинний вибір | Масив об'єктів {"_id", "label"} | | Довідка | {"_id": <ідентифікатор запису>, "label": <мітка запису>} — та сама зрозуміла для людини мітка, яку запис має в усьому додатку | | Множинне посилання | Масив об'єктів {"_id", "label"} | | Географічна точка | {"LATITUDE", "LONGITUDE", "ACCURACY"} | | Вкладення | Масив об'єктів {"_id", "filename", "mimetype"} | | Обчислено | Результат формули | | Значення дати та часу (_lastEditTime, _trigger.time) | ISO-8601 UTC, напр. "2026-08-02T11:30:00Z" |

_previous присутній лише для тригера редагування; записи _user мають значення null для змін, які не можна віднести до користувача.

Налаштування

Ви самі пишете текст запиту як шаблон з посиланнями ${...} — ті самі посилання, що використовуються в шаблонах кроку емейлу, які обробляються на основі даних кроку тригера. Цей формат слід використовувати, коли система-одержувач диктує форму тексту, наприклад, для публікації повідомлення безпосередньо в просторі Google Chat:

{"text": "Пацієнт ${NAME} у ${CLINIC.NAME} тепер ${STATUS} (був ${_previous.STATUS}), оновлено користувачем ${_user.name}"}

створює:

{"text": "Пацієнт Аміна Юсуф у Медичний пункт Мангіна тепер Відновлено (був На лікуванні), оновлено користувачем Амара Діалло"}

Посилання може бути кодом поля, навігацією через поле посилання, записом _previous/_user/_trigger або будь-якою формулою — повна мова формул доступна вбудовано:

{"text": "Пацієнт ${NAME} (${IF(AGE >= 18, 'дорослий', 'неповнолітній')}, вік ${AGE}) тепер ${STATUS}"}

створює:

{"text": "Пацієнт Аміна Юсуф (дорослий, вік 34) тепер Відновлено"}

Використовуйте одинарні лапки для тексту всередині вбудованої формули, як у IF(AGE >= 18, 'adult', 'minor') — мова формул приймає обидва стилі лапок, а одинарні лапки зберігають читабельність навколишнього шаблону JSON.

Інтерпольовані значення автоматично екрануються для JSON: лапки, зворотні скісні риски та розриви рядків у ваших даних надходять як \", \\ та \n, тому шаблон, що є документом JSON, залишається дійсним JSON незалежно від вмісту даних. Все, що знаходиться поза ${...}, надсилається точно так, як написано, — включаючи послідовності зі зворотною скісною рискою, як-от \n, які ви вводите самі, — а посилання ${...}, яке не може бути розпізнане, залишається як є.

Редактор шаблонів перевіряє кожне посилання ${...} на відповідність даним кроку тригера і пропонує той самий список полів для вибору, що й кроки фільтра та емейлу.

Див. також

Наступний елемент
Довідка