Webhooks

Příchozí webhook umožňuje jinému systému odesílat zprávy do kanálu tím, že pošle JSON na tajné URL. Odchozí webhook dělá opak: pošle zprávy na vaše URL, a to buď ty, které začínají na spouštěcí slovo, nebo ty, které si lidé vyberou v menu zprávy, a zveřejní to, co mu odpovíte.

Kde spravovat webhooks

Otevřete nabídku týmu, pak Nastavení týmu a na konci karet klikněte na Integrace. Stránky integrací aktuálního týmu obsahují seznamy Příchozí webhooks a Odchozí webhooks. Každý webhook patří do jednoho týmu.

Ve výchozím nastavení mohou webhooks vytvářet administrátoři komunity a systémoví administrátoři. Systémový administrátor může toto oprávnění udělit i jiným rolím v nastaveních oprávnění Systémové konzole. Systémový administrátor může také v Systémová konzole › Integrace › Správa integrací vypnout každý typ: Povolit příchozí webhooks i Povolit odchozí webhooks jsou ve výchozím nastavení zapnuté.

A channel with messages from a CI bot and from GitHub, shown as cards with fields, pipeline stages and a button
Zprávy integrací vykreslené jako karty: pole, fáze potrubí a tlačítko pro akci.

Vytvoření příchozího webhooku

  1. V Integrace vyberte Příchozí webhooks a poté Přidat příchozí webhook.
  2. Vyplňte Název a Popis: zobrazí se pouze na stránkách integrací.
  3. Vyberte Kanál, do kterého se zprávy odesílají ve výchozím nastavení. U soukromého kanálu musíte být jeho členem.
  4. Zaškrtněte Zamknout na tento kanál, pokud by odesílatelé neměli mít možnost publikovat jinde.
  5. Volitelně nastavte Uživatelské jméno a URL Profilového obrázku pro jeho zprávy (viz Jméno a ikona).
  6. Vyberte Uložit. Zkopírujte zobrazené URL: https://chat.example.com/hooks/<key>.
URL je jediným tajemstvím: kdokoli, kdo ji má, může publikovat v kanálu. Nechávejte ji mimo veřejná úložiště a pokud se ztratí, webhook smažte.

Přes API: POST /api/v4/hooks/incoming s {"channel_id", "display_name", "description", "username", "icon_url", "channel_locked"}; id v odpovědi je klíč. Z příkazového řádku: amctl webhook create-incoming --channel <channel id> --user <user> --display-name "CI".

Odeslání zprávy do příchozího webhooku

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:"}'

Server odpoví 200 s tělem ok. Přijímá také application/x-www-form-urlencoded s JSONem v poli payload, stejně jako webhooks Slacku, takže nástroje vytvořené pro Slack obvykle fungují bez změn.

PoleVýznam
textZpráva v Markdownu. Povinné, pokud nejsou attachments. Text delší než povolená délka zprávy na serveru se rozdělí do více zpráv.
channelJiný kanál komunity webhooaku, podle jména (ops-alerts nebo #ops-alerts), nebo @username pro přímou zprávu od vlastníka webhooaku. Pokud je webhook uzamčen ke svému kanálu, je to zamítnuto. Staré jméno town-square stále dosáhne výchozího kanálu komunity, který se nyní jmenuje general.
username, icon_url, icon_emojiJméno a obrázek, které se zobrazí, pokud to server umožňuje.
attachmentsPřílohy zprávy, vykreslené jako karty (viz níže).
propsDalší vlastnosti uložené ve zprávě pro aplikace, které je čtou. Pro odeslání příspěvku do fórového kanálu je nutné uvést props.am_thread_title (1 až 100 znaků): bez tohoto údaje je webhook odmítnut (viz Fóra přijímají pouze témata).
typeVlastní typ zprávy, např. custom_poll, pro aplikaci, která ho vykreslí. Typy začínající na system_ jsou odmítnuty.
root_idID první zprávy vlákna, do kterého se má odpovědět.
priorityPriorita zprávy, např. {"priority": "urgent"}.
silenttrue odešle zprávu bez push oznámení.

Každá zpráva, kterou webhook zveřejní, nese vedle jména štítek BOT, i když se zobrazuje pod jménem svého tvůrce, aby ji lidé mohli rozlišit od zprávy skutečné osoby. Zprávy od webhooků nikdy nespouštějí odchozí webhooks.

Jméno a ikona

Webhook publikuje jako osoba, která ho vytvořila, pokud to server neumožňuje jinak. Dvě nastavení v Systémová konzole › Integrace › Správa integrací, obě výchozí vypnutá, to mění:

  • Povolit integracím přepis uživatelských jmen (ServiceSettings.EnablePostUsernameOverride): místo jména se zobrazí Uživatelské jméno webhooku nebo username z požadavku; pokud ani jedno není, je jméno webhook.
  • Povolit integracím přepisovat ikony profilových obrázků (ServiceSettings.EnablePostIconOverride): zobrazí se Profilový obrázek webhooku, nebo icon_url nebo icon_emoji z požadavku.

Hodnota z požadavku má přednost před hodnotou uloženou na webhooku.

Přílohy

Přílohy přidávají strukturovaný obsah pod text. Sledují formát příloh zpráv 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
  }]
}
PoleVýznam
fallbackČistý text pro místa, kde se karta nezobrazí, např. v oznámeních.
colorBareva: šestnácková barva, nebo good, warning, danger.
pretextText nad kartou.
author_name, author_link, author_iconMalá záhlaví.
title, title_linkNázev karty, volitelně odkaz.
textTělo karty, v Markdownu.
fieldsSeznam {"title", "value", "short"}; pole short se zobrazí vedle sebe.
image_url, thumb_urlVelký obrázek dole, nebo malý po boku.
footer, footer_icon, tsPatička a čas (Unixové sekundy).
actionsTlačítka a nabídky: viz Interaktivní zprávy.

Karty: fáze a grafy

Antimatter přidává k přílohám dvě pole, která zobrazuje výchozí rozhraní:

  • stages: kroky potrubí ve formě štítků, nejvýše 20. Každý má tvar {"name", "status"}, kde stav je passed, failed, running, pending, skipped nebo canceled.
  • chart: malý čárový graf nedávných hodnot, {"values": [2 to 200 numbers], "threshold": number, "label": "…"}. Práh je vykreslen jako přerušovaná čára, představující limit upozornění.
{
  "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"}
  }]
}

Klasické rozhraní a ostatní klienty tato dvě pole ignorují, proto vložte podstatné informace i do text nebo fields.

Vytvoření odchozího webhooku

Odchozí webhook sleduje Veřejný kanály komunity. Zprávu pošle na vaše URL buď tehdy, když první slovo zprávy odpovídá jednomu z jeho spouštěcích slov, nebo když ji někdo vybere v menu zprávy (jako akce se zprávou).

  1. V Integrace zvolte Odchozí webhooks a poté Přidat odchozí webhook.
  2. Vyplňte Název a Popis.
  3. Zvolte Typ obsahu požadavku: application/x-www-form-urlencoded nebo application/json.
  4. Vyberte Kanál, zadejte Spouštěcí slova (jedno na řádek) nebo obojí. S kanálem a bez spouštěcích slov se pošle každá zpráva z tohoto kanálu. S oběma musí zpráva odpovídat oběma podmínkám.
  5. V sekci Spustit, když vyberte První slovo přesně odpovídá spouštěcímu slovu, První slovo začíná na spouštěcí slovo nebo Z menu zprávy. Při volbě Z menu zprávy zmizí spouštěcí slova, Kanál je volitelný (bez něj se akce nabízí ve všech veřejných kanálech komunity) a Název je povinný: je to název akce v menu.
  6. Zadejte Callback URL (jedna na řádek). Každá URL obdrží každou odpovídající zprávu.
  7. Volitelně nastavte Uživatelské jméno a Profilový obrázek používané pro odpovědi. Pro akci z menu zprávy pole Ikona nahrazuje Profilový obrázek: je to URL obrázku ve formátu .png nebo .jpg nebo, ve výchozím rozhraní Antimatter, nahratý obrázek. V menu se zobrazuje v šedé; bez něj dostane akce neutrální ikonu.
  8. Zvolte Uložit a zkopírujte zobrazený token. Vaše služba ho použije k ověření, že požadavky pocházejí z vašeho serveru.

Přes API: POST /api/v4/hooks/outgoing s tělesem {"team_id", "channel_id", "trigger_words", "trigger_when", "callback_urls", "content_type", "display_name"} (parametr trigger_when: 0 pro přesnou shodu, 1 pro „začíná s“, 2 pro „z nabídky zprávy“). Webhook s hodnotou trigger_when 2 nevyžaduje spouštěcí slova, ale vyžaduje display_name. Ikonu lze nahrát přes POST /api/v4/hooks/outgoing/{hook_id}/icon (multipart, pole image: PNG, JPEG nebo GIF, uloží se jako PNG o rozměru 128 px); pole icon_url pak ukazuje na 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
Spouštěč Nastaveno na Z menu zprávy s polem Ikona.
Pokud je vaše služba v soukromé síti, musí administrátor systému povolit její adresu v Povolit nespolehlivé interní připojení k (ServiceSettings.AllowedUntrustedInternalConnections). Server jinak soukromé adresy nezavolá.

Odchozí požadavek

Antimatter odešle POST s těmito poli, jako JSON nebo form-encoded podle typu obsahu:

{
  "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": ""
}

Před jakýmkoli dalším krokem porovnejte token s tokenem webhooku. Ve verzi kódované jako formulář je timestamp v sekundách, ne v milisekundách. Server na vaši odpověď počítá tak dlouho, jak to dovoluje Časový limit požadavků integrací (výchozí hodnota je 30 sekund, ServiceSettings.OutgoingIntegrationRequestsTimeout).

Odpověď na odchozí webhook

Chcete-li odpovědět, pošlete JSON. Chcete-li neposlat nic, pošlete prázdné tělo.

{
  "text": "Deploying **api 2.4.0** to staging…",
  "response_type": "comment",
  "username": "deploy-bot",
  "icon_url": "https://chat.example.com/static/deploy.png"
}
  • text a attachments: obsah odpovědi. Pokud chybí oba, nic se nepublikuje.
  • response_type: comment publikuje odpověď do vlákna spouštěcí zprávy; jinak se publikuje do kanálu.
  • username, icon_url: zobrazí se, pokud to server dovoluje; jinak se použijí vlastní hodnoty webhooku.
  • props, type, priority: stejně jako u příchozích webhooků.

Odpověď se publikuje jako autor webhooku, případně pod přepsaným jménem. Pro delší odpovědi odpovídejte okamžitě a publikujte je později pomocí příchozího webhooku nebo API.

Akce zprávy

Akce se zprávou je odchozí webhook, u kterého je nastaveno Spustit, když na Z nabídky zprávy. Nikdy se nespustí na základě odeslaných zpráv. Místo toho ji lidé najdou v nabídce konkrétní zprávy: Akce se zprávou (⋯) › Další akce, pod záhlavím Integrace, spolu s její ikonou. V klasickém rozhraní se akce se zprávou nezobrazují. Po výběru se ta jedna zpráva odešle na callback URL a krátce se zobrazí oznámení Odesláno do se jménem akce, případně se zobrazí váš ephemeral_text.

  • Kde se zobrazuje: v kanálu, ke kterému je webhook přiřazen, nebo, pokud kanál není zadán, ve všech veřejných kanálech dané komunity. Akce se zprávou mají pouze veřejné kanály.
  • Hosté mají přístup pouze k akcím přiřazeným ke kanálu, ve kterém se nacházejí, nikoli k akcím platným pro celou komunitu.
  • Archivované a kanály pouze pro čtení: zprávu je stále možné odeslat. Archivace kanálu smaže webhooks k němu přiřazené, takže archivovaný kanál si ponechá pouze akce platné pro celou komunitu. Odpověď, kterou daná osoba nemohla odeslat do kanálu, se zobrazí pouze jí.
  • Limit frekvence: každý uživatel může spustit 10 akcí se zprávou za minutu, po počátečním výpadku 5. Nad tento limit server odpoví kódem 429.
  • Privátní sítě: podobně jako u jiných odchozích webhooků, interní adresy musí být povoleny v nastavení Povolit nespolehlivé interní připojení k.

Požadavek

Tělo požadavku se odesílá jako JSON nebo ve formulářovém kódování, podle obsahu typu webhooku:

{
  "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
}
  • Pole user_id a user_name označují osobu, která akci vybrala; post_user_id a post_user_name označují autora zprávy.
  • Odesílá se pouze ta jedna zpráva, nikdy ne zbytek vlákna.
  • Pole files obsahuje soubory zprávy pouze v případě, že osoba, která akci vybrala, má oprávnění je stáhnout. Stahování odkazu link vyžaduje relaci nebo token, stejně jako jakýkoli jiný soubol v API.
  • Zpráva, která se spálí po přečtení, je odeslána bez textu a souborů, s nastavením burn_on_read na true.
  • Při form-encoded přenosu se soubory přenášejí jako opakovaná pole file_id, file_name a file_link ve stejném pořadí.

Odpověď

Odpovězte jako u libovolného odchozího webhooku (viz Odpověď na odchozí webhook): text nebo attachments zveřejní odpověď v kanálu, a "response_type": "comment" ji zveřejní ve vláknu zprávy. Můžete také odpovědět pomocí ephemeral_text (oříznuto na 300 znaků): zobrazí se pouze osobě, která akci vybrala, v oznámení. Prázdné tělo nezveřejní nic.

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

Přes API

  • GET /api/v4/channels/{channel_id}/message_actions: akce, které můžete vybrat v kanálu, s id, display_name, description a icon_url. Nevrací se ani tokeny, ani URL kallbacků.
  • POST /api/v4/posts/{post_id}/message_actions/{hook_id}: spustí akci na zprávu, kterou můžete přečíst. Odpovídá {"ephemeral_text"}.

Když webhook nefunguje

  • 501 z URL webhooku: příchozí webhooks jsou na serveru vypnuté.
  • 400 "Failed to decode the payload…": JSON je neplatný, nebo pole formuláře se jmenuje jinak než payload. "No text specified." znamená, že požadavek neobsahuje ani text, ani attachments.
  • 403: webhook je uzamčen pro jiný kanál, nebo jeho vlastník už nemůže kanál číst.
  • Odchozí webhook se nikdy nespustí: kanál je soukromý, spouštěcí slovo není prvním slovem, zpráva pochází z webhooku, nebo je webhook nastaven tak, aby se spouštěl Z nabídky zprávy.
  • Akce na zprávu se nezobrazí v nabídce: kanál je soukromý, akce je přiřazena k jinému kanálu, osoba je host a akce nemá přiřazený kanál, nebo jsou odchozí webhooks vypnuté.
  • 404 při spuštění akce na zprávu: akce neexistuje, nebo neobsahuje kanál dané zprávy pro danou osobu. 429: osoba spustila více než 10 akcí za minutu. 502: žádná z callback URL nebyla dosažitelná (důvod je v logu).
  • Příspěvek do fóra je odmítnut: zpráva webhooku musí mít titulek (props.am_thread_title); chybová hláška uvádí důvod, například app.post.forum.title_required.app_error, místo obecné chyby (viz Typy kanálů).
  • Logy: s povoleným Povolit ladění webhooků (LogSettings.EnableWebhookDebugging) a úrovní logování DEBUG server loguje obsah neúspěšných příchozích požadavků. Neúspěšné odchozí volání se loguje jako Outgoing Webhook POST failed.