Tempo reale
Stato del centralino in tempo reale: chiamate in corso, interni e telefoni collegati, linee, code, parcheggio e stato del servizio. Disponibile con richieste REST (fotografia dello stato) ed eventi SSE o WebSocket (aggiornamenti). Scope live:read.
Fotografia dello stato
curl -s https://centralino.exovoip.it/api/v1/live/snapshot -H "X-API-Key: $EXOPBX_API_KEY"
curl -s https://centralino.exovoip.it/api/v1/live/extensions -H "X-API-Key: $EXOPBX_API_KEY"const snap = await pbx.live.snapshot();
console.log(`${snap.channels.length} chiamate in corso`);
const { extensions } = await pbx.live.extensions();
const offline = extensions.filter((e) => e.availability === 'offline');$snap = $pbx->live->snapshot();
$extensions = $pbx->live->extensions()['extensions'];snap = pbx.live.snapshot()
extensions = pbx.live.extensions()["extensions"]
offline = [e for e in extensions if e["availability"] == "offline"]| Endpoint | Contenuto |
|---|---|
GET /v1/live/snapshot | Tutto in una chiamata: chiamate, interni, linee, code, parcheggio, salute |
GET /v1/live/channels | Chiamate in corso |
GET /v1/live/extensions | Interni: stato, registrazione, disponibilità, "non disturbare", dispositivi |
GET /v1/live/devices | Un elemento per telefono registrato (IP, user agent, latenza, raggiungibilità) |
GET /v1/live/trunks | Linee: registrazione, raggiungibilità, chiamate attive |
GET /v1/live/queues | Code: chiamanti in attesa, attesa massima, operatori |
GET /v1/live/health | Stato del servizio: operational, degraded, outage |
Disponibilità di un interno (availability): available, ringing, busy, on_hold, dnd, unreachable (registrato ma non risponde), offline (nessun telefono registrato).
Eventi (SSE)
GET /v1/live/events mantiene aperta la connessione e invia un evento per ogni cambiamento. Alla connessione arriva uno snapshot completo, poi solo le variazioni; ogni 15 secondi un heartbeat. Con ?types= si ricevono solo i tipi indicati (snapshot e heartbeat arrivano sempre).
# -N disattiva il buffer: gli eventi arrivano appena accadono
curl -N "https://centralino.exovoip.it/api/v1/live/events?types=channel.update,channel.hangup,calendar.override" \
-H "X-API-Key: $EXOPBX_API_KEY"const live = pbx.live.stream({ types: ['channel.update', 'channel.hangup', 'calendar.override'] });
live.on('snapshot', (s) => console.log('stato iniziale', s.channels.length));
live.on('channel.update', (e) => console.log(e.channel.callerNumber, e.channel.state));
live.on('calendar.override', (e) => console.log(e.name, e.forceState, e.state));
// oppure: for await (const event of live) { ... }
// live.close() per chiudere$pbx->live->stream(function (array $event): bool {
if ($event['type'] === 'channel.update') {
echo $event['channel']['callerNumber'] ?? '-', ' ', $event['channel']['state'], PHP_EOL;
}
return true; // false per fermarsi
}, ['channel.update', 'channel.hangup', 'calendar.override']);for event in pbx.live.stream(types=["channel.update", "channel.hangup", "calendar.override"]):
if event["type"] == "channel.update":
print(event["channel"]["callerNumber"], event["channel"]["state"])Gli SDK si riconnettono automaticamente con attese crescenti e, dopo ogni riconnessione, ricevono un nuovo snapshot: usalo come stato di riferimento invece di accumulare le variazioni. Una chiave non valida o senza permessi interrompe il flusso senza nuovi tentativi.
Eventi (WebSocket)
GET /v1/live/ws invia gli stessi eventi, uno per messaggio JSON. L'SSE resta il canale consigliato; il WebSocket è utile negli ambienti che lo preferiscono.
# WebSocket: stessi eventi dell'SSE, un evento JSON per messaggio
websocat -H "X-API-Key: $EXOPBX_API_KEY" "wss://centralino.exovoip.it/api/v1/live/ws?types=extension.state"// Node 22+ (WebSocket globale) o browser; in Node 18/20 passare il costruttore del pacchetto ws
const ws = pbx.live.websocket({ types: ['extension.state'] });
ws.on('extension.state', (e) => console.log(e.number, e.state));Nel browser i WebSocket e EventSource non possono inviare header: funzionano con la sessione del pannello. Le chiavi API vanno usate solo lato server.
Tipi di evento
| Tipo | Quando |
|---|---|
snapshot | Connessione o riallineamento |
channel.update | Nuova chiamata, cambio di stato, risposta, attesa, registrazione, collegamento |
channel.hangup | Fine di una chiamata (causa, durata) |
extension.state | Qualsiasi cambio di stato di un interno |
extension.registration | Primo telefono registrato / ultimo scollegato |
extension.contact | Telefono aggiunto, rimosso, raggiungibile o non raggiungibile |
trunk.state | Registrazione, raggiungibilità o chiamate attive di una linea |
queue.caller.join / queue.caller.leave | Chiamante entra / esce dalla coda (risposto, abbandonato, uscito) |
queue.member | Stato o pausa di un operatore |
parking.update | Chiamata parcheggiata, ripresa, scaduta o abbandonata |
calendar.override | Forzatura degli orari (pannello, API, telefono, scadenza) |
system.status | Cambio dello stato del servizio |
heartbeat | Ogni 15 secondi |
Solo per la piattaforma: system.asterisk, system.service, system.reload.
Esempio di evento:
{
"type": "calendar.override",
"tenantId": 3,
"calendarId": 4,
"name": "Ufficio",
"forceState": "closed",
"forceUntil": "2026-11-04T12:00:00.000Z",
"previousForceState": "auto",
"state": "closed"
}Lo schema completo di ogni evento (campi e valori) è nel riferimento Swagger, alla voce GET /v1/live/events.
Vista globale
Per una chiave globale senza X-Tenant-Id (o ?tenantId=) gli eventi e le fotografie riguardano tutte le aziende; ogni oggetto riporta il tenantId.
Endpoint
| Descrizione | Richiesta | Scope | Metodo SDK |
|---|---|---|---|
| Fotografia completa in tempo reale (chiamate, interni, linee, code, parcheggio, stato servizio) | GET /v1/live/snapshot | live:read | live.snapshot() |
| Chiamate in corso | GET /v1/live/channels | live:read | live.channels() |
| Stato interni (registrazione, disponibilità, dispositivi) | GET /v1/live/extensions | live:read | live.extensions() |
| Dispositivi registrati (IP, porta, trasporto, latenza, raggiungibilità) | GET /v1/live/devices | live:read | live.devices() |
| Stato linee (registrazione, raggiungibilità, chiamate attive) | GET /v1/live/trunks | live:read | live.trunks() |
| Code: chiamanti in attesa e stato operatori | GET /v1/live/queues | live:read | live.queues() |
| Stato del servizio (dettaglio tecnico solo piattaforma) | GET /v1/live/health | live:read | live.health() |
| Eventi in tempo reale (SSE), filtrabili con ?types= | GET /v1/live/events | live:read | live.stream() |
| Eventi in tempo reale (WebSocket), filtrabili con ?types= | GET /v1/live/ws | live:read | live.websocket() (TS) |
