EFSwitch Media-Bug Live Transcription: Real-Time Call Text on Agent Desk Without Jambonz

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

  1. Input: Customer and agent are connected (CHANNEL_BRIDGE on EFSwitch).

  2. Processing: mod_azure_transcribe streams 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.

  3. 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

  1. Install and build mod_azure_transcribe, configure .env.azure, and start tmb-relay-azure.

  2. Set TMB_MODE=active, tenant/call-type allowlists, Azure credentials, and CCM root/base URL.

  3. If EFCX APISIX auth is enabled, set AUTH_ENABLED=true, API_USERNAME, and API_PASS, then restart the relay.

  4. Place a bridged test call; confirm FINAL and CCM ok in 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_mono uses two Azure streams per bridged call (plan Azure quota and CPU)

  • Do not set CCM_OUTBOUND_SERVICE_IDENTIFIER to 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 but AUTH_ENABLED=false, or bad API credentials
    Resolution: Set AUTH_ENABLED=true with a valid Keycloak Expertflow user (admin + default); restart tmb-relay-azure; confirm AUTH token acquired and CCM ok status=200

  • Symptom: No BRIDGE / no FINAL in logs
    Likely cause: Call never bridged, allowlist/gates skipped the call, or module not loaded
    Resolution: Confirm module_exists mod_azure_transcribe, TMB_MODE=active, domain/call-type gates, and that the call reached CHANNEL_BRIDGE

  • Symptom: CCM ok but wrong / empty conversation on desk
    Likely cause: Wrong conversation id or service identifier mapping
    Resolution: Check CCM_ROUTE log 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: Lower TMB_MAX_CONCURRENT; size Azure Speech concurrency; load-test before production