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 plikiDo pięciu plików na wiadomość: logi, raporty, zrzuty ekranu.
- Dodawaj przyciskiLinki albo przyciski, które zmieniają kartę lub łączą się z twoją usługą.
- Zmieniaj ją późniejOdpowiedź zawiera callback URL do aktualizacji lub usunięcia wiadomości.
W aplikacji
Jedno żądanie z CI, jedna karta na #deploys. Nazwa u góry to nazwa nadana webhookowi.
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:
urlhttps://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.
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"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.
{
"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.
{
"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" }
]
}
}Przyciski
Dodaj tablicę actions, aby umieścić przyciski pod wiadomością. Jak działają, opisuje strona przyciski.
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ę.
{
"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/.... |
content_base64 albo url. Oba naraz albo żadne to błąd.| 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ń
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>.
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 i {"error": "INVALID_SIGNATURE"}. Tylko webhook bez sekretu, na przykład utworzony przez MCP bez webhook_secret, przyjmuje niepodpisane żądania.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ąć.
{
"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. Traktuj każde body z kluczem error jako błąd, niezależnie od kodu statusu.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}`);
}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.
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. |
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. 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. |