Webhooks

Un webhook entrant permet a un altre sistema publicar en un canal enviant JSON a una URL secreta. Un webhook sortint fa el contrari: envia missatges a la vostra URL, aquells que comencen per una paraula d'activació o que algú tria al menú de missatges, i publica el que respongueu.

On gestionar els webhooks

Obriu el menú de l'equip, després Configuració de l’equip, i feu clic a Integracions al final de les seves pestanyes. Les pàgines d'integracions de l'equip actual mostren els Webhooks entrants i els Webhooks sortints. Cada webhook pertany a un equip.

Per defecte, els administradors de comunitat i els administradors del sistema poden crear webhooks. Un administrador del sistema pot atorgar aquest permís a altres rols a la configuració de permisos de la Consola del sistema. Un administrador del sistema també pot desactivar cada tipus a Consola del sistema › Integracions › Gestió d'integracions: Habilita els Webhooks entrants i Activa els webhooks sortints estan activats per defecte.

A channel with messages from a CI bot and from GitHub, shown as cards with fields, pipeline stages and a button
Missatges d'integració dibuixats com a targetes: camps, etapes del flux de treball i un botó d'acció.

Crea un webhook entrant

  1. A Integracions, trieu Webhooks entrants i, a continuació, Afegeix un webhook entrant.
  2. Ompliu un Títol i una Descripció: només es mostren a les pàgines d'integracions.
  3. Trieu el Canal on van els missatges per defecte. Per a un canal privat, heu de ser-ne membre.
  4. Marca Bloqueja en aquest canal si els emissors no han de poder publicar en altres llocs.
  5. Opcionalment, establix un Nom d’usuari i una URL d'Imatge de perfil per als seus missatges (vegeu Nom i icona).
  6. Trieu Desa. Copieu la URL que es mostra: https://chat.example.com/hooks/<key>.
La URL és l'únic secret: qualsevol persona que la tingui pot publicar al canal. Mantingueu-la fora dels repositoris públics i suprimiu el webhook si es filtra.

Amb la API: POST /api/v4/hooks/incoming amb {"channel_id", "display_name", "description", "username", "icon_url", "channel_locked"}; el id de la resposta és la clau. Des de la línia d'ordres: amctl webhook create-incoming --channel <channel id> --user <user> --display-name "CI".

Envia un missatge a un webhook entrant

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

El servidor respon 200 amb el cos ok. També accepta application/x-www-form-urlencoded amb el JSON en un camp payload, com fan els webhooks de Slack, de manera que les eines fetes per a Slack solen funcionar sense canvis.

CampSignificat
textEl missatge, en Markdown. Obligatori si no hi ha attachments. Un text més llarg que el límit de missatges del servidor es divideix en diversos missatges.
channelUn altre canal de la comunitat del webhook, pel nom (ops-alerts o #ops-alerts), o @username per a un missatge directe de l'amo del webhook. Es rebutja quan el webhook està bloquejat al seu canal. El nom antic town-square encara arriba al canal per defecte de la comunitat, ara anomenat general.
username, icon_url, icon_emojiEl nom i la imatge a mostrar, quan el servidor permet substitucions.
attachmentsAdjunts del missatge, representats com a targetes (a continuació).
propsPropietats addicionals desades al missatge, per a aplicacions que les llegeixen. Per publicar en un canal de fòrum cal props.am_thread_title (d'1 a 100 caràcters): si no n'hi ha, el hook es rebutja (vegeu Els fòrums només accepten temes).
typeUn tipus de missatge personalitzat, com ara custom_poll, per a una aplicació que el dibuixa. Els tipus que comencen per system_ es rebutgen.
root_idL'ID del primer missatge d'un fil, per respondre en aquest fil.
priorityPrioritat del missatge, per exemple {"priority": "urgent"}.
silenttrue envia el missatge sense notificacions push.

Cada missatge que publica un webhook porta una etiqueta BOT al costat del seu nom, fins i tot quan es mostra sota el nom del seu creador, perquè la gent pugui distingir-lo d'un missatge d'una persona real. Els missatges de webhook mai no activen webhooks sortints.

Nom i icona

Un webhook publica com la persona que el va crear, llevat que el servidor permeti substitucions. Dos paràmetres a Consola del sistema › Integracions › Gestió d'integracions, tots dos desactivats per defecte, canvien això:

  • Activa les integracions per substituir els noms d’usuari (ServiceSettings.EnablePostUsernameOverride): es mostra el Nom d’usuari del webhook o el username de la sol·licitud; si no n'hi ha cap, el nom és webhook.
  • Habilita que les integracions substituïssin les icones de la imatge de perfil (ServiceSettings.EnablePostIconOverride): es mostra l'Imatge de perfil del webhook, o el icon_url o el icon_emoji de la sol·licitud.

Un valor a la sol·licitud té prioritat sobre el desat al webhook.

Adjunts

Els adjunts afegeixen contingut estructurat sota el text. Segueixen el format d'adjunts de missatges de 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
  }]
}
CampSignificat
fallbackText senzill per a llocs que no poden mostrar la targeta, com ara les notificacions.
colorLa barra de color: un color hexadecimal, o good, warning, danger.
pretextText sobre la targeta.
author_name, author_link, author_iconUna línia de capçalera petita.
title, title_linkEl títol de la targeta, opcionalment un enllaç.
textEl cos de la targeta, en Markdown.
fieldsUna llista de {"title", "value", "short"}; els camps short es col·loquen costat a costat.
image_url, thumb_urlUna imatge gran a sota, o una petita al costat.
footer, footer_icon, tsUna línia de peu i un temps (segons Unix).
actionsBotons i menús: consulta Missatges interactius.

Targetes: etapes i gràfics

Antimatter afegeix dos camps als adjunts, que la interfície per defecte dibuixa:

  • stages: els passos d'un flux de treball com a pastilles, fins a 20. Cada un és {"name", "status"}, amb un estat de passed, failed, running, pending, skipped o canceled.
  • chart: un petit gràfic de línia dels valors recents, {"values": [2 to 200 numbers], "threshold": number, "label": "…"}. El llindar es dibuixa com una línia discontinua, com a límit de l'alerta.
{
  "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"}
  }]
}

La interfície clàssica i altres clients ignoren aquests dos camps, així que poseu també els elements essencials a text o fields.

Crea un webhook sortant

Un webhook sortint vigila els canals Públic d'una comunitat. Envia un missatge a la vostra URL quan la primera paraula del missatge coincideix amb una de les seves paraules d'activació, o quan algú el tria al menú del missatge (una acció de missatge).

  1. A Integracions, tria Webhooks sortints i després Afegeix webhook sortant.
  2. Ompliu el Títol i la Descripció.
  3. Trieu el Tipus de contingut de la sol·licitud: application/x-www-form-urlencoded o application/json.
  4. Trieu un Canal, introduïu Paraules d'activació (una per línia) o ambdós. Amb un canal i sense paraules d'activació, s'envia cada missatge d'aquell canal. Amb ambdós, el missatge ha de coincidir amb tots dos.
  5. Sota Activar quan, trieu La primera paraula coincideix exactament amb una paraula d'activació, La primera paraula comença per una paraula d'activació o Des del menú de missatges. Amb Des del menú de missatges, les paraules d'activació desapareixen, el Canal és opcional (sense un, l'acció s'ofereix en tots els canals públics de la comunitat) i el Títol és obligatori: és el nom de l'acció al menú.
  6. Introduïu les URLs de retorn (una per línia). Cada URL rep tots els missatges que coincideixin.
  7. Opcionalment, configureu el Nom d’usuari i la Imatge de perfil utilitzats per a les respostes. Per a una acció des del menú de missatges, el camp Icona substitueix la Imatge de perfil: l'URL d'una imatge .png o .jpg o, a la interfície per defecte d'Antimatter, una imatge penjada. El menú la mostra en gris; sense una, l'acció rep una icona neutra.
  8. Trieu Desa i copieu el token mostrat. El vostre servei l'utilitza per comprovar que les sol·licituds provenen del vostre servidor.

Mitjançant la API: POST /api/v4/hooks/outgoing amb {"team_id", "channel_id", "trigger_words", "trigger_when", "callback_urls", "content_type", "display_name"} (trigger_when: 0 per a una coincidència exacta, 1 per a «comença per», 2 per a «des del menú del missatge»). Un webhook amb trigger_when 2 no requereix paraules d'activació i necessita un display_name. Penja-ne la icona amb POST /api/v4/hooks/outgoing/{hook_id}/icon (multipart, camp image: PNG, JPEG o GIF, emmagatzemada com a PNG de 128 px); el seu icon_url llavors apunta a 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
Disparador quan es configura Des del menú del missatge, amb el camp Icona.
Si el vostre servei està en una xarxa privada, un administrador del sistema ha de permetre la seva adreça a Permet connexions internes no fiables a (ServiceSettings.AllowedUntrustedInternalConnections). El servidor no crida adreces privades altrament.

La sol·licitud sortant

Antimatter envia un POST amb aquests camps, com a JSON o codificat en formulari segons el tipus de contingut:

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

Compara el token amb el token del webhook abans de fer res. En la versió codificada en formulari, el timestamp és en segons i no en mil·lisegons. El servidor espera la teva resposta durant el temps que permet el Temps d’espera de la sol·licitud d’integració (30 segons per defecte, ServiceSettings.OutgoingIntegrationRequestsTimeout).

Resposta a un webhook sortant

Per publicar una resposta, respon amb JSON. Per no publicar res, respon amb un cos buit.

{
  "text": "Deploying **api 2.4.0** to staging…",
  "response_type": "comment",
  "username": "deploy-bot",
  "icon_url": "https://chat.example.com/static/deploy.png"
}
  • text i attachments: la resposta. Sense cap d'aquests dos camps, no es publica res.
  • response_type: comment publica la resposta al fil del missatge que l'ha activat; en cas contrari, es publica al canal.
  • username, icon_url: es mostren quan el servidor permet substitucions; en cas contrari, s'utilitzen els valors propis del webhook.
  • props, type, priority: com per als webhooks entrants.

La resposta es publica com a l'usuari creador del webhook, sota el nom substituït si n'hi ha. Per a res més llarg que una resposta ràpida, respon de seguida i publica després amb un webhook entrant o l'API.

Accions de missatge

Una acció del missatge és un webhook sortant amb Activar quan establert a Des del menú del missatge. Mai s'activa amb missatges publicats. En canvi, les persones la veuen al menú d'un missatge: Accions del missatge (⋯) › Més accions, sota el títol Integracions, amb la seva icona. La interfície clàssica no mostra les accions del missatge. En triar-la, s'envia aquest missatge concret a les URL de callback, i un avís breu diu Enviat a el nom de l'acció, o mostra el teu ephemeral_text.

  • On es mostra: al canal del webhook o, sense canal, a tots els canals públics de la seva comunitat. Només els canals públics tenen accions del missatge.
  • Els Convidats només reben les accions vinculades a un canal en què són, no les de tota la comunitat.
  • Canals arxivats i només lectura: el missatge encara es pot enviar. Arxivar un canal suprimeix els webhooks vinculats a ell, de manera que un canal arxivat només manté les accions de tota la comunitat. Una resposta que la persona no pogués publicar-hi se li mostra només a ella.
  • Límit de freqüència: cada persona pot executar 10 accions del missatge per minut, després d'un pic de 5. Per sobre d'això, el servidor respon 429.
  • Xarxes privades: com amb altres webhooks sortants, s'han de permetre les adreces internes a Permet connexions internes no fiables a.

La sol·licitud

La càrrega s'envia com a JSON o codificada en formulari, segons el tipus de contingut del 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 i user_name són la persona que ha triat l'acció; post_user_id i post_user_name l'autor del missatge.
  • Només s'envia aquest missatge, mai la resta del seu fil.
  • files llista els fitxers del missatge només si la persona que ha triat l'acció pot descarregar-los. Descarregar un link requereix una sessió o un testimoni, com qualsevol fitxer de la API.
  • Un missatge que s'elimina en llegir-lo s'envia sense el seu text ni fitxers, amb burn_on_read establert a true.
  • En codificació de formulari, les fitxers arriben com a camps repetits de file_id, file_name i file_link, en el mateix ordre.

La resposta

Respon com per a qualsevol webhook sortant (vegeu Resposta a un webhook sortant): text o attachments publica una resposta al canal, i "response_type": "comment" la publica al fil del missatge. També podeu respondre amb ephemeral_text (tallat a 300 caràcters): es mostra només a la persona que va triar l'acció, a la notificació. Un cos buit no publica res.

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

Amb la API

  • GET /api/v4/channels/{channel_id}/message_actions: les accions que podeu triar en un canal, amb id, display_name, description i icon_url. No es retornen ni fitxes ni URL de callback.
  • POST /api/v4/posts/{post_id}/message_actions/{hook_id}: executa una acció en un missatge que podeu llegir. Respon {"ephemeral_text"}.

Quan un webhook no funciona

  • 501 des de l'URL del webhook: els webhooks entrants estan desactivats al servidor.
  • 400 «Failed to decode the payload…»: el JSON no és vàlid, o el camp del formulari no s'anomena payload. «No text specified.» significa que la sol·licitud no té ni text ni attachments.
  • 403: el webhook està bloquejat a un altre canal, o el seu propietari ja no pot llegir el canal.
  • Un webhook sortant mai no s'activa: el canal és privat, el desencadenant no és la primera paraula, el missatge va provenir d'un webhook, o el webhook està configurat per activar-se Des del menú del missatge.
  • Una acció de missatge no apareix al menú: el canal és privat, l'acció està vinculada a un altre canal, la persona és un invitat i l'acció no té canal, o els webhooks sortants estan desactivats.
  • 404 en executar una acció de missatge: l'acció no existeix, o no cobreix el canal d'aquest missatge per a aquesta persona. 429: la persona va executar més de 10 accions en un minut. 502: cap de les URL de callback va poder ser arribada (el registre conté la raó).
  • Es rebutja la publicació en un fòrum: el missatge del hook necessita un títol (props.am_thread_title); l'error indica el motiu, com ara app.post.forum.title_required.app_error, en lloc d'un error genèric (vegeu Tipus de canal).
  • Registres: amb Habilita el depuració de webhooks activat (LogSettings.EnableWebhookDebugging) i el nivell de registre a DEBUG, el servidor registra les càrregues de les sol·licituds entrants fallides. Les crides sortints fallides es registren com a Outgoing Webhook POST failed.