---
title: "Live-Updates: mssgs-Nachrichten nach dem Posten ändern"
description: "Ändere oder lösche mssgs-Nachrichten nach dem Posten per Callback-URL, zeig Fortschritt mit einem Loader und hör Antworten, Reaktionen und Buttons live mit."
canonical: https://mss.gs/de/docs/live-updates
language: de
---

# 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 zeigen** Ein Loader, der Schritt für Schritt weiterläuft, und dann das Ergebnis.

- **Sie löschen** Entferne eine Nachricht, sobald sie nicht mehr stimmt.

- **Mithören** Antworten, Reaktionen und Button-Drücke auf deine Nachricht, live.

In der App

Mit einem Loader gepostet

Aktualisiert: Schritt 2 von 3

#### Deploy abgeschlossen

Aktualisiert: fertig, mit einem Button

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

- [Schnellstart](#quick-start)

- [Aktualisieren](#update)

- [Fortschritt zeigen](#progress)

- [Löschen](#delete)

- [Mithören](#stream)

## Schnellstart

### Die Callback-URL aufbewahren

Jeder Post per [Webhook](https://mss.gs/de/docs/webhooks) und jeder Request zu einem [Befehl](https://mss.gs/de/docs/commands) 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-..."}
```

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

### 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.

| Feld | Typ | Was es tut |
| --- | --- | --- |
| message_container | object | Die neue Karte. Siehe [Nachrichtenkarten](https://mss.gs/de/docs/bots). |
| actions | array | Neue Buttons. "actions": [] entfernt alle; lässt du das Feld weg, bleiben sie. |
| content | string | Neuer Text. |
| title , description , color , loader , ... | string | Kurzform: Kartenfelder auf oberster Ebene werden für dich in eine Karte verpackt. |

### Antworten

| Status | Code | Bedeutung |
| --- | --- | --- |
| 200 | {"success": true} | Angenommen. Das Update folgt direkt danach. |
| 400 | MISSING_FIELDS | Im Body steht nichts zum Aktualisieren. |
| 400 | INVALID_BODY | Der Body ist kein gültiges JSON. |
| 400 | ein Button-Code | Mit einem Button stimmt etwas nicht, siehe [Buttons](https://mss.gs/de/docs/buttons). |
| 401 | INVALID_TOKEN | Die URL ist nicht gültig. |
| 404 | TOKEN_NOT_FOUND | Die URL ist abgelaufen oder wurde schon zum Löschen der Nachricht verwendet. |
| 502 | PUBLISH_FAILED | Das 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: {}
```

| Event | Wann | Daten |
| --- | --- | --- |
| action | Ein Button wurde gedrückt. | action_id und der gespeicherte Button in action samt payload |
| reaction | Eine Reaktion wurde hinzugefügt oder entfernt. | emoji und action : add, remove oder removeall |
| reply | Jemand hat auf die Nachricht geantwortet. | Der content der Antwort |
| expired | Der Stream wird geschlossen. Als benanntes Event gesendet. | Keine |

### 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 bekommst | Wie lange offen |
| --- | --- |
| Ein Webhook-Post mit Buttons | 10 Minuten, oder eine Stunde mit "sse_event_extended_timeout": true |
| Jeder Request zu einem Befehl | 10 Minuten |

### Fehler

| Status | Code | Bedeutung |
| --- | --- | --- |
| 401 | INVALID_TOKEN | Das Token in der URL ist falsch. |
| 404 | NOT_FOUND | Der Stream ist abgelaufen oder hat nie existiert. |

## Weiterbauen
