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
Zachowaj callback URL
Każdy post z webhooka i każde żądanie komendy ma
callback_urltej wiadomości.bashBODY='{"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, żeby zaktualizować
Wyślij nowy stan. Karta zmienia się w miejscu u wszystkich.
bashcurl -X PUT "$CALLBACK_URL" -H "Content-Type: application/json" \ -d '{"message_container": {"color": "green", "title": "Deploy complete", "description": "v2.1 is live."}}'DELETE, żeby usunąć
Body nie jest potrzebne.
bashcurl -X DELETE "$CALLBACK_URL"
Aktualizacja wiadomości
Wyślij JSON metodą PUT na callback_url. Wysyłaj tylko to, co chcesz zmienić.
| Pole | Typ | Co robi |
|---|---|---|
message_container | object | Nowa karta. Zobacz karty wiadomości. |
actions | array | Nowe przyciski. "actions": [] usuwa wszystkie; pominięcie pola je zachowuje. |
content | string | Nowy tekst. |
title, description, color, loader, ... | string | Skrót: pola karty podane na najwyższym poziomie zostaną za ciebie opakowane w kartę. |
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
| Status | Kod | Znaczenie |
|---|---|---|
200 | {"success": true} | Przyjęto. Aktualizacja nastąpi zaraz potem. |
400 | MISSING_FIELDS | W body nie ma nic do zaktualizowania. |
400 | INVALID_BODY | Body nie jest poprawnym JSON-em. |
400 | kod przycisku | Coś jest nie tak z przyciskiem, zobacz przyciski. |
401 | INVALID_TOKEN | URL jest nieprawidłowy. |
404 | TOKEN_NOT_FOUND | URL wygasł albo został użyty do usunięcia wiadomości. |
502 | PUBLISH_FAILED | Nie 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).
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:
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: {}| Zdarzenie | Kiedy | Dane |
|---|---|---|
action | Naciśnięto przycisk. | action_id i zapisany przycisk w action z jego payload |
reaction | Dodano albo usunięto reakcję. | emoji i action: add, remove albo removeall |
reply | Ktoś odpowiedział na wiadomość. | content odpowiedzi |
expired | Strumień się zamyka. Wysyłane jako nazwane zdarzenie. | Brak |
message_id, informację, kto to zrobił (member_guid, member), i kiedy (ts). Wiersz komentarza co 20 sekund utrzymuje połączenie.Nasłuchiwanie w JavaScripcie
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 pochodzi | Otwarty przez |
|---|---|
| Post z webhooka z przyciskami | 10 minut albo godzinę z "sse_event_extended_timeout": true |
| Każde żądanie komendy | 10 minut |
Błędy
| Status | Kod | Znaczenie |
|---|---|---|
401 | INVALID_TOKEN | Token w URL-u jest błędny. |
404 | NOT_FOUND | Strumień wygasł albo nigdy nie istniał. |