Przejdź do treści głównej
Deweloperzy Aktualizacje na żywo

Aktualizuj wiadomości na żywo

Wiadomość nie musi zostać taka, jaką ją wysłano. Pokazuj postęp w trakcie zadania, zamień loader na wynik, zabierz przyciski, gdy ktoś już zdecyduje, albo usuń wiadomość. Wszyscy na kanale od razu widzą zmianę.

Co możesz z tym zrobić

  • Aktualizuj kartęZmieniaj tekst, kolor i przyciski w tym samym miejscu.
  • Pokazuj postępLoader, który przechodzi przez kolejne kroki, a potem wynik.
  • Usuń jąUsuń wiadomość, gdy przestaje być aktualna.
  • Słuchaj jejOdpowiedzi, reakcje i kliknięcia przycisków na twojej wiadomości, na żywo.

W aplikacji

Wysłana z loaderem

Zaktualizowana: krok 2 z 3

Zaktualizowana: gotowe, z przyciskiem

Jedna wiadomość, zaktualizowana dwa razy przez jej callback URL. Nikt nie widzi trzech wiadomości, tylko jedną, która się zmienia.

Szybki start

  1. Zachowaj callback URL

    Każdy post z webhooka i każde żądanie komendy ma callback_url tej wiadomości.

    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, żeby zaktualizować

    Wyślij nowy stan. Karta zmienia się w miejscu u wszystkich.

    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, żeby usunąć

    Body nie jest potrzebne.

    bash
    curl -X DELETE "$CALLBACK_URL"

Aktualizacja wiadomości

Wyślij JSON metodą PUT na callback_url. Wysyłaj tylko to, co chcesz zmienić.

PoleTypCo robi
message_containerobjectNowa karta. Zobacz karty wiadomości.
actionsarrayNowe przyciski. "actions": [] usuwa wszystkie; pominięcie pola je zachowuje.
contentstringNowy tekst.
title, description, color, loader, ...stringSkrót: pola karty podane na najwyższym poziomie zostaną za ciebie opakowane w kartę.
Nowy message_container zastępuje starą kartę w całości: pole, które pominiesz, znika. Przenoszą się tylko jej typ, nazwa i awatar. Dlatego za każdym razem wysyłaj pełną kartę.

Odpowiedzi

StatusKodZnaczenie
200{"success": true}Przyjęto. Aktualizacja nastąpi zaraz potem.
400MISSING_FIELDSW body nie ma nic do zaktualizowania.
400INVALID_BODYBody nie jest poprawnym JSON-em.
400kod przyciskuCoś jest nie tak z przyciskiem, zobacz przyciski.
401INVALID_TOKENURL jest nieprawidłowy.
404TOKEN_NOT_FOUNDURL wygasł albo został użyty do usunięcia wiadomości.
502PUBLISH_FAILEDNie udało się dostarczyć aktualizacji. Spróbuj ponownie.

Jak długo działa

30 minut od chwili wysłania wiadomości albo użycia komendy. Aktualizacja nie wydłuża tego czasu. Usunięcie wiadomości zużywa URL. Przez aktualizację nie można dodawać plików.

Pokazywanie postępu

Wyślij kartę z loaderem, aktualizuj jej podtekst w miarę postępu zadania i zakończ wynikiem. Loader to spinner z wierszem tekstu i mniejszym wierszem pod nim (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' }]
});

Usuwanie wiadomości

Wyślij DELETE na callback_url, a wiadomość zniknie u wszystkich. Potem tego URL-a nie można już użyć.

Nasłuchiwanie wiadomości

stream_url to strumień na żywo (Server-Sent Events) tego, co dzieje się z twoją wiadomością. Otwórz go, a zdarzenia przychodzą na bieżąco, każde jako wiersz JSON data:, którego type mówi, czym jest:

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: {}
ZdarzenieKiedyDane
actionNaciśnięto przycisk.action_id i zapisany przycisk w action z jego payload
reactionDodano albo usunięto reakcję.emoji i action: add, remove albo removeall
replyKtoś odpowiedział na wiadomość.content odpowiedzi
expiredStrumień się zamyka. Wysyłane jako nazwane zdarzenie.Brak
Zdarzenia nie są przechowywane na później. Otwórz strumień, gdy tylko masz URL: to, co dzieje się przed połączeniem, nie zostanie wysłane. Każde zdarzenie zawiera też message_id, informację, kto to zrobił (member_guid, member), i kiedy (ts). Wiersz komentarza co 20 sekund utrzymuje połączenie.

Nasłuchiwanie w JavaScripcie

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

Skąd go wziąć

Skąd pochodziOtwarty przez
Post z webhooka z przyciskami10 minut albo godzinę z "sse_event_extended_timeout": true
Każde żądanie komendy10 minut

Błędy

StatusKodZnaczenie
401INVALID_TOKENToken w URL-u jest błędny.
404NOT_FOUNDStrumień wygasł albo nigdy nie istniał.

Buduj dalej