Overview. EFSwitch Media-Bug Live Transcription converts live call audio to text on the Media Server and posts final transcripts into the Expertflow CX conversation so agents see speech as text during the call. It uses an EFSwitch media-bug module (Azure Speech) and a lightweight ESL relay — without sending call audio through Jambonz or LiveKit.
Define the Feature
This feature runs on the CX Voice Media Server (EFSwitch). When a call is bridged between customer and agent, EFSwitch attaches Azure Speech media-bugs to the call legs. A Python relay listens over ESL, receives final ASR results, and posts them to CCM (/ccm/message/receive) on the existing CX conversation. Agents see caller and agent text in Agent Desk in near real time.
It is the EFSwitch-native alternative to the older Jambonz eavesdrop / /sipRec transcription path documented on Real-Time Transcription.
Objectives
-
Deliver live transcription for CX Voice calls without adding Jambonz to the audio path
-
Keep ASR scaling on EFSwitch + Azure Speech, with a light relay for CX messaging
-
Support inbound, manual outbound, and campaign calls with tenant and call-type controls
-
Work with EFCX when APISIX authentication is enabled (same auth pattern as Voice Connector)
Business benefits
Contact centers get live transcript visibility on Agent Desk with fewer moving parts and lower dependency on Jambonz for transcription. Operations can enable the feature per tenant and call type, and turn APISIX-compatible auth on when the CX gateway requires it — without changing agent workflows.
Intended Audience and Use Cases
-
Primary users: Contact center agents (consume transcripts), supervisors (visibility), RMT / voice engineers (deploy and configure), CX admins (Keycloak / APISIX when auth is on)
-
Key scenarios:
-
Live agent assist / compliance visibility on CX Voice inbound and outbound calls
-
Deployments that want Azure Speech on EFSwitch instead of Jambonz transcription
-
EFCX environments where APISIX OIDC is enabled and CCM requires a Bearer token
-
How it works (high level)
Inputs → processing → outputs
-
Input: Customer and agent are connected (
CHANNEL_BRIDGEon EFSwitch). -
Processing:
mod_azure_transcribestreams audio to Azure Speech (typically two mono sessions per call — caller + agent). The relay (tmb_app_azure.py/tmb-relay-azure) receives finals over ESL, resolves conversation id / service / ANI, and posts PLAIN messages to CCM. -
Output: Final transcript lines appear on the same CX conversation in Agent Desk (caller as CONNECTOR, agent as AGENT).
The relay does not create the CX conversation. Voice Connector already attaches the conversation when the agent is reserved; the relay only appends transcript messages.
For component detail, sequence flows, and APISIX auth internals, see Media-Bug Azure Transcription — Architecture Guide.
Capabilities
Live dual-leg transcription (Azure Speech)
Final speech from caller and agent is transcribed separately (dual_mono) and labeled correctly on Agent Desk.
Call-type and tenant controls
Operators can allow transcription by EFSwitch tenant (TMB_DOMAIN_ALLOWLIST), call kind (inbound / manual outbound / campaign), and optional inbound DID filter (TMB_ALLOWLIST).
Multi-tenant CCM routing
CCM host is resolved as https://{FS domain_name}.{CCM_ROOT_DOMAIN}/ccm, matching CX IVR / Voice Connector tenant FQDN patterns, with CCM_BASE_URL as fallback.
APISIX-compatible CCM auth
When AUTH_ENABLED=true, the relay obtains a token from {tenantFqdn}/unified-admin/keycloakLogin and sends Authorization: Bearer … on CCM calls — same pattern as Voice Connector. Default is false for environments without APISIX.
Safe operate modes
TMB_MODE=observe vs active, plus a kill file (DISABLE.azure) so transcription can be stopped without uninstalling the module.
Getting started
Prerequisites
-
Product requirements: CX Voice Media Server (EFSwitch), Expertflow CX with CCM, Azure Speech resource (key + region or endpoint)
-
Permissions: Root/sudo on Media Server; GitLab access to
rtc/media-bug-for-transcription; Keycloak Expertflow-realm API user with admin and default roles when APISIX is on -
Dependencies: Voice Connector healthy (conversation already exists); EFSwitch ESL locally (
8021); valid API user credentials when APISIX protects CCM
Enabling and configuring
-
Install and build
mod_azure_transcribe, configure.env.azure, and starttmb-relay-azure. -
Set
TMB_MODE=active, tenant/call-type allowlists, Azure credentials, and CCM root/base URL. -
If EFCX APISIX auth is enabled, set
AUTH_ENABLED=true,API_USERNAME, andAPI_PASS, then restart the relay. -
Place a bridged test call; confirm
FINALandCCM okin relay logs and text on Agent Desk.
For detailed setup instructions, see: Set up Azure live call transcription on an EFSwitch server
Compatibility and integrations
-
Environments: On-prem / private cloud Media Server (Debian EFSwitch) with EFCX (single-tenant or multi-tenant); APISIX auth on or off
-
Products: Expertflow CX Voice (EFSwitch + Voice Connector); Azure Speech via
mod_azure_transcribe -
Alternate path: Deepgram (
tmb_app.py/mod_deepgram_transcribe) — do not run Azure and Deepgram relays on the same traffic at once
User interface overview
-
Navigation: Agent Desk → open the active voice conversation during a bridged call
-
Key screen: Conversation view shows live PLAIN transcript messages for customer (CONNECTOR) and agent (AGENT). There is no separate transcription UI.
Security, compliance, and privacy
Data processed
-
Call audio (EFSwitch → Azure Speech)
-
Final transcript text posted to CCM
-
Call metadata for routing (conversation id, service identifier, customer ANI, tenant domain)
Data storage and retention
-
Audio is streamed to Azure Speech for recognition; retention follows Azure and CX conversation policies for the deployment
-
The relay does not persist transcript archives locally (logs may contain short text snippets at INFO)
Access control and auditing
-
Agent Desk access follows CX / Keycloak roles
-
When APISIX is on, relay→CCM uses a dedicated Keycloak API user (
API_USERNAME/API_PASS) -
Relay systemd logs provide operational markers:
BRIDGE,FINAL,AUTH token acquired,CCM ok/ failures
Compliance
Treat transcripts as personal / sensitive conversation data. Apply customer data-residency and retention requirements for Azure region and CX storage. Do not commit Azure keys, ESL passwords, or API passwords to Git.
Supported cases and limitations
|
Case |
Status |
|---|---|
|
Inbound (bridged) |
Supported |
|
Manual outbound (bridged) |
Supported |
|
Campaign outbound (bridged, allowed tenant) |
Supported |
|
Consult / transfer / conference / barge |
Not supported |
|
Voicemail |
Not supported |
|
Unanswered / never-bridged |
Not supported |
-
Transcription starts on bridge, not early media / ringing
-
ASR may mis-hear noise as words; accuracy drops in noisy environments
-
Hold: customer speech may still be transcribed while the agent is on hold
-
dual_monouses two Azure streams per bridged call (plan Azure quota and CPU) -
Do not set
CCM_OUTBOUND_SERVICE_IDENTIFIERto an inbound Branch DN -
Do not run Deepgram and Azure relays on the same live traffic
FAQ
What is this feature?
Live speech-to-text on CX Voice calls using EFSwitch media-bugs and Azure Speech, shown on Agent Desk without Jambonz in the audio path.
How does text get to the agent?
EFSwitch → Azure ASR → ESL finals → relay → CCM /message/receive → Agent Desk conversation.
Who uses it?
Agents see text during calls; engineers enable and operate the Media Server relay; admins supply Keycloak API users when APISIX is on.
What do I need before go-live?
Working CX Voice + Voice Connector, Azure Speech credentials, relay in active mode, and AUTH_ENABLED=true with API credentials if APISIX protects CCM.
Is it secure with APISIX?
Yes, when configured: the relay uses the same Keycloak login + Bearer pattern as Voice Connector. Leave AUTH_ENABLED=false only when APISIX is off.
Transcripts appear in logs but not on the desk — what now?
Confirm CCM status=200, conversation id matches the Agent Desk conversation, and the agent is viewing that same conversation. Check for 401 when APISIX is on and auth is off or credentials are wrong.
Troubleshooting
-
Symptom: No transcript on Agent Desk; relay shows
401/ CCM rejection
Likely cause: APISIX enabled butAUTH_ENABLED=false, or bad API credentials
Resolution: SetAUTH_ENABLED=truewith a valid Keycloak Expertflow user (admin + default); restarttmb-relay-azure; confirmAUTH token acquiredandCCM ok status=200 -
Symptom: No
BRIDGE/ noFINALin logs
Likely cause: Call never bridged, allowlist/gates skipped the call, or module not loaded
Resolution: Confirmmodule_exists mod_azure_transcribe,TMB_MODE=active, domain/call-type gates, and that the call reachedCHANNEL_BRIDGE -
Symptom:
CCM okbut wrong / empty conversation on desk
Likely cause: Wrong conversation id or service identifier mapping
Resolution: CheckCCM_ROUTElog line; fix dialplan/VC headers; never invent outbound SI from inbound allowlist -
Symptom: High CPU / Azure throttling under load
Likely cause: Two streams per call × concurrency above quota
Resolution: LowerTMB_MAX_CONCURRENT; size Azure Speech concurrency; load-test before production
Related resources
-
Set up Azure live call transcription on an EFSwitch server — install / build / configure
-
Media-Bug Azure Transcription — Architecture Guide — Architecture Guide
-
Real-Time Transcription — Jambonz eavesdrop path (for comparison)
-
Voice Connector Deployment Guide —
AUTH_ENABLEDpattern reference -
CX Voice with APISIX Auth: Required NodePort Exposure for EFCX Services
-
GitLab: rtc/media-bug-for-transcription
-
Related work: CCC-2329 (media-bug implementation), CCC-2331 (APISIX transcription)