Vai al contenuto principale
Sviluppatori Aggiornamenti live

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 cardCambia il testo, il colore e i pulsanti, sul posto.
  • Mostra l’avanzamentoUn loader che passa da un passo all’altro, poi il risultato.
  • EliminaloRimuovi un messaggio quando non è più vero.
  • AscoltaloRisposte, reazioni e pressioni dei pulsanti sul tuo messaggio, dal vivo.

Nell'app

Pubblicata con un loader

Aggiornata: passo 2 di 3

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

  1. Conserva la callback URL

    Ogni post da webhook e ogni richiesta di un comando 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-..."}
  2. 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."}}'
  3. 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.

CampoTipoCosa fa
message_containerobjectLa nuova card. Vedi card dei messaggi.
actionsarrayNuovi pulsanti. "actions": [] li toglie tutti; se ometti il campo, restano.
contentstringNuovo testo.
title, description, color, loader, ...stringForma breve: i campi della card al primo livello vengono racchiusi in una card per te.
Un nuovo message_container sostituisce per intero la vecchia card: un campo che ometti sparisce. Restano solo il tipo, il nome e l’avatar. Quindi invia ogni volta la card completa.

Risposte

StatusCodiceSignificato
200{"success": true}Accettato. L’aggiornamento segue subito dopo.
400MISSING_FIELDSNel body non c’è niente da aggiornare.
400INVALID_BODYIl body non è JSON valido.
400un codice dei pulsantiC’è qualcosa che non va in un pulsante, vedi pulsanti.
401INVALID_TOKENL’URL non è valido.
404TOKEN_NOT_FOUNDL’URL è scaduto o è stato usato per eliminare il messaggio.
502PUBLISH_FAILEDNon è 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: {}
EventoQuandoDati
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
replyQualcuno ha risposto al messaggio.Il content della risposta
expiredLo stream si sta chiudendo. Inviato come evento con nome.Nessuno
Gli eventi non vengono conservati per dopo. Apri lo stream appena hai l’URL: ciò che succede prima che ti colleghi non viene inviato. Ogni evento porta anche il message_id, chi l’ha fatto (member_guid, member) e quando (ts). Una riga di commento ogni 20 secondi tiene aperta la connessione.

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 arrivaAperto per
Un post da webhook con pulsanti10 minuti, oppure un’ora con "sse_event_extended_timeout": true
Ogni richiesta di un comando10 minuti

Errori

StatusCodiceSignificato
401INVALID_TOKENIl token nell’URL è sbagliato.
404NOT_FOUNDLo stream è scaduto o non è mai esistito.

Continua a costruire