Querying channel state
Three server-side reads list occupied channels, inspect one channel, and list the members of a presence channel. Authenticate each request with your Bird API key and the Realtime app's key and secret.
import { BirdClient } from "@messagebird/sdk";
const bird = new BirdClient({
apiKey: process.env.BIRD_API_KEY,
realtime: {
key: process.env.BIRD_REALTIME_KEY,
secret: process.env.BIRD_REALTIME_SECRET,
},
});import os
from bird import Bird
client = Bird(
api_key=os.environ["BIRD_API_KEY"],
realtime_key=os.environ["BIRD_REALTIME_KEY"],
realtime_secret=os.environ["BIRD_REALTIME_SECRET"],
)client, err := bird.NewClient(
option.WithAPIKey(os.Getenv("BIRD_API_KEY")),
option.WithRealtimeCredentials(os.Getenv("BIRD_REALTIME_KEY"), os.Getenv("BIRD_REALTIME_SECRET")),
)
if err != nil {
log.Fatal(err)
}use MessageBird\Bird;
use MessageBird\RealtimeOptions;
$bird = new Bird(
getenv('BIRD_API_KEY') ?: '',
realtime: new RealtimeOptions(
key: getenv('BIRD_REALTIME_KEY') ?: '',
secret: getenv('BIRD_REALTIME_SECRET') ?: '',
),
);Which channels are occupied
const { data } = await bird.realtime.channels.list(appId, { prefix: "presence-" });
for (const channel of data) {
console.log(channel.name);
}channels = client.realtime.channels.list(app_id, prefix="presence-")
for channel in channels.data:
print(channel.name)channels, err := client.Realtime.Channels.List(context.Background(), appID, bird.RealtimeChannelListParams{
Prefix: "presence-",
})
if err != nil {
log.Fatal(err)
}
for _, ch := range channels.Data {
fmt.Println(ch.Name)
}$channels = $bird->realtime->channels->list($appId, ['prefix' => 'presence-']);
foreach ($channels->getData() ?? [] as $channel) {
echo $channel->getName(), "\n";
}curl "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/channels?prefix=presence-" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET"A channel appears in the list while at least one connection is subscribed. Channels are not created or registered separately, so empty channels do not appear. Use prefix to restrict the result to a family such as presence- or orders-.
The response is not paginated and returns every occupied channel in one live snapshot. See List Realtime channels.
Inspect one channel
const channel = await bird.realtime.channels.get(appId, "presence-lobby", {
include: ["member_count"],
});
if (!channel.occupied) return; // nobody is listening; skip the workchannel = client.realtime.channels.get(app_id, "presence-lobby", include=["member_count"])
if not channel.occupied:
return # nobody is listening; skip the workchannel, err := client.Realtime.Channels.Get(context.Background(), appID, "presence-lobby", bird.RealtimeChannelGetParams{
Include: []bird.RealtimeChannelInclude{bird.RealtimeIncludeMemberCount},
})
if err != nil {
log.Fatal(err)
}
if !channel.Occupied {
return // nobody is listening; skip the work
}$channel = $bird->realtime->channels->get($appId, 'presence-lobby', ['include' => ['member_count']]);
if (!$channel->getOccupied()) {
return; // nobody is listening; skip the work
}curl "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/channels/presence-lobby?include=member_count" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET"An unknown or unused name returns 200 OK with occupied: false. Use this result to skip work when no connection can receive it. See Get a Realtime channel.
Counts, through include
include is repeatable and accepts exactly two values:
- member_count is the number of distinct members, and it works on presence channels only.
- connection_count is the number of connections subscribed to the channel, and it requires the app's connection-counting setting.
Any other value returns 400 Bad Request. The API also returns 400 Bad Request for member_count on a non-presence channel, a list request without a presence prefix, or connection_count when connection counting is disabled.
Requesting attributes counts as one extra message toward usage. Omit them when occupied answers your question.
One member can hold several connections. A room with three people who each have two tabs open reports a member_count of 3 and a connection_count of 6. Presence channels explains the distinction.
Who is present
const { members } = await bird.realtime.channels.members(appId, "presence-lobby");
for (const member of members) {
console.log(member.member_id);
}presence = client.realtime.channels.members(app_id, "presence-lobby")
for member in presence.members:
print(member.member_id)members, err := client.Realtime.Channels.Members(context.Background(), appID, "presence-lobby")
if err != nil {
log.Fatal(err)
}
for _, m := range members.Members {
fmt.Println(m.MemberId)
}$presence = $bird->realtime->channels->members($appId, 'presence-lobby');
foreach ($presence->getMembers() ?? [] as $member) {
echo $member->getMemberId(), "\n";
}curl "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/channels/presence-lobby/members" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET"The response contains only member IDs. member_info is delivered to subscribed clients and is not available through this REST operation. Join the IDs with your own records to render names or avatars. See List channel members.
Reading state while you publish
When publishing, use include to return the same counts for every target channel at publish time. See Reading channel state as you publish.
Point-in-time behavior
Each response is a point-in-time snapshot and can become stale immediately. Use it for one-time decisions rather than polling for continuous state.
For continuous state, subscribe an endpoint to the Realtime webhook groups. realtime.channel_existence reports occupied and vacated channels, realtime.presence reports member changes, and realtime.connection_count reports connection-count changes. Use channel-state reads to initialize or reconcile your stored view.
Next steps
- Publishing events covers publishing, batching, and the include shortcut.
- Presence channels explains members, connections, and member_info.
- Realtime overview explains apps, keys, and where usage shows up.