Δημοσίευσε μηνύματα με webhook
Ένα webhook είναι ένα URL που δημοσιεύει στην κοινότητά σου. Στείλε του JSON από ό,τι μπορεί να κάνει αίτημα HTTP, όπως CI, monitoring, μια εργασία cron ή ένα script, και το μήνυμα εμφανίζεται στο κανάλι.
Τι μπορείς να κάνεις
- Δημοσίευσε κείμενο ή κάρταΑπλό κείμενο ή κάρτα με τίτλο, χρώμα, markdown, πεδία και εικόνες.
- Επισύναψε αρχείαΈως πέντε αρχεία ανά μήνυμα: logs, αναφορές, στιγμιότυπα οθόνης.
- Πρόσθεσε κουμπιάΣυνδέσμους, ή κουμπιά που αλλάζουν την κάρτα ή φτάνουν στην υπηρεσία σου.
- Άλλαξέ το αργότεραΗ απόκριση περιέχει ένα callback URL για να ενημερώσεις ή να διαγράψεις το μήνυμα.
Στην εφαρμογή
Ένα αίτημα από το CI, μία κάρτα στο #deploys. Το όνομα στην κορυφή είναι το όνομα που έδωσες στο webhook.
Γρήγορη εκκίνηση
Δημιούργησε το webhook
Στην εφαρμογή για υπολογιστή, άνοιξε στην κοινότητά σου Manage Server → Webhooks, δημιούργησε ένα webhook, διάλεξε τα κανάλια όπου μπορεί να δημοσιεύει και αντίγραψε το URL για ένα κανάλι. Έχει αυτή τη μορφή:
urlhttps://mss.gs/api/v1/webhook/{webhook_guid}/{token}/{channel_guid}Στείλε ένα μήνυμα
Υπόγραψε το JSON με το μυστικό του webhook και στείλε το με POST. Ένα webhook που φτιάχτηκε στην εφαρμογή για υπολογιστή έχει πάντα μυστικό: αντίγραψέ το από το Webhook Secret στις ρυθμίσεις του webhook.
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"Διάβασε την απόκριση
Η απόκριση σου δίνει το 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-..." }
Τι μπορείς να στείλεις
Ένα μήνυμα είναι είτε η σύντομη μορφή (κείμενο με τίτλο και χρώμα) είτε μια πλήρης κάρτα, και οποιοδήποτε από τα δύο μπορεί να έχει κουμπιά και αρχεία. Το όνομα στην κορυφή της κάρτας είναι πάντα το όνομα του ίδιου του webhook. Στις ρυθμίσεις του webhook αποφασίζεις επίσης αν μπορεί να δημοσιεύει εικόνες και να κάνει mention σε άτομα.
Σύντομη μορφή
Αρκεί για τις περισσότερες ειδοποιήσεις.
{
"content": "Server backup completed at 03:00 UTC",
"color": "green",
"title": "Backup Bot"
}| Πεδίο | Τύπος | Τι κάνει |
|---|---|---|
content | string | Το κείμενο του μηνύματος. Υποχρεωτικό, εκτός αν στέλνεις κάρτα ή αρχεία. |
color | string | blue (προεπιλογή), green, orange, red, yellow ή purple. |
title | string | Τίτλος πάνω από το κείμενο. Προεπιλογή: το όνομα του webhook. |
Πλήρης κάρτα
Στείλε ένα message_container για κάρτα με τίτλο που είναι σύνδεσμος, υπότιτλο, markdown, πεδία και εικόνες. Μέσω webhook μια κάρτα δέχεται type, color, title, title_url, sub_title, description, fields, avatar_url, image_url, image_base64, images και τα πεδία του loader. Η ένδειξη κατάστασης, το badge, τα στατιστικά diff και ο συμπτυγμένος συλλογισμός είναι για απαντήσεις σε εντολές. Όλα τα πεδία θα τα βρεις στις κάρτες μηνυμάτων.
{
"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" }
]
}
}Κουμπιά
Πρόσθεσε έναν πίνακα actions για να βάλεις κουμπιά κάτω από το μήνυμα. Πώς λειτουργούν θα το βρεις στη σελίδα κουμπιά.
Αρχεία
Δημοσίευσε πραγματικά αρχεία μαζί με ένα μήνυμα: ένα log, μια αναφορά, ένα στιγμιότυπο οθόνης. Εμφανίζονται όπως κάθε άλλο συνημμένο, ως γραμμή λήψης, ή μέσα στο μήνυμα για εικόνες, βίντεο και ήχο. Ένα μήνυμα μόνο με αρχεία είναι εντάξει: παράλειψε το content και την κάρτα.
{
"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"
}
]
}| Πεδίο | Τύπος | Τι κάνει |
|---|---|---|
name | string | Το όνομα με το οποίο κατεβαίνει το αρχείο. Υποχρεωτικό. Μια διαδρομή περικόπτεται στο τελευταίο της τμήμα. |
content_base64 | string | Τα bytes του αρχείου σε base64, σκέτα ή ως URI data:. Το mssgs αποθηκεύει το αρχείο και κρατά στο μήνυμα μόνο έναν σύνδεσμο. |
mime_type | string | Ο τύπος περιεχομένου του content_base64. Προεπιλογή: text/plain. |
url | string | Ένα αρχείο που φιλοξενείται ήδη στο 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 θα το φιλοξενήσει.
Μια αποτυχημένη μεταφόρτωση δεν ακυρώνει το μήνυμα
Τα αρχεία ελέγχονται από πριν, αλλά ανεβαίνουν μετά. Αν μια μεταφόρτωση αποτύχει, εκείνο το αρχείο παραλείπεται και το υπόλοιπο μήνυμα δημοσιεύεται κανονικά, χωρίς σφάλμα: καλύτερα να χαθεί το αρχείο παρά η αναφορά. Αν ένα αρχείο είναι σημαντικό, έλεγξε ότι έφτασε.
Ένα αρχείο από τη γραμμή εντολών
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>.
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 λεπτά.
{
"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 στο σώμα. Θεώρησε αποτυχία κάθε σώμα με κλειδί error, όποιος κι αν είναι ο κωδικός κατάστασης.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}`);
}Όταν το μήνυμα έχει κουμπιά, η απόκριση περιέχει επίσης ένα 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-event | Pushes, pull requests και reviews, issues και σχόλια, branches και tags, releases. Μια σειρά αλλαγών σε ένα issue ή pull request μέσα σε λίγο χρόνο συγκεντρώνεται σε μία κάρτα. |
| UniFi Protect | User agent protect-alarm-manager | Χτυπήματα κουδουνιού, κίνηση, καθώς και άτομα, οχήματα ή δέματα που εντοπίζουν οι κάμερές σου. |
| App Store Connect | Το σώμα των ειδοποιήσεών του ή η κεφαλίδα x-apple-signature | Ειδοποιήσεις του App Store Connect. |