Skip to main content
Vobiz Calling for Salesforce puts a Vobiz softphone inside Salesforce Lightning. Your agents make and take real phone calls in the browser, from a panel in the Salesforce utility bar. Phone numbers across Salesforce become click-to-dial, the matching record opens when a call starts, and every finished call is logged as a completed Task. It is built on Salesforce Open CTI, so there is no package to install and no AppExchange review. You run a small calling backend, included in the repository, and Salesforce frames the panel it serves.

Source code

vobiz-ai/Vobiz-Salesforce-Calling — the panel, the calling backend and the Call Center definition.

SIP Endpoints

The endpoints the panel registers as.

What you get

How it works

  • Salesforce frames a page you host. A Call Center record holds the panel’s URL; the panel uses Open CTI to make numbers clickable, open records and write Tasks.
  • Your backend serves the panel and talks to Vobiz. The panel never calls the Vobiz API itself. The backend calls the Vobiz REST API and answers Vobiz’s webhooks.
  • Audio goes straight between the browser and Vobiz. The panel registers as a Vobiz SIP endpoint over a secure WebSocket. Call audio never passes through your backend.
  • Outbound: the browser places the call, Vobiz asks your backend what to do, and the backend puts the agent in a conference room and dials the destination into it.
  • Inbound: the backend holds the caller in a conference room with hold audio and the panel rings. When the agent accepts, the panel joins that room.
Because each call is a conference with two legs, each call produces two Vobiz call records (CDRs), one per leg, with matching durations.

Prerequisites

Set it up

1

Get the code and configure the backend

In backend/.env, set PUBLIC_BASE_URL to the backend’s public HTTPS address, with no trailing slash:
No Vobiz credentials go here. Agents sign in from the panel.
2

Start it and expose it over HTTPS

Put it behind HTTPS at PUBLIC_BASE_URL, then check it from outside your network:
For a quick trial on your own machine, cloudflared tunnel --url http://localhost:8080 gives you a public HTTPS address. Use a tunnel that does not show a browser warning page — Salesforce cannot display one inside its frame.
3

Trust the backend in Salesforce

Setup → Trusted URLs → New Trusted URL:
  • URL: your backend’s origin, e.g. https://calling.example.com
  • CSP Context: All
  • CSP Directives: tick frame-src and connect-src
  • Permissions Policy Directives: tick microphone
If microphone is greyed out, go to Setup → Session Settings → Browser Feature Permissions, set Microphone to Trusted URLs Only, save, and come back.
Without frame-src, the phone panel is a blank box. Without the microphone permission, calls connect with no audio.
4

Import the Call Center

Setup → Call Centers → Import, and choose call-center/call-center-definition.xml from the repository. Open the imported Vobiz Calling record, click Edit, and set CTI Adapter URL to:
Use your own backend host, your own My Domain URL, and an agentId for this agent (letters, digits, - or _, up to 40 characters). Type a plain & here; the & in the XML file is only XML escaping.
5

Assign the agent

On the Call Center record, click Manage Call Center Users → Add More Users, select the agent, and click Add to Call Center.
6

Add the Open CTI Softphone utility item

Setup → App Manager → your Lightning app (for example Service Console) → Edit → Utility Items (Desktop Only) → Add Utility Item → Open CTI Softphone. Set the height to at least 600 and the width to 400, then save.
7

Hard-refresh and open the phone

Open the app and hard-refresh with Ctrl+Shift+R (Cmd+Shift+R on a Mac). Salesforce caches the adapter URL, so a normal refresh keeps the old one. Click Phone in the utility bar and sign in.

Several agents

Salesforce stores one adapter URL per Call Center, so create one Call Center per agent. For each extra agent, copy call-center-definition.xml, change its InternalName, Display Name and the agentId in the adapter URL, import the copy, and assign that agent to it.
Every agent on the same Vobiz account needs a different agentId. The agentId decides which SIP endpoint an agent gets, so two agents sharing one would take each other’s calls. Agents on different Vobiz accounts can reuse a value.

Sign in

The panel has two tabs. Any Vobiz account works with either, and agents on different Vobiz accounts can share one backend.
Salesforce Service Console with the Phone utility panel open, showing Sign in to Vobiz with Vobiz account and SIP direct tabs, an Auth ID field, a masked Auth Token, and a Log in button

The panel in the Salesforce utility bar, on the Vobiz account tab.

Choose a caller ID

On the Vobiz account tab, Calling from lists every active, voice-enabled number on the account, with the application each is on now. The first is selected; pick another at any time. The backend refuses any number that is not on the account.
The panel with the Calling from field expanded into a dropdown of account numbers above a Record this call checkbox

Selecting the outbound caller ID.

What SIP direct does differently

  • Outbound works as with an account sign-in: click-to-dial, screen pop, recording and the call Task.
  • Inbound calls to the Calling from number ring the panel directly. The caller’s record opens while it rings and the call is logged as a Task — answered, missed or declined. To record these calls and send them to voicemail, use a Vobiz account sign-in.
  • The Calling from dropdown and Enable inbound calls come with a Vobiz account sign-in; the panel says Sign in with your Vobiz account to use this.

Enable inbound calls

On the Vobiz account tab, click Enable inbound calls once, under Receive calls here. The backend:
  1. finds or creates an application named VobizSF_in with answer URL https://calling.example.com/inbound-answer, and
  2. attaches the number selected in Calling from to it.
This moves the number off the application it is on now, so whatever that number was routed to stops receiving its calls. The dropdown shows the number’s current application, and the panel names the application it was moved off. This button is the only thing in the integration that changes a number’s routing. To undo it, attach the number to its previous application in the Vobiz Console.
The Receive calls here section with an Enable inbound calls button and a line confirming that inbound calls to the account number now ring this panel

Inbound enabled — the panel names the number now routed to it.

To route several numbers, select each in Calling from and click Enable inbound calls for each.

Using it

Make a call

Wait for the status badge to turn green — the Call button stays disabled until the panel is signed in and registered. Type a number in E.164 format and click Call, or click any phone number in Salesforce. The first call asks for microphone permission; allow it.
The Place a call step showing a destination in the Number to call field, a ticked Record this call checkbox, and a Call button

A destination entered, with recording armed.

If the other side is busy or rejects the call, it ends straight away. If nobody answers, it ends after 45 seconds (OUTBOUND_RING_SECONDS).

Receive a call

A call to an enabled number rings every open panel signed in to that Vobiz account, while the caller hears Please hold while we connect you. The panel plays a ringtone, shows the caller’s number and opens their record.
  • Accept (or Enter) connects you. The first agent to accept takes the call.
  • Decline (or Esc) sends the caller to voicemail.
  • Unanswered after 45 seconds (INBOUND_RING_SECONDS), the caller goes to voicemail.
The panel showing a green READY badge and an incoming-call card with the caller number, Accept and Decline buttons, and the hint Enter to accept, Escape to decline

An incoming call, with keyboard shortcuts.

The caller goes straight to voicemail when no panel on the account is listening — the Salesforce tab is closed, or every agent is on a call or already ringing. If nobody from the account has signed in since the backend started, the caller hears Sorry, this number cannot take calls right now.
Keep one Salesforce tab with the panel open. Several tabs register the same phone line and replace each other.

Call logging

When a call ends, the panel writes a completed Task, which appears in the record’s Activity History: Screen pop. A click-to-dial uses the record you clicked. A typed number, and an inbound caller’s number, are searched when the call starts: one match opens automatically, several leave Salesforce’s search results for you to choose, and no match logs the Task without a related record. A Salesforce error never interrupts a call.

Recordings

Tick Record this call before you click Call — or before Accept for an inbound call; recording starts when you join, so hold time is not included. Recorded calls are billed by Vobiz.
Recordings and voicemail messages are stored in your Vobiz account. Play or download them in Vobiz Console → Voice → Recordings. The panel and the backend do not list or serve recordings.

Configuration

Backend environment variables

Set in backend/.env or the environment. There are no Vobiz credentials in the backend’s configuration.

CTI Adapter URL parameters

Running it in production

  • HTTPS on a stable hostname. If the hostname changes, update PUBLIC_BASE_URL, every adapter URL and the Trusted URL, and have agents sign in again.
  • Run one instance. Sessions and calls in progress live in one process’s memory.
  • Keep DATA_DIR on persistent storage, and private.
  • Set REQUIRE_VOBIZ_SIGNATURE=true once you have confirmed your account signs webhooks.
  • Keep the process running with a service manager; GET /healthz returns {"ok":true}.
  • Scope the Trusted URL to your exact backend origin, not a wildcard.

Security and privacy

  • Your Auth Token never reaches the browser and is never stored on disk. The backend keeps it in memory only and never logs it.
  • On disk, the backend keeps only endpoints.json: endpoint ids and SIP usernames per agent — no passwords, tokens or call data.
  • The browser receives the agent’s SIP username, a SIP password that changes on every sign-in, the account’s numbers, and an HttpOnly session cookie. The SIP password goes only to the Vobiz registrar.
  • The browser stores nothing on the Vobiz account tab. On SIP direct, only if the agent ticks Remember these: that endpoint’s username, password and caller ID, in local storage.
  • Cross-site requests are refused. The backend accepts panel requests only as JSON from its own origin and sends no CORS headers.
  • Only an agent’s own line can spend their account, and only Salesforce can frame the panel.
  • Webhook signatures are verified with the owning account’s Auth Token when present; a bad signature is refused.
  • No recording links. Recordings are played in the Vobiz Console only.

Troubleshooting

The backend’s origin is not a Trusted URL with frame-src ticked, or the adapter URL is plain HTTP. If you use a tunnel, make sure it does not show a browser warning page.
Assign the user with Manage Call Center Users, and add Open CTI Softphone to the app in App Manager.
Salesforce caches it. Hard-refresh with Ctrl+Shift+R.
The adapter URL is missing org (or it is not a Salesforce host), or missing agentId.
The backend is down, or the panel is not served by the backend. Check https://calling.example.com/healthz, and load the panel from https://calling.example.com/salesforce/softphone.html — it only talks to the address it was loaded from.
Copy both again from Console → API credentials. The Auth Token is not your login password.
The hint under the button says what is missing: sign-in, registration, or — if the panel says the account has no phone numbers yet — an active, voice-enabled number on the account.
The backend restarted or the session expired (SESSION_HOURS). Sign in again.
Salesforce is blocking the microphone. Tick microphone on the Trusted URL; if it is greyed out, set Session Settings → Browser Feature Permissions → Microphone to Trusted URLs Only first. Then check the browser’s site settings.
No panel on that account was listening. Keep the Salesforce tab with the panel open and signed in; an agent already on a call is not rung.
Nobody from that account has signed in since the backend started, or (SIP direct) no agent is signed in with that number as Calling from.
The number is not attached to the integration’s application. Click Enable inbound calls, or for SIP direct attach the number to your application.
The endpoint is not attached to an application whose answer URL is https://calling.example.com/answer, or Calling from is not a number on that account.
PUBLIC_BASE_URL does not match the address Vobiz was given. Set it exactly, restart, and sign in again.

Operating notes

  • Sign in again after the backend restarts, and run one backend instance — sessions are held in memory.
  • Each call has two CDRs, one per leg.
  • Use one agent per Call Center, and one Salesforce tab per agent.
  • Each agent takes one inbound call at a time. Other callers go to voicemail.
  • Agents call from the browser.
  • Calls are logged as Tasks.
  • Recordings and voicemails are in the Vobiz Console.
  • A Vobiz account sign-in gives you the caller ID dropdown, Enable inbound calls, and recording and voicemail for inbound calls.
  • Serve the panel from the backend. It talks to the address it was loaded from.

Next steps