# Migrate Custom UI Integration: Voice Extensions, Voice Toolkit, LMS Bridge

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](https://help.salesforce.com/s/articleView?id=service.voice_pt_setup_extensions.htm\&type=5).

The LWC must declare in `.js-meta.xml`:

- Target: `lightning__VoiceExtension`
- Capability: `lightning__ServiceCloudVoiceToolkitApi`

```sfdocs-code {"lang":"xml"}
<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_SCOPE` and filter out their own messages

```sfdocs-code {"lang":"javascript"}
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](https://developer.salesforce.com/docs/platform/lwc/guide/events.md).

## 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       |

## See Also

- [Voice Toolkit API — Component Reference](https://developer.salesforce.com/docs/component-library/bundle/lightning-service-cloud-voice-toolkit-api/documentation)
- [VoiceCall Object Reference](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_voicecall.htm)
- [Omni Toolkit API — Component Reference](https://developer.salesforce.com/docs/component-library/bundle/lightning-omni-toolkit/documentation)
