---
title: "Webhookovi: objavljuj poruke u mssgs kanalu"
description: "Pošalji poruku ili karticu u mssgs kanal iz CI-ja, nadzora ili bilo koje skripte jednim HTTP zahtjevom. Formati, datoteke, potpisivanje, pogreške i ograničenja."
canonical: https://docs.mss.gs/hr/webhooks
language: hr
---

# Objavljuj poruke webhookom

Webhook je URL koji objavljuje u tvojoj zajednici. Pošalji mu JSON iz bilo čega što može poslati HTTP zahtjev, primjerice iz CI-ja, sustava za nadzor, cron posla ili skripte, i poruka se pojavi u kanalu.

## Što možeš napraviti

- **Objavi tekst ili karticu** Običan tekst ili kartica s naslovom, bojom, markdownom, poljima i slikama.

- **Priloži datoteke** Do pet datoteka po poruci: logovi, izvještaji, snimke zaslona.

- **Dodaj gumbe** Poveznice ili gumbi koji mijenjaju karticu ili se javljaju tvojoj usluzi.

- **Promijeni je kasnije** Odgovor sadrži callback URL za ažuriranje ili brisanje poruke.

U aplikaciji

#### Build #1847 je prošao

Jedan zahtjev iz CI-ja, jedna kartica u #deploys. Ime na vrhu je ime koje si dao webhooku.

- [Brzi početak](#quick-start)

- [Što možeš poslati](#format)

- [Datoteke](#attachments)

- [Potpisivanje](#signing)

- [Odgovori i pogreške](#responses)

- [Ograničenja](#limits)

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

## Brzi početak

### Izradi webhook

U aplikaciji za računalo otvori u svojoj zajednici **Manage Server → Webhooks**, izradi webhook, odaberi kanale u kojima smije objavljivati i kopiraj URL za kanal. Izgleda ovako:

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

### Pošalji poruku

Potpiši JSON tajnim ključem webhooka i pošalji ga POST zahtjevom. Webhook izrađen u aplikaciji za računalo uvijek ga ima: kopiraj ga iz polja **Webhook Secret** u postavkama 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"
```

### Pročitaj odgovor

Odgovor ti daje id poruke i callback_url kojim kasnije možeš promijeniti poruku.

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

## Što možeš poslati

Poruka je ili kratki oblik (tekst s naslovom i bojom) ili puna kartica, a oba mogu nositi gumbe i datoteke. Ime na vrhu kartice uvijek je ime samog webhooka. U postavkama webhooka odlučuješ i smije li objavljivati slike i spominjati ljude.

### Kratki oblik

Dovoljan za većinu upozorenja.

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

| Polje | Tip | Što radi |
| --- | --- | --- |
| content | string | Tekst poruke. Obavezan, osim ako šalješ karticu ili datoteke. |
| color | string | blue (zadano), green , orange , red , yellow ili purple . |
| title | string | Naslov iznad teksta. Zadano je ime webhooka. |

### Puna kartica

Pošalji message_container za karticu s naslovom koji je poveznica, podnaslovom, markdownom, poljima i slikama. Kroz webhook kartica prima type , color , title , title_url , sub_title , description , fields , avatar_url , image_url , image_base64 , images i polja loadera. Oznaka statusa, značka, statistika diffa i sklopljeno razmišljanje namijenjeni su odgovorima na naredbe. Sva polja opisuje stranica [kartice poruka](https://docs.mss.gs/hr/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 je prošao

### Gumbi

Dodaj niz actions i ispod poruke pojavit će se gumbi. Kako rade, opisuje stranica [gumbi](https://docs.mss.gs/hr/buttons).

## Datoteke

Uz poruku objavi prave datoteke: log, izvještaj, snimku zaslona. Prikazuju se kao svaki drugi privitak, kao redak za preuzimanje, a slike, video i zvuk izravno u poruci. Poruka samo s datotekama sasvim je u redu: izostavi content i karticu.

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

| Polje | Tip | Što radi |
| --- | --- | --- |
| name | string | Ime pod kojim se datoteka preuzima. Obavezno. Putanja se skraćuje na zadnji dio. |
| content_base64 | string | Bajtovi datoteke u base64, sirovi ili kao data: URI. mssgs pohranjuje datoteku, a u poruci zadržava samo poveznicu. |
| mime_type | string | Vrsta sadržaja za content_base64 . Zadano je text/plain . |
| url | string | Datoteka koja je već na mssgs: putanja /static/... ili URL https://mss.gs/... . |

| Ograničenje | Vrijednost |
| --- | --- |
| Datoteke po poruci | **5** |
| Veličina datoteke nakon dekodiranja | **8 MB** |
| Ime datoteke | 200 znakova |
| Cijeli zahtjev | Oko 10 MB. Base64 povećava datoteku za trećinu, pa jedna datoteka veća od otprilike 7 MB neće stati. |

### Zašto url prima samo mssgs adrese

URL webhooka često završi zalijepljen u nadzorne ploče drugih usluga. Ako procuri, nitko ga ne smije moći iskoristiti da aplikacija svakog člana preuzme datoteku sa servera koji je sam odabrao. Ako je tvoja datoteka negdje drugdje, pošalji je kao content_base64 i mssgs će je hostati.

### Neuspjeli prijenos datoteke ne ruši poruku

Datoteke se provjeravaju unaprijed, ali se prenose naknadno. Ako prijenos ne uspije, ta datoteka izostaje, a ostatak poruke ipak se objavi, bez pogreške: bolje izgubiti datoteku nego izvještaj. Ako ti je datoteka važna, provjeri je li stigla.

### Datoteka iz naredbenog retka

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

## Potpisivanje zahtjeva

Webhook s tajnim ključem prihvaća samo zahtjeve koji dokazuju da ga znaju, a webhook izrađen u aplikaciji za računalo uvijek ga ima (**Webhook Secret** u njegovim postavkama). Potpiši sirovo tijelo zahtjeva algoritmom HMAC-SHA256 pomoću tajnog ključa i pošalji heksadecimalni sažetak malim slovima u zaglavlju X-Mssgs-Signature kao 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
});
```

Prihvaća se i GitHubovo vlastito zaglavlje X-Hub-Signature-256 , pa GitHub webhook s istim tajnim ključem radi bez izmjena. Potpis nema vremensku oznaku, pa ne sprječava ponovno slanje presretnutog zahtjeva: tajna koja se zaista računa ostaje URL.

## Odgovori i pogreške

Objavljena poruka vraća se sa svojim id-jem i callback_url kojim je 30 minuta možeš ažurirati ili izbrisati.

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

Kad poruka ima gumbe, odgovor sadrži i stream_url : stream uživo s odgovorima, reakcijama i pritiscima gumba na toj poruci, otvoren 10 minuta, ili sat vremena ako pošalješ "sse_event_extended_timeout": true . Pogledaj [ažuriranja uživo](https://docs.mss.gs/hr/live-updates).

### Statusni kodovi

| Status | Kada |
| --- | --- |
| 401 | Webhook ima tajni ključ, a potpis nedostaje ili je pogrešan. |
| 403 | Ovaj webhook ne smije objavljivati u tom kanalu. |
| 404 | Na ovom URL-u nema webhooka. |
| 413 | Zahtjev je prevelik. |
| 429 | Previše zahtjeva. Uspori i pokušaj ponovno. |
| 502 | Poruku nije bilo moguće isporučiti. Pokušaj ponovno. |

### Kodovi pogrešaka

| Kôd | Značenje |
| --- | --- |
| MISSING_CONTENT | Nema se što objaviti: nema teksta, kartice ni datoteka. |
| INVALID_MESSAGE_CONTAINER | message_container nije objekt. |
| INVALID_MESSAGE_CONTAINER_TYPE | Vrsta kartice nije ni embed_message ni system_message . |
| MISSING_MESSAGE_CONTAINER_DESCRIPTION | Kartici treba opis, osim ako je loader. |
| MISSING_MESSAGE_CONTAINER_LOADER_TEXT | Kartici loadera treba loader_text . |
| INVALID_WEBHOOK_BINDING | Ovaj webhook ne smije objavljivati u tom kanalu. |
| INVALID_SIGNATURE | Zaglavlje potpisa nedostaje ili je pogrešno. |
| REQUEST_BODY_TOO_LARGE | Zahtjev prelazi ograničenje veličine. |
| PUBLISH_FAILED | Poruku nije bilo moguće isporučiti. |
| INVALID_ACTIONS_FORMAT , INVALID_ACTION_MISSING_FIELDS , DUPLICATE_ACTION_ID , INVALID_TRIGGERS_FORMAT , INVALID_TRIGGER_MISSING_ACTION , INVALID_TRIGGER_ACTION_NOT_ALLOWED | Nešto nije u redu s gumbom. Pogledaj [gumbe](https://docs.mss.gs/hr/buttons). |

### Pogreške s datotekama

| Kôd | Značenje |
| --- | --- |
| INVALID_ATTACHMENTS_FORMAT | attachments nije popis ili neki unos nije objekt. |
| TOO_MANY_ATTACHMENTS | Više od pet datoteka. |
| MISSING_ATTACHMENT_NAME | Datoteka nema ime. |
| INVALID_ATTACHMENT_NAME | Od imena ne ostaje ništa upotrebljivo, primjerice kod .. . |
| MISSING_ATTACHMENT_SOURCE | Nema ni url ni content_base64 . |
| AMBIGUOUS_ATTACHMENT_SOURCE | Poslani su i url i content_base64 . |
| INVALID_ATTACHMENT_BASE64 | Base64 se ne može dekodirati. |
| ATTACHMENT_TOO_LARGE | Datoteka nakon dekodiranja ima više od 8 MB. |
| INVALID_ATTACHMENT_URL | url nije mssgs adresa. |

## Ograničenja

| Ograničenje | Vrijednost |
| --- | --- |
| Veličina zahtjeva | Oko 10 MB |
| Datoteke po poruci | 5, svaka do 8 MB |
| Opis kartice | Do 50.000 bajtova. Iznad 1.000 bajtova članovi vide početak i gumb **Show more**. |
| Naknadno ažuriranje poruke | 30 minuta, preko callback_url |
| Stream uživo za poruku s gumbima | 10 minuta, ili sat vremena na zahtjev |

Zahtjevi imaju ograničenje učestalosti. Kad dobiješ 429 , pričekaj prije ponovnog slanja, a upozorenja koja stižu u naletima spoji u jednu poruku.

## GitHub, UniFi i App Store Connect

Usmjeri jednu od ovih usluga na URL webhooka i mssgs će je prepoznati i objaviti urednu karticu, bez pisanja payloada. Pogledaj [integracije](https://mss.gs/hr/integrations). Te usluge u odgovoru dobivaju {"success": true} i nikakav callback URL.

| Izvor | Prepoznaje se po | Što objavljuje |
| --- | --- | --- |
| GitHub | Zaglavlje x-github-event | Pushevi, pull requestovi i recenzije, issueji i komentari, grane i tagovi, izdanja. Nalet promjena na jednom issueu ili pull requestu skuplja se u jednu karticu. |
| UniFi Protect | User agent protect-alarm-manager | Zvono na vratima, pokret te osobe, vozila ili paketi koje otkriju tvoje kamere. |
| App Store Connect | Tijelo njegove obavijesti ili zaglavlje x-apple-signature | Obavijesti iz App Store Connecta. |

## Nastavi graditi
