Webhooks

Входящият Webhook позволява на друга система да публикува в канал, като изпраща JSON до тайна URL. Изходящият Webhook прави обратното: изпраща съобщения до вашата URL, тези, които започват със задействаща дума, или тези, които хората избират за него в менюто на съобщението, и публикува отговора ви.

Къде да управлявате webhooks

Отворете менюто на екипа, след което изберете Настройки на екипа и кликнете върху Интеграции в края на раздела. Страниците за интеграции на текущия екип показват списъци с Входящи webhook и Изходящи webhooks. Всеки webhook принадлежи към един екип.

По подразбиране, администраторите на общността и системните администратори могат да създават webhooks. Системен администратор може да даде това право на други роли в настройките за разрешения в Системната конзола. Системен администратор може също да изключи всеки вид в Системна конзола › Интеграции › Управление на интеграциите: Разреши входящите Webhooks и Разреши изходящите webhook са включени по подразбиране.

A channel with messages from a CI bot and from GitHub, shown as cards with fields, pipeline stages and a button
Съобщения от интеграции, изобразени като карти: полета, етапи на конвейера и бутон за действие.

Създаване на входящ webhook

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

С 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".

Изпращане на съобщение до входящ webhook

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, както webhooks на Slack, така че инструменти, създадени за Slack, обикновено работят без промени.

ПолеЗначение
textСъобщението в Markdown. Задължително, освен ако има attachments. Текст, по-дълъг от лимита на съобщения на сървъра, се разделя на няколко съобщения.
channelДруг канал от общността на Webhook-а, по име (ops-alerts или #ops-alerts), или @username за директно съобщение от собственика на Webhook-а. Отказва се, когато Webhook-ът е заключен за своя канал. Старото име town-square все още достига до канала по подразбиране на общността, сега наречен general.
username, icon_url, icon_emojiИмето и снимката, които да се показват, когато сървърът позволява припокриване.
attachmentsПрикачени файлове към съобщението, изобразени като карти (по-долу).
propsДопълнителни свойства, съхранявани в съобщението, за приложения, които ги четат. Публикуването във форумен канал изисква props.am_thread_title (от 1 до 100 знака): ако липсва, хукът се отказва (вижте Форумите приемат само теми).
typeПерсонализиран тип съобщение, например custom_poll, за приложение, което го изобразява. Типове, започващи с system_, се отхвърлят.
root_idИдентификаторът на първото съобщение в нишка, за да се отговори в тази нишка.
priorityПриоритет на съобщението, например {"priority": "urgent"}.
silenttrue изпраща съобщението без пуш известия.

Всяко съобщение, публикувано от Webhook, носи етикет БОТ до името си, дори когато се показва под името на създателя му, за да могат хората да го разграничат от съобщение на реален човек. Съобщенията от Webhook никога не задействат изходящи Webhook-и.

Име и икона

Webhook-ът публикува като лицето, което го е създало, освен ако сървърът не позволява припокриване. Две настройки в Системна конзола › Интеграции › Управление на интеграциите, и двете изключени по подразбиране, променят това:

  • Разреши интеграциите да припокриват потребителски имена (ServiceSettings.EnablePostUsernameOverride): потребителското име на Webhook-а (Потребителско име) или username от заявката се показва вместо него; без нито едно от двете, името е webhook.
  • Разреши интеграциите да припокриват профилни снимки (ServiceSettings.EnablePostIconOverride): снимката на профила на Webhook-а (Снимка на профила), или icon_url или icon_emoji от заявката, се показва.

Стойност от заявката има предимство пред тази, запазена в Webhook-а.

Прикачени файлове

Прикачените файлове добавят структурирано съдържание под текста. Те следват формата на прикачени файлове в съобщенията на 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Ред за поддръжка и време (в секунди от Unix).
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.

Създаване на изходящ Webhook

Изходящият webhook следи публичните канали на общността. Той изпраща съобщение към вашия URL, когато първата дума на съобщението съвпада с едно от неговите тригерни думи, или когато някой го избере от менюто на съобщението (действие върху съобщение).

  1. В Интеграции, изберете Изходящи webhooks, след това Добавете изходяща Webhook.
  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 за „от менюто на съобщението“). Webhook с 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.

The outgoing webhook form with Trigger When set to From the message menu, and the Icon field below it
Тригерът е зададен на От менюто на съобщението, с полето Икона.
Ако вашата услуга е в частна мрежа, системният администратор трябва да разреши нейния адрес в Разрешаване на ненадеждни вътрешни връзки към (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 с токена на Webhook-а, преди да направите каквото и да е. В версията с кодиране на формуляри timestamp е в секунди, а не в милисекунди. Сервърът чака отговора ви толкова дълго, колкото позволява Време за изчакване на заявката за интегриране (по подразбиране 30 секунди, ServiceSettings.OutgoingIntegrationRequestsTimeout).

Отговор към изходящ Webhook

За да публикувате отговор, отговорете с 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 публикува отговора в нишката на съобщението, което е предизвикало Webhook-а; в противен случай той отива в канала.
  • username, icon_url: показват се, когато сервърът разрешава замяна; в противен случай се използват собствените стойности на Webhook-а.
  • props, type, priority: както при входящите Webhooks.

Отговорът се публикува от името на създателя на Webhook-а, под замяната, ако има такава. За отговори, по-дълги от кратък отговор, отговорете веднага и публикувайте по-късно с входящ Webhook или API.

Действия върху съобщение

Действие върху съобщение е изходящ webhook, при който Задейства кога е зададено на От менюто на съобщението. То никога не се задейства при публикувани съобщения. Вместо това хората го виждат в менюто на съобщението: Действия върху съобщение (⋯) › Още действия, под заглавието Интеграции, с иконата си. Класическият интерфейс не показва действията върху съобщения. Изборът му изпраща точно това съобщение към URL-ите за обратна връзка, а кратко известие показва Изпратено към името на действието или показва ephemeral_text на потребителя.

  • Къде се показва: в канала на webhook-а или, ако няма канал, във всеки публичен канал на общността. Само публичните канали имат действия върху съобщения.
  • Гости виждат само действията, свързани с канал, в който са, а не общностните.
  • Архивирани и само за четене канали: съобщението все още може да бъде изпратено. Архивирането на канал изтрива webhook-овете, свързани с него, така че архивираният канал запазва само общностните действия. Отговор, който потребителят не може да публикува там, се показва само на него.
  • Лимит на честота: всеки потребител може да изпълни 10 действия върху съобщения на минута, след поредица от 5. Над този лимит сървърът отговаря с 429.
  • Частни мрежи: както при другите изходящи webhooks, вътрешните адреси трябва да бъдат разрешени в Разрешаване на ненадеждни вътрешни връзки към.

Заявката

Натоварването се изпраща като JSON или като кодирана форма, според типа на съдържанието на webhook-а:

{
  "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 са на потребителя, който е изbral действието; post_user_id и post_user_name са на автора на съобщението.
  • Изпраща се само това съобщение, а не останалата част от нишката му.
  • files изброява файловете на съобщението само ако потребителят, който е изbral действието, може да ги изтегли. Изтеглянето на link изисква сесия или токен, както всеки файл в API.
  • Съобщение, което се изгаря при четене, се изпраща без текст и файлове, като стойността на burn_on_read е true.
  • При form-encoded данните файловете се изпращат като повтарящи се полета file_id, file_name и file_link в същия ред.

Отговорът

Отговорът е както за всеки изходящ webhook (вижте Отговор на изходящ webhook): text или attachments публикува отговор в канала, а "response_type": "comment" го публикува в нишката на съобщението. Можете също да отговорите с ephemeral_text (обрязано до 300 символа): то се показва само на човека, който е изbral действието, в известието. Празно тяло не публикува нищо.

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

С API

  • GET /api/v4/channels/{channel_id}/message_actions: действията, които можете да изберете в канал, с id, display_name, description и icon_url. Нито токени, нито callback URL-и се връщат.
  • POST /api/v4/posts/{post_id}/message_actions/{hook_id}: изпълнява действие върху съобщение, което можете да прочетете. Отговаря с {"ephemeral_text"}.

Когато Webhook не работи

  • 501 от URL на Webhook: входящите Webhooks са изключени на сервъра.
  • 400 "Failed to decode the payload…": JSON е невалиден, или полето на формуляра не се казва payload. "No text specified." означава, че заявката няма нито text, нито attachments.
  • 403: Webhook-ът е заключен за друг канал, или неговият собственик вече не може да чете канала.
  • Изходящ webhook никога не се задейства: каналът е частен, тригърът не е първата дума, съобщението е дошло от webhook, или webhook-ът е настроен да се задейства От менюто на съобщението.
  • Действие върху съобщение липсва в менюто: каналът е частен, действието е свързано с друг канал, човекът е гост и действието няма канал, или изходящите webhooks са изключени.
  • 404 при изпълнение на действие върху съобщение: действието не съществува или не покрива канала на съобщението за този човек. 429: човекът е изпълнил повече от 10 действия за минута. 502: нито един от callback URL-ите не може да бъде достигнат (причината е в лога).
  • Публикуването във форум се отказва: съобщението на хука трябва да има заглавие (props.am_thread_title); грешката посочва причината, например app.post.forum.title_required.app_error, вместо обща грешка (вижте Типове канали).
  • Лог: с Разреши отстраняването на грешки в Webhook включено (LogSettings.EnableWebhookDebugging) и ниво на лог DEBUG, сервърът записва натоварванията на неуспешни входящи заявки. Неуспешните изходящи заявки се записват като Outgoing Webhook POST failed.