---
title: "Webhooks: posta meddelanden i en mssgs-kanal"
description: "Skicka ett meddelande eller kort till en mssgs-kanal från CI, övervakning eller skript med ett HTTP-anrop. Format, filer, signering, fel, gränser och GitHub."
canonical: https://docs.mss.gs/sv/webhooks
language: sv
---

# 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 kort** Ren text, eller ett kort med rubrik, färg, markdown, fält och bilder.

- **Bifoga filer** Upp till fem filer per meddelande: loggar, rapporter, skärmbilder.

- **Lägg till knappar** Länkar, eller knappar som ändrar kortet eller når din tjänst.

- **Ändra det senare** Svaret innehåller en callback-URL som uppdaterar eller raderar meddelandet.

I appen

#### Bygge #1847 lyckades

Ett anrop från CI, ett kort i #deploys. Namnet högst upp är namnet du gav webhooken.

- [Snabbstart](#quick-start)

- [Vad du kan skicka](#format)

- [Filer](#attachments)

- [Signering](#signing)

- [Svar och fel](#responses)

- [Gränser](#limits)

- [GitHub, UniFi, App Store](#special)

## 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:

```url
https://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.

```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"
```

### Läs svaret

Svaret ger dig meddelandets id och en callback_url som ä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.

```json
{
  "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](https://docs.mss.gs/sv/bots).

```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" }
    ]
  }
}
```

#### Bygge #1847 lyckades

### Knappar

Lägg till en actions -array för att sätta knappar under meddelandet. Hur de fungerar står under [knappar](https://docs.mss.gs/sv/buttons).

## 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.

```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"
    }
  ]
}
```

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

| 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

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

## 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> .

```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
});
```

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.

```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-..."
}
```

```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}`);
}
```

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](https://docs.mss.gs/sv/live-updates).

### 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](https://docs.mss.gs/sv/buttons). |

### 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](https://mss.gs/sv/integrations). 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. |

## Bygg vidare
