---
title: "Aggiornamenti live: cambia un messaggio mssgs dopo l’invio"
description: "Aggiorna o elimina un messaggio mssgs con la sua callback URL, mostra l’avanzamento con un loader e ascolta risposte, reazioni e pulsanti su uno stream live."
canonical: https://mss.gs/it/docs/live-updates
language: it
---

# Aggiorna i messaggi in tempo reale

Un messaggio non deve restare com’è stato pubblicato. Mostra l’avanzamento mentre un lavoro è in corso, sostituisci un loader con il risultato, togli i pulsanti quando qualcuno ha deciso, oppure eliminalo. Tutti nel canale vedono subito il cambiamento.

## Cosa puoi fare

- **Aggiorna la card** Cambia il testo, il colore e i pulsanti, sul posto.

- **Mostra l’avanzamento** Un loader che passa da un passo all’altro, poi il risultato.

- **Eliminalo** Rimuovi un messaggio quando non è più vero.

- **Ascoltalo** Risposte, reazioni e pressioni dei pulsanti sul tuo messaggio, dal vivo.

Nell'app

Pubblicata con un loader

Aggiornata: passo 2 di 3

#### Deploy completato

Aggiornata: fatto, con un pulsante

Un solo messaggio, aggiornato due volte tramite la sua callback URL. Nessuno vede tre messaggi, solo uno che cambia.

- [Per iniziare](#quick-start)

- [Aggiornare](#update)

- [Mostrare l’avanzamento](#progress)

- [Eliminare](#delete)

- [Ascoltare](#stream)

## Per iniziare

### Conserva la callback URL

Ogni post da [webhook](https://mss.gs/it/docs/webhooks) e ogni richiesta di un [comando](https://mss.gs/it/docs/commands) arriva con una callback_url per quel messaggio.

```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 per aggiornare

Invia il nuovo stato. La card cambia sul posto per tutti.

```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 per rimuovere

Non serve nessun body.

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

## Aggiornare un messaggio

Invia JSON in PUT alla callback_url . Invia solo ciò che vuoi cambiare.

| Campo | Tipo | Cosa fa |
| --- | --- | --- |
| message_container | object | La nuova card. Vedi [card dei messaggi](https://mss.gs/it/docs/bots). |
| actions | array | Nuovi pulsanti. "actions": [] li toglie tutti; se ometti il campo, restano. |
| content | string | Nuovo testo. |
| title , description , color , loader , ... | string | Forma breve: i campi della card al primo livello vengono racchiusi in una card per te. |

### Risposte

| Status | Codice | Significato |
| --- | --- | --- |
| 200 | {"success": true} | Accettato. L’aggiornamento segue subito dopo. |
| 400 | MISSING_FIELDS | Nel body non c’è niente da aggiornare. |
| 400 | INVALID_BODY | Il body non è JSON valido. |
| 400 | un codice dei pulsanti | C’è qualcosa che non va in un pulsante, vedi [pulsanti](https://mss.gs/it/docs/buttons). |
| 401 | INVALID_TOKEN | L’URL non è valido. |
| 404 | TOKEN_NOT_FOUND | L’URL è scaduto o è stato usato per eliminare il messaggio. |
| 502 | PUBLISH_FAILED | Non è stato possibile consegnare l’aggiornamento. Riprova. |

### Per quanto tempo funziona

30 minuti dal momento in cui il messaggio è stato pubblicato, o in cui è stato usato il comando. Aggiornare non allunga questo tempo. Eliminare il messaggio consuma l’URL. Con un aggiornamento non si possono aggiungere file.

## Mostrare l’avanzamento

Pubblica una card con un loader, aggiorna il suo testo secondario man mano che il lavoro avanza e chiudi con il risultato. Il loader è uno spinner con una riga e una riga più piccola sotto ( 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' }]
});
```

## Eliminare un messaggio

Invia DELETE alla callback_url e il messaggio sparisce per tutti. Dopo, l’URL non si può più usare.

## Ascoltare un messaggio

Uno stream_url è uno stream live (Server-Sent Events) di ciò che succede sul tuo messaggio. Aprilo e gli eventi arrivano man mano che accadono, ognuno come riga JSON data: il cui type dice di cosa si tratta:

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

| Evento | Quando | Dati |
| --- | --- | --- |
| action | È stato premuto un pulsante. | action_id , e il pulsante salvato in action con il suo payload |
| reaction | È stata aggiunta o rimossa una reazione. | emoji , e action : add, remove o removeall |
| reply | Qualcuno ha risposto al messaggio. | Il content della risposta |
| expired | Lo stream si sta chiudendo. Inviato come evento con nome. | Nessuno |

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

### Dove ne ricevi uno

| Da dove arriva | Aperto per |
| --- | --- |
| Un post da webhook con pulsanti | 10 minuti, oppure un’ora con "sse_event_extended_timeout": true |
| Ogni richiesta di un comando | 10 minuti |

### Errori

| Status | Codice | Significato |
| --- | --- | --- |
| 401 | INVALID_TOKEN | Il token nell’URL è sbagliato. |
| 404 | NOT_FOUND | Lo stream è scaduto o non è mai esistito. |

## Continua a costruire
