Migrate Rep Presence Status

Manage rep presence through Omni-Channel instead of your previous Open CTI pattern.

Open CTI doesn't natively integrate with Omni-Channel for presence. Adapters that managed presence typically did one of the following:

  • Maintained an in-adapter presence widget that didn't talk to Omni-Channel at all
  • Mirrored adapter status to Omni-Channel via custom Apex REST endpoints setting UserServicePresence
  • Relied on the rep manually changing their Omni-Channel status in the UI

This means for many Open CTI orgs, there is no Omni-Channel integration to migrate from. You're moving from "adapter has its own presence" to "Omni-Channel owns presence."

What Omni-Channel Does and Doesn't Do

Omni-Channel is channel-agnostic. It manages presence across Voice, Chat, Messaging, Cases, and more for the same rep. A single presence status (for example, "Available") can signal readiness for routing across all enabled channels.

Omni-Channel does not change presence status when a rep accepts a call. When a rep takes a call, they go "busy" from a routing standpoint. Their capacity is consumed via AgentWork, but their Omni-Channel presence status itself doesn't change. They're still "Available." Capacity is the routing-side concept. Presence is the user-facing concept; they're decoupled.

Omni-Channel does not set status to anything during the call. Reps stay on their selected presence status throughout the call. The "I'm on a call" indicator comes from AgentWork, not from presence status.

enqueueNextState is the bridge between rep intent ("I want to go offline") and call lifecycle ("but they're still on a call"). Without it, premature status changes drop calls.

note: Partners coming from non-Omni-Channel telephony platforms expect an explicit "On Call" status. There isn't one in Omni-Channel. The rep stays Available; their capacity is fully consumed by AgentWork for the duration. We recommend covering this in your training materials.

Salesforce Voice with Partner Telephony Pattern for Presence Status

Your connector responds to Omni-Channel in the new Salesforce Voice with Partner Telephony pattern. Here's an example of how to handle changes in rep status.

async setAgentStatus(agentStatus, statusInfo, enqueueNextState) {
    // agentStatus: 'Online' | 'Offline' | 'AfterCallWork' | <custom>
    if (enqueueNextState) {
        // Rep clicked "Go Offline" mid-call — apply AFTER the call ends
        await myBackend.queueStatusChange(agentStatus);
    } else {
        await myBackend.setStatus(agentStatus);
    }
    // Return a Promise<GenericResult>
}

async getSharedCapabilities() {
    return new VoiceCapabilitiesResult({
        hasPendingStatusChange: true,  // enables enqueueNextState behavior
        hasTransferToOmniFlow: true,
    });
}

important: Skipping enqueueNextState causes dropped calls. If you apply Offline immediately while a call is active, your backend tears down the rep's session, and the call drops. Offline is the worst status to flip to mid-call. This is the root cause of numerous support cases with partner telephony. Always honor the enqueueNextState flag.