Zum Hauptinhalt springen
Entwickler Live-Updates

Nachrichten live aktualisieren

Eine Nachricht muss nicht so bleiben, wie sie gepostet wurde. Zeig den Fortschritt, während ein Job läuft, tausch einen Loader gegen das Ergebnis, nimm die Buttons weg, sobald jemand entschieden hat, oder lösch sie. Alle im Kanal sehen die Änderung sofort.

Was du damit machen kannst

  • Die Karte aktualisierenÄndere Text, Farbe und Buttons, an Ort und Stelle.
  • Fortschritt zeigenEin Loader, der Schritt für Schritt weiterläuft, und dann das Ergebnis.
  • Sie löschenEntferne eine Nachricht, sobald sie nicht mehr stimmt.
  • MithörenAntworten, Reaktionen und Button-Drücke auf deine Nachricht, live.

In der App

Mit einem Loader gepostet

Aktualisiert: Schritt 2 von 3

Aktualisiert: fertig, mit einem Button

Eine Nachricht, zweimal über ihre Callback-URL aktualisiert. Niemand sieht drei Nachrichten, nur eine, die sich ändert.

Schnellstart

  1. Die Callback-URL aufbewahren

    Jeder Post per Webhook und jeder Request zu einem Befehl bringt eine callback_url für diese Nachricht mit.

    bash
    BODY='{"message_container": {"color": "blue", "loader": true, "loader_text": "Deploying…"}}'
    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"
    
    # {"success": true, "message_id": "...", "callback_url": "https://mss.gs/api/v1/trigger-callback/8f14e45f-..."}
  2. PUT zum Aktualisieren

    Sende den neuen Zustand. Die Karte ändert sich für alle an Ort und Stelle.

    bash
    curl -X PUT "$CALLBACK_URL" -H "Content-Type: application/json" \
      -d '{"message_container": {"color": "green", "title": "Deploy complete", "description": "v2.1 is live."}}'
  3. DELETE zum Entfernen

    Kein Body nötig.

    bash
    curl -X DELETE "$CALLBACK_URL"

Eine Nachricht aktualisieren

Sende JSON per PUT an die callback_url. Schick nur, was du ändern willst.

FeldTypWas es tut
message_containerobjectDie neue Karte. Siehe Nachrichtenkarten.
actionsarrayNeue Buttons. "actions": [] entfernt alle; lässt du das Feld weg, bleiben sie.
contentstringNeuer Text.
title, description, color, loader, ...stringKurzform: Kartenfelder auf oberster Ebene werden für dich in eine Karte verpackt.
Ein neuer message_container ersetzt die alte Karte vollständig: Ein Feld, das du weglässt, ist weg. Nur Typ, Name und Avatar werden übernommen. Sende also jedes Mal die komplette Karte.

Antworten

StatusCodeBedeutung
200{"success": true}Angenommen. Das Update folgt direkt danach.
400MISSING_FIELDSIm Body steht nichts zum Aktualisieren.
400INVALID_BODYDer Body ist kein gültiges JSON.
400ein Button-CodeMit einem Button stimmt etwas nicht, siehe Buttons.
401INVALID_TOKENDie URL ist nicht gültig.
404TOKEN_NOT_FOUNDDie URL ist abgelaufen oder wurde schon zum Löschen der Nachricht verwendet.
502PUBLISH_FAILEDDas Update konnte nicht zugestellt werden. Versuch es erneut.

Wie lange sie funktioniert

30 Minuten ab dem Moment, in dem die Nachricht gepostet oder der Befehl benutzt wurde. Ein Update verlängert das nicht. Das Löschen der Nachricht verbraucht die URL. Über ein Update lassen sich keine Dateien hinzufügen.

Fortschritt zeigen

Poste eine Karte mit Loader, aktualisiere ihren Untertext, während der Job vorankommt, und ende mit dem Ergebnis. Der Loader ist ein Spinner mit einer Zeile und einer kleineren Zeile darunter (loader_text, loader_sub_text).

javascript
const { callback_url } = await post({
  message_container: { color: 'blue', loader: true, loader_text: 'Deploying…', loader_sub_text: 'Step 1 of 3: building' }
});

const update = (body) => {
  return fetch(callback_url, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
};

await build();
await update({ message_container: { color: 'blue', loader: true, loader_text: 'Deploying…', loader_sub_text: 'Step 2 of 3: running migrations' } });

await migrate();
await update({
  message_container: { color: 'green', title: 'Deploy complete', description: 'v2.1 is live on production.' },
  actions: [{ type: 'url:https://ci.example.com/deploys/218', text: 'View logs', color: 'green' }]
});

Eine Nachricht löschen

Sende DELETE an die callback_url, und die Nachricht ist für alle weg. Danach lässt sich die URL nicht mehr verwenden.

Eine Nachricht mithören

Eine stream_url ist ein Live-Stream (Server-Sent Events) dessen, was auf deiner Nachricht passiert. Öffne ihn, und Events kommen an, sobald sie passieren, jedes als JSON-Zeile data:, deren type sagt, was es ist:

sse
curl -N "$STREAM_URL"

data: {"type": "reaction", "message_id": "...", "emoji": ":tada:", "action": "add", "member_guid": "...", "member": {...}, "ts": 1790000000000}

data: {"type": "action", "message_id": "...", "action_id": "approve", "action": {"id": "approve", "payload": {"deploy": 218}, ...}, "member_guid": "...", "member": {...}, "ts": 1790000004200}

data: {"type": "reply", "message_id": "...", "content": "Ship it!", "member_guid": "...", "member": {...}, "ts": 1790000009800}

event: expired
data: {}
EventWannDaten
actionEin Button wurde gedrückt.action_id und der gespeicherte Button in action samt payload
reactionEine Reaktion wurde hinzugefügt oder entfernt.emoji und action: add, remove oder removeall
replyJemand hat auf die Nachricht geantwortet.Der content der Antwort
expiredDer Stream wird geschlossen. Als benanntes Event gesendet.Keine
Events werden nicht für später gespeichert. Öffne den Stream, sobald du die URL hast: Was passiert, bevor du verbunden bist, wird nicht gesendet. Jedes Event trägt außerdem die message_id, wer es ausgelöst hat (member_guid, member) und wann (ts). Eine Kommentarzeile alle 20 Sekunden hält die Verbindung offen.

Mithören in JavaScript

javascript
const events = new EventSource(streamUrl);

// Every event arrives as a plain message; its kind is in "type".
events.onmessage = (e) => {
  const ev = JSON.parse(e.data);
  if ((ev.type === 'action') && (ev.action_id === 'approve')) {
    startDeploy(ev.action.payload.deploy);
  }
};

// The one named event: the stream is closing.
events.addEventListener('expired', () => {
  events.close();
});

Wo du einen bekommst

Woher du ihn bekommstWie lange offen
Ein Webhook-Post mit Buttons10 Minuten, oder eine Stunde mit "sse_event_extended_timeout": true
Jeder Request zu einem Befehl10 Minuten

Fehler

StatusCodeBedeutung
401INVALID_TOKENDas Token in der URL ist falsch.
404NOT_FOUNDDer Stream ist abgelaufen oder hat nie existiert.

Weiterbauen