Μετάβαση στο κύριο περιεχόμενο
Προγραμματιστές Webhooks

Δημοσίευσε μηνύματα με webhook

Ένα webhook είναι ένα URL που δημοσιεύει στην κοινότητά σου. Στείλε του JSON από ό,τι μπορεί να κάνει αίτημα HTTP, όπως CI, monitoring, μια εργασία cron ή ένα script, και το μήνυμα εμφανίζεται στο κανάλι.

Τι μπορείς να κάνεις

  • Δημοσίευσε κείμενο ή κάρταΑπλό κείμενο ή κάρτα με τίτλο, χρώμα, markdown, πεδία και εικόνες.
  • Επισύναψε αρχείαΈως πέντε αρχεία ανά μήνυμα: logs, αναφορές, στιγμιότυπα οθόνης.
  • Πρόσθεσε κουμπιάΣυνδέσμους, ή κουμπιά που αλλάζουν την κάρτα ή φτάνουν στην υπηρεσία σου.
  • Άλλαξέ το αργότεραΗ απόκριση περιέχει ένα callback URL για να ενημερώσεις ή να διαγράψεις το μήνυμα.

Στην εφαρμογή

$ curl -X POST "$MSSGS_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "X-Mssgs-Signature: sha256=$SIG" \
-d '{"message_container": {"title": "Το build #1847 πέρασε", ...}}'
{"success": true, "message_id": "aZZ1a2b-..."}

Ένα αίτημα από το CI, μία κάρτα στο #deploys. Το όνομα στην κορυφή είναι το όνομα που έδωσες στο webhook.

Γρήγορη εκκίνηση

  1. Δημιούργησε το webhook

    Στην εφαρμογή για υπολογιστή, άνοιξε στην κοινότητά σου Manage Server → Webhooks, δημιούργησε ένα webhook, διάλεξε τα κανάλια όπου μπορεί να δημοσιεύει και αντίγραψε το URL για ένα κανάλι. Έχει αυτή τη μορφή:

    url
    https://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}
  2. Στείλε ένα μήνυμα

    Υπόγραψε το JSON με το μυστικό του webhook και στείλε το με POST. Ένα webhook που φτιάχτηκε στην εφαρμογή για υπολογιστή έχει πάντα μυστικό: αντίγραψέ το από το Webhook Secret στις ρυθμίσεις του webhook.

    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"
  3. Διάβασε την απόκριση

    Η απόκριση σου δίνει το id του μηνύματος και ένα callback_url για να αλλάξεις το μήνυμα αργότερα.

    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-..."
    }
Όποιος έχει το URL και το μυστικό μπορεί να δημοσιεύει σε αυτό το κανάλι. Κράτα τα μακριά από δημόσια αποθετήρια και από κώδικα που τρέχει στον client.

Τι μπορείς να στείλεις

Ένα μήνυμα είναι είτε η σύντομη μορφή (κείμενο με τίτλο και χρώμα) είτε μια πλήρης κάρτα, και οποιοδήποτε από τα δύο μπορεί να έχει κουμπιά και αρχεία. Το όνομα στην κορυφή της κάρτας είναι πάντα το όνομα του ίδιου του webhook. Στις ρυθμίσεις του webhook αποφασίζεις επίσης αν μπορεί να δημοσιεύει εικόνες και να κάνει mention σε άτομα.

Σύντομη μορφή

Αρκεί για τις περισσότερες ειδοποιήσεις.

json
{
  "content": "Server backup completed at 03:00 UTC",
  "color": "green",
  "title": "Backup Bot"
}
ΠεδίοΤύποςΤι κάνει
contentstringΤο κείμενο του μηνύματος. Υποχρεωτικό, εκτός αν στέλνεις κάρτα ή αρχεία.
colorstringblue (προεπιλογή), green, orange, red, yellow ή purple.
titlestringΤίτλος πάνω από το κείμενο. Προεπιλογή: το όνομα του webhook.

Πλήρης κάρτα

Στείλε ένα message_container για κάρτα με τίτλο που είναι σύνδεσμος, υπότιτλο, markdown, πεδία και εικόνες. Μέσω webhook μια κάρτα δέχεται type, color, title, title_url, sub_title, description, fields, avatar_url, image_url, image_base64, images και τα πεδία του loader. Η ένδειξη κατάστασης, το badge, τα στατιστικά diff και ο συμπτυγμένος συλλογισμός είναι για απαντήσεις σε εντολές. Όλα τα πεδία θα τα βρεις στις κάρτες μηνυμάτων.

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" }
    ]
  }
}
deploys
System
Message from CI

Το build #1847 πέρασε

Και τα 212 τεστ πράσινα στο main.
Duration
2m 34s
Commit
1a2b3c4

Κουμπιά

Πρόσθεσε έναν πίνακα actions για να βάλεις κουμπιά κάτω από το μήνυμα. Πώς λειτουργούν θα το βρεις στη σελίδα κουμπιά.

Αρχεία

Δημοσίευσε πραγματικά αρχεία μαζί με ένα μήνυμα: ένα log, μια αναφορά, ένα στιγμιότυπο οθόνης. Εμφανίζονται όπως κάθε άλλο συνημμένο, ως γραμμή λήψης, ή μέσα στο μήνυμα για εικόνες, βίντεο και ήχο. Ένα μήνυμα μόνο με αρχεία είναι εντάξει: παράλειψε το content και την κάρτα.

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"
    }
  ]
}
ΠεδίοΤύποςΤι κάνει
namestringΤο όνομα με το οποίο κατεβαίνει το αρχείο. Υποχρεωτικό. Μια διαδρομή περικόπτεται στο τελευταίο της τμήμα.
content_base64stringΤα bytes του αρχείου σε base64, σκέτα ή ως URI data:. Το mssgs αποθηκεύει το αρχείο και κρατά στο μήνυμα μόνο έναν σύνδεσμο.
mime_typestringΟ τύπος περιεχομένου του content_base64. Προεπιλογή: text/plain.
urlstringΈνα αρχείο που φιλοξενείται ήδη στο mssgs: μια διαδρομή /static/... ή ένα URL https://mss.gs/....
Στείλε για κάθε αρχείο ακριβώς ένα από τα δύο: content_base64 ή url. Και τα δύο μαζί ή κανένα είναι σφάλμα.
ΌριοΤιμή
Αρχεία ανά μήνυμα5
Μέγεθος ανά αρχείο, μετά την αποκωδικοποίηση8 MB
Όνομα αρχείου200 χαρακτήρες
Ολόκληρο το αίτημαΠερίπου 10 MB. Το base64 μεγαλώνει ένα αρχείο κατά ένα τρίτο, οπότε ένα μεμονωμένο αρχείο πάνω από περίπου 7 MB δεν θα χωρέσει.

Γιατί το url δέχεται μόνο διευθύνσεις του mssgs

Ένα URL webhook συχνά καταλήγει επικολλημένο σε άλλα dashboards. Αν διαρρεύσει, δεν πρέπει να επιτρέπει σε κάποιον να βάλει την εφαρμογή κάθε μέλους να κατεβάζει ένα αρχείο από έναν server της επιλογής του. Αν το αρχείο σου βρίσκεται αλλού, στείλε το ως content_base64 και το mssgs θα το φιλοξενήσει.

Μια αποτυχημένη μεταφόρτωση δεν ακυρώνει το μήνυμα

Τα αρχεία ελέγχονται από πριν, αλλά ανεβαίνουν μετά. Αν μια μεταφόρτωση αποτύχει, εκείνο το αρχείο παραλείπεται και το υπόλοιπο μήνυμα δημοσιεύεται κανονικά, χωρίς σφάλμα: καλύτερα να χαθεί το αρχείο παρά η αναφορά. Αν ένα αρχείο είναι σημαντικό, έλεγξε ότι έφτασε.

Ένα αρχείο από τη γραμμή εντολών

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

Υπογραφή αιτημάτων

Ένα webhook με μυστικό δέχεται μόνο αιτήματα που αποδεικνύουν ότι το γνωρίζουν, και ένα webhook που φτιάχτηκε στην εφαρμογή για υπολογιστή έχει πάντα μυστικό (Webhook Secret στις ρυθμίσεις του). Υπόγραψε το ακατέργαστο σώμα του αιτήματος με HMAC-SHA256 χρησιμοποιώντας το μυστικό και στείλε το hex digest με πεζά γράμματα στην κεφαλίδα X-Mssgs-Signature ως 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
});
Ένα αίτημα χωρίς έγκυρη υπογραφή παίρνει 401 και {"error": "INVALID_SIGNATURE"}. Μόνο ένα webhook χωρίς μυστικό, όπως ένα που δημιουργήθηκε μέσω MCP χωρίς webhook_secret, δέχεται ανυπόγραφα αιτήματα.

Γίνεται δεκτή και η κεφαλίδα του ίδιου του GitHub, X-Hub-Signature-256, οπότε ένα webhook του GitHub με το ίδιο μυστικό λειτουργεί ως έχει. Η υπογραφή δεν έχει χρονοσφραγίδα, άρα δεν εμποδίζει την εκ νέου αποστολή ενός αιτήματος που υποκλάπηκε: το URL παραμένει το μυστικό που μετράει.

Αποκρίσεις και σφάλματα

Ένα μήνυμα που δημοσιεύτηκε επιστρέφει με το id του και ένα callback_url για να το ενημερώσεις ή να το διαγράψεις μέσα σε 30 λεπτά.

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-..."
}
Διάβαζε το σώμα, όχι μόνο το status. Ένα payload που απορρίφθηκε δίνει την αιτία ως κωδικό error στο σώμα. Θεώρησε αποτυχία κάθε σώμα με κλειδί error, όποιος κι αν είναι ο κωδικός κατάστασης.
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}`);
}

Όταν το μήνυμα έχει κουμπιά, η απόκριση περιέχει επίσης ένα stream_url: μια ζωντανή ροή με τις απαντήσεις, τις αντιδράσεις και τα πατήματα κουμπιών σε εκείνο το μήνυμα, ανοιχτή για 10 λεπτά, ή για μία ώρα όταν στέλνεις "sse_event_extended_timeout": true. Δες τις ζωντανές ενημερώσεις.

Κωδικοί κατάστασης

StatusΠότε
401Το webhook έχει μυστικό και η υπογραφή λείπει ή είναι λάθος.
403Αυτό το webhook δεν μπορεί να δημοσιεύει σε εκείνο το κανάλι.
404Δεν υπάρχει webhook σε αυτό το URL.
413Το αίτημα είναι πολύ μεγάλο.
429Πάρα πολλά αιτήματα. Κόψε ταχύτητα και δοκίμασε ξανά.
502Το μήνυμα δεν μπόρεσε να παραδοθεί. Δοκίμασε ξανά.

Κωδικοί σφάλματος

ΚωδικόςΣημασία
MISSING_CONTENTΤίποτα για δημοσίευση: ούτε κείμενο, ούτε κάρτα, ούτε αρχεία.
INVALID_MESSAGE_CONTAINERΤο message_container δεν είναι αντικείμενο.
INVALID_MESSAGE_CONTAINER_TYPEΟ τύπος της κάρτας δεν είναι ούτε embed_message ούτε system_message.
MISSING_MESSAGE_CONTAINER_DESCRIPTIONΜια κάρτα χρειάζεται περιγραφή, εκτός αν είναι loader.
MISSING_MESSAGE_CONTAINER_LOADER_TEXTΜια κάρτα loader χρειάζεται loader_text.
INVALID_WEBHOOK_BINDINGΑυτό το webhook δεν μπορεί να δημοσιεύει σε εκείνο το κανάλι.
INVALID_SIGNATUREΗ κεφαλίδα υπογραφής λείπει ή η υπογραφή είναι λάθος.
REQUEST_BODY_TOO_LARGEΤο αίτημα ξεπερνά το όριο μεγέθους.
PUBLISH_FAILEDΤο μήνυμα δεν μπόρεσε να παραδοθεί.
INVALID_ACTIONS_FORMAT, INVALID_ACTION_MISSING_FIELDS, DUPLICATE_ACTION_ID, INVALID_TRIGGERS_FORMAT, INVALID_TRIGGER_MISSING_ACTION, INVALID_TRIGGER_ACTION_NOT_ALLOWEDΚάτι δεν πάει καλά με ένα κουμπί. Δες τα κουμπιά.

Σφάλματα αρχείων

ΚωδικόςΣημασία
INVALID_ATTACHMENTS_FORMATΤο attachments δεν είναι λίστα ή μια καταχώριση δεν είναι αντικείμενο.
TOO_MANY_ATTACHMENTSΠερισσότερα από πέντε αρχεία.
MISSING_ATTACHMENT_NAMEΈνα αρχείο δεν έχει όνομα.
INVALID_ATTACHMENT_NAMEΑπό το όνομα δεν μένει τίποτα χρήσιμο, όπως με το ...
MISSING_ATTACHMENT_SOURCEΟύτε url ούτε content_base64.
AMBIGUOUS_ATTACHMENT_SOURCEΚαι url και content_base64.
INVALID_ATTACHMENT_BASE64Το base64 δεν αποκωδικοποιείται.
ATTACHMENT_TOO_LARGEΈνα αρχείο ξεπερνά τα 8 MB μετά την αποκωδικοποίηση.
INVALID_ATTACHMENT_URLΤο url δεν είναι διεύθυνση του mssgs.

Όρια

ΌριοΤιμή
Μέγεθος αιτήματοςΠερίπου 10 MB
Αρχεία ανά μήνυμα5, έως 8 MB το καθένα
Περιγραφή κάρταςΈως 50.000 bytes. Πάνω από τα 1.000 bytes, τα μέλη βλέπουν την αρχή και ένα κουμπί Show more.
Ενημέρωση του μηνύματος αργότερα30 λεπτά, μέσω callback_url
Ζωντανή ροή μηνύματος με κουμπιά10 λεπτά, ή μία ώρα αν το ζητήσεις

Τα αιτήματα έχουν όριο ρυθμού. Όταν πάρεις 429, περίμενε πριν στείλεις ξανά, και μάζευε σε ένα μήνυμα τις ειδοποιήσεις που έρχονται κατά κύματα.

GitHub, UniFi και App Store Connect

Στρέψε μία από αυτές τις υπηρεσίες σε ένα URL webhook και το mssgs την αναγνωρίζει και δημοσιεύει μια κανονική κάρτα, χωρίς να γράψεις payload. Δες τις ενσωματώσεις. Αυτές παίρνουν ως απάντηση {"success": true} χωρίς callback URL.

ΠηγήΑναγνωρίζεται απόΤι δημοσιεύει
GitHubΚεφαλίδα x-github-eventPushes, pull requests και reviews, issues και σχόλια, branches και tags, releases. Μια σειρά αλλαγών σε ένα issue ή pull request μέσα σε λίγο χρόνο συγκεντρώνεται σε μία κάρτα.
UniFi ProtectUser agent protect-alarm-managerΧτυπήματα κουδουνιού, κίνηση, καθώς και άτομα, οχήματα ή δέματα που εντοπίζουν οι κάμερές σου.
App Store ConnectΤο σώμα των ειδοποιήσεών του ή η κεφαλίδα x-apple-signatureΕιδοποιήσεις του App Store Connect.

Συνέχισε να φτιάχνεις