Preskoči na glavni sadržaj
Programeri Webhookovi

Objavljuj poruke webhookom

Webhook je URL koji objavljuje u tvojoj zajednici. Pošalji mu JSON iz bilo čega što može poslati HTTP zahtjev, primjerice iz CI-ja, sustava za nadzor, cron posla ili skripte, i poruka se pojavi u kanalu.

Što možeš napraviti

  • Objavi tekst ili karticuObičan tekst ili kartica s naslovom, bojom, markdownom, poljima i slikama.
  • Priloži datotekeDo pet datoteka po poruci: logovi, izvještaji, snimke zaslona.
  • Dodaj gumbePoveznice ili gumbi koji mijenjaju karticu ili se javljaju tvojoj usluzi.
  • Promijeni je kasnijeOdgovor sadrži callback URL za ažuriranje ili brisanje poruke.

U 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 prošao", ...}}'
{"success": true, "message_id": "aZZ1a2b-..."}

Jedan zahtjev iz CI-ja, jedna kartica u #deploys. Ime na vrhu je ime koje si dao webhooku.

Brzi početak

  1. Izradi webhook

    U aplikaciji za računalo otvori u svojoj zajednici Manage Server → Webhooks, izradi webhook, odaberi kanale u kojima smije objavljivati i kopiraj URL za kanal. Izgleda ovako:

    url
    https://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}
  2. Pošalji poruku

    Potpiši JSON tajnim ključem webhooka i pošalji ga POST zahtjevom. Webhook izrađen u aplikaciji za računalo uvijek ga ima: kopiraj ga iz polja Webhook Secret u postavkama 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. Pročitaj odgovor

    Odgovor ti daje id poruke i callback_url kojim kasnije možeš promijeniti poruku.

    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-..."
    }
Svatko tko ima URL i tajni ključ može objavljivati u tom kanalu. Ne stavljaj ih u javne repozitorije ni u kôd na strani klijenta.

Što možeš poslati

Poruka je ili kratki oblik (tekst s naslovom i bojom) ili puna kartica, a oba mogu nositi gumbe i datoteke. Ime na vrhu kartice uvijek je ime samog webhooka. U postavkama webhooka odlučuješ i smije li objavljivati slike i spominjati ljude.

Kratki oblik

Dovoljan za većinu upozorenja.

json
{
  "content": "Server backup completed at 03:00 UTC",
  "color": "green",
  "title": "Backup Bot"
}
PoljeTipŠto radi
contentstringTekst poruke. Obavezan, osim ako šalješ karticu ili datoteke.
colorstringblue (zadano), green, orange, red, yellow ili purple.
titlestringNaslov iznad teksta. Zadano je ime webhooka.

Puna kartica

Pošalji message_container za karticu s naslovom koji je poveznica, podnaslovom, markdownom, poljima i slikama. Kroz webhook kartica prima type, color, title, title_url, sub_title, description, fields, avatar_url, image_url, image_base64, images i polja loadera. Oznaka statusa, značka, statistika diffa i sklopljeno razmišljanje namijenjeni su odgovorima na naredbe. Sva polja opisuje stranica kartice poruka.

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 prošao

Svih 212 testova prolazi na main.
Duration
2m 34s
Commit
1a2b3c4

Gumbi

Dodaj niz actions i ispod poruke pojavit će se gumbi. Kako rade, opisuje stranica gumbi.

Datoteke

Uz poruku objavi prave datoteke: log, izvještaj, snimku zaslona. Prikazuju se kao svaki drugi privitak, kao redak za preuzimanje, a slike, video i zvuk izravno u poruci. Poruka samo s datotekama sasvim je u redu: izostavi content i karticu.

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"
    }
  ]
}
PoljeTipŠto radi
namestringIme pod kojim se datoteka preuzima. Obavezno. Putanja se skraćuje na zadnji dio.
content_base64stringBajtovi datoteke u base64, sirovi ili kao data: URI. mssgs pohranjuje datoteku, a u poruci zadržava samo poveznicu.
mime_typestringVrsta sadržaja za content_base64. Zadano je text/plain.
urlstringDatoteka koja je već na mssgs: putanja /static/... ili URL https://mss.gs/....
Za svaku datoteku pošalji točno jedno od dvoga: content_base64 ili url. Oba ili nijedno je pogreška.
OgraničenjeVrijednost
Datoteke po poruci5
Veličina datoteke nakon dekodiranja8 MB
Ime datoteke200 znakova
Cijeli zahtjevOko 10 MB. Base64 povećava datoteku za trećinu, pa jedna datoteka veća od otprilike 7 MB neće stati.

Zašto url prima samo mssgs adrese

URL webhooka često završi zalijepljen u nadzorne ploče drugih usluga. Ako procuri, nitko ga ne smije moći iskoristiti da aplikacija svakog člana preuzme datoteku sa servera koji je sam odabrao. Ako je tvoja datoteka negdje drugdje, pošalji je kao content_base64 i mssgs će je hostati.

Neuspjeli prijenos datoteke ne ruši poruku

Datoteke se provjeravaju unaprijed, ali se prenose naknadno. Ako prijenos ne uspije, ta datoteka izostaje, a ostatak poruke ipak se objavi, bez pogreške: bolje izgubiti datoteku nego izvještaj. Ako ti je datoteka važna, provjeri je li stigla.

Datoteka iz naredbenog retka

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

Potpisivanje zahtjeva

Webhook s tajnim ključem prihvaća samo zahtjeve koji dokazuju da ga znaju, a webhook izrađen u aplikaciji za računalo uvijek ga ima (Webhook Secret u njegovim postavkama). Potpiši sirovo tijelo zahtjeva algoritmom HMAC-SHA256 pomoću tajnog ključa i pošalji heksadecimalni sažetak malim slovima u zaglavlju X-Mssgs-Signature kao 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
});
Zahtjev bez valjanog potpisa dobiva 401 i {"error": "INVALID_SIGNATURE"}. Nepotpisane zahtjeve prihvaća samo webhook bez tajnog ključa, primjerice onaj izrađen preko MCP-a bez webhook_secret.

Prihvaća se i GitHubovo vlastito zaglavlje X-Hub-Signature-256, pa GitHub webhook s istim tajnim ključem radi bez izmjena. Potpis nema vremensku oznaku, pa ne sprječava ponovno slanje presretnutog zahtjeva: tajna koja se zaista računa ostaje URL.

Odgovori i pogreške

Objavljena poruka vraća se sa svojim id-jem i callback_url kojim je 30 minuta možeš ažurirati ili izbrisati.

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-..."
}
Čitaj tijelo, ne samo status. Odbijeni payload navodi razlog kao kôd error u tijelu. Svako tijelo s ključem error smatraj neuspjehom, bez obzira na statusni kôd.
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}`);
}

Kad poruka ima gumbe, odgovor sadrži i stream_url: stream uživo s odgovorima, reakcijama i pritiscima gumba na toj poruci, otvoren 10 minuta, ili sat vremena ako pošalješ "sse_event_extended_timeout": true. Pogledaj ažuriranja uživo.

Statusni kodovi

StatusKada
401Webhook ima tajni ključ, a potpis nedostaje ili je pogrešan.
403Ovaj webhook ne smije objavljivati u tom kanalu.
404Na ovom URL-u nema webhooka.
413Zahtjev je prevelik.
429Previše zahtjeva. Uspori i pokušaj ponovno.
502Poruku nije bilo moguće isporučiti. Pokušaj ponovno.

Kodovi pogrešaka

KôdZnačenje
MISSING_CONTENTNema se što objaviti: nema teksta, kartice ni datoteka.
INVALID_MESSAGE_CONTAINERmessage_container nije objekt.
INVALID_MESSAGE_CONTAINER_TYPEVrsta kartice nije ni embed_message ni system_message.
MISSING_MESSAGE_CONTAINER_DESCRIPTIONKartici treba opis, osim ako je loader.
MISSING_MESSAGE_CONTAINER_LOADER_TEXTKartici loadera treba loader_text.
INVALID_WEBHOOK_BINDINGOvaj webhook ne smije objavljivati u tom kanalu.
INVALID_SIGNATUREZaglavlje potpisa nedostaje ili je pogrešno.
REQUEST_BODY_TOO_LARGEZahtjev prelazi ograničenje veličine.
PUBLISH_FAILEDPoruku nije bilo moguće isporučiti.
INVALID_ACTIONS_FORMAT, INVALID_ACTION_MISSING_FIELDS, DUPLICATE_ACTION_ID, INVALID_TRIGGERS_FORMAT, INVALID_TRIGGER_MISSING_ACTION, INVALID_TRIGGER_ACTION_NOT_ALLOWEDNešto nije u redu s gumbom. Pogledaj gumbe.

Pogreške s datotekama

KôdZnačenje
INVALID_ATTACHMENTS_FORMATattachments nije popis ili neki unos nije objekt.
TOO_MANY_ATTACHMENTSViše od pet datoteka.
MISSING_ATTACHMENT_NAMEDatoteka nema ime.
INVALID_ATTACHMENT_NAMEOd imena ne ostaje ništa upotrebljivo, primjerice kod ...
MISSING_ATTACHMENT_SOURCENema ni url ni content_base64.
AMBIGUOUS_ATTACHMENT_SOURCEPoslani su i url i content_base64.
INVALID_ATTACHMENT_BASE64Base64 se ne može dekodirati.
ATTACHMENT_TOO_LARGEDatoteka nakon dekodiranja ima više od 8 MB.
INVALID_ATTACHMENT_URLurl nije mssgs adresa.

Ograničenja

OgraničenjeVrijednost
Veličina zahtjevaOko 10 MB
Datoteke po poruci5, svaka do 8 MB
Opis karticeDo 50.000 bajtova. Iznad 1.000 bajtova članovi vide početak i gumb Show more.
Naknadno ažuriranje poruke30 minuta, preko callback_url
Stream uživo za poruku s gumbima10 minuta, ili sat vremena na zahtjev

Zahtjevi imaju ograničenje učestalosti. Kad dobiješ 429, pričekaj prije ponovnog slanja, a upozorenja koja stižu u naletima spoji u jednu poruku.

GitHub, UniFi i App Store Connect

Usmjeri jednu od ovih usluga na URL webhooka i mssgs će je prepoznati i objaviti urednu karticu, bez pisanja payloada. Pogledaj integracije. Te usluge u odgovoru dobivaju {"success": true} i nikakav callback URL.

IzvorPrepoznaje se poŠto objavljuje
GitHubZaglavlje x-github-eventPushevi, pull requestovi i recenzije, issueji i komentari, grane i tagovi, izdanja. Nalet promjena na jednom issueu ili pull requestu skuplja se u jednu karticu.
UniFi ProtectUser agent protect-alarm-managerZvono na vratima, pokret te osobe, vozila ili paketi koje otkriju tvoje kamere.
App Store ConnectTijelo njegove obavijesti ili zaglavlje x-apple-signatureObavijesti iz App Store Connecta.

Nastavi graditi