Listen for events
Once a user has joined a room, you keep the conversation live by following the updates cursor. Each poll returns the events since the cursor you passed and a fresh cursor for the next poll — new messages, reactions, replies, and moderation actions all arrive on the same stream.
import { ChatClient } from 'sportstalk-sdk';
// Public app id only. userToken comes from whichever auth model you chose.const client = ChatClient.init({ appId: APP_ID });client.setUserToken(userToken);client.setUser({ userid: 'u-8842' }); // same user you joined as
// Handle the events you care about — the SDK tracks the cursor for you.client.setEventHandlers({ onChatEvent: (e) => render(e), onReaction: (e) => bump(e), onAnnouncement: (e) => banner(e),});
// Join, then start the long-poll loop.await client.joinRoomByCustomId('live-event-chat');client.startListeningToEventUpdates();GET /api/v3/{appid}/chat/rooms/{roomid}/updates/{cursor} — use the
TalkLabs-assigned room.id returned by join, then feed each response’s cursor
into the next request.
using System.Net.Http.Headers;
using var http = new HttpClient();http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", userToken);
var cursor = "";var roomId = joinedRoom.Id; // TalkLabs ID returned by joinwhile (true){ var url = $"https://api.sportstalk247.com/api/v3/{appId}" + $"/chat/rooms/{roomId}/updates/{cursor}?limit=100";
using var doc = System.Text.Json.JsonDocument.Parse(await http.GetStringAsync(url)); var data = doc.RootElement.GetProperty("data");
foreach (var ev in data.GetProperty("events").EnumerateArray()) Console.WriteLine(ev.GetProperty("body").GetString());
cursor = data.GetProperty("cursor").GetString() ?? "";}let cursor = '';const roomId = joinedRoom.id; // TalkLabs ID returned by join
while (true) { const url = `https://api.sportstalk247.com/api/v3/${appId}` + `/chat/rooms/${roomId}/updates/${cursor}?limit=100`;
const res = await fetch(url, { headers: { 'Authorization': `Bearer ${userToken}` }, }); if (!res.ok) throw new Error(`updates failed: ${res.status}`);
const { data } = await res.json(); for (const ev of data.events) { console.log(`${ev.user.displayname}: ${ev.body}`); } cursor = data.cursor; // advance}cursor := ""roomID := joinedRoom.ID // TalkLabs ID returned by joinfor { url := fmt.Sprintf( "https://api.sportstalk247.com/api/v3/%s/chat/rooms/%s/updates/%s?limit=100", appID, roomID, cursor)
req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Authorization", "Bearer "+userToken)
res, err := http.DefaultClient.Do(req) if err != nil { panic(err) }
var out struct { Data struct { Cursor string `json:"cursor"` Events []struct { Body string `json:"body"` } `json:"events"` } `json:"data"` } json.NewDecoder(res.Body).Decode(&out) res.Body.Close()
for _, ev := range out.Data.Events { fmt.Println(ev.Body) } cursor = out.Data.Cursor // advance}# One poll from the tail. Feed the returned cursor back in for the next call.curl -s \ "https://api.sportstalk247.com/api/v3/$APP_ID/chat/rooms/$ROOM_ID/updates/?limit=100" \ -H "Authorization: Bearer $USER_TOKEN"- Authentication models → — the auth step that precedes this.
GET /chat/rooms/{roomid}/updates/{cursor}in the reference →