---
title: "Liveopdateringer: ændr mssgs-beskeder efter opslaget"
description: "Opdatér eller slet en mssgs-besked efter opslaget med dens callback-URL, vis fremskridt med en loader, og lyt live til svar, reaktioner og knaptryk."
canonical: https://mss.gs/da/docs/live-updates
language: da
---

# Opdatér beskeder live

En besked behøver ikke at blive, som den blev postet. Vis fremskridt, mens et job kører, skift en loader ud med resultatet, fjern knapperne, når nogen har besluttet sig, eller slet den. Alle i kanalen ser ændringen med det samme.

## Det kan du

- **Opdatér kortet** Ændr teksten, farven og knapperne, på stedet.

- **Vis fremskridt** En loader, der går gennem trinnene, og så resultatet.

- **Slet den** Fjern en besked, når den ikke længere passer.

- **Lyt til den** Svar, reaktioner og tryk på knapper på din besked, live.

I appen

Postet med en loader

Opdateret: trin 2 af 3

#### Deploy færdig

Opdateret: færdig, med en knap

Én besked, opdateret to gange gennem dens callback-URL. Ingen ser tre beskeder, kun én, der ændrer sig.

- [Kom godt i gang](#quick-start)

- [Opdatér](#update)

- [Vis fremskridt](#progress)

- [Slet](#delete)

- [Lyt](#stream)

## Kom godt i gang

### Gem callback-URL'en

Alle opslag fra en [webhook](https://mss.gs/da/docs/webhooks) og alle requests fra en [kommando](https://mss.gs/da/docs/commands) kommer med en callback_url til den besked.

```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 for at opdatere

Send den nye tilstand. Kortet ændrer sig på stedet for alle.

```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 for at fjerne

Ingen body nødvendig.

```bash
curl -X DELETE "$CALLBACK_URL"
```

## Opdatér en besked

Send JSON med PUT til callback_url . Send kun det, du vil ændre.

| Felt | Type | Hvad det gør |
| --- | --- | --- |
| message_container | object | Det nye kort. Se [beskedkort](https://mss.gs/da/docs/bots). |
| actions | array | Nye knapper. "actions": [] fjerner dem alle; udelader du feltet, bliver de. |
| content | string | Ny tekst. |
| title , description , color , loader , ... | string | Genvej: kortfelter på øverste niveau bliver pakket ind i et kort for dig. |

### Svar

| Status | Kode | Betydning |
| --- | --- | --- |
| 200 | {"success": true} | Accepteret. Opdateringen følger lige efter. |
| 400 | MISSING_FIELDS | Intet at opdatere i body. |
| 400 | INVALID_BODY | Body er ikke gyldig JSON. |
| 400 | en knapkode | Der er noget galt med en knap, se [knapper](https://mss.gs/da/docs/buttons). |
| 401 | INVALID_TOKEN | URL'en er ikke gyldig. |
| 404 | TOKEN_NOT_FOUND | URL'en er udløbet eller blev brugt til at slette beskeden. |
| 502 | PUBLISH_FAILED | Opdateringen kunne ikke leveres. Prøv igen. |

### Hvor længe den virker

30 minutter fra det øjeblik, beskeden blev postet, eller kommandoen blev brugt. En opdatering forlænger ikke tiden. Sletter du beskeden, er URL'en brugt op. Filer kan ikke tilføjes gennem en opdatering.

## Vis fremskridt

Post et kort med en loader, opdatér dens undertekst, efterhånden som jobbet skrider frem, og slut af med resultatet. Loaderen er en spinner med en linje og en mindre linje under den ( 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' }]
});
```

## Slet en besked

Send DELETE til callback_url , så er beskeden væk for alle. URL'en kan ikke bruges igen bagefter.

## Lyt til en besked

En stream_url er en live stream (Server-Sent Events) af det, der sker på din besked. Åbn den, så ankommer hændelserne, efterhånden som de sker, hver som en JSON-linje med data: , hvis type siger, hvad det er:

```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: {}
```

| Hændelse | Hvornår | Data |
| --- | --- | --- |
| action | Der blev trykket på en knap. | action_id og den gemte knap i action med dens payload |
| reaction | En reaktion blev tilføjet eller fjernet. | emoji og action : add, remove eller removeall |
| reply | Nogen svarede på beskeden. | Svarets content |
| expired | Streamen lukker. Sendes som en navngivet hændelse. | Ingen |

### Lyt i 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();
});
```

### Hvor du får en

| Hvor den kommer fra | Åben i |
| --- | --- |
| Et webhook-opslag med knapper | 10 minutter, eller en time med "sse_event_extended_timeout": true |
| Hver kommando-request | 10 minutter |

### Fejl

| Status | Kode | Betydning |
| --- | --- | --- |
| 401 | INVALID_TOKEN | Tokenet i URL'en er forkert. |
| 404 | NOT_FOUND | Streamen er udløbet eller har aldrig eksisteret. |

## Byg videre
