In Open CTI, custom UI lived inside the adapter iframe and pushed data to the page via opencti.* calls or window.postMessage. In Salesforce Voice with Partner Telephony, four dedicated mechanisms replace this: Voice Extensions, Voice Toolkit, LMS bridge, and custom Lightning events.
Voice Extensions: Before, During, and After Call UI
A Voice Extension is a Lightning page (FlexiPage of type VoiceExtension) that Salesforce renders inside the softphone panel alongside the standard call controls. It is visible pre-call (when the rep is signed in but not on a call), during the call, and during ACW (post-call). Use it for custom IVR data display, call notes, knowledge prompts, after-call disposition forms, anything the rep needs at any phase of the call lifecycle.
Voice Extensions are assigned to a Contact Center. See Customize Call Controls and Voice Extensions.
The LWC must declare in .js-meta.xml:
- Target:
lightning__VoiceExtension - Capability:
lightning__ServiceCloudVoiceToolkitApi
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>57.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__VoiceExtension</target>
</targets>
<capabilities>
<capability>lightning__ServiceCloudVoiceToolkitApi</capability>
</capabilities>
</LightningComponentBundle>
Voice Toolkit
The Voice Toolkit, the lightning-service-cloud-voice-toolkit-api base component, gives a Voice Extension LWC access to live telephony events. It's a Lightning base component that you embed in the template and query via this.template.querySelector('lightning-service-cloud-voice-toolkit-api').
The Voice Extension FlexiPage is the primary context, but the Voice Toolkit API can also be invoked from components on a record page when the host page has access to the Salesforce Voice with Partner Telephony capability and the rep is signed into Omni-Channel.
LMS Bridge
Once a Voice Extension has call data from the toolkit, it relays to LWCs anywhere on the page via LMS. Salesforce ships a standard channel: ServiceCloudVoiceMessageChannel__c.
The pattern:
- Voice Extension publishes with
source: 'CONNECTOR' - Subscribers use
APPLICATION_SCOPEand filter out their own messages
import { publish, subscribe, APPLICATION_SCOPE, MessageContext } from "lightning/messageService";
import SAMPLEMC from "@salesforce/messageChannel/ServiceCloudVoiceMessageChannel__c";
export default class LwcBridge extends LightningElement {
@wire(MessageContext) messageContext;
@api handleMessage;
connectedCallback() {
subscribe(
this.messageContext,
SAMPLEMC,
(message) => {
if (message.source !== "CONNECTOR") {
this.handleMessage(message.payload);
}
},
{ scope: APPLICATION_SCOPE },
);
}
}
Custom Lightning Events
To learn more about custom Lightning events, see Communicate with Events.
When to Use Each Tool
| Tool | Use When |
|---|---|
| Voice Extension | Building any custom UI in the softphone panel area |
Voice Toolkit (lightning-service-cloud-voice-toolkit-api) |
Voice Extension LWC (or record-page LWC) needs live call events from the connector |
LMS (ServiceCloudVoiceMessageChannel__c or custom) |
Relaying call data from Voice Extension to record page LWCs |
| Custom Lightning Events | Parent-child or sibling communication within the same Voice Extension region |