---
schema_version: "1"
id: b88b2c53239d27a08df913fdb69006572772393c70097cdf6ffa888a6e2b1953
title: Build Your Connector
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/service-cloud/api-cti/guides/build-connector.md
canonical_url: https://developer.salesforce.com/docs/service/api-cti/guide/build-connector.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 9af26a8e59cfd03f07eb0e5f0e692b28da8b1a1bbb2ff9ed84a06f188367857b
products:
  - Open CTI Developer Guide
  - Service Cloud Developer Content
---

# Build Your Connector

Starting from the demo connector, replace Open CTI adapter logic with Salesforce Voice with Partner Telephony connector methods and events.

## Start From the Demo Connector

In the cloned demo connector location, open `src/main/connector.js`. This file already has `VendorConnector` and `TelephonyConnector` fully scaffolded. Your migration task is to replace the mock backend calls in each method with calls to your real telephony system.

| Direction                       | What It Means                                                                                                                                                                                                | Examples                                                           |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ |
| Your connector calls Salesforce | Your connector publishes an event; Salesforce reacts.                                                                                                                                                        | `publishEvent(CALL_STARTED)`, `publishEvent(HANGUP)`               |
| Salesforce calls your connector | Your connector implements a method and returns a promise; Salesforce invokes it when an in-org event occurs. Return a promise with the result; do not call `publishEvent()` yourself from inside the method. | `acceptCall()`, `endCall()`, `setAgentStatus()`, `superviseCall()` |

## Use AI Assistants to Accelerate the Rewrite

After cloning the demo connector, consider using AI coding assistants for the mechanical translation of your Open CTI adapter logic into Salesforce Voice with Partner Telephony connector methods. Because patterns are systematic and each `opencti.*` call maps to a specific connector method or event, AI agents are helpful for this migration.

Although you can use an AI assistant for certain straightforward tasks, such as translating `opencti` calls to connector methods, writing unit tests, or generating SOQL for reporting, other tasks require manual insight. Make sure that you check or implement these items yourself:

- Whether to use `enqueueNextState` correctly. The timing is subtle.
- Multiparty event sequencing: AI can generate the call paths, but you should validate each pattern (blind transfer, warm transfer, consult, add caller) manually.
- Deciding which custom fields belong on VoiceCall vs. a child object: This is a domain decision, not a coding decision.
- Final Flow construction: The AI gives you the spec; Flow Builder is where you implement.
- Auth / SSO into your backend: This should be reviewed by a human; AI-generated auth code is a common source of security issues.

Here are sample prompts to start migrating your adapter.

1. Feed the assistant your Open CTI adapter and related information.

   ```plaintext
I'm migrating an Open CTI adapter to a Salesforce Voice with Partner Telephony connector.
   Here is my current Open CTI adapter: [paste or attach]
   SDK: https://github.com/salesforce/scv-connector-base
   Demo connector (my starting point): https://github.com/salesforce-misc/byo-demo-connector
   Developer guide: https://developer.salesforce.com/docs/atlas.en-us.voice_pt_developer_guide.meta/voice_pt_developer_guide/voice_pt_intro.htm
   For each opencti.* API call in my adapter, tell me:
   1. The Salesforce Voice connector equivalent method or event
   2. Where in byo-demo-connector it's already stubbed
   3. What I need to replace
```

   **tip:** If your AI tool isn't able to parse the [Salesforce Voice with Partner Telephony Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.voice_pt_developer_guide.meta/voice_pt_developer_guide/voice_pt_intro.htm), point it to the latest PDF version (available from the guide overview page).

2. Generate connector methods one at a time. Don't ask for the whole file at once. Migrate method by method, in priority order.

   ```plaintext
In my Open CTI adapter, call acceptance looks like this:
   [paste your existing code]
   Generate the Salesforce Voice TelephonyConnector.acceptCall() implementation
   that calls my backend at [your endpoint], using the PhoneCall and CallResult
   types from scv-connector-base. Return a Promise<CallResult> — do not call
   publishEvent() from inside acceptCall().
```

3. Repeat for `endCall()`, `dial()`, `hold()`, `mute()`, `setAgentStatus()`, `wrapUpCall()`, etc.

4. Generate unit tests against the SDK's test fixtures.

   ```plaintext
Generate Jest unit tests for my acceptCall() implementation using the
   test patterns in byo-demo-connector/src/main/__tests__/. Mock the backend
   with the same vendor-sdk.js mock pattern the demo uses.
```

5. Validate with the CCaaS.html simulator. After generating code, test against the demo connector's mock backend before connecting your real backend. The simulator catches event-ordering bugs early, such as `CALL_CONNECTED` before `CALL_STARTED`, missing `voiceCallId`, and other rejections the base connector enforces.

   ```bash
cd byo-demo-connector
   npm run serve
   # Open the printed CCaaS.html URL in a browser tab.
   # Simulate inbound/outbound calls, hangups, and transfers without a real PBX.
```

6. Generate Omni-Channel Flow specifications (build in Flow Builder). For Flows (screen pop, post-call automation), AI tools generate Flow specifications and step-by-step build instructions, not deployable Flow XML. Use the AI output as a buildable spec. Build the actual Flow in Flow Builder.

## Methods to Replace, in Priority Order

Priority 1 (required for basic calls):

```javascript
acceptCall(); // replace mock with your accept API → Promise<CallResult>
declineCall(); // replace mock with your decline API → Promise<CallResult>
endCall(); // replace mock with your hangup API → Promise<HangupResult>
dial(); // replace mock with your outbound dial → Promise<CallResult>
getActiveCalls(); // replace mock with your call state query → Promise<ActiveCallsResult>
```

Priority 2 (required for complete experience):

```javascript
hold() / resume();
mute() / unmute();
setAgentStatus() / getAgentStatus();
wrapUpCall();
```

Priority 3 (advanced features):

```javascript
addParticipant(); // transfers and consults
superviseCall(); // supervisor listen-in
supervisorBargeIn();
getVoiceCapabilities() / getSharedCapabilities();
```

## Publish Call Events

When your telephony system fires events, translate them using the pattern that’s already in the demo connector’s event publisher:

```javascript
// Inbound call ringing → publish to Salesforce Voice
publishEvent({
  eventType: Constants.VOICE_EVENT_TYPE.CALL_STARTED,
  payload: {
    call: new PhoneCall({
      callId: vendorCallId,
      callType: Constants.CALL_TYPE.INBOUND,
      state: Constants.CALL_STATE.RINGING,
      phoneNumber: callerNumber,
      callAttributes: new PhoneCallAttributes({
        voiceCallId: sfVoiceCallId, // ← 0LQ... Salesforce VoiceCall record ID
        participantType: Constants.PARTICIPANT_TYPE.INITIAL_CALLER,
      }),
      callInfo: new CallInfo({ isOnHold: false, acceptEnabled: true, declineEnabled: true }),
    }),
  },
});
```

**important:** `voiceCallId` in `callAttributes` must be the Salesforce VoiceCall record ID (`0LQ…`). This is the binding between your call and everything Salesforce does (AgentWork creation, supervisor view, reporting).
