Крок вебхука

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

Крок вебхука надсилає 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 від "{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, які ви вводите самостійно — а посилання ${...}, яке не може бути вирішене, залишається як є.

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

Див. також

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