Vue d'ensemble du SDK
Le SDK Vonage Cloud Runtime constitue l'interface principale avec tous les fournisseurs de plateformes. Il est disponible pour Node.js et Python.
| Temps d'exécution | Paquet | Version minimale | Dernière version | Notes |
|---|---|---|---|---|
| Node.js | @vonage/vcr-sdk | 2.0.0 | 2.1.5 | SDK >=2.1.0 nécessite Node.js 22 (Active LTS) |
| Python | vonage_cloud_runtime | 2.0.0 | 2.1.5 |
Les vcr Singleton
Le SDK exporte un vcr singleton qui est le point d'entrée pour toutes les opérations.
Node.js :
import { vcr } from '@vonage/vcr-sdk';
Python :
from vonage_cloud_runtime.vcr import VCR
vcr = VCR()
Les vcr fournit les méthodes suivantes :
| Méthode | Description |
|---|---|
vcr.createSession(ttl?) | Créer une nouvelle session avec un TTL optionnel en secondes (par défaut : 7 jours) |
vcr.createSessionWithId(id) | Créer une session avec un identifiant spécifique |
vcr.getSessionById(id) | Récupérer une session existante par ID |
vcr.getSessionFromRequest(req) | Extraire la session d'une requête HTTP entrante |
vcr.getGlobalSession() | Obtenir la session globale (partagée entre toutes les demandes) |
vcr.getInstanceState() | Obtenir l'état de l'instance (partagé entre les sessions au sein de l'instance) |
vcr.getAccountState() | Obtenir un état au niveau du compte (partagé par toutes les applications du compte) |
vcr.getAppUrl() | Obtenir l'URL publique de l'application en cours d'exécution |
vcr.createVonageToken(params) | Créer un JWT signé pour l'authentification de l'API Vonage |
vcr.verifyAuth(token) | Verify un jeton d'authentification |
vcr.unsubscribe(id, provider?) | Se désabonner d'un abonnement à un fournisseur |
Sessions
Les sessions sont nécessaires pour initialiser tout fournisseur. Chaque constructeur de fournisseur prend une session comme premier argument.
Node.js :
import { vcr } from '@vonage/vcr-sdk';
// New session with default 7-day TTL
const session = vcr.createSession();
// New session with a 1-hour TTL
const shortSession = vcr.createSession(3600);
// Session with a specific ID (useful for correlating with a user or call)
const userSession = vcr.createSessionWithId('user-123');
// Extract session from an incoming request
const reqSession = vcr.getSessionFromRequest(req);
// Global session — shared singleton across the entire instance
const globalSession = vcr.getGlobalSession();
Python :
from vonage_cloud_runtime.vcr import VCR
vcr = VCR()
session = vcr.createSession() # default 7-day TTL
session = vcr.createSession(3600) # 1-hour TTL
session = vcr.createSessionWithId('user-123')
session = vcr.getSessionFromRequest(req)
session = vcr.getGlobalSession()
Propriétés et méthodes de la session :
| Description | |
|---|---|
session.id | L'identifiant unique de la session |
session.getToken() | Obtenir le jeton d'authentification de la session |
session.createUUID() | Générer un nouvel UUID |
session.log(level, message, context?) | Enregistrer un message avec un contexte structuré |
Définition du champ d'application de la session - Orientations essentielles
Avertissement : vcr.createSession() génère un aléatoire, éphémère à chaque fois qu'il est appelé. Les données stockées sous cette session (via new State(session)) n'est accessible que si vous disposez de l'identifiant de session exact. Si vous appelez vcr.createSession() au niveau global/module et l'utiliser avec State, chaque réplique créera une session différenteLes répliques et les données seront cloisonnées et inaccessibles à d'autres répliques ou requêtes. Cela met fin à l'architecture sans état.
Règles :
- Jamais appel
vcr.createSession()à l'échelle globale de l'application pour initialiser State ou d'autres fournisseurs qui ont besoin d'un accès partagé aux données. - Pour l'état partagé entre les répliques, utiliser
vcr.getInstanceState()(ouvcr.getAccountState()pour les données inter-applications). - Pour l'état par demande ou par conversation, utiliser
vcr.createSessionWithId(id)avec un déterministe ID du contexte de la demande - tel queconversation_uuidd'un rappel vocal, un numéro de téléphone de l'expéditeur d'un rappel SMS, ou un identifiant d'utilisateur. Cela permet de s'assurer que la même session est récupérable à travers les répliques et les requêtes. vcr.getGlobalSession()est destiné à enregistrer des abonnements à l'échelle de l'instance (par ex,voice.onCall(),messages.onMessage()). Il doit pas être utilisée comme session polyvalente pour l'État.
// WRONG — random session at global scope, state is unreachable by other replicas/requests
const session = vcr.createSession();
const state = new State(session); // Data siloed to this random session
// CORRECT — shared state across all replicas
const state = vcr.getInstanceState();
// CORRECT — per-conversation state using a deterministic ID from a callback
app.post('/onCall', async (req, res) => {
const session = vcr.createSessionWithId(req.body.conversation_uuid);
const state = new State(session); // Same conversation_uuid = same state, any replica
await state.set('step', 'greeting');
});
Voir Architecture sans état pour des conseils détaillés.
Initialisation du fournisseur
Tous les fournisseurs suivent le même schéma : ils transmettent une session au constructeur.
Node.js :
import { vcr, State, Queue, Scheduler, Messages, Voice, Assets } from '@vonage/vcr-sdk';
const session = vcr.createSession();
// For shared state across replicas, use getInstanceState() — not new State(session)
const state = vcr.getInstanceState();
const queue = new Queue(session);
const scheduler = new Scheduler(session);
const messages = new Messages(session);
const voice = new Voice(session);
const assets = new Assets(session);
Python :
from vonage_cloud_runtime.vcr import VCR
from vonage_cloud_runtime.providers.state.state import State
from vonage_cloud_runtime.providers.queue.queue import Queue
from vonage_cloud_runtime.providers.scheduler.scheduler import Scheduler
from vonage_cloud_runtime.providers.messages.messages import Messages
from vonage_cloud_runtime.providers.voice.voice import Voice
from vonage_cloud_runtime.providers.assets.assets import Assets
vcr = VCR()
session = vcr.createSession()
# For shared state across replicas, use getInstanceState() — not State(session)
state = vcr.getInstanceState()
queue = Queue(session)
scheduler = Scheduler(session)
messages = Messages(session)
voice = Voice(session)
assets = Assets(session)
Portée de l'État
Le RCV offre trois niveaux d'état :
| Champ d'application | Comment accéder | Visibilité |
|---|---|---|
| État de la session | new State(session) | Isolé à la session spécifique |
| État de l'instance | vcr.getInstanceState() | Partagé entre toutes les sessions d'une même instance |
| État du compte | vcr.getAccountState() | Partagé entre toutes les Applications du compte Vonage |
// Per-user state
const session = vcr.createSessionWithId(userId);
const userState = new State(session);
// Shared across all replicas of this instance
const instanceState = vcr.getInstanceState();
// Shared across all applications in the account
const accountState = vcr.getAccountState();
Voir Architecture sans état pour savoir quand utiliser chaque champ d'application.
Authentification
Verify Incoming Requests (vérification des demandes entrantes)
Utilisation vcr.verifyAuth(token) pour valider les jetons sur les demandes entrantes :
app.use((req, res, next) => {
const token = req.headers.authorization?.replace('Bearer ', '');
try {
const decoded = vcr.verifyAuth(token);
req.user = decoded;
next();
} catch (err) {
res.status(401).json({ error: 'Invalid token' });
}
});
Création de jetons Vonage
Utilisation vcr.createVonageToken(params) pour générer des JWT signés pour l'authentification de l'API Vonage :
const token = vcr.createVonageToken({
exp: Math.floor(Date.now() / 1000) + 3600, // 1-hour expiry
aclPaths: { '/*/users/**': {} }, // optional ACL paths
subject: 'user-123', // optional subject
});
| Paramètres | Type | Exigée | Description |
|---|---|---|---|
exp | Numbers | Oui | Expiration du jeton sous forme d'horodatage Unix (secondes) |
aclPaths | Enregistrement<chaîne, any> | Non | Restrictions des chemins d'accès ACL |
subject | chaîne de caractères | Non | Sujet du jeton (par exemple, identifiant de l'utilisateur) |
Méthodes d'utilité
vcr.getAppUrl()
Renvoie l'URL publique de l'instance VCR en cours d'exécution. Cela équivaut à lire l'adresse VCR_INSTANCE_PUBLIC_URL variable d'environnement.
const appUrl = vcr.getAppUrl();
// e.g. "https://my-app-dev.use1.runtime.vonage.cloud"
vcr.unsubscribe(id, provider?)
Arrêter de recevoir des rappels d'un abonnement à un fournisseur :
const subId = await voice.onCall('onCall');
// Later, when you want to stop receiving calls:
await vcr.unsubscribe(subId, 'voice');
Structure d'une application typique
Node.js (Express) :
import express from 'express';
import { vcr, Voice, Messages, State } from '@vonage/vcr-sdk';
const app = express();
app.use(express.json());
// Use getGlobalSession() for registering instance-wide subscriptions.
// Do NOT use vcr.createSession() here — it creates a random session that
// cannot be shared across replicas or requests.
const globalSession = vcr.getGlobalSession();
const voice = new Voice(globalSession);
const messages = new Messages(globalSession);
await voice.onCall('onCall');
await messages.onMessage('onMessage',
{ type: 'sms', number: process.env.VONAGE_NUMBER },
{ type: 'sms', number: undefined }
);
app.post('/onCall', async (req, res) => {
// Scope session to the conversation using its unique ID from the callback
const session = vcr.createSessionWithId(req.body.conversation_uuid);
const state = new State(session);
await state.set('status', 'answered');
res.json([{ action: 'talk', text: 'Hello from VCR!' }]);
});
app.post('/onMessage', async (req, res) => {
// Scope session to the sender — deterministic, same across replicas
const session = vcr.createSessionWithId(req.body.from);
const state = new State(session);
await state.set('lastMessage', req.body.text);
res.sendStatus(200);
});
app.get('/_/health', (req, res) => res.sendStatus(200));
// Must bind to 0.0.0.0 — VCR routes traffic via an internal proxy
const port = process.env.VCR_PORT || 8080;
app.listen(port, '0.0.0.0');
Python (FastAPI) :
import os
from fastapi import FastAPI, Request
from vonage_cloud_runtime.vcr import VCR
from vonage_cloud_runtime.providers.voice.voice import Voice
from vonage_cloud_runtime.providers.messages.messages import Messages
from vonage_cloud_runtime.providers.state.state import State
app = FastAPI()
vcr = VCR()
# Use getGlobalSession() for registering instance-wide subscriptions.
# Do NOT use vcr.createSession() here — it creates a random session that
# cannot be shared across replicas or requests.
global_session = vcr.getGlobalSession()
voice = Voice(global_session)
messages = Messages(global_session)
@app.on_event("startup")
async def startup():
await voice.onCall("onCall")
await messages.onMessage("onMessage",
{"type": "sms", "number": os.environ.get("VONAGE_NUMBER")},
{"type": "sms", "number": None}
)
@app.post("/onCall")
async def on_call(request: Request):
body = await request.json()
# Scope session to the conversation using its unique ID from the callback
session = vcr.createSessionWithId(body.get("conversation_uuid"))
state = State(session)
await state.set("status", "answered")
return [{"action": "talk", "text": "Hello from VCR!"}]
@app.post("/onMessage")
async def on_message(request: Request):
body = await request.json()
# Scope session to the sender — deterministic, same across replicas
session = vcr.createSessionWithId(body.get("from"))
state = State(session)
await state.set("lastMessage", body.get("text"))
return {"status": "ok"}
@app.get("/_/health")
async def health():
return {"status": "ok"}
if __name__ == "__main__":
import uvicorn
port = int(os.environ.get("VCR_PORT", 8080))
uvicorn.run(app, host="0.0.0.0", port=port)
Important : Liez toujours votre serveur à 0.0.0.0, pas localhost ou 127.0.0.1. VCR achemine le trafic entrant via un proxy interne et l'application ne sera pas joignable si elle n'écoute que sur l'interface de bouclage.