service-omni-service-channel-configure
SkillCommunicationLets your agent set up Salesforce Omni-Channel correctly by applying this omni Claude skill that keeps one channel per record type.
Available today. Use it from your connected AI after setup.
No other account needed.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
Then ask your AI: use the service-omni-service-channel-configure skill
About this skill
Use to ensure exactly one ServiceChannel exists on a Salesforce org for a routable sObject (Case | Incident | MessagingSession | VoiceCall), reusing any standard or custom channel already bound to that sObject and only deploying a canonical template when none exists. Salesforce enforces one ServiceC
What this skill tells your AI
The instructions your AI receives, as published by forcedotcom/sf-skills in skills/service-omni-service-channel-configure/SKILL.md and read by ahel’s review.
Ensure exactly one ServiceChannel is present for a routable sObject, reusing whatever is already bound (Salesforce standard or a pre-existing custom channel) and deploying the skill's canonical v66 template only when none exists. Salesforce enforces one ServiceChannel per RelatedEntity, so the skill detects first and never deploys blindly — deploying a second channel for an sObject that already has one fails with "This Salesforce object is already in use by another Service channel." It handles one sObject per call; callers configuring multiple sObjects invoke it once for each sObject, after service-omni-base-settings-configure has enabled Omni-Channel.
| sObject | Standard channel (if any) | Canonical asset |
|---|---|---|
Case | Cases | Cases.serviceChannel-meta.xml |
Incident | none (Incident Management sObject) | Incidents.serviceChannel-meta.xml — deployed on first run |
MessagingSession | sfdc_livemessage | MessagingSessions.serviceChannel-meta.xml — deployed only if the standard channel is missing |
VoiceCall | sfdc_phone | VoiceCalls.serviceChannel-meta.xml — deployed only if the standard channel is missing |
Inputs
bash scripts/deploy-and-report.sh <org-alias> [Case|Incident|MessagingSession|VoiceCall]
org-alias(required).sobject_type(optional, defaultCase) — one ofCase | Incident | MessagingSession | VoiceCall.
Preconditions and safety
- Target org authenticated via
sfCLI (My Domain URL), Service Cloud license,sfCLI ≥ 2.139.6. - Omni-Channel base settings enabled (
service-omni-base-settings-configure) —ServiceChannelis only queryable/writable whenenableOmniChannel=true; aINVALID_TYPEon deploy means base settings are off. Incidentrequires the Incident Management feature enabled;MessagingSessionrequires Enhanced Messaging. The skill verifiesEntityDefinitionfirst and blocks with a click-path when the target sObject is absent.
Run
deploy-and-report.sh performs the prereq check, discovery, and (only when needed) deploy, then emits the report:
- Prereq — confirm the target sObject is queryable via
EntityDefinition; block with a click-path otherwise. - Discover — query the Tooling API for a
ServiceChannelwithRelatedEntity = <sobject_type>.ServiceChannelis a Tooling entity on v66; the standard Data API returnsINVALID_TYPE. A hit means reuse. - Deploy (only when nothing was found) —
sf project deploy startof the canonical XML (Cases|Incidents|MessagingSessions|VoiceCalls); aChangedstate iscreated,Unchangedisreused.
Behavior
Detect-then-reuse-or-deploy. Because Salesforce rejects a second channel per RelatedEntity, deploy-first is unsafe: an operator who renamed the standard Cases channel would hit the "already in use" error instead of gracefully reusing. Tooling discovery is fast and returns both the reuse decision and the discovered DeveloperName in one call. The trade-off is that the skill cannot tell "our canonical shape matches" from "some custom channel is bound" — an operator with a non-canonical channel gets reused and their channel is left untouched (v1 never overwrites operator state).
Capacity model. The canonical assets use TAB_BASED for every variant. STATUS_BASED requires companion fields whose full schema is undocumented, so it is out of scope; per-agent capacity tuning belongs to PresenceUserConfig.Capacity, not this skill.
Concurrency. If a deploy fails with "already in use," another process created the channel between discovery and deploy; the skill soft-fails and a re-run reuses it.
Output contract
A single JSON object per invocation with status ∈ created | reused | blocked, plus sobject_type, channel_developer_name, channel_id, channel_origin, target_capacity_model, target_related_entity_type, before_state, deploy_id, manual_actions, and blocking_issue.
reused— an existing channel was found (discovery hit, or a deploy returnedUnchanged).created— no channel existed; the canonical XML deployed withChanged.blocked— the sObject is not on the org, base settings are off (INVALID_TYPE), or a race left the channel already in use.channel_originis one ofsalesforce_standard(ansfdc_*name orCases),canonical_asset(a shipped asset name),canonical_template(freshly deployed this run), orcustom(a pre-existing org-specific channel).channel_idis populated whenever a channel exists (nullonblocked);deploy_idis populated only on the deploy branch;blocking_issueis non-null only whenstatus: blocked.
Limitations
- One sObject per invocation.
- Only
Case,Incident,MessagingSession,VoiceCallare supported — extend by adding anassets/force-app/main/default/serviceChannels/<Name>.serviceChannel-meta.xmlfile and a dispatcher branch. - Always reuses an existing channel; it does not reset a mis-configured channel to canonical shape.
References
| File | When to read |
|---|---|
references/api-notes.md | On unexpected discovery results, deploy failures, or sObject-specific schema questions |
Signals
- GitHub stars
- 1k
- Forks
- 348
- Last commit
- Sep 2026
Advanced
- Item type
- skill
- Key
service-omni-service-channel-configure- Source
- github.com/forcedotcom/sf-skills