Вебхуки

Вхідний вебхук дозволяє іншій системі публікувати в канал, надсилаючи JSON на секретний URL. Вихідний вебхук робить протилежне: він надсилає повідомлення на ваш URL — ті, що починаються з ключового слова, або ті, які користувачі обирають у меню повідомлення, — і публікує вашу відповідь.

Де керувати вебхуками

Відкрийте свій аватар у правому верхньому куті, потім Інтеграції. На сторінках інтеграцій поточного робочого середовища перелічено Вхідні вебхуки та Вихідні вебхуки. Кожен вебхук належить до одного робочого середовища.

За замовчуванням вебхуки можуть створювати адміністратори спільноти та системні адміністратори. Системний адміністратор може надати цю можливість іншим ролям у налаштуваннях дозволів Системної консолі. Системний адміністратор також може вимкнути кожен тип у Системна консоль › Інтеграції › Управління інтеграцією: Увімкнути вхідні веб-хуки та Увімкнути вихідні вебхуки за замовчуванням увімкнені.

A channel with messages from a CI bot and from GitHub, shown as cards with fields, pipeline stages and a button
Повідомлення інтеграцій, відображені як картки: поля, етапи конвеєра та кнопка дії.

Створення вхідного вебхука

  1. У Інтеграції оберіть Вхідні вебхуки, потім Додати вхідний вебхук.
  2. Заповніть Назву та Опис: вони відображаються лише на сторінках інтеграцій.
  3. Оберіть Канал, куди за замовчуванням надсилатимуться повідомлення. Для приватного каналу ви маєте бути його учасником.
  4. Поставте галочку Прикріпити до цього каналу, якщо відправники не повинні мати змогу публікувати повідомлення в інших каналах.
  5. За бажанням встановіть Логін та URL Зображення профілю для його повідомлень (див. Ім’я та значок).
  6. Оберіть Зберегти. Скопіюйте відображений URL: https://chat.example.com/hooks/<key>.
URL — єдиний секрет: будь-хто, хто його має, може публікувати в каналі. Не розміщуйте його в публічних репозиторіях і видаліть вебхук, якщо він втече.

З API: POST /api/v4/hooks/incoming з {"channel_id", "display_name", "description", "username", "icon_url", "channel_locked"}; id у відповіді — це ключ. З командного рядка: amctl webhook create-incoming --channel <channel id> --user <user> --display-name "CI".

Надсилання повідомлення на вхідний вебхук

curl -X POST https://chat.example.com/hooks/xgh5ycrx1jf7mbs9w8z4c8e7ho \
  -H 'Content-Type: application/json' \
  -d '{"text": "Deploy of **api 2.4.0** finished :white_check_mark:"}'

Сервер відповідає 200 з тілом ok. Він також приймає application/x-www-form-urlencoded з JSON у полі payload, як вебхуки Slack, тому інструменти, створені для Slack, зазвичай працюють без змін.

ПолеЗначення
textПовідомлення у форматі Markdown. Обов’язкове, якщо немає attachments. Текст, що перевищує ліміт довжини повідомлення сервера, розбивається на кілька повідомлень.
channelІнший канал спільноти вебхука, за назвою (ops-alerts або #ops-alerts), або @username для приватного повідомлення від власника вебхука. Відхиляється, якщо вебхук прив’язаний до свого каналу. Стару назву town-square досі можна використовувати для каналу за замовчуванням спільноти, який зараз називається general.
username, icon_url, icon_emojiІм’я та зображення, які відображатимуться, якщо сервер дозволяє перевизначення.
attachmentsВкладення до повідомлення, які відображаються як картки (нижче).
propsДодаткові властивості, що зберігаються в повідомленні для застосунків, які їх читають.
typeКористувацький тип повідомлення, наприклад custom_poll, для застосунку, який його відображає. Типи, що починаються з system_, відхиляються.
root_idІдентифікатор першого повідомлення обговорення, щоб відповісти в ньому.
priorityПріоритет повідомлення, наприклад {"priority": "urgent"}.
silenttrue відправляє повідомлення без push-сповіщень.

Кожне повідомлення, опубліковане вебхуком, має мітку БОТ поруч із назвою, навіть якщо воно відображається під ім’ям його автора, щоб користувачі могли відрізнити його від повідомлення від справжньої людини. Повідомлення вебхуків ніколи не запускають вихідні вебхуки.

Ім’я та іконка

Вебхук публікує повідомлення від імені людини, яка його створила, якщо сервер не дозволяє заміну. Дві налаштування у Системна консоль › Інтеграції › Управління інтеграцією, обидві вимкнені за замовчуванням, змінюють це:

  • Увімкнути інтеграцію, щоб замінити імена користувачів (ServiceSettings.EnablePostUsernameOverride): замість імені відображається Логін вебхука або username із запиту; якщо жодного з них немає, ім’я буде webhook.
  • Увімкніть інтеграцію, щоб замінити значки зображень профілю (ServiceSettings.EnablePostIconOverride): замість значка відображається Зображення профілю вебхука або icon_url або icon_emoji із запиту.

Значення із запиту має пріоритет над тим, що збережено в вебхуку.

Вкладення

Вкладення додають структурований контент під текстом. Вони відповідають формату вкладень повідомлень Slack:

{
  "text": "Build failed on `main`",
  "attachments": [{
    "fallback": "main #1902 failed",
    "color": "#d24b4e",
    "author_name": "GitHub Actions",
    "author_icon": "https://chat.example.com/static/ci.png",
    "title": "main #1902 failed",
    "title_link": "https://ci.example.com/runs/1902",
    "text": "Commit `0f4d8e2` by Jonas Weber",
    "fields": [
      {"title": "Branch", "value": "zephyr-3.7", "short": true},
      {"title": "Duration", "value": "3m 40s", "short": true}
    ],
    "footer": "Lumen CI",
    "ts": 1760000000
  }]
}
ПолеЗначення
fallbackЗвичайний текст для місць, де картку не можна відобразити, наприклад у сповіщеннях.
colorКольорова смуга: шістнадцятковий колір або good, warning, danger.
pretextТекст над карткою.
author_name, author_link, author_iconНевеликий рядок заголовка.
title, title_linkЗаголовок картки, за бажанням із посиланням.
textТіло картки у форматі Markdown.
fieldsСписок {"title", "value", "short"}; поля short розміщуються поруч.
image_url, thumb_urlВелике зображення внизу або маленьке збоку.
footer, footer_icon, tsРядок підпису та час (уніксіанські секунди).
actionsКнопки та меню: див. Інтерактивні повідомлення.

Картки: етапи та діаграми

Antimatter додає два поля до вкладень, які відображає стандартний інтерфейс:

  • stages: кроки конвеєра у вигляді пігулок, до 20. Кожен має вигляд {"name", "status"}, де статус може бути passed, failed, running, pending, skipped або canceled.
  • chart: невеликий лінійний графік останніх значень, {"values": [2 to 200 numbers], "threshold": number, "label": "…"}. Порогове значення відображається як пунктирна лінія, наприклад, для ліміту сповіщення.
{
  "attachments": [{
    "color": "danger",
    "title": "main #1902 failed",
    "stages": [
      {"name": "build", "status": "failed"},
      {"name": "unit", "status": "skipped"},
      {"name": "publish", "status": "skipped"}
    ]
  }, {
    "color": "warning",
    "title": "API latency above 400 ms",
    "chart": {"values": [210, 230, 260, 390, 450, 470], "threshold": 400, "label": "p95 latency, ms"}
  }]
}

Класичний інтерфейс та інші клієнти ігнорують ці два поля, тому також додавайте основну інформацію у text або fields.

Створення вихідного вебхука

Вихідний вебхук стежить за публічними каналами спільноти. Він надсилає повідомлення на ваш URL, коли перше слово повідомлення збігається з одним із його ключових слів, або коли хтось обирає його в меню повідомлення (дія з повідомленням).

  1. У розділі Інтеграції оберіть Вихідні вебхуки, а потім Додати вихідний вебхук.
  2. Заповніть Назву та Опис.
  3. Оберіть Тип вмісту запиту: application/x-www-form-urlencoded або application/json.
  4. Оберіть Канал, введіть Ключові слова (по одному на рядок) або обидва. Якщо вказано канал, але немає ключових слів, надсилаються всі повідомлення цього каналу. Якщо вказано обидва, повідомлення має відповідати обом умовам.
  5. У розділі Умова спрацьовування оберіть Перше слово точно відповідає слову події, Перше слово починається з ключового слова або З меню повідомлення. Якщо обрано З меню повідомлення, ключові слова зникають, Канал є необов’язковим (без нього дія пропонується в кожному відкритому каналі спільноти), а Назва є обов’язковою: це назва дії в меню.
  6. Введіть URL-адреси зворотного виклику (по одній на рядок). Кожна URL-адреса отримує кожне відповідне повідомлення.
  7. За бажанням встановіть Логін та Зображення профілю, які використовуватимуться для відповідей. Для дії з меню повідомлень поле Іконка замінює Зображення профілю: URL зображення у форматі .png або .jpg або, у стандартному інтерфейсі Antimatter, завантажене зображення. У меню воно відображається сірим; без нього дія отримує нейтральну іконку.
  8. Оберіть Зберегти та скопіюйте відображений токен. Ваша служба використовує його, щоб перевіряти, що запити надходять з вашого сервера.

Через API: POST /api/v4/hooks/outgoing з {"team_id", "channel_id", "trigger_words", "trigger_when", "callback_urls", "content_type", "display_name"} (trigger_when: 0 для точного збігу, 1 для «починається з», 2 для «з меню повідомлення»). Вебхук з trigger_when 2 не потребує слів-спусків і вимагає display_name. Завантажте його іконку через POST /api/v4/hooks/outgoing/{hook_id}/icon (multipart, поле image: PNG, JPEG або GIF, зберігається як PNG 128 px); тоді його icon_url вказує на GET /api/v4/hooks/outgoing/{hook_id}/icon.

Якщо ваш сервіс перебуває в приватній мережі, системний адміністратор має дозволити його адресу у Дозволити ненадійні внутрішні з'єднання (ServiceSettings.AllowedUntrustedInternalConnections). Інакше сервер не викликає приватні адреси.

Вихідний запит

Antimatter надсилає POST із такими полями, у форматі JSON або form-encoded, залежно від типу вмісту:

{
  "token": "6kd1ofo5ojr5zgu5ipfipybgnc",
  "team_id": "…",
  "team_domain": "lumen-labs",
  "channel_id": "…",
  "channel_name": "ops-alerts",
  "timestamp": 1760010000000,
  "user_id": "…",
  "user_name": "priya",
  "post_id": "…",
  "text": "deploy api 2.4.0",
  "trigger_word": "deploy",
  "file_ids": ""
}

Перед будь-якими діями порівняйте token з токеном вебхука. У версії з кодуванням форми timestamp вказано у секундах, а не у мілісекундах. Сервер очікує вашу відповідь протягом часу, визначеного параметром Час очікування запиту інтеграції (за замовчуванням — 30 секунд, ServiceSettings.OutgoingIntegrationRequestsTimeout).

Відповідь на вихідний вебхук

Щоб надіслати відповідь, відповіть у форматі JSON. Щоб нічого не надсилати, відповіть порожнім тілом.

{
  "text": "Deploying **api 2.4.0** to staging…",
  "response_type": "comment",
  "username": "deploy-bot",
  "icon_url": "https://chat.example.com/static/deploy.png"
}
  • text та attachments: текст відповіді. Якщо відсутні обидва поля, нічого не буде надіслано.
  • response_type: comment надсилає відповідь в обговорення повідомлення, яке викликало вебхук; інакше відповідь надсилається в канал.
  • username, icon_url: відображаються, якщо сервер дозволяє перевизначення; інакше використовуються власні значення вебхука.
  • props, type, priority: як для вхідних вебхуків.

Відповідь надсилається від імені автора вебхука, а за наявності перевизначення — під перевизначеним ім'ям. Для відповідей, довших за коротке повідомлення, надішліть відповідь одразу, а потім опублікуйте її пізніше за допомогою вхідного вебхука або API.

Дії з повідомленнями

Дія з повідомленням — це вихідний вебхук, для якого Умова спрацьовування встановлена на З меню повідомлення. Вона ніколи не спрацьовує на опублікованих повідомленнях. Натомість люди бачать її в меню повідомлення: Дії з повідомленнями (⋯) › Інші дії, під заголовком Інтеграції, з її іконкою. Класичний інтерфейс не відображає дій з повідомленнями. Обрання дії надсилає саме це повідомлення на адреси зворотного виклику, а коротке сповіщення показує Надсилання до назви дії або відображає ваш ephemeral_text.

  • Де відображається: у каналі вебхука або, якщо канал не вказано, у всіх відкритих каналах спільноти. Дії з повідомленнями доступні лише у відкритих каналах.
  • Гості отримують лише ті дії, які прив’язані до каналу, в якому вони перебувають, а не спільнотні.
  • Архівовані та канали лише для читання: повідомлення все одно можна надіслати. Архівування каналу видаляє вебхуки, прив’язані до нього, тому в архівованому каналі залишаються лише спільнотні дії. Відповідь, яку людина не змогла опублікувати в каналі, показується лише їй.
  • Обмеження частоти: кожна людина може виконати 10 дій з повідомленнями за хвилину після сплеску з 5. Перевищення цього ліміту призводить до відповіді сервера 429.
  • Приватні мережі: як і для інших вихідних вебхуків, внутрішні адреси мають бути дозволеними в Дозволити ненадійні внутрішні з'єднання.

Запит

Дані надсилаються у форматі JSON або як форма, відповідно до типу вмісту вебхука:

{
  "token": "6kd1ofo5ojr5zgu5ipfipybgnc",
  "trigger": "message_action",
  "team_id": "…",
  "team_domain": "lumen-labs",
  "channel_id": "…",
  "channel_name": "ops-alerts",
  "timestamp": 1760010000000,
  "user_id": "…",
  "user_name": "priya",
  "post_id": "…",
  "post_root_id": "",
  "post_create_at": 1760009000000,
  "post_user_id": "…",
  "post_user_name": "jonas",
  "permalink": "https://chat.example.com/lumen-labs/pl/…",
  "text": "The staging database is full again",
  "files": [{"id": "…", "name": "df.txt", "link": "https://chat.example.com/api/v4/files/…"}],
  "priority": "",
  "requested_ack": false,
  "burn_on_read": false
}
  • user_id та user_name — це людина, яка обрала дію; post_user_id та post_user_name — автор повідомлення.
  • Надсилається лише це повідомлення, а не решта його обговорення.
  • files перелічує файли повідомлення лише тоді, коли людина, яка обрала дію, має право їх завантажити. Завантаження link вимагає сесії або токена, як і будь-який файл API.
  • Повідомлення, що згорає після прочитання, надсилається без тексту та файлів, з burn_on_read, встановленим у true.
  • У форм-кодуванні файли передаються як повторювані поля file_id, file_name та file_link у тому ж порядку.

Відповідь

Відповідайте так, як для будь-якого вихідного вебхука (див. Відповідь на вихідний вебхук): text або attachments публікує відповідь у каналі, а "response_type": "comment" — у обговоренні повідомлення. Ви також можете відповісти за допомогою ephemeral_text (обрізано до 300 символів): його бачить лише та людина, яка обрала дію, у сповіщенні. Порожнє тіло не публікує нічого.

{"ephemeral_text": "Ticket OPS-412 created"}

З API

  • GET /api/v4/channels/{channel_id}/message_actions: дії, які можна обрати в каналі, з id, display_name, description та icon_url. Токени та URL-адреси зворотного виклику не повертаються.
  • POST /api/v4/posts/{post_id}/message_actions/{hook_id}: виконує дію над повідомленням, яке ви можете прочитати. Відповідає {"ephemeral_text"}.

Якщо вебхук не працює

  • 501 від URL вебхука: вхідні вебхуки вимкнені на сервері.
  • 400 "Failed to decode the payload…": JSON недійсний, або поле форми не називається payload. "No text specified." означає, що запит не містить ні text, ні attachments.
  • 403: вебхук прив'язаний до іншого каналу, або його власник більше не може читати канал.
  • Вихідний вебхук ніколи не спрацьовує: канал є приватним, тригер не є першим словом, повідомлення надійшло від вебхука, або вебхук налаштовано на спрацювання З меню повідомлення.
  • Дія над повідомленням відсутня в меню: канал є приватним, дія прив’язана до іншого каналу, людина є гостем, а дія не має каналу, або вихідні вебхуки вимкнено.
  • 404 під час виконання дії над повідомленням: дія не існує, або вона не покриває канал цього повідомлення для цієї людини. 429: людина виконала понад 10 дій за хвилину. 502: жоден із URL-адрес зворотного виклику не був доступний (причина вказана в журналі).
  • Журнали: якщо увімкнено Увімкнути налагодження Webhook (LogSettings.EnableWebhookDebugging) і рівень журналу встановлено на DEBUG, сервер записує в журнал навантаження невдалих вхідних запитів. Невдалі вихідні виклики записуються як Outgoing Webhook POST failed.