Pereiti prie pagrindinio turinio
Programuotojams Webhook’ai

Skelbk žinutes per webhook

Webhook yra URL, kuris skelbia į tavo bendruomenę. Siųsk jam JSON iš bet ko, kas gali atlikti HTTP užklausą, pavyzdžiui, iš CI, stebėsenos, cron užduoties ar skripto, ir žinutė atsiras kanale.

Ką gali padaryti

  • Skelbk tekstą ar kortelęPaprastas tekstas arba kortelė su pavadinimu, spalva, markdown, laukais ir paveikslėliais.
  • Pridėk failusIki penkių failų vienoje žinutėje: žurnalai, ataskaitos, ekrano nuotraukos.
  • Pridėk mygtukusNuorodos arba mygtukai, kurie keičia kortelę ar kreipiasi į tavo paslaugą.
  • Pakeisk vėliauAtsakyme yra callback URL, skirtas žinutei atnaujinti ar ištrinti.

Programėlėje

$ curl -X POST "$MSSGS_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "X-Mssgs-Signature: sha256=$SIG" \
-d '{"message_container": {"title": "Build #1847 sėkmingas", ...}}'
{"success": true, "message_id": "aZZ1a2b-..."}

Viena užklausa iš CI, viena kortelė kanale #deploys. Viršuje rodomas pavadinimas, kurį davei webhook’ui.

Greita pradžia

  1. Sukurk webhook

    Kompiuterio programėlėje atidaryk savo bendruomenės Manage Server → Webhooks, sukurk webhook, pasirink kanalus, kuriuose jis gali skelbti, ir nukopijuok kanalo URL. Jis atrodo taip:

    url
    https://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}
  2. Išsiųsk žinutę

    Pasirašyk JSON webhook’o slaptuoju raktu ir išsiųsk jį POST užklausa. Kompiuterio programėlėje sukurtas webhook visada turi slaptąjį raktą: nukopijuok jį iš Webhook Secret webhook’o nustatymuose.

    bash
    BODY='{"content": "Build #1847 passed on main"}'
    SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$MSSGS_WEBHOOK_SECRET" | sed 's/^.* //')
    
    curl -X POST "$MSSGS_WEBHOOK_URL" \
      -H "Content-Type: application/json" \
      -H "X-Mssgs-Signature: sha256=$SIG" \
      -d "$BODY"
  3. Perskaityk atsakymą

    Atsakyme gausi žinutės id ir callback_url, kuriuo vėliau galėsi pakeisti žinutę.

    json
    {
      "success": true,
      "message_id": "aZZ1a2b-...",
      "callback_url": "https://mss.gs/api/v1/trigger-callback/8f14e45f-...",
      "stream_url": "https://mss.gs/api/v1/instant/6b1e...c0?token=a1b2c3d4-..."
    }
Kiekvienas, kas turi URL ir slaptąjį raktą, gali skelbti tame kanale. Nelaikyk jų viešose saugyklose ar kliento pusės kode.

Ką gali siųsti

Žinutė yra arba trumpoji forma (tekstas su pavadinimu ir spalva), arba visa kortelė, ir abi gali turėti mygtukų bei failų. Kortelės viršuje visada rodomas paties webhook’o pavadinimas. Webhook’o nustatymuose taip pat nusprendi, ar jis gali skelbti paveikslėlius ir paminėti žmones.

Trumpoji forma

Pakanka daugumai įspėjimų.

json
{
  "content": "Server backup completed at 03:00 UTC",
  "color": "green",
  "title": "Backup Bot"
}
LaukasTipasKą daro
contentstringŽinutės tekstas. Privalomas, nebent siunti kortelę ar failus.
colorstringblue (numatytoji), green, orange, red, yellow arba purple.
titlestringPavadinimas virš teksto. Numatytai webhook’o pavadinimas.

Visa kortelė

Siųsk message_container, kad gautum kortelę su pavadinimu nuoroda, paantrašte, markdown, laukais ir paveikslėliais. Per webhook kortelė priima type, color, title, title_url, sub_title, description, fields, avatar_url, image_url, image_base64, images ir loader laukus. Būsenos ženkliukas, žymė, diff statistika ir suskleisti samprotavimai skirti atsakymams į komandas. Visi laukai aprašyti puslapyje žinučių kortelės.

json
{
  "message_container": {
    "type": "embed_message",
    "color": "green",
    "title": "Build #1847 passed",
    "title_url": "https://ci.example.com/builds/1847",
    "description": "All 212 tests green on **main**.",
    "fields": [
      { "field": "Duration", "value": "2m 34s" },
      { "field": "Commit", "value": "1a2b3c4" }
    ]
  }
}
deploys
System
Message from CI

Build #1847 sėkmingas

Visi 212 testų main šakoje praeina.
Duration
2m 34s
Commit
1a2b3c4

Mygtukai

Pridėk actions masyvą, kad po žinute atsirastų mygtukai. Kaip jie veikia, rasi puslapyje mygtukai.

Failai

Skelbk su žinute tikrus failus: žurnalą, ataskaitą, ekrano nuotrauką. Jie rodomi kaip bet kuris kitas priedas: kaip atsisiuntimo eilutė, o paveikslėliai, vaizdo ir garso įrašai tiesiai žinutėje. Žinutė vien su failais taip pat tinka: praleisk content ir kortelę.

json
{
  "message_container": {
    "color": "orange",
    "title": "Log dump: ios",
    "description": "DMs stopped arriving after switching networks"
  },
  "attachments": [
    {
      "name": "mssgs-logs-20260803-141205.log",
      "content_base64": "MjAyNi0wOC0wMyAxNDoxMjowNSBbV1NdIGNvbm5lY3RlZAo=",
      "mime_type": "text/plain"
    }
  ]
}
LaukasTipasKą daro
namestringFailo pavadinimas atsisiunčiant. Privalomas. Kelias sutrumpinamas iki paskutinės dalies.
content_base64stringFailo baitai base64 formatu, gryni arba kaip data: URI. mssgs saugo failą, o žinutėje palieka tik nuorodą.
mime_typestringcontent_base64 turinio tipas. Numatytai text/plain.
urlstringFailas, jau talpinamas mssgs: /static/... kelias arba https://mss.gs/... URL.
Kiekvienam failui siųsk lygiai vieną iš dviejų: content_base64 arba url. Abu kartu arba nė vieno yra klaida.
LimitasReikšmė
Failų vienoje žinutėje5
Failo dydis po dekodavimo8 MB
Failo pavadinimas200 simbolių
Visa užklausaApie 10 MB. Base64 padidina failą trečdaliu, todėl vienas didesnis nei maždaug 7 MB failas netilps.

Kodėl url priima tik mssgs adresus

Webhook URL dažnai atsiduria įklijuotas kitų paslaugų skydeliuose. Nutekėjęs URL neturi leisti kam nors priversti kiekvieno nario programėlės parsisiųsti failo iš jo pasirinkto serverio. Jei tavo failas yra kitur, siųsk jį kaip content_base64, ir mssgs jį talpins.

Nepavykęs įkėlimas nesustabdo žinutės

Failai patikrinami iš anksto, bet įkeliami vėliau. Jei įkėlimas nepavyksta, tas failas praleidžiamas, o likusi žinutė vis tiek paskelbiama, be klaidos: geriau prarasti failą nei ataskaitą. Jei failas svarbus, patikrink, ar jis atkeliavo.

Failas iš komandinės eilutės

bash
BODY='{"attachments":[{"name":"report.csv","content_base64":"'"$(base64 < report.csv | tr -d '\n')"'","mime_type":"text/csv"}]}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$MSSGS_WEBHOOK_SECRET" | sed 's/^.* //')

printf '%s' "$BODY" | curl -sS -X POST "$MSSGS_WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -H "X-Mssgs-Signature: sha256=$SIG" \
  --data-binary @-

Užklausų pasirašymas

Webhook su slaptuoju raktu priima tik tas užklausas, kurios įrodo, kad jį žino, o kompiuterio programėlėje sukurtas webhook visada jį turi (Webhook Secret jo nustatymuose). Pasirašyk neapdorotą užklausos turinį HMAC-SHA256 algoritmu naudodamas slaptąjį raktą ir siųsk mažosiomis raidėmis užrašytą hex santrauką antraštėje X-Mssgs-Signature kaip sha256=<hex>.

javascript
import crypto from 'node:crypto';

const body = JSON.stringify({ content: 'Deploy finished' });
const signature = crypto.createHmac('sha256', process.env.MSSGS_WEBHOOK_SECRET)
  .update(body)
  .digest('hex');

await fetch(process.env.MSSGS_WEBHOOK_URL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Mssgs-Signature': `sha256=${signature}`
  },
  body
});
Užklausa be galiojančio parašo gauna 401 ir {"error": "INVALID_SIGNATURE"}. Nepasirašytas užklausas priima tik webhook be slaptojo rakto, pavyzdžiui, sukurtas per MCP be webhook_secret.

Priimama ir paties GitHub antraštė X-Hub-Signature-256, todėl GitHub webhook su tuo pačiu slaptuoju raktu veikia be pakeitimų. Parašas neturi laiko žymos, todėl neapsaugo nuo to, kad perimta užklausa būtų išsiųsta dar kartą: svarbiausia paslaptis lieka pats URL.

Atsakymai ir klaidos

Paskelbta žinutė grąžinama su savo id ir callback_url, kuriuo 30 minučių gali ją atnaujinti ar ištrinti.

json
{
  "success": true,
  "message_id": "aZZ1a2b-...",
  "callback_url": "https://mss.gs/api/v1/trigger-callback/8f14e45f-...",
  "stream_url": "https://mss.gs/api/v1/instant/6b1e...c0?token=a1b2c3d4-..."
}
Skaityk ne tik būseną, bet ir turinį. Atmesto payload priežastis nurodoma turinyje kaip error kodas. Bet kokį turinį su error raktu laikyk nesėkme, nesvarbu, koks būsenos kodas.
http
HTTP/1.1 200 OK
Content-Type: application/json

{ "error": "ATTACHMENT_TOO_LARGE" }
javascript
const res = await fetch(webhookUrl, { method: 'POST', headers, body });
const reply = await res.json().catch(() => null);

// A rejected payload still comes back as 200: read the body.
if (!res.ok || (reply && reply.error)) {
  throw new Error(`webhook rejected: ${reply?.error ?? res.status}`);
}

Kai žinutėje yra mygtukų, atsakyme taip pat yra stream_url: gyvas tos žinutės atsakymų, reakcijų ir mygtukų paspaudimų srautas, atviras 10 minučių arba valandą, jei siunti "sse_event_extended_timeout": true. Žr. atnaujinimai realiuoju laiku.

Būsenos kodai

BūsenaKada
401Webhook turi slaptąjį raktą, o parašo nėra arba jis neteisingas.
403Šis webhook negali skelbti tame kanale.
404Šiuo URL webhook’o nėra.
413Užklausa per didelė.
429Per daug užklausų. Sulėtink ir bandyk dar kartą.
502Žinutės nepavyko pristatyti. Bandyk dar kartą.

Klaidų kodai

KodasReikšmė
MISSING_CONTENTNėra ko skelbti: nėra nei teksto, nei kortelės, nei failų.
INVALID_MESSAGE_CONTAINERmessage_container nėra objektas.
INVALID_MESSAGE_CONTAINER_TYPEKortelės tipas nėra nei embed_message, nei system_message.
MISSING_MESSAGE_CONTAINER_DESCRIPTIONKortelei reikia aprašymo, nebent tai loader kortelė.
MISSING_MESSAGE_CONTAINER_LOADER_TEXTLoader kortelei reikia loader_text.
INVALID_WEBHOOK_BINDINGŠis webhook negali skelbti tame kanale.
INVALID_SIGNATUREParašo antraštės nėra arba ji neteisinga.
REQUEST_BODY_TOO_LARGEUžklausa viršija dydžio limitą.
PUBLISH_FAILEDŽinutės nepavyko pristatyti.
INVALID_ACTIONS_FORMAT, INVALID_ACTION_MISSING_FIELDS, DUPLICATE_ACTION_ID, INVALID_TRIGGERS_FORMAT, INVALID_TRIGGER_MISSING_ACTION, INVALID_TRIGGER_ACTION_NOT_ALLOWEDKažkas negerai su mygtuku. Žr. mygtukai.

Failų klaidos

KodasReikšmė
INVALID_ATTACHMENTS_FORMATattachments nėra sąrašas arba kuris nors įrašas nėra objektas.
TOO_MANY_ATTACHMENTSDaugiau nei penki failai.
MISSING_ATTACHMENT_NAMEFailas neturi pavadinimo.
INVALID_ATTACHMENT_NAMEIš pavadinimo nelieka nieko tinkamo, pavyzdžiui, ...
MISSING_ATTACHMENT_SOURCENėra nei url, nei content_base64.
AMBIGUOUS_ATTACHMENT_SOURCEYra ir url, ir content_base64.
INVALID_ATTACHMENT_BASE64Base64 nepavyksta dekoduoti.
ATTACHMENT_TOO_LARGEFailas po dekodavimo didesnis nei 8 MB.
INVALID_ATTACHMENT_URLurl nėra mssgs adresas.

Limitai

LimitasReikšmė
Užklausos dydisApie 10 MB
Failų vienoje žinutėje5, kiekvienas iki 8 MB
Kortelės aprašymasIki 50 000 baitų. Viršijus 1 000 baitų, nariai mato pradžią ir mygtuką Show more.
Žinutės atnaujinimas po paskelbimo30 minučių, per callback_url
Žinutės su mygtukais gyvas srautas10 minučių arba valanda, jei paprašai

Užklausų dažnis ribojamas. Gavęs 429, palauk prieš siųsdamas vėl, o pliūpsniais ateinančius įspėjimus sujunk į vieną žinutę.

GitHub, UniFi ir App Store Connect

Nukreipk vieną iš šių paslaugų į webhook URL, ir mssgs ją atpažins bei paskelbs tvarkingą kortelę, nereikės rašyti jokio payload. Žr. integracijos. Šios paslaugos atsakymu gauna {"success": true} ir jokio callback URL.

ŠaltinisAtpažįstama pagalKą skelbia
GitHubAntraštė x-github-eventPush’ai, pull request’ai ir peržiūros, issues ir komentarai, šakos ir žymos, leidimai. Daug pakeitimų per trumpą laiką viename issue ar pull request’e sujungiami į vieną kortelę.
UniFi ProtectUser agent protect-alarm-managerDurų skambučiai, judesys ir tavo kamerų aptikti žmonės, transporto priemonės ar siuntiniai.
App Store ConnectJo pranešimų turinys arba antraštė x-apple-signatureApp Store Connect pranešimai.

Kurk toliau