Starting from the demo connector, replace Open CTI adapter logic with Salesforce Voice 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.
After cloning the demo connector, consider using AI coding assistants for the mechanical translation of your Open CTI adapter logic into Salesforce Voice 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.
Feed the assistant your Open CTI adapter and related information.
Example prompt
1I'm migrating an Open CTI adapter to a Salesforce Voice Partner Telephony connector.2Here is my current Open CTI adapter: [paste or attach]3SDK: https://github.com/salesforce/scv-connector-base4Demo connector (my starting point): https://github.com/salesforce-misc/byo-demo-connector5Developer guide: https://developer.salesforce.com/docs/atlas.en-us.voice_pt_developer_guide.meta/voice_pt_developer_guide/voice_pt_intro.htm6For each opencti.* API call in my adapter, tell me:71. The Salesforce Voice connector equivalent method or event82. Where in byo-demo-connector it's already stubbed93. What I need to replace
Generate connector methods one at a time. Don’t ask for the whole file at once. Migrate method by method, in priority order.
Example prompt
1In my Open CTI adapter, call acceptance looks like this:2[paste your existing code]3Generate the Salesforce Voice TelephonyConnector.acceptCall() implementation4that calls my backend at [your endpoint], using the PhoneCall and CallResult5types from scv-connector-base. Return a Promise<CallResult> — do not call6publishEvent() from inside acceptCall().
Repeat for endCall(), dial(), hold(), mute(), setAgentStatus(), wrapUpCall(), etc.
Generate unit tests against the SDK’s test fixtures.
Example prompt
1Generate Jest unit tests for my acceptCall() implementation using the2test patterns in byo-demo-connector/src/main/__tests__/. Mock the backend3with the same vendor-sdk.js mock pattern the demo uses.
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.
1cd byo-demo-connector2npm run serve3# Open the printed CCaaS.html URL in a browser tab.4# Simulate inbound/outbound calls, hangups, and transfers without a real PBX.
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):
1acceptCall(); // replace mock with your accept API → Promise<CallResult>2declineCall(); // replace mock with your decline API → Promise<CallResult>3endCall(); // replace mock with your hangup API → Promise<HangupResult>4dial(); // replace mock with your outbound dial → Promise<CallResult>5getActiveCalls(); // replace mock with your call state query → Promise<ActiveCallsResult>
1addParticipant(); // transfers and consults2superviseCall(); // supervisor listen-in3supervisorBargeIn();4getVoiceCapabilities() / 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:
1// Inbound call ringing → publish to Salesforce Voice2publishEvent({3 eventType: Constants.VOICE_EVENT_TYPE.CALL_STARTED,4 payload:{5 call: new PhoneCall({6 callId: vendorCallId,7 callType: Constants.CALL_TYPE.INBOUND,8 state: Constants.CALL_STATE.RINGING,9 phoneNumber: callerNumber,10 callAttributes: new PhoneCallAttributes({11 voiceCallId: sfVoiceCallId, // ← 0LQ... Salesforce VoiceCall record ID12 participantType: Constants.PARTICIPANT_TYPE.INITIAL_CALLER,13}),14 callInfo: new CallInfo({isOnHold: false, acceptEnabled: true, declineEnabled: true}),15}),16},17});
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).