SDK-Übersicht
Das Vonage Cloud Runtime SDK ist die primäre Schnittstelle zu allen Plattformanbietern. Es ist für Node.js und Python verfügbar.
| Laufzeit | Paket | Minimale Version | Letzte Version | Anmerkungen |
|---|---|---|---|---|
| Node.js | @vonage/vcr-sdk | 2.0.0 | 2.1.5 | SDK >=2.1.0 erfordert Node.js 22 (Active LTS) |
| Python | vonage_cloud_runtime | 2.0.0 | 2.1.5 |
Die vcr Singleton
Das SDK exportiert eine vcr Singleton, das der Einstiegspunkt für alle Operationen ist.
Node.js:
import { vcr } from '@vonage/vcr-sdk';
Python:
from vonage_cloud_runtime.vcr import VCR
vcr = VCR()
Die vcr Objekt bietet die folgenden Methoden:
| Methode | Beschreibung |
|---|---|
vcr.createSession(ttl?) | Erstellen einer neuen Sitzung mit optionaler TTL in Sekunden (Standard: 7 Tage) |
vcr.createSessionWithId(id) | Erstellen einer Sitzung mit einer bestimmten ID |
vcr.getSessionById(id) | Eine bestehende Sitzung nach ID abrufen |
vcr.getSessionFromRequest(req) | Extrahieren der Sitzung aus einer eingehenden HTTP-Anfrage |
vcr.getGlobalSession() | Abrufen der globalen Sitzung (gemeinsam für alle Anfragen) |
vcr.getInstanceState() | Abrufen des Zustands auf Instanzebene (gemeinsam für alle Sitzungen innerhalb der Instanz) |
vcr.getAccountState() | Status auf Account-Ebene abrufen (gemeinsam für alle Applications im Account) |
vcr.getAppUrl() | Abrufen der öffentlichen URL der laufenden Anwendung |
vcr.createVonageToken(params) | Erstellen Sie ein signiertes JWT für die Vonage API-Authentifizierung |
vcr.verifyAuth(token) | Verify eines Authentifizierungstokens |
vcr.unsubscribe(id, provider?) | Abmeldung von einem Anbieter-Abonnement |
Sitzungen
Sitzungen sind erforderlich, um einen Anbieter zu initialisieren. Jeder Anbieterkonstruktor nimmt eine Sitzung als erstes Argument an.
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()
Eigenschaften und Methoden der Sitzung:
| Beschreibung | |
|---|---|
session.id | Der eindeutige Bezeichner der Sitzung |
session.getToken() | Abrufen des Authentifizierungs-Tokens der Sitzung |
session.createUUID() | Eine neue UUID generieren |
session.log(level, message, context?) | Protokollieren einer Nachricht mit strukturiertem Kontext |
Sitzungs-Scoping - Kritischer Leitfaden
Warnung: vcr.createSession() erzeugt eine zufällig, kurzlebig Sitzungs-ID jedes Mal, wenn sie aufgerufen wird. Die unter dieser Sitzung gespeicherten Daten (über new State(session)) ist nur zugänglich, wenn Sie genau diese Sitzungs-ID haben. Wenn Sie vcr.createSession() auf globaler/Modul-Ebene und verwenden sie mit State, jede Replik erstellt eine andere Sitzungund die Daten werden isoliert und sind für andere Replikate oder Anfragen unerreichbar. Dies bricht die zustandslose Architektur.
Regeln:
- Niemals aufrufen
vcr.createSession()im globalen Anwendungsbereich, um State oder andere Provider zu initialisieren, die gemeinsamen Datenzugriff benötigen. - Für gemeinsame Zustände zwischen Replikatenverwenden
vcr.getInstanceState()(odervcr.getAccountState()für app-übergreifende Daten). - Für den Status pro Anfrage oder pro Gesprächverwenden
vcr.createSessionWithId(id)mit einer deterministisch ID aus dem Anfragekontext - wie z. B.conversation_uuidaus einem Sprachrückruf, eine Absendertelefonnummer aus einem SMS-Rückruf oder eine Benutzer-ID. Dadurch wird sichergestellt, dass dieselbe Sitzung über Replikate und Anfragen hinweg abrufbar ist. vcr.getGlobalSession()ist für die Registrierung von instanzweiten Abonnements vorgesehen (z.B.,voice.onCall(),messages.onMessage()). Es sollte nicht als Allzwecksitzung für den Staat verwendet werden.
// 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');
});
Siehe Zustandslose Architektur für eine ausführliche Anleitung.
Initialisierung des Anbieters
Alle Anbieter folgen demselben Muster: Sie übergeben dem Konstruktor eine Sitzung.
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)
Staatliches Scoping
VCR bietet drei Stufen des Status:
| Umfang | Wie man Zugang erhält | Sichtbarkeit |
|---|---|---|
| Zustand der Sitzung | new State(session) | Isoliert auf die spezifische Sitzung |
| Zustand der Instanz | vcr.getInstanceState() | Gemeinsame Nutzung durch alle Sitzungen innerhalb derselben Instanz |
| Account-Status | vcr.getAccountState() | Gemeinsame Nutzung durch alle Applikationen im Vonage Account |
// 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();
Siehe Zustandslose Architektur für Hinweise, wann die einzelnen Bereiche zu verwenden sind.
Authentifizierung
Eingehende Anfragen verifizieren
Verwenden Sie vcr.verifyAuth(token) um Token bei eingehenden Anfragen zu validieren:
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' });
}
});
Vonage-Tokens erstellen
Verwenden Sie vcr.createVonageToken(params) um signierte JWTs für die Vonage API-Authentifizierung zu erzeugen:
const token = vcr.createVonageToken({
exp: Math.floor(Date.now() / 1000) + 3600, // 1-hour expiry
aclPaths: { '/*/users/**': {} }, // optional ACL paths
subject: 'user-123', // optional subject
});
| Parameter | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
exp | Number | Ja | Token-Ablauf als Unix-Zeitstempel (Sekunden) |
aclPaths | Datensatz<Zeichenfolge, beliebig> | Nein | ACL-Pfadbeschränkungen |
subject | String | Nein | Token-Subjekt (z. B. Benutzerkennzeichen) |
Utility-Methoden
vcr.getAppUrl()
Gibt die öffentliche URL der laufenden VCR-Instanz zurück. Äquivalent zum Lesen der VCR_INSTANCE_PUBLIC_URL Umgebungsvariable.
const appUrl = vcr.getAppUrl();
// e.g. "https://my-app-dev.use1.runtime.vonage.cloud"
vcr.unsubscribe(id, provider?)
Beenden Sie den Empfang von Rückrufen von einem Anbieterabonnement:
const subId = await voice.onCall('onCall');
// Later, when you want to stop receiving calls:
await vcr.unsubscribe(subId, 'voice');
Typische Struktur der Applications
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)
Das ist wichtig: Binden Sie Ihren Server immer an 0.0.0.0, nicht localhost oder 127.0.0.1. VCR leitet den eingehenden Verkehr über einen internen Proxy, und die Anwendung ist nicht erreichbar, wenn sie nur auf der Loopback-Schnittstelle lauscht.