Posta meddelanden med en webhook
En webhook är en URL som postar i din community. Skicka JSON till den från allt som kan göra ett HTTP-anrop, som CI, övervakning, ett cron-jobb eller ett skript, så dyker meddelandet upp i kanalen.
Det här kan du göra
- Posta text eller ett kortRen text, eller ett kort med rubrik, färg, markdown, fält och bilder.
- Bifoga filerUpp till fem filer per meddelande: loggar, rapporter, skärmbilder.
- Lägg till knapparLänkar, eller knappar som ändrar kortet eller når din tjänst.
- Ändra det senareSvaret innehåller en callback-URL som uppdaterar eller raderar meddelandet.
I appen
Ett anrop från CI, ett kort i #deploys. Namnet högst upp är namnet du gav webhooken.
Snabbstart
Skapa webhooken
Öppna Hantera community → Webhooks för din community i skrivbordsappen, skapa en webhook, välj vilka kanaler den får posta i och kopiera URL:en för en kanal. Den ser ut så här:
urlhttps://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}Skicka ett meddelande
Signera JSON:en med webhookens hemlighet och gör en POST med den. En webhook som du skapar i skrivbordsappen har alltid en: kopiera den under Webhook-hemlighet i webhookens inställningar.
bashBODY='{"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"Läs svaret
Svaret ger dig meddelandets id och en
callback_urlsom ändrar meddelandet senare.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-..." }
Vad du kan skicka
Ett meddelande är antingen den korta formen (text med rubrik och färg) eller ett helt kort, och båda kan ha knappar och filer. Namnet högst upp på kortet är alltid webhookens eget namn. I webhookens inställningar bestämmer du också om den får posta bilder och nämna personer.
Kort form
Räcker för de flesta larm.
{
"content": "Server backup completed at 03:00 UTC",
"color": "green",
"title": "Backup Bot"
}| Fält | Typ | Vad det gör |
|---|---|---|
content | string | Meddelandets text. Krävs om du inte skickar ett kort eller filer. |
color | string | blue (standard), green, orange, red, yellow eller purple. |
title | string | En rubrik ovanför texten. Standard är webhookens namn. |
Ett helt kort
Skicka en message_container för ett kort med länkad rubrik, underrubrik, markdown, fält och bilder. Via en webhook tar ett kort emot type, color, title, title_url, sub_title, description, fields, avatar_url, image_url, image_base64, images och laddningsfälten. Statuspillen, märket, diff-statistiken och det hopfällda resonemanget är till för kommandosvar. Alla fält finns under meddelandekort.
{
"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" }
]
}
}Knappar
Lägg till en actions-array för att sätta knappar under meddelandet. Hur de fungerar står under knappar.
Filer
Posta riktiga filer med ett meddelande: en logg, en rapport, en skärmbild. De visas som vilken bilaga som helst, som en nedladdningsrad eller inbäddade för bilder, video och ljud. Ett meddelande med bara filer går bra: utelämna content och kortet.
{
"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"
}
]
}| Fält | Typ | Vad det gör |
|---|---|---|
name | string | Filnamnet den laddas ned som. Krävs. En sökväg kortas ned till sin sista del. |
content_base64 | string | Filens bytes som base64, råa eller som en data:-URI. mssgs sparar filen och behåller bara en länk på meddelandet. |
mime_type | string | Innehållstypen för content_base64. Standard är text/plain. |
url | string | En fil som redan finns på mssgs: en /static/...-sökväg eller en https://mss.gs/...-URL. |
content_base64 eller url per fil. Båda, eller ingen av dem, är ett fel.| Gräns | Värde |
|---|---|
| Filer per meddelande | 5 |
| Storlek per fil, efter avkodning | 8 MB |
| Filnamn | 200 tecken |
| Hela anropet | Cirka 10 MB. Base64 gör en fil en tredjedel större, så en enskild fil över ungefär 7 MB får inte plats. |
Varför url bara tar emot mssgs-adresser
En webhook-URL hamnar ofta inklistrad i andra dashboards. En URL som har läckt får inte kunna användas för att få varje medlems app att hämta en fil från en server som någon annan har valt. Ligger din fil någon annanstans skickar du den som content_base64, så hostar mssgs den.
En misslyckad uppladdning stoppar inte meddelandet
Filerna kontrolleras direkt men laddas upp efteråt. Misslyckas en uppladdning utelämnas den filen och resten av meddelandet postas ändå, utan något fel: hellre förlora filen än rapporten. Är en fil viktig bör du kontrollera att den kom fram.
En fil från kommandoraden
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 @-Signera anrop
En webhook med en hemlighet tar bara emot anrop som bevisar att de känner till den, och en webhook som du skapar i skrivbordsappen har alltid en (Webhook-hemlighet i dess inställningar). Signera den råa bodyn i anropet med HMAC-SHA256 och hemligheten, och skicka hex-digesten i gemener i headern X-Mssgs-Signature som sha256=<hex>.
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
});401 och {"error": "INVALID_SIGNATURE"}. Bara en webhook utan hemlighet, till exempel en som skapats via MCP utan webhook_secret, tar emot osignerade anrop.GitHubs egen header X-Hub-Signature-256 accepteras också, så en GitHub-webhook med samma hemlighet fungerar som den är. Signaturen har ingen tidsstämpel, så den hindrar inte att ett uppsnappat anrop skickas igen: det är fortfarande URL:en som är den hemlighet som räknas.
Svar och fel
Ett meddelande som har postats kommer tillbaka med sitt id och en callback_url som uppdaterar eller raderar det i 30 minuter.
{
"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-..."
}error-kod i bodyn. Behandla varje body med en error-nyckel som ett misslyckande, oavsett statuskod.HTTP/1.1 200 OK
Content-Type: application/json
{ "error": "ATTACHMENT_TOO_LARGE" }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}`);
}När meddelandet har knappar innehåller svaret också en stream_url: en liveström av svaren, reaktionerna och knapptrycken på meddelandet, öppen i 10 minuter, eller en timme när du skickar "sse_event_extended_timeout": true. Se liveuppdateringar.
Statuskoder
| Status | När |
|---|---|
401 | Webhooken har en hemlighet och signaturen saknas eller är fel. |
403 | Den här webhooken får inte posta i den kanalen. |
404 | Det finns ingen webhook på den här URL:en. |
413 | Anropet är för stort. |
429 | För många anrop. Sakta ned och försök igen. |
502 | Meddelandet kunde inte levereras. Försök igen. |
Felkoder
| Kod | Betydelse |
|---|---|
MISSING_CONTENT | Inget att posta: ingen text, inget kort och inga filer. |
INVALID_MESSAGE_CONTAINER | message_container är inte ett objekt. |
INVALID_MESSAGE_CONTAINER_TYPE | Korttypen är varken embed_message eller system_message. |
MISSING_MESSAGE_CONTAINER_DESCRIPTION | Ett kort behöver en beskrivning, om det inte är ett laddningskort. |
MISSING_MESSAGE_CONTAINER_LOADER_TEXT | Ett laddningskort behöver loader_text. |
INVALID_WEBHOOK_BINDING | Den här webhooken får inte posta i den kanalen. |
INVALID_SIGNATURE | Signaturheadern saknas eller är fel. |
REQUEST_BODY_TOO_LARGE | Anropet är över storleksgränsen. |
PUBLISH_FAILED | Meddelandet kunde inte levereras. |
INVALID_ACTIONS_FORMAT, INVALID_ACTION_MISSING_FIELDS, DUPLICATE_ACTION_ID, INVALID_TRIGGERS_FORMAT, INVALID_TRIGGER_MISSING_ACTION, INVALID_TRIGGER_ACTION_NOT_ALLOWED | Något är fel med en knapp. Se knappar. |
Filfel
| Kod | Betydelse |
|---|---|
INVALID_ATTACHMENTS_FORMAT | attachments är inte en lista, eller en post är inte ett objekt. |
TOO_MANY_ATTACHMENTS | Fler än fem filer. |
MISSING_ATTACHMENT_NAME | En fil saknar namn. |
INVALID_ATTACHMENT_NAME | Namnet blir inget användbart när det kortas ned, som ... |
MISSING_ATTACHMENT_SOURCE | Varken url eller content_base64. |
AMBIGUOUS_ATTACHMENT_SOURCE | Både url och content_base64. |
INVALID_ATTACHMENT_BASE64 | Base64-datan går inte att avkoda. |
ATTACHMENT_TOO_LARGE | En fil är över 8 MB efter avkodning. |
INVALID_ATTACHMENT_URL | url är inte en mssgs-adress. |
Gränser
| Gräns | Värde |
|---|---|
| Anropets storlek | Cirka 10 MB |
| Filer per meddelande | 5, på upp till 8 MB var |
| Kortets beskrivning | Upp till 50 000 byte. Efter 1 000 byte ser medlemmarna början och en Visa mer-knapp. |
| Uppdatera meddelandet efteråt | 30 minuter, via callback_url |
| Liveström för ett meddelande med knappar | 10 minuter, eller en timme på begäran |
Anropen är hastighetsbegränsade. När du får en 429 väntar du innan du skickar igen, och samlar larm som kommer i skurar i ett enda meddelande.
GitHub, UniFi och App Store Connect
Peka en av de här tjänsterna mot en webhook-URL så känner mssgs igen den och postar ett ordentligt kort, utan någon payload att skriva. Se integrationer. De här svarar med {"success": true} och ingen callback-URL.
| Källa | Känns igen på | Vad den postar |
|---|---|---|
| GitHub | Headern x-github-event | Pushar, pull requests och granskningar, issues och kommentarer, brancher och taggar, releaser. En skur av ändringar i samma issue eller pull request samlas i ett kort. |
| UniFi Protect | User agent protect-alarm-manager | Ringningar på dörrklockan, rörelse, och personer, fordon eller paket som dina kameror upptäcker. |
| App Store Connect | Dess notifieringsbody eller headern x-apple-signature | Notifieringar från App Store Connect. |