Gå til hovedindhold
Udviklere Webhooks

Post beskeder med en webhook

En webhook er en URL, der poster i dit fællesskab. Send den JSON fra alt, der kan lave en HTTP-request, som CI, overvågning, et cron-job eller et script, og beskeden dukker op i kanalen.

Det kan du

  • Post tekst eller et kortRen tekst eller et kort med titel, farve, markdown, felter og billeder.
  • Vedhæft filerOp til fem filer pr. besked: logs, rapporter, skærmbilleder.
  • Tilføj knapperLinks, eller knapper, der ændrer kortet eller når din tjeneste.
  • Ændr den senereSvaret indeholder en callback-URL, som du kan opdatere eller slette beskeden med.

I appen

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

Én request fra CI, ét kort i #deploys. Navnet øverst er det navn, du gav webhooken.

Kom godt i gang

  1. Opret webhooken

    Åbn Administrer fællesskab → Webhooks for dit fællesskab i desktop-appen, opret en webhook, vælg de kanaler, den må poste i, og kopiér URL'en til en kanal. Den ser sådan ud:

    url
    https://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}
  2. Send en besked

    Signér JSON'en med webhookens hemmelighed, og send den med POST. En webhook, du opretter i skrivebordsappen, har altid en: kopiér den under Webhook-hemmelighed i webhookens indstillinger.

    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. Læs svaret

    Svaret giver dig beskedens id og en callback_url, så du kan ændre beskeden senere.

    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-..."
    }
Alle, der har URL'en og hemmeligheden, kan poste i den kanal. Hold dem begge ude af offentlige repositories og kode på klientsiden.

Det kan du sende

En besked er enten den korte form (tekst med en titel og en farve) eller et helt kort, og begge kan have knapper og filer. Navnet øverst på kortet er altid webhookens eget navn. I webhookens indstillinger bestemmer du også, om den må poste billeder og omtale folk.

Kort form

Nok til de fleste advarsler.

json
{
  "content": "Server backup completed at 03:00 UTC",
  "color": "green",
  "title": "Backup Bot"
}
FeltTypeHvad det gør
contentstringBeskedteksten. Påkrævet, medmindre du sender et kort eller filer.
colorstringblue (standard), green, orange, red, yellow eller purple.
titlestringEn titel over teksten. Standard er webhookens navn.

Et helt kort

Send en message_container for et kort med en titel som link, en undertitel, markdown, felter og billeder. Gennem en webhook tager et kort type, color, title, title_url, sub_title, description, fields, avatar_url, image_url, image_base64, images og loader-felterne. Statuspillen, mærket, diff-statistikken og den sammenfoldede tænkning er til kommandosvar. Alle felter står under beskedkort.

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
Besked fra CI

Build #1847 bestået

Alle 212 tests er grønne på main.
Duration
2m 34s
Commit
1a2b3c4

Knapper

Tilføj et actions-array for at sætte knapper under beskeden. Hvordan de virker, står under knapper.

Filer

Post rigtige filer med en besked: en log, en rapport, et skærmbillede. De vises som alle andre vedhæftede filer, som en række, der kan downloades, eller inline for billeder, video og lyd. En besked med kun filer er fin: udelad content og kortet.

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"
    }
  ]
}
FeltTypeHvad det gør
namestringDet filnavn, filen downloades under. Påkrævet. En sti reduceres til sidste del.
content_base64stringFilens bytes som base64, rå eller som en data:-URI. mssgs gemmer filen og beholder kun et link på beskeden.
mime_typestringContent type for content_base64. Standard er text/plain.
urlstringEn fil, der allerede er hostet hos mssgs: en /static/...-sti eller en https://mss.gs/...-URL.
Send præcis én af content_base64 eller url pr. fil. Begge dele, eller ingen af dem, giver en fejl.
GrænseVærdi
Filer pr. besked5
Størrelse pr. fil, efter afkodning8 MB
Filnavn200 tegn
Hele requestenOmkring 10 MB. Base64 gør en fil en tredjedel større, så en enkelt fil over cirka 7 MB kan ikke være der.

Hvorfor url kun tager mssgs-adresser

En webhook-URL ender ofte med at blive indsat i andre dashboards. En lækket URL må ikke kunne bruges til at få alle medlemmers app til at hente en fil fra en server, som afsenderen selv har valgt. Ligger din fil et andet sted, så send den som content_base64, så hoster mssgs den.

En mislykket upload stopper ikke beskeden

Filer tjekkes på forhånd, men uploades bagefter. Fejler en upload, udelades den fil, og resten af beskeden bliver stadig postet, uden en fejl: det er bedre at miste filen end at miste rapporten. Er en fil vigtig, så tjek, at den kom frem.

En fil fra kommandolinjen

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

Signering af requests

En webhook med en hemmelighed accepterer kun requests, der beviser, at de kender den, og en webhook, du opretter i skrivebordsappen, har altid en (Webhook-hemmelighed i dens indstillinger). Signér den rå request-body med HMAC-SHA256 og hemmeligheden, og send det hexadecimale digest med små bogstaver i headeren X-Mssgs-Signature som 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
});
En request uden gyldig signatur får 401 og {"error": "INVALID_SIGNATURE"}. Kun en webhook uden hemmelighed, for eksempel en, der er oprettet via MCP uden webhook_secret, accepterer requests uden signatur.

GitHubs egen header X-Hub-Signature-256 accepteres også, så en GitHub-webhook med den samme hemmelighed virker, som den er. Signaturen har intet tidsstempel, så den forhindrer ikke, at en opsnappet request bliver sendt igen: det er stadig URL'en, der er hemmeligheden, der betyder noget.

Svar og fejl

En besked, der blev postet, kommer tilbage med sit id og en callback_url, som du kan opdatere eller slette den med i 30 minutter.

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-..."
}
Læs body, ikke kun statuskoden. En afvist payload har sin årsag som en error-kode i body. Behandl enhver body med en error-nøgle som en fejl, uanset statuskoden.
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}`);
}

Har beskeden knapper, indeholder svaret også en stream_url: en live stream af svar, reaktioner og tryk på knapper på den besked, åben i 10 minutter, eller en time, når du sender "sse_event_extended_timeout": true. Se liveopdateringer.

Statuskoder

StatusHvornår
401Webhooken har en hemmelighed, og signaturen mangler eller er forkert.
403Denne webhook må ikke poste i den kanal.
404Der er ingen webhook på denne URL.
413Requesten er for stor.
429For mange requests. Sæt tempoet ned, og prøv igen.
502Beskeden kunne ikke leveres. Prøv igen.

Fejlkoder

KodeBetydning
MISSING_CONTENTIntet at poste: ingen tekst, intet kort og ingen filer.
INVALID_MESSAGE_CONTAINERmessage_container er ikke et objekt.
INVALID_MESSAGE_CONTAINER_TYPEKorttypen er ikke embed_message eller system_message.
MISSING_MESSAGE_CONTAINER_DESCRIPTIONEt kort skal have en beskrivelse, medmindre det er en loader.
MISSING_MESSAGE_CONTAINER_LOADER_TEXTEt loader-kort skal have loader_text.
INVALID_WEBHOOK_BINDINGDenne webhook må ikke poste i den kanal.
INVALID_SIGNATURESignaturheaderen mangler eller er forkert.
REQUEST_BODY_TOO_LARGERequesten er over størrelsesgrænsen.
PUBLISH_FAILEDBeskeden kunne ikke leveres.
INVALID_ACTIONS_FORMAT, INVALID_ACTION_MISSING_FIELDS, DUPLICATE_ACTION_ID, INVALID_TRIGGERS_FORMAT, INVALID_TRIGGER_MISSING_ACTION, INVALID_TRIGGER_ACTION_NOT_ALLOWEDDer er noget galt med en knap. Se knapper.

Filfejl

KodeBetydning
INVALID_ATTACHMENTS_FORMATattachments er ikke en liste, eller en post er ikke et objekt.
TOO_MANY_ATTACHMENTSMere end fem filer.
MISSING_ATTACHMENT_NAMEEn fil har intet navn.
INVALID_ATTACHMENT_NAMENavnet reduceres til intet brugbart, som ...
MISSING_ATTACHMENT_SOURCEHverken url eller content_base64.
AMBIGUOUS_ATTACHMENT_SOURCEBåde url og content_base64.
INVALID_ATTACHMENT_BASE64Base64-teksten kan ikke afkodes.
ATTACHMENT_TOO_LARGEEn fil er over 8 MB efter afkodning.
INVALID_ATTACHMENT_URLurl er ikke en mssgs-adresse.

Grænser

GrænseVærdi
Størrelse på en requestOmkring 10 MB
Filer pr. besked5, på op til 8 MB hver
Kortets beskrivelseOp til 50.000 bytes. Efter 1.000 bytes ser medlemmerne starten og en Vis mere-knap.
Opdatering af beskeden bagefter30 minutter, gennem callback_url
Live stream af en besked med knapper10 minutter, eller en time efter anmodning

Requests er rate-begrænsede. Får du en 429, så vent, før du sender igen, og saml advarsler, der kommer i ryk, i én besked.

GitHub, UniFi og App Store Connect

Peg en af disse tjenester mod en webhook-URL, så genkender mssgs den og poster et ordentligt kort, uden at du skal skrive en payload. Se integrationer. De får {"success": true} som svar og ingen callback-URL.

KildeGenkendes påHvad den poster
GitHubHeaderen x-github-eventPushes, pull requests og reviews, issues og kommentarer, branches og tags, releases. Mange ændringer i træk til ét issue eller én pull request samles i ét kort.
UniFi ProtectUser agenten protect-alarm-managerNår nogen ringer på døren, bevægelse, og personer, køretøjer eller pakker, som dine kameraer opdager.
App Store ConnectDens notifikations-body eller headeren x-apple-signatureNotifikationer fra App Store Connect.

Byg videre