---
title: "Webhooki: publikuj wiadomości na kanale mssgs"
description: "Wyślij wiadomość lub kartę na kanał mssgs z CI, monitoringu albo skryptu jednym żądaniem HTTP. Formaty, pliki, podpisy, błędy, limity, GitHub."
canonical: https://docs.mss.gs/pl/webhooks
language: pl
---

# Publikuj wiadomości webhookiem

Webhook to URL, który publikuje w twojej społeczności. Wyślij na niego JSON z czegokolwiek, co potrafi wykonać żądanie HTTP, na przykład z CI, monitoringu, zadania cron albo skryptu, a wiadomość pojawi się na kanale.

## Co możesz z tym zrobić

- **Publikuj tekst albo kartę** Zwykły tekst albo karta z tytułem, kolorem, markdownem, polami i obrazami.

- **Dołączaj pliki** Do pięciu plików na wiadomość: logi, raporty, zrzuty ekranu.

- **Dodawaj przyciski** Linki albo przyciski, które zmieniają kartę lub łączą się z twoją usługą.

- **Zmieniaj ją później** Odpowiedź zawiera callback URL do aktualizacji lub usunięcia wiadomości.

W aplikacji

#### Build #1847 zakończony sukcesem

Jedno żądanie z CI, jedna karta na #deploys. Nazwa u góry to nazwa nadana webhookowi.

- [Szybki start](#quick-start)

- [Co można wysłać](#format)

- [Pliki](#attachments)

- [Podpisywanie](#signing)

- [Odpowiedzi i błędy](#responses)

- [Limity](#limits)

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

## Szybki start

### Utwórz webhook

W aplikacji desktopowej otwórz w swojej społeczności **Manage Server → Webhooks**, utwórz webhook, wybierz kanały, na których może publikować, i skopiuj URL dla kanału. Wygląda tak:

```url
https://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}
```

### Wyślij wiadomość

Podpisz JSON sekretem webhooka i wyślij go POST-em. Webhook utworzony w aplikacji desktopowej zawsze ma sekret: skopiuj go z pola **Webhook Secret** w ustawieniach 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"
```

### Odczytaj odpowiedź

Odpowiedź zawiera id wiadomości i callback_url , którym później zmienisz wiadomość.

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

## Co można wysłać

Wiadomość to albo forma skrócona (tekst z tytułem i kolorem), albo pełna karta, a każda z nich może zawierać przyciski i pliki. Nazwa u góry karty to zawsze nazwa samego webhooka. W ustawieniach webhooka decydujesz też, czy może publikować obrazy i oznaczać ludzi.

### Forma skrócona

Wystarcza do większości alertów.

```json
{
  "content": "Server backup completed at 03:00 UTC",
  "color": "green",
  "title": "Backup Bot"
}
```

| Pole | Typ | Co robi |
| --- | --- | --- |
| content | string | Tekst wiadomości. Wymagany, chyba że wysyłasz kartę lub pliki. |
| color | string | blue (domyślnie), green , orange , red , yellow lub purple . |
| title | string | Tytuł nad tekstem. Domyślnie nazwa webhooka. |

### Pełna karta

Wyślij message_container , aby dostać kartę z tytułem jako linkiem, podtytułem, markdownem, polami i obrazami. Przez webhook karta przyjmuje type , color , title , title_url , sub_title , description , fields , avatar_url , image_url , image_base64 , images oraz pola loadera. Pigułka statusu, odznaka, statystyki diffu i zwinięte rozumowanie są zarezerwowane dla odpowiedzi na komendy. Wszystkie pola opisuje strona [karty wiadomości](https://docs.mss.gs/pl/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" }
    ]
  }
}
```

#### Build #1847 zakończony sukcesem

### Przyciski

Dodaj tablicę actions , aby umieścić przyciski pod wiadomością. Jak działają, opisuje strona [przyciski](https://docs.mss.gs/pl/buttons).

## Pliki

Publikuj z wiadomością prawdziwe pliki: log, raport, zrzut ekranu. Wyświetlają się jak każdy inny załącznik, jako wiersz do pobrania, a obrazy, wideo i audio bezpośrednio w wiadomości. Wiadomość z samymi plikami też jest w porządku: pomiń content i kartę.

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

| Pole | Typ | Co robi |
| --- | --- | --- |
| name | string | Nazwa, pod jaką plik się pobiera. Wymagana. Ścieżka jest skracana do ostatniego członu. |
| content_base64 | string | Bajty pliku w base64, surowe albo jako URI data: . mssgs przechowuje plik, a w wiadomości zostawia tylko link. |
| mime_type | string | Typ zawartości content_base64 . Domyślnie text/plain . |
| url | string | Plik już hostowany w mssgs: ścieżka /static/... albo URL https://mss.gs/... . |

| Limit | Wartość |
| --- | --- |
| Pliki na wiadomość | **5** |
| Rozmiar pliku po zdekodowaniu | **8 MB** |
| Nazwa pliku | 200 znaków |
| Całe żądanie | Około 10 MB. Base64 powiększa plik o jedną trzecią, więc pojedynczy plik większy niż mniej więcej 7 MB się nie zmieści. |

### Dlaczego url przyjmuje tylko adresy mssgs

URL webhooka często trafia do paneli innych usług. Jeśli wycieknie, nie może pozwolić nikomu sprawić, by aplikacja każdego członka pobierała plik z wybranego przez niego serwera. Jeśli twój plik jest gdzie indziej, wyślij go jako content_base64 , a mssgs będzie go hostować.

### Nieudane przesłanie pliku nie blokuje wiadomości

Pliki są sprawdzane z góry, ale przesyłane później. Jeśli przesyłanie się nie powiedzie, ten plik zostaje pominięty, a reszta wiadomości i tak zostaje opublikowana, bez błędu: lepiej stracić plik niż raport. Jeśli plik jest ważny, sprawdź, czy dotarł.

### Plik z wiersza poleceń

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

## Podpisywanie żądań

Webhook z sekretem przyjmuje tylko żądania, które dowodzą, że go znają, a webhook utworzony w aplikacji desktopowej zawsze ma sekret (**Webhook Secret** w jego ustawieniach). Podpisz surowe body żądania algorytmem HMAC-SHA256 z użyciem sekretu i wyślij digest hex małymi literami w nagłówku X-Mssgs-Signature jako 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
});
```

Akceptowany jest też własny nagłówek GitHuba X-Hub-Signature-256 , więc webhook GitHuba z tym samym sekretem działa bez zmian. Podpis nie zawiera znacznika czasu, więc nie chroni przed ponownym wysłaniem przechwyconego żądania: to URL pozostaje sekretem, który się liczy.

## Odpowiedzi i błędy

Opublikowana wiadomość wraca z id i callback_url , którym przez 30 minut możesz ją zaktualizować lub usunąć.

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

Gdy wiadomość ma przyciski, odpowiedź zawiera też stream_url : strumień na żywo z odpowiedziami, reakcjami i naciśnięciami przycisków na tej wiadomości, otwarty przez 10 minut albo godzinę, jeśli wyślesz "sse_event_extended_timeout": true . Zobacz [aktualizacje na żywo](https://docs.mss.gs/pl/live-updates).

### Kody statusu

| Status | Kiedy |
| --- | --- |
| 401 | Webhook ma sekret, a podpisu brakuje lub jest błędny. |
| 403 | Ten webhook nie może publikować na tym kanale. |
| 404 | Pod tym URL nie ma webhooka. |
| 413 | Żądanie jest za duże. |
| 429 | Za dużo żądań. Zwolnij i spróbuj ponownie. |
| 502 | Nie udało się dostarczyć wiadomości. Spróbuj ponownie. |

### Kody błędów

| Kod | Znaczenie |
| --- | --- |
| MISSING_CONTENT | Nie ma czego opublikować: brak tekstu, karty i plików. |
| INVALID_MESSAGE_CONTAINER | message_container nie jest obiektem. |
| INVALID_MESSAGE_CONTAINER_TYPE | Typ karty to ani embed_message , ani system_message . |
| MISSING_MESSAGE_CONTAINER_DESCRIPTION | Karta potrzebuje opisu, chyba że jest loaderem. |
| MISSING_MESSAGE_CONTAINER_LOADER_TEXT | Karta loadera potrzebuje loader_text . |
| INVALID_WEBHOOK_BINDING | Ten webhook nie może publikować na tym kanale. |
| INVALID_SIGNATURE | Brak nagłówka podpisu lub podpis jest błędny. |
| REQUEST_BODY_TOO_LARGE | Żądanie przekracza limit rozmiaru. |
| PUBLISH_FAILED | Nie udało się dostarczyć wiadomości. |
| INVALID_ACTIONS_FORMAT , INVALID_ACTION_MISSING_FIELDS , DUPLICATE_ACTION_ID , INVALID_TRIGGERS_FORMAT , INVALID_TRIGGER_MISSING_ACTION , INVALID_TRIGGER_ACTION_NOT_ALLOWED | Coś jest nie tak z przyciskiem. Zobacz [przyciski](https://docs.mss.gs/pl/buttons). |

### Błędy plików

| Kod | Znaczenie |
| --- | --- |
| INVALID_ATTACHMENTS_FORMAT | attachments nie jest listą albo któryś wpis nie jest obiektem. |
| TOO_MANY_ATTACHMENTS | Więcej niż pięć plików. |
| MISSING_ATTACHMENT_NAME | Plik nie ma nazwy. |
| INVALID_ATTACHMENT_NAME | Z nazwy nie zostaje nic użytecznego, na przykład przy .. . |
| MISSING_ATTACHMENT_SOURCE | Ani url , ani content_base64 . |
| AMBIGUOUS_ATTACHMENT_SOURCE | Jednocześnie url i content_base64 . |
| INVALID_ATTACHMENT_BASE64 | Nie da się zdekodować base64. |
| ATTACHMENT_TOO_LARGE | Plik po zdekodowaniu ma ponad 8 MB. |
| INVALID_ATTACHMENT_URL | url nie jest adresem mssgs. |

## Limity

| Limit | Wartość |
| --- | --- |
| Rozmiar żądania | Około 10 MB |
| Pliki na wiadomość | 5, każdy do 8 MB |
| Opis karty | Do 50 000 bajtów. Powyżej 1000 bajtów członkowie widzą początek i przycisk **Show more**. |
| Aktualizacja wiadomości po publikacji | 30 minut, przez callback_url |
| Strumień na żywo wiadomości z przyciskami | 10 minut albo godzina na życzenie |

Żądania mają limit częstotliwości. Gdy dostaniesz 429 , odczekaj przed ponownym wysłaniem, a alerty, które przychodzą falami, łącz w jedną wiadomość.

## GitHub, UniFi i App Store Connect

Skieruj jedną z tych usług na URL webhooka, a mssgs ją rozpozna i opublikuje porządną kartę, bez pisania payloadu. Zobacz [integracje](https://mss.gs/pl/integrations). Te usługi dostają w odpowiedzi {"success": true} i żadnego callback URL.

| Źródło | Rozpoznawane po | Co publikuje |
| --- | --- | --- |
| GitHub | Nagłówek x-github-event | Pushe, pull requesty i recenzje, issues i komentarze, gałęzie i tagi, wydania. Wiele zmian w krótkim czasie w jednym issue lub pull requeście trafia do jednej karty. |
| UniFi Protect | User agent protect-alarm-manager | Dzwonek do drzwi, ruch oraz osoby, pojazdy lub paczki wykryte przez twoje kamery. |
| App Store Connect | Treść jego powiadomień lub nagłówek x-apple-signature | Powiadomienia App Store Connect. |

## Buduj dalej
