Control only (no audio)
Pass mediaFactory: null to skip the WebRTC leg entirely. The client still opens the control stream, mirrors
AgentView, and accepts every non-audio intent — it just never negotiates audio. This is the right mode
whenever audio is handled elsewhere (or not at all):
:::caution null, not omitted
It must be explicitly null. Omitting mediaFactory defaults to the browser audio leg
(browserMediaFactory) — so leaving it out does not give you a control-only client.
:::
import { BabelconnectClient } from "@babelforce/babelconnect-sdk";
const bc = BabelconnectClient.connect({ serverUrl, token, mediaFactory: null });
bc.subscribe(render); // render(AgentView) on every update
bc.sendSms("+49301234567", "On my way!");
bc.setPresence("available");
This runs in Node 20+ as well as the browser, with no WebRTC dependency.
:::caution Reachability: register() still marks the agent WebRTC-reachable
register() does two jobs — it loads the agent's reference data (presence options, caller-ID numbers,
contacts, feature config) and marks the agent WebRTC-reachable on the backend so its call leg routes
to this client. A control-only client has no media leg to carry that audio, so a call ringing here can't
be answered — it rings at a client that can't carry audio and fails on answer. If this agent takes live calls,
a call-taking control-only client must pair register() with setWebrtc(false) + setAgentNumber(...)
(see below) to bridge calls to an external phone instead. If the agent never takes calls here — a pure
wallboard, or an outbound-only automation whose audio lives elsewhere — you can leave it; no audio leg simply
means no audio.
:::
When to use it
- Supervisor / wallboard dashboards — subscribe to
AgentViewand render live call, presence, and queue state without ever touching audio. - Back-end services — a Node process that reacts to state (logging, analytics, automations) or drives intents (place calls, send SMS) on behalf of agents.
- CLI / tooling — scripts that fetch history or contacts, set presence, or send SMS.
- Bring-your-own audio — the call's audio is handled by a separate device or stack, and this client only drives control + state.
What works without audio
Everything except answering a call with in-browser audio:
- ✅ Observe all state — calls, presence, SMS, conferences, wrap-up, config — via
subscribe. - ✅ Non-audio intents —
setPresence,transfer,hangup,sendSms,markConversationRead, recording controls, conference management, etc. - ✅ Unary fetches — history, SMS threads, contacts.
- ⚠️ Audio answering — there's no media leg, so this client won't produce mic/speaker audio for a call. It
still sees the ringing call in
AgentView; it just can't carry the audio itself. - ⚠️ Placing calls still works as an intent, but the agent's own audio has to live elsewhere — turn WebRTC
off (
setWebrtc(false)) so the backend bridges the call to the agent's externalsetAgentNumber.
The omission is silent by design: a control-only client simply doesn't act on the WebRTC offer. If you need
audio, supply a mediaFactory (the browser default, or your own Media implementation) instead of null.
See ConnectOptions for the full set of connect options,
State & events for what the subscribe callback delivers, and the
Intents reference for everything you can send. Doing the same from a Go service? See
Back-end automation (no audio).