Opérateurs
Les opérateurs sont l’équipe humaine qui répond aux conversations d’un
tenant. La surface backend (/api/v1/relay/*, signée en HMAC#1) permet
à votre backend de provisionner des opérateurs et de leur frapper un jeton,
sans que vos utilisateurs ne détiennent jamais de mot de passe relais.
C’est le modèle « chat marchand » : un marchand de votre marketplace devient un opérateur scopé à ses propres files, et s’authentifie via votre système d’identité — le relais fait confiance à votre signature HMAC#1.
Lane humaine vs lane bot
Section intitulée « Lane humaine vs lane bot »Rappel du modèle (voir Présentation) : à la création
d’une session visiteur, le champ mode choisit la file.
bot(par défaut) — les messages vont à l’assistant RAG jusqu’à une escalade, qui les bascule vers la file humaine.human— le premier message crée directement une affectation en attente et le bot n’intervient jamais.
Les opérateurs servent la lane humaine. La liste routing_keys les
restreint à certaines files (par exemple les store id d’un marchand) ;
null ou liste vide signifie « opérateur de tout le tenant », qui voit
chaque conversation.
Provisionner un opérateur
Section intitulée « Provisionner un opérateur »POST /relay/provision/operator crée-ou-réutilise un opérateur pour l’un
de vos propres utilisateurs. L’opération est idempotente sur (email, tenant appelant) : re-provisionner rafraîchit les routing_keys de
l’appartenance (un marchand qui gagne une seconde boutique) au lieu
d’échouer. Le mot de passe est aléatoire et jamais renvoyé — l’échange
de jeton ci-dessous est le seul chemin d’authentification.
- Votre backend authentifie le marchand avec votre système (session, JWT applicatif, etc.).
- Votre backend appelle
/relay/provision/operatorsigné en HMAC#1, avec l’email du marchand, son nom d’affichage et sesrouting_keys. - Le relais crée l’opérateur (ou rafraîchit son appartenance) et renvoie
son
operator_id.
from bloonio_chat_relay_client import get_chat_client
chat = get_chat_client() # signe HMAC#1 automatiquement# La méthode exacte du SDK enveloppe POST /relay/provision/operator.curl $BASE_URL/api/v1/relay/provision/operator \ -X POST \ -H "X-Bloonio-Tenant-Id: 019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f" \ -H "X-Bloonio-Timestamp: 1718960000000" \ -H "X-Bloonio-Signature: <signature>" \ -H "Content-Type: application/json" \ -d '{ "email": "merchant@acme.com", "display_name": "Acme Boutique", "routing_keys": ["store_42", "store_77"] }'Réponse — 201 à la création, 200 quand l’opérateur existait déjà
(created: false) :
{ "status_code": 201, "data": { "operator_id": "019e4af0-...", "email": "merchant@acme.com", "display_name": "Acme Boutique", "tenant_id": "019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f", "routing_keys": ["store_42", "store_77"], "created": true }, "message": "Operator provisioned"}Champs du corps : email (clé stable côté tenant, requis),
display_name (requis), avatar_url (optionnel), routing_keys
(optionnel, jusqu’à 50 entrées ; null = tout le tenant).
Frapper un jeton opérateur
Section intitulée « Frapper un jeton opérateur »POST /relay/fetch/operator-token échange la confiance HMAC#1 du tenant
contre un JWT opérateur. Gérez cet appel derrière votre propre
authentification utilisateur : ainsi l’identité côté relais s’appuie sur
votre système.
curl $BASE_URL/api/v1/relay/fetch/operator-token \ -X POST \ -H "X-Bloonio-Tenant-Id: 019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f" \ -H "X-Bloonio-Timestamp: 1718960000000" \ -H "X-Bloonio-Signature: <signature>" \ -H "Content-Type: application/json" \ -d '{"email": "merchant@acme.com"}'{ "status_code": 200, "data": { "operator_id": "019e4af0-...", "display_name": "Acme Boutique", "operator_token": "<jwt>", "expires_at": 1719564800, "tenant_id": "019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f", "routing_keys": ["store_42", "store_77"] }, "message": "Operator token minted"}Le jeton est valable ~7 jours (expires_at en secondes unix). L’opérateur
l’utilise pour ouvrir son WebSocket et servir sa file.
L’invariant de scoping : tids
Section intitulée « L’invariant de scoping : tids »Le JWT frappé porte uniquement l’appartenance du tenant appelant dans
sa revendication tids ({tenant_id: rôle}). Un opérateur peut appartenir
à plusieurs tenants (modèle « espace de travail Slack »), mais :
Conditions d’émission : l’opérateur doit exister et être active (sinon
404), et avoir une appartenance active dans le tenant appelant (sinon
403).
Étapes suivantes
Section intitulée « Étapes suivantes »- Brancher le widget côté visiteur. Voir Widget & SDK.
- Réagir aux événements d’affectation d’agent. Voir Webhooks.
- Gérer les opérateurs à la main. Voir Console.
- La recette de signature HMAC#1. Voir Authentification.