Preskoči na glavno vsebino
Razvijalci Webhooki

Objavljaj sporočila z webhookom

Webhook je URL, ki objavlja v tvoji skupnosti. Pošlji mu JSON iz česar koli, kar zna poslati zahtevo HTTP, na primer iz CI, nadzornega sistema, opravila cron ali skripte, in sporočilo se prikaže v kanalu.

Kaj lahko narediš

  • Objavi besedilo ali karticoNavadno besedilo ali kartica z naslovom, barvo, markdownom, polji in slikami.
  • Priloži datotekeDo pet datotek na sporočilo: dnevniki, poročila, posnetki zaslona.
  • Dodaj gumbePovezave ali gumbi, ki spremenijo kartico ali pokličejo tvojo storitev.
  • Spremeni ga poznejeOdgovor vsebuje callback URL, s katerim sporočilo posodobiš ali izbrišeš.

V aplikaciji

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

Ena zahteva iz CI, ena kartica v #deploys. Ime na vrhu je ime, ki si ga dal webhooku.

Hiter začetek

  1. Ustvari webhook

    V namizni aplikaciji v svoji skupnosti odpri Manage Server → Webhooks, ustvari webhook, izberi kanale, v katerih sme objavljati, in kopiraj URL za kanal. Ima to obliko:

    url
    https://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}
  2. Pošlji sporočilo

    JSON podpiši s skrivnim ključem webhooka in ga pošlji z zahtevo POST. Webhook, ustvarjen v namizni aplikaciji, ga ima vedno: kopiraj ga iz polja Webhook Secret v nastavitvah webhooka.

    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. Preberi odgovor

    Odgovor vsebuje ID sporočila in callback_url, s katerim sporočilo pozneje spremeniš.

    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-..."
    }
Kdor ima URL in skrivni ključ, lahko objavlja v tem kanalu. Ne hrani ju v javnih repozitorijih ali v kodi na strani odjemalca.

Kaj lahko pošlješ

Sporočilo je bodisi kratka oblika (besedilo z naslovom in barvo) bodisi cela kartica, obe pa lahko vsebujeta gumbe in datoteke. Ime na vrhu kartice je vedno ime samega webhooka. V nastavitvah webhooka določiš tudi, ali sme objavljati slike in omenjati ljudi.

Kratka oblika

Dovolj za večino opozoril.

json
{
  "content": "Server backup completed at 03:00 UTC",
  "color": "green",
  "title": "Backup Bot"
}
PoljeTipKaj naredi
contentstringBesedilo sporočila. Obvezno, razen če pošlješ kartico ali datoteke.
colorstringblue (privzeto), green, orange, red, yellow ali purple.
titlestringNaslov nad besedilom. Privzeto je to ime webhooka.

Cela kartica

Pošlji message_container za kartico z naslovom kot povezavo, podnaslovom, markdownom, polji in slikami. Prek webhooka kartica sprejme type, color, title, title_url, sub_title, description, fields, avatar_url, image_url, image_base64, images in polja za indikator nalaganja. Oznaka stanja, značka, statistika sprememb in skrito razmišljanje so namenjeni odgovorom na ukaze. Vsa polja so opisana na strani kartice sporočil.

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 je uspel

Vseh 212 testov na main je zelenih.
Duration
2m 34s
Commit
1a2b3c4

Gumbi

Dodaj seznam actions in pod sporočilom se prikažejo gumbi. Kako delujejo, piše na strani gumbi.

Datoteke

S sporočilom objavi prave datoteke: dnevnik, poročilo, posnetek zaslona. Prikažejo se kot vsaka druga priponka, kot vrstica za prenos, slike, video in zvok pa neposredno v sporočilu. Tudi sporočilo samo z datotekami je v redu: izpusti content in kartico.

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"
    }
  ]
}
PoljeTipKaj naredi
namestringIme, pod katerim se datoteka prenese. Obvezno. Pot se skrajša na zadnji del.
content_base64stringBajti datoteke v base64, surovi ali kot URI data:. mssgs datoteko shrani, v sporočilu pa obdrži le povezavo.
mime_typestringVrsta vsebine v content_base64. Privzeto text/plain.
urlstringDatoteka, ki že gostuje na mssgs: pot /static/... ali URL https://mss.gs/....
Za vsako datoteko pošlji natanko eno od dveh: content_base64 ali url. Oboje hkrati ali nobeno je napaka.
OmejitevVrednost
Datoteke na sporočilo5
Velikost datoteke po dekodiranju8 MB
Ime datoteke200 znakov
Celotna zahtevaPribližno 10 MB. Base64 datoteko poveča za tretjino, zato ena sama datoteka nad približno 7 MB ne bo šla skozi.

Zakaj url sprejema samo naslove mssgs

URL webhooka pogosto pristane prilepljen v druge nadzorne plošče. Če uide v javnost, ne sme nikomur omogočiti, da bi aplikacija vsakega člana prenesla datoteko s strežnika po njegovi izbiri. Če je tvoja datoteka drugje, jo pošlji kot content_base64 in mssgs jo bo gostil.

Neuspešno nalaganje datoteke ne ustavi sporočila

Datoteke se preverijo vnaprej, naložijo pa pozneje. Če nalaganje spodleti, ta datoteka izpade, preostanek sporočila pa se vseeno objavi, brez napake: bolje izgubiti datoteko kot poročilo. Če je datoteka pomembna, preveri, ali je prispela.

Datoteka iz ukazne vrstice

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 @-

Podpisovanje zahtev

Webhook s skrivnim ključem sprejme le zahteve, ki dokažejo, da ga poznajo, webhook, ustvarjen v namizni aplikaciji, pa ga ima vedno (Webhook Secret v njegovih nastavitvah). Surovo telo zahteve podpiši s HMAC-SHA256 in skrivnim ključem, šestnajstiški povzetek z malimi črkami pa pošlji v glavi X-Mssgs-Signature kot 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
});
Zahteva brez veljavnega podpisa dobi 401 in {"error": "INVALID_SIGNATURE"}. Nepodpisane zahteve sprejme le webhook brez skrivnega ključa, na primer tak, ki je bil ustvarjen prek MCP brez webhook_secret.

Sprejeta je tudi GitHubova glava X-Hub-Signature-256, zato webhook na GitHubu z istim skrivnim ključem deluje brez sprememb. Podpis nima časovnega žiga, zato ne prepreči ponovnega pošiljanja prestrežene zahteve: skrivnost, ki res šteje, ostaja URL.

Odgovori in napake

Objavljeno sporočilo se vrne s svojim ID-jem in callback_url, s katerim ga lahko 30 minut posodabljaš ali ga izbrišeš.

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-..."
}
Preberi telo odgovora, ne le statusa. Zavrnjen payload navede razlog v telesu kot kodo error. Vsako telo s ključem error obravnavaj kot neuspeh, ne glede na statusno kodo.
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}`);
}

Če ima sporočilo gumbe, odgovor vsebuje tudi stream_url: tok v živo z odgovori, reakcijami in pritiski gumbov na tem sporočilu, odprt 10 minut ali eno uro, če pošlješ "sse_event_extended_timeout": true. Glej posodobitve v živo.

Statusne kode

StatusKdaj
401Webhook ima skrivni ključ, podpis pa manjka ali je napačen.
403Ta webhook ne sme objavljati v tem kanalu.
404Na tem URL-ju ni webhooka.
413Zahteva je prevelika.
429Preveč zahtev. Upočasni in poskusi znova.
502Sporočila ni bilo mogoče dostaviti. Poskusi znova.

Kode napak

KodaPomen
MISSING_CONTENTNi ničesar za objavo: ni besedila, kartice niti datotek.
INVALID_MESSAGE_CONTAINERmessage_container ni objekt.
INVALID_MESSAGE_CONTAINER_TYPEVrsta kartice ni ne embed_message ne system_message.
MISSING_MESSAGE_CONTAINER_DESCRIPTIONKartica potrebuje opis, razen če gre za indikator nalaganja.
MISSING_MESSAGE_CONTAINER_LOADER_TEXTKartica z indikatorjem nalaganja potrebuje loader_text.
INVALID_WEBHOOK_BINDINGTa webhook ne sme objavljati v tem kanalu.
INVALID_SIGNATUREGlava s podpisom manjka ali je podpis napačen.
REQUEST_BODY_TOO_LARGEZahteva presega omejitev velikosti.
PUBLISH_FAILEDSporočila ni bilo mogoče dostaviti.
INVALID_ACTIONS_FORMAT, INVALID_ACTION_MISSING_FIELDS, DUPLICATE_ACTION_ID, INVALID_TRIGGERS_FORMAT, INVALID_TRIGGER_MISSING_ACTION, INVALID_TRIGGER_ACTION_NOT_ALLOWEDNekaj je narobe z gumbom. Glej gumbe.

Napake pri datotekah

KodaPomen
INVALID_ATTACHMENTS_FORMATattachments ni seznam ali pa kateri od vnosov ni objekt.
TOO_MANY_ATTACHMENTSVeč kot pet datotek.
MISSING_ATTACHMENT_NAMEDatoteka nima imena.
INVALID_ATTACHMENT_NAMEOd imena ne ostane nič uporabnega, na primer pri ...
MISSING_ATTACHMENT_SOURCENi ne url ne content_base64.
AMBIGUOUS_ATTACHMENT_SOURCEHkrati url in content_base64.
INVALID_ATTACHMENT_BASE64Base64 se ne da dekodirati.
ATTACHMENT_TOO_LARGEDatoteka ima po dekodiranju več kot 8 MB.
INVALID_ATTACHMENT_URLurl ni naslov mssgs.

Omejitve

OmejitevVrednost
Velikost zahtevePribližno 10 MB
Datoteke na sporočilo5, vsaka do 8 MB
Opis karticeDo 50.000 bajtov. Po 1000 bajtih člani vidijo začetek in gumb Show more.
Posodabljanje sporočila po objavi30 minut, prek callback_url
Tok v živo za sporočilo z gumbi10 minut ali na zahtevo ena ura

Število zahtev je omejeno. Ko dobiš 429, počakaj, preden znova pošlješ, opozorila, ki prihajajo v valovih, pa združi v eno sporočilo.

GitHub, UniFi in App Store Connect

Usmeri eno od teh storitev na URL webhooka in mssgs jo prepozna ter objavi pravo kartico, ne da bi ti moral pisati payload. Glej integracije. Te storitve dobijo odgovor {"success": true} brez callback URL-ja.

VirPrepoznan poKaj objavi
GitHubGlava x-github-eventPushi, pull requesti in pregledi, issueji in komentarji, veje in oznake, izdaje. Val sprememb v enem issueju ali pull requestu se zbere v eno kartico.
UniFi ProtectUser agent protect-alarm-managerZvonjenje na vratih, gibanje ter ljudje, vozila ali paketi, ki jih zaznajo tvoje kamere.
App Store ConnectTelo njegovih obvestil ali glava x-apple-signatureObvestila App Store Connect.

Gradi naprej