Publier des événements
Publiez depuis votre serveur avec votre clé Bird API ainsi que la clé et le secret de l'application Realtime. Ne livrez jamais le secret de l'application dans le code client. Pour permettre aux clients abonnés d'échanger des signaux éphémères, utilisez les événements client sur les canaux privés ou de présence.
Une publication minimale
Un événement nécessite un nom et au moins un canal. Son contenu optionnel peut être n'importe quel objet, tableau ou scalaire JSON.
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,
},
});
await bird.realtime.publish("rap_01krdgeqcxet5s7t44vh8rt9mg", {
event: "order-updated",
channels: ["orders"],
data: { id: 42, status: "shipped" },
});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.realtime.publish(
"rap_01krdgeqcxet5s7t44vh8rt9mg",
event="order-updated",
channels=["orders"],
data={"id": 42, "status": "shipped"},
)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)
}
_, err = client.Realtime.Publish(context.Background(), "rap_01krdgeqcxet5s7t44vh8rt9mg", bird.RealtimePublishParams{
Event: "order-updated",
Channels: []string{"orders"},
Data: map[string]any{"id": 42, "status": "shipped"},
})use MessageBird\Bird;
use MessageBird\RealtimeOptions;
use MessageBird\Wire\Model\RealtimePublish;
$bird = new Bird(
getenv('BIRD_API_KEY') ?: '',
realtime: new RealtimeOptions(
key: getenv('BIRD_REALTIME_KEY') ?: '',
secret: getenv('BIRD_REALTIME_SECRET') ?: '',
),
);
$bird->realtime->publish('rap_01krdgeqcxet5s7t44vh8rt9mg', (new RealtimePublish())
->setEvent('order-updated')
->setChannels(['orders'])
->setData(['id' => 42, 'status' => 'shipped']));curl -X POST https://us1.platform.bird.com/v1/realtime/apps/rap_01krdgeqcxet5s7t44vh8rt9mg/events \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "order-updated",
"channels": ["orders"],
"data": { "id": 42, "status": "shipped" }
}'Les clients liés à order-updated sur orders reçoivent l'événement. Le API rejette les noms publiés par le serveur qui commencent par les préfixes de protocole bird: ou bird_internal:. Les noms d'événements émis par le client doivent commencer par client-.
La requête et la réponse complètes, avec chaque champ, se trouvent dans la référence publier un événement.
Ce que signifie un 200
La publication se termine dès que le point d'entrée Realtime accepte l'événement. La livraison est asynchrone et ne génère aucun accusé de réception par client. Un client qui se déconnecte pendant la livraison peut manquer l'événement, et Realtime ne le rejoue pas après reconnexion.
Stockez l'état durable dans votre base de données. Utilisez les événements pour signaler les changements, puis faites recharger l'état courant par les clients après reconnexion.
Diffuser vers plusieurs canaux
Un seul appel peut envoyer le même événement à 100 canaux maximum. Un canal private-encrypted- doit être le seul canal de sa publication, car chaque canal chiffré utilise une clé différente. Le API rejette une diffusion chiffrée avec E23000. Voir Canaux chiffrés.
await bird.realtime.publish(appId, {
event: "price-changed",
channels: ["ticker-btc", "ticker-eth", "ticker-sol"],
data: { at: "2026-07-31T09:00:00Z" },
});client.realtime.publish(
app_id,
event="price-changed",
channels=["ticker-btc", "ticker-eth", "ticker-sol"],
data={"at": "2026-07-31T09:00:00Z"},
)_, err := client.Realtime.Publish(context.Background(), appID, bird.RealtimePublishParams{
Event: "price-changed",
Channels: []string{"ticker-btc", "ticker-eth", "ticker-sol"},
Data: map[string]any{"at": "2026-07-31T09:00:00Z"},
})$bird->realtime->publish($appId, (new RealtimePublish())
->setEvent('price-changed')
->setChannels(['ticker-btc', 'ticker-eth', 'ticker-sol'])
->setData(['at' => '2026-07-31T09:00:00Z']));curl -X POST "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/events" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "price-changed",
"channels": ["ticker-btc", "ticker-eth", "ticker-sol"],
"data": { "at": "2026-07-31T09:00:00Z" }
}'Chaque canal cible compte comme un message distinct pour la consommation. Cet exemple compte comme trois messages. Une publication vers 10 000 canaux par utilisateur compte donc comme 10 000 messages.
Regrouper des événements indépendants
Une diffusion envoie un événement vers plusieurs canaux. Un lot envoie jusqu'à 10 événements différents, chacun vers un canal, en une seule requête.
await bird.realtime.publishBatch(appId, {
events: [
{ event: "order-updated", channels: ["orders-42"], data: { status: "shipped" } },
{ event: "stock-changed", channels: ["inventory-99"], data: { left: 3 } },
],
});client.realtime.publish_batch(
app_id,
events=[
{"event": "order-updated", "channels": ["orders-42"], "data": {"status": "shipped"}},
{"event": "stock-changed", "channels": ["inventory-99"], "data": {"left": 3}},
],
)_, err := client.Realtime.PublishBatch(context.Background(), appID, bird.RealtimePublishBatchParams{
Events: []bird.RealtimeBatchEventParams{
{Event: "order-updated", Channel: "orders-42", Data: map[string]any{"status": "shipped"}},
{Event: "stock-changed", Channel: "inventory-99", Data: map[string]any{"left": 3}},
},
})$bird->realtime->publishBatch($appId, (new RealtimeBatchPublish())
->setEvents([
(new RealtimeBatchEvent())->setEvent('order-updated')->setChannel('orders-42')->setData(['status' => 'shipped']),
(new RealtimeBatchEvent())->setEvent('stock-changed')->setChannel('inventory-99')->setData(['left' => 3]),
]));curl -X POST "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/batch-events" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"events": [
{ "event": "order-updated", "channel": "orders-42", "data": { "status": "shipped" } },
{ "event": "stock-changed", "channel": "inventory-99", "data": { "left": 3 } }
]
}'Utilisez un lot pour combiner des mises à jour indépendantes en une seule requête. Chaque événement compte toujours séparément pour la consommation, et un lot accepte au maximum 10 événements. Voir Publier un lot.
Exclure le client à l'origine de l'action
Si un client a déjà appliqué son action localement, transmettez son identifiant de connexion pour empêcher la publication résultante d'appliquer le même changement une seconde fois. Le point d'entrée ignore uniquement cette connexion.
await bird.realtime.publish(appId, {
event: "message.created",
channels: ["presence-room-1"],
data: { body: "hello" },
exclude_connection_id: "26896.319537",
});client.realtime.publish(
app_id,
event="message.created",
channels=["presence-room-1"],
data={"body": "hello"},
exclude_connection_id="26896.319537",
)_, err := client.Realtime.Publish(context.Background(), appID, bird.RealtimePublishParams{
Event: "message.created",
Channels: []string{"presence-room-1"},
Data: map[string]any{"body": "hello"},
ExcludeConnectionID: "26896.319537",
})$bird->realtime->publish($appId, (new RealtimePublish())
->setEvent('message.created')
->setChannels(['presence-room-1'])
->setData(['body' => 'hello'])
->setExcludeConnectionId('26896.319537'));curl -X POST "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/events" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "message.created",
"channels": ["presence-room-1"],
"data": { "body": "hello" },
"exclude_connection_id": "26896.319537"
}'Lisez l'identifiant depuis la connexion courante du client et incluez-le dans la requête qui déclenche le changement. Les autres onglets utilisent des connexions séparées et reçoivent toujours l'événement.
Lire l'état du canal lors de la publication
Utilisez include pour renvoyer l'état de chaque canal cible au moment de la publication et éviter une requête d'état de canal séparée :
const result = await bird.realtime.publish(appId, {
event: "order-updated",
channels: ["presence-lobby"],
data: { id: 42 },
include: ["member_count", "connection_count"],
});result = client.realtime.publish(
app_id,
event="order-updated",
channels=["presence-lobby"],
data={"id": 42},
include=["member_count", "connection_count"],
)result, err := client.Realtime.Publish(context.Background(), appID, bird.RealtimePublishParams{
Event: "order-updated",
Channels: []string{"presence-lobby"},
Data: map[string]any{"id": 42},
Include: []bird.RealtimeChannelInclude{bird.RealtimeIncludeMemberCount, bird.RealtimeIncludeConnectionCount},
})$result = $bird->realtime->publish($appId, (new RealtimePublish())
->setEvent('order-updated')
->setChannels(['presence-lobby'])
->setData(['id' => 42])
->setInclude(['member_count', 'connection_count']));curl -X POST "https://us1.platform.bird.com/v1/realtime/apps/$APP_ID/events" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "X-Realtime-Key: $BIRD_REALTIME_KEY" \
-H "X-Realtime-Secret: $BIRD_REALTIME_SECRET" \
-H "Content-Type: application/json" \
-d '{
"event": "order-updated",
"channels": ["presence-lobby"],
"data": { "id": 42 },
"include": ["member_count", "connection_count"]
}'member_count fonctionne uniquement sur les canaux de présence. connection_count nécessite le comptage des connexions sur l'application. Demander ces attributs compte comme un message supplémentaire pour la consommation.
Limites
| Limite | Valeur |
|---|---|
| Canaux par publication | 100 |
| Événements par lot | 10 |
| Contenu de l'événement | 10 Ko sérialisé |
| Nom du canal | 164 caractères, lettres, chiffres et _ - = @ , . ; |
| Nom de l'événement | 200 caractères |
Dépasser une limite renvoie une erreur de validation. Le API ne tronque pas la requête.
Réessayer en toute sécurité
Réessayez une publication avec la même Idempotency-Key pour éviter une livraison en double. Les SDK TypeScript et Go génèrent une clé et la réutilisent pour les tentatives automatiques. Si votre application réessaie une requête, fournissez et réutilisez sa propre clé. Voir Idempotence.
Étapes suivantes
- Autoriser les canaux est ce dont un canal private- ou presence- a besoin avant qu'un client puisse s'abonner.
- Vue d'ensemble de Realtime explique les canaux, les membres et les connexions, et où la consommation apparaît.
- Exclure des destinataires d'événements empêche le client à l'origine de l'action de recevoir son propre changement.
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet. Les ressources sont en anglais.
Explorer la fonctionnalitéRealtimeSuivre le parcours d'apprentissageBuild your first integrationGuide d'implémentationSend your first realtime event
Essayez la pratique et obtenez un guide d'implémentation