@salesforce/afv-skills 1.40.0 → 1.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/package.json +1 -1
  2. package/skills/automation-flow-generate/SKILL.md +32 -43
  3. package/skills/experience-portal-create/SKILL.md +497 -0
  4. package/skills/experience-portal-create/assets/report-template.md +30 -0
  5. package/skills/experience-portal-create/references/mcp-invocation.md +288 -0
  6. package/skills/experience-portal-create/references/post-creation-activate-publish.md +165 -0
  7. package/skills/experience-portal-create/references/templates.md +253 -0
  8. package/skills/experience-ui-bundle-features-generate/SKILL.md +5 -1
  9. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -0
  10. package/skills/experience-ui-bundle-frontend-generate/references/page.md +1 -0
  11. package/skills/platform-datamask-run/SKILL.md +345 -0
  12. package/skills/platform-datamask-run/references/api-surface.md +130 -0
  13. package/skills/platform-datamask-run/references/policy-authoring.md +185 -0
  14. package/skills/platform-datamask-run/references/run-and-abort.md +116 -0
  15. package/skills/platform-datamask-run/scripts/poll-job.sh +115 -0
  16. package/skills/platform-dataspace-access-configure/SKILL.md +51 -3
  17. package/skills/platform-dataspace-access-configure/scripts/inspect-dataspace-scopes.sh +56 -0
  18. package/skills/platform-lightning-type-widget-coordinate/references/build-plan-format.md +1 -0
  19. package/skills/platform-sandbox-configure/SKILL.md +17 -2
  20. package/skills/platform-trial-org-create/SKILL.md +175 -0
  21. package/skills/platform-trial-org-create/examples/create_request.json +9 -0
  22. package/skills/platform-trial-org-create/examples/error_response.json +41 -0
  23. package/skills/platform-trial-org-create/examples/success_response.json +27 -0
  24. package/skills/platform-trial-org-create/references/error_codes.md +42 -0
  25. package/skills/platform-trial-org-create/references/signup_request_fields.md +69 -0
  26. package/skills/platform-trial-org-create/scripts/create_signup_request.sh +175 -0
  27. package/skills/platform-trial-org-create/scripts/get_signup_request.sh +155 -0
  28. package/skills/platform-widget-generate/SKILL.md +47 -6
  29. package/skills/platform-widget-generate/examples/conditional.json +3 -3
  30. package/skills/platform-widget-generate/examples/list-with-foreach.json +2 -2
  31. package/skills/platform-widget-generate/examples/single-object.json +2 -2
  32. package/skills/platform-widget-generate/references/widget-bundle-layout.md +1 -1
  33. package/skills/service-agentforce-channel-configure/SKILL.md +271 -0
  34. package/skills/service-agentforce-channel-configure/references/agent-wiring.md +97 -0
  35. package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +145 -0
  36. package/skills/service-agentforce-channel-configure/references/channel-branch-voice.md +69 -0
  37. package/skills/service-agentforce-channel-configure/references/channel-types.md +61 -0
  38. package/skills/service-agentforce-channel-configure/references/live-traffic-gate.md +86 -0
  39. package/skills/service-agentforce-channel-configure/references/queue-resolution.md +135 -0
  40. package/skills/service-agentforce-channel-configure/references/routing-flow.md +384 -0
  41. package/skills/service-catalog-template-deploy/SKILL.md +310 -0
  42. package/skills/service-catalog-template-deploy/references/cli-invocation.md +258 -0
  43. package/skills/service-catalog-template-deploy/scripts/activate-verify.mjs +164 -0
  44. package/skills/service-catalog-template-deploy/scripts/build-deploy-payload.mjs +94 -0
  45. package/skills/service-catalog-template-deploy/scripts/resolve-template.mjs +331 -0
  46. package/skills/service-catalog-template-search/SKILL.md +212 -0
  47. package/skills/service-catalog-template-search/references/cli-invocation.md +128 -0
  48. package/skills/service-catalog-template-search/scripts/classify-catalog.mjs +205 -0
  49. package/skills/service-concierge-portal-generate/SKILL.md +126 -0
  50. package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1428 -0
  51. package/skills/service-digital-engagement-channel-configure/SKILL.md +46 -6
  52. package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml +2 -1
  53. package/skills/service-digital-engagement-channel-configure/examples/asa_agent_channel.xml +4 -1
  54. package/skills/service-helpagent-coordinate/README.md +8 -2
  55. package/skills/service-helpagent-coordinate/SKILL.md +126 -130
  56. package/skills/service-helpagent-coordinate/assets/help-agent-spec.md +70 -53
  57. package/skills/service-helpagent-coordinate/references/agent-script.md +571 -457
  58. package/skills/service-helpagent-coordinate/references/channel-voice.md +38 -9
  59. package/skills/service-helpagent-coordinate/references/channel-web-chat.md +173 -49
  60. package/skills/service-helpagent-coordinate/references/output-report-format.md +126 -0
  61. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +153 -0
  62. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +79 -0
  63. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +35 -0
  64. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +271 -0
  65. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +265 -0
  66. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +220 -0
  67. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-final-report.mjs +102 -0
  68. package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/record-enable-result.mjs +73 -0
  69. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +206 -0
  70. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +194 -0
  71. package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +223 -0
  72. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +45 -7
  73. package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +45 -5
  74. package/skills/service-itsm-agentic-setup-configure/SKILL.md +116 -0
  75. package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +64 -0
  76. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +158 -0
  77. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/cli-invocation.md +361 -0
  78. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/error-taxonomy.md +44 -0
  79. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/reactivation.md +66 -0
  80. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +66 -0
  81. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/specialized-templates.md +148 -0
  82. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +169 -0
  83. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/build-create-body.mjs +116 -0
  84. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-agent-existence.mjs +185 -0
  85. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-preflight.mjs +168 -0
  86. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/create-scratch-dir.mjs +58 -0
  87. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +197 -0
  88. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +186 -0
  89. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +51 -0
  90. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/cli-invocation.md +345 -0
  91. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/error-taxonomy.md +44 -0
  92. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/reactivation.md +63 -0
  93. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +44 -0
  94. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +149 -0
  95. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +110 -0
  96. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +201 -0
  97. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-activate-result.mjs +135 -0
  98. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-agent-existence.mjs +194 -0
  99. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-preflight.mjs +158 -0
  100. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/create-scratch-dir.mjs +58 -0
  101. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +191 -0
  102. package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +133 -0
  103. package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +71 -0
  104. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +308 -0
  105. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +23 -0
  106. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +193 -0
  107. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +57 -0
  108. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +394 -0
  109. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +266 -0
  110. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +106 -0
  111. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +142 -0
  112. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +82 -0
  113. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-action-surface.mjs +137 -0
  114. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-assignment-state.mjs +99 -0
  115. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +120 -0
  116. package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/resolve-target-user.mjs +86 -0
  117. package/skills/service-itsm-agentic-setup-uel-user-create/SKILL.md +284 -0
  118. package/skills/service-itsm-agentic-setup-uel-user-create/references/mcp-invocation.md +302 -0
  119. package/skills/service-itsm-channels-coordinate/SKILL.md +472 -0
  120. package/skills/service-itsm-incident-mgmt-configure/SKILL.md +212 -0
  121. package/skills/service-itsm-incident-mgmt-configure/references/mcp-invocation.md +225 -0
  122. package/skills/service-itsm-incident-priority-configure/SKILL.md +53 -12
  123. package/skills/service-itsm-swarming-configure/SKILL.md +212 -0
  124. package/skills/service-itsm-teams-configure/SKILL.md +395 -0
  125. package/skills/service-itsm-teams-configure/references/azure-credential-population.md +213 -0
  126. package/skills/service-itsm-teams-configure/references/gotchas.md +23 -0
  127. package/skills/service-itsm-teams-coordinate/SKILL.md +175 -0
  128. package/skills/service-itsm-teams-coordinate/examples/output-templates.md +85 -0
  129. package/skills/service-itsm-teams-debug/SKILL.md +144 -0
  130. package/skills/service-itsm-teams-debug/references/configuration-checklists.md +277 -0
  131. package/skills/service-itsm-teams-debug/references/report-generation.md +95 -0
  132. package/skills/service-itsm-teams-employee-agent-configure/SKILL.md +139 -0
  133. package/skills/service-itsm-teams-employee-agent-configure/assets/Teams_AgentForce.EmbeddedServiceConfig-meta.xml +43 -0
  134. package/skills/service-itsm-teams-employee-agent-configure/references/teams-embedded-employee-agent.md +480 -0
  135. package/skills/service-itsm-teams-itdesk-configure/SKILL.md +232 -0
  136. package/skills/service-itsm-teams-itservice-configure/SKILL.md +391 -0
@@ -0,0 +1,271 @@
1
+ ---
2
+ name: service-agentforce-channel-configure
3
+ description: "Wires an existing, active Agentforce agent to a channel by resolving a fallback queue, setting up inbound routing (either PATCH SessionHandlerId on the MessagingChannel, or an inbound RoutingFlow for Voice/Email), and optionally configuring outbound escalation. Use when the user wants to add a channel to an existing agent, connect an agent to a messaging or voice channel, route Voice or Email-to-Case to an Agentforce agent, or set up a fallback queue for an agent channel. Applies to any already-created agent, including an existing Help Agent. The channel infrastructure (MessagingChannel, Voice config, email-to-case) must already exist — this skill only adds the routing. DO NOT TRIGGER when the agent does not yet exist or still needs Help Agent setup (use agentforce-generate or service-helpagent-coordinate), when creating the MessagingChannel itself (use service-digital-engagement-channel-configure), or when creating an Embedded Service Deployment (use service-digital-engagement-deployment-configure)."
4
+ allowed-tools: Bash Read Write Edit Glob Grep AskUserQuestion
5
+ metadata:
6
+ version: "1.0"
7
+ domains: ["Service", "Agentforce"]
8
+ minApiVersion: "67.0"
9
+ relatedSkills:
10
+ - "agentforce-generate"
11
+ - "service-digital-engagement-channel-configure"
12
+ - "service-digital-engagement-deployment-configure"
13
+ - "service-helpagent-coordinate"
14
+ cliTools:
15
+ - tool: ["python3"]
16
+ semver: ">=3.8"
17
+ - tool: ["sf"]
18
+ semver: ">=2.0.0"
19
+ ---
20
+
21
+ # service-agentforce-channel-configure: Wire an Agentforce agent to a channel
22
+
23
+ Adds inbound routing between an existing channel and an existing Agentforce agent. The agent receives work items from the channel; a fallback queue handles overflow when the agent is unavailable.
24
+
25
+ This skill is generic — it works for any Agentforce agent, not just the Help Agent template.
26
+
27
+ ## Scope
28
+
29
+ **In scope:**
30
+ - Resolving or creating a fallback queue with the correct `QueueSobject` SobjectType
31
+ - Branch A (Enhanced Chat / Enhanced Messaging): deploying `sessionHandlerType=AgentforceServiceAgent` + `sessionHandlerQueue` on an existing MessagingChannel, then binding `SessionHandlerId` via Data API PATCH
32
+ - Branch B (Voice): assumes the phone number and `PstnVoice` MessagingChannel already exist (provisioned by the caller, e.g. `service-helpagent-coordinate`), then creating an inbound RoutingFlow (`routingType: Copilot`) that routes to the agent with the queue as fallback
33
+ - Branch C (Email-to-Case): same inbound RoutingFlow, using the org-specific Case-based ServiceChannel
34
+ - Optional outbound escalation: adding the appropriate `connection {type}:` block to the agent and republishing
35
+
36
+ **Out of scope:**
37
+ - Creating the agent — use `agentforce-generate` or `service-helpagent-coordinate`
38
+ - Creating the MessagingChannel — use `service-digital-engagement-channel-configure`
39
+ - Creating the Embedded Service Deployment — use `service-digital-engagement-deployment-configure`
40
+ - Creating the Voice or Email-to-Case channel infrastructure
41
+ - Outbound escalation RoutingFlow creation — surface the gap if one is needed and doesn't exist
42
+
43
+ ---
44
+
45
+ ## Required inputs
46
+
47
+ - **Agent `DeveloperName`** and **agent label** (`MasterLabel`) — must be an existing, active agent
48
+ - **Channel type** — one of: Enhanced Chat, Enhanced Messaging (3rd-party), Voice, Email-to-Case
49
+ - **Channel identifier** — MessagingChannel `DeveloperName` (Branch A), or the channel name/context (Branches B/C)
50
+ - **Target org alias**
51
+
52
+ ---
53
+
54
+ ## Workflow
55
+
56
+ Steps are sequential. Read `references/channel-types.md` first to confirm the routing branch before proceeding.
57
+
58
+ ### Phase 1 — Verify agent and resolve queue
59
+
60
+ 1. **Confirm the agent exists and has an active version:**
61
+ ```bash
62
+ # Get the definition
63
+ sf data query --target-org $ORG --json \
64
+ --query "SELECT Id, DeveloperName, MasterLabel FROM BotDefinition WHERE DeveloperName='{AGENT_DEVELOPER_NAME}'"
65
+
66
+ # Check for an Active version
67
+ sf data query --target-org $ORG --json \
68
+ --query "SELECT Id, Status FROM BotVersion WHERE BotDefinitionId='{BOT_DEFINITION_ID}' AND Status='Active' LIMIT 1"
69
+ ```
70
+ Stop with a clear message if the definition is not found or no version has `Status = Active`.
71
+
72
+ 2. **Resolve the fallback queue and routing configuration** — follow `references/queue-resolution.md`:
73
+ - Determine SobjectType from the channel type (see `references/channel-types.md`)
74
+ - Query existing compatible queues; present via `AskUserQuestion` or create new
75
+ - Query for an existing `QueueRoutingConfig`; create one with the correct capacity percentage if absent
76
+ - Capture `QUEUE_DEVELOPER_NAME`, `QUEUE_NAME`, and `QUEUE_ID`
77
+
78
+ ---
79
+
80
+ ### Phase 2 — Wire inbound routing
81
+
82
+ #### Live-traffic warning gate (runs before any branch)
83
+
84
+ Before making any routing change, detect whether the channel already has active inbound routing (Branch A: non-empty `SessionHandlerType`; Branches B/C: any active RoutingFlow assigned to the service channel). If it does, first check whether the user's prompt already answered the timing choice ("do not cut over" / "wire manually" / "review first" → defer silently; "cut over now" / "activate immediately" → proceed silently). Only if the prompt is silent, warn via `AskUserQuestion` and let the user choose **"Re-route now"** or **"Set up, then wire manually"** — and on any ambiguous or no-selection response, default to the deferred path (never to a live re-route). When deferred, set `DEFER_INBOUND_ROUTING=true`, skip the channel-activation step in the chosen branch, and print the manual wiring instructions at the end of Phase 2.
85
+
86
+ If the channel has no existing routing, skip this gate entirely and proceed directly.
87
+
88
+ Full detection queries, exact `AskUserQuestion` block, deferred-flow rules per branch, and manual-wiring copy: `references/live-traffic-gate.md`.
89
+
90
+ ---
91
+
92
+ #### Branch A — Enhanced Chat / Enhanced Messaging (3rd-party)
93
+
94
+ No RoutingFlow required. Deploy the MessagingChannel with `sessionHandlerType` + `sessionHandlerQueue` only, then bind the bot via a Data API PATCH. `sessionHandlerAsa` is not accepted by the Metadata API at v67 — the deploy silently drops it and `SessionHandlerId` stays null unless you run the PATCH. The bot must be Active before the PATCH ("Only active Agentforce Service Agents are supported" otherwise).
95
+
96
+ All five steps below are mandatory and must run in order — do **not** skip the retrieve/edit/deploy and jump straight to the PATCH. Run the retrieve and edit in the **current working directory** (a real SFDX project), so the edited `.messagingChannel-meta.xml` is saved into the project's `force-app` tree — not a throwaway temp dir. Steps 1–3 record the routing change in source; steps 4–5 apply the binding the Metadata API can't.
97
+
98
+ 1. **Retrieve the current MessagingChannel metadata** into the working-directory project:
99
+ ```bash
100
+ sf project retrieve start \
101
+ --metadata "MessagingChannel:{CHANNEL_DEVELOPER_NAME}" \
102
+ --target-org $ORG
103
+ ```
104
+
105
+ 2. **Edit the retrieved `.messagingChannel-meta.xml` in place** — set exactly these two fields (do NOT add `<sessionHandlerAsa>`):
106
+ ```xml
107
+ <sessionHandlerType>AgentforceServiceAgent</sessionHandlerType>
108
+ <sessionHandlerQueue>{QUEUE_DEVELOPER_NAME}</sessionHandlerQueue>
109
+ ```
110
+ Apply this edit with the file-editing tool (Edit/Write) so the change is saved to the retrieved file at `force-app/main/default/messagingChannels/{CHANNEL_DEVELOPER_NAME}.messagingChannel-meta.xml` in the working directory — do **not** hand-edit it through an inline `sed`/`cat` heredoc into a temp path. The deploy in step 3 must read this same on-disk file.
111
+
112
+ 3. **Deploy:**
113
+ ```bash
114
+ sf project deploy start \
115
+ --metadata "MessagingChannel:{CHANNEL_DEVELOPER_NAME}" \
116
+ --target-org $ORG
117
+ ```
118
+
119
+ 4. **Bind the bot via Data API PATCH:**
120
+ ```bash
121
+ CHAN_ID=$(sf data query --target-org $ORG --json \
122
+ --query "SELECT Id FROM MessagingChannel WHERE DeveloperName='{CHANNEL_DEVELOPER_NAME}'" \
123
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
124
+ BOT_ID=$(sf data query --target-org $ORG --json \
125
+ --query "SELECT Id FROM BotDefinition WHERE DeveloperName='{AGENT_DEVELOPER_NAME}'" \
126
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
127
+ QUEUE_ID=$(sf data query --target-org $ORG --json \
128
+ --query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='{QUEUE_DEVELOPER_NAME}'" \
129
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
130
+
131
+ sf api request rest --method PATCH -o $ORG \
132
+ "/services/data/v67.0/sobjects/MessagingChannel/${CHAN_ID}" \
133
+ --body "{\"SessionHandlerId\":\"${BOT_ID}\",\"FallbackQueueId\":\"${QUEUE_ID}\"}"
134
+ # Expected: HTTP 204
135
+ ```
136
+
137
+ 5. **Verify:**
138
+ ```bash
139
+ sf data query --target-org $ORG --json \
140
+ --query "SELECT SessionHandlerId, FallbackQueueId FROM MessagingChannel WHERE Id='${CHAN_ID}'"
141
+ ```
142
+ Both `SessionHandlerId` and `FallbackQueueId` must be non-null.
143
+
144
+ No agent file changes — no republish needed. Proceed to Phase 3 (optional).
145
+
146
+ ---
147
+
148
+ #### Branch B — Voice
149
+
150
+ Wires a `PstnVoice` MessagingChannel to the agent via an inbound `Copilot`-type RoutingFlow with the queue as fallback. Distinct from Branch A: no `sessionHandlerAsa`; the channel is bound to the flow (`sessionHandlerType=Flow`), and the agent needs a `modality voice:` block appended before republish.
151
+
152
+ Follow `references/channel-branch-voice.md` end to end. Highlights:
153
+
154
+ - Step 0 — reuse an existing `PstnVoice` MessagingChannel or have `service-helpagent-coordinate` provision one first (its `references/channel-voice.md`); abort if the org uses a partner telephony provider (see `references/channel-types.md`).
155
+ - Steps 1–3 — write and deploy the inbound RoutingFlow using the template in `references/routing-flow.md`, verifying `ActiveVersionId` is non-null.
156
+ - Step 4 — deploy a `MessagingChannel` metadata file for `{CHANNEL_DEVELOPER_NAME}` with `sessionHandlerType=Flow`, `sessionHandlerFlow={FLOW_DEVELOPER_NAME}`, `sessionHandlerQueue={QUEUE_DEVELOPER_NAME}`. Without this the flow is never executed and calls hang up. Verify `SessionHandlerId` starts with `300`.
157
+ - Step 5 — append the platform-default `modality voice:` block (voice_id `UgBBYS2sOqTuMpoF3BR0`, "Mark", en_US) to the `.agent` file if missing; do not ask the user. Republish per `references/agent-wiring.md`.
158
+
159
+ Proceed to Phase 3 (optional).
160
+
161
+ ---
162
+
163
+ #### Branch C — Email-to-Case
164
+
165
+ Same inbound RoutingFlow shape as Branch B, but using the org-specific Case-based ServiceChannel. Additionally requires an outbound `connection service_email:` and a mandatory manual BotEmailDefinition step in Setup — these are not optional and cannot be deferred to Phase 3.
166
+
167
+ Follow `references/channel-branch-email.md` end to end. Highlights:
168
+
169
+ - Step 0 — verify `emailToCase.enableEmailToCase` and `emailToCase.enableOnDemandEmailToCase` are `true` in CaseSettings via the Tooling API; if either is off, deploy a settings file that enables both (safe-fields-only pattern) before continuing.
170
+ - Step 1 — reuse an existing `EmailRoutingAddress` or create one for the support email address, then patch `caseOrigin` / `saveEmailHeaders: true` / `addressType: EmailToCase` for that entry in `CaseSettings.Metadata.caseEmailRoutingAddresses` via Tooling-API PATCH (fallback: `sf project deploy start --metadata Settings:Case`). Inform the user about the verification email but do not block on it.
171
+ - Step 2 — query the Case-based ServiceChannel (see `references/channel-types.md`), then write and deploy the inbound RoutingFlow using the template in `references/routing-flow.md`; verify `ActiveVersionId` is non-null.
172
+ - Step 3 — mandatory outbound: reuse or create `{AgentDevName}_Outbound_Email_Flow` (QueueBased template in `references/routing-flow.md` Part 2), then add `connection service_email:` to the agent and republish per `references/agent-wiring.md`.
173
+ - Step 4 — mandatory manual: prompt the user to create an **Email Configuration for Agentforce Service Agent** at `{ORG_INSTANCE_URL}/lightning/setup/AsaForEmail/home` and set the Agentforce Configuration field on the Email-to-Case routing address. Wait for user confirmation.
174
+
175
+ Branch C is complete once the user confirms Step 4. Skip Phase 3 for Email-to-Case (outbound escalation is already handled inline).
176
+
177
+ ---
178
+
179
+ ### Phase 3 — Outbound escalation (optional — Branches A/B only)
180
+
181
+ > **Branch C (Email-to-Case):** outbound escalation was handled inline in Branch C above. Do not run Phase 3 for Email-to-Case.
182
+
183
+ After inbound routing is confirmed (Branches A or B), ask the user:
184
+
185
+ > *"Inbound routing is now set up — the channel will route to [agent name]. Do you also want to configure outbound escalation so the agent can hand off to a human when requested?"*
186
+
187
+ If yes:
188
+
189
+ 1. **Resolve the escalation queue** — follow the escalation queue resolution steps in `references/queue-resolution.md` (Step 6). The user may want a different queue for escalation than the inbound fallback. Capture `ESCALATION_QUEUE_DEVELOPER_NAME` and `ESCALATION_QUEUE_ID`.
190
+
191
+ 2. **Determine the outbound flow name** from the channel type (see naming table in `references/routing-flow.md` Part 2).
192
+
193
+ 3. **Check if an active outbound flow already exists:**
194
+ ```bash
195
+ sf data query --target-org $ORG --json \
196
+ --query "SELECT ApiName, ActiveVersionId FROM FlowDefinitionView WHERE ApiName='{OUTBOUND_FLOW_DEVELOPER_NAME}' AND ProcessType='RoutingFlow'"
197
+ ```
198
+ - Row exists with non-null `ActiveVersionId` → reuse it; skip to step 4.
199
+ - Row missing or `ActiveVersionId` null → create the flow using the QueueBased template in `references/routing-flow.md` Part 2, substituting `ESCALATION_QUEUE_DEVELOPER_NAME` for `QUEUE_DEVELOPER_NAME`. Deploy and verify `ActiveVersionId` is non-null before continuing.
200
+
201
+ 4. **Add the connection block** to the agent's `.agent` file and republish — follow `references/agent-wiring.md`. The connection key depends on channel type:
202
+ - **Enhanced Chat (EmbeddedMessaging)** → `connection customer_web_client:`
203
+ - **Enhanced Messaging (3rd-party)** → `connection messaging:`
204
+ - **Voice** → `connection telephony:`
205
+ - **Email-to-Case** → `connection service_email:`
206
+
207
+ ---
208
+
209
+ ## Rules / constraints
210
+
211
+ | Rule | Rationale |
212
+ |---|---|
213
+ | Verify the agent exists and is Active before making any changes | Wiring a channel to a non-existent or inactive agent silently fails at runtime |
214
+ | If the channel already has active inbound routing, honor an explicit defer/cutover intent in the prompt without asking; otherwise warn via `AskUserQuestion` and default to defer on ambiguity | Re-routing takes effect immediately and affects live traffic — queue and RoutingFlow creation always proceed; only the activation step is gated, and the safe default is non-destructive |
215
+ | When deferred, print exact manual wiring instructions before Phase 3 | The operator needs to know precisely what to run when they're ready to cut over |
216
+ | Never modify the MessagingChannel without retrieving the current metadata first | Overwriting without retrieval discards existing settings |
217
+ | Branch A: no RoutingFlow, no agent republish; deploy `sessionHandlerType` + `sessionHandlerQueue` via metadata, then bind `SessionHandlerId` via Data API PATCH | `sessionHandlerAsa` is not accepted by the Metadata API at v67 — the deploy silently drops it, so bot binding must happen via the Data API PATCH after deploy. Bot must be Active before the PATCH |
218
+ | Branches B/C: always create a new RoutingFlow — never reuse existing org flows | OOB platform flows commonly have `ActiveVersionId: null` and cannot be referenced |
219
+ | Branches B/C: use `routingType: Copilot` and `copilotLabel` — not `QueueBased` | `QueueBased` routes to the queue directly; `Copilot` routes to the agent first with the queue as fallback |
220
+ | Queue `Id` must be queried and embedded in the RoutingFlow XML | The `queueId` parameter requires a hardcoded 18-char record Id — do not leave it empty |
221
+ | Queue naming: `{ChannelTypeLabel} Queue` | Named after the channel type, not the agent |
222
+ | Outbound escalation is optional for Branches A/B — mandatory for Branch C (Email-to-Case) | BotEmailDefinition (Email Configuration in Setup) requires `connection service_email:` to already be on the agent; it cannot be created before the connection block is deployed |
223
+
224
+ ---
225
+
226
+ ## Verification checklist
227
+
228
+ ### Queue
229
+ - [ ] Queue has a `QueueSobject` record with the correct `SobjectType` for the channel type
230
+ - [ ] Running user is a member of the queue (if newly created)
231
+ - [ ] Queue has a `QueueRoutingConfig` with the correct `CapacityPercentage` (50 / 100 / 25 for Chat / Voice / Email)
232
+
233
+ ### Branch A — MessagingChannel
234
+ - [ ] `SessionHandlerType = AgentforceServiceAgent` after deploy
235
+ - [ ] Bot is Active before the Data API PATCH
236
+ - [ ] `SessionHandlerId` is non-null after the Data API PATCH (matches the bot's `BotDefinition.Id`, starts with `0Xx`)
237
+ - [ ] `FallbackQueueId` is non-null after the Data API PATCH (matches the resolved queue Id)
238
+
239
+ ### Branches B/C — RoutingFlow
240
+ - [ ] RoutingFlow `ActiveVersionId` is non-null
241
+ - [ ] `routingType = Copilot` in the flow's `routeWork` action
242
+ - [ ] `copilotLabel` matches the agent's exact `MasterLabel`
243
+ - [ ] `queueId` is populated (non-empty)
244
+
245
+ ### Branch C — Email routing address
246
+ - [ ] If new: `EmailRoutingAddress` record created with correct `PersonalName` and `Address`
247
+ - [ ] If new: CaseSettings patched with `caseOrigin`, `saveEmailHeaders: true`, `addressType: EmailToCase`
248
+ - [ ] If new: user informed that a verification email was sent to the support address (non-blocking)
249
+
250
+ ### Branch C — BotEmailDefinition
251
+ - [ ] User has confirmed creation of Email Configuration for Agentforce Service Agent at `/lightning/setup/AsaForEmail/home`
252
+ - [ ] Email-to-Case routing address has the Agentforce Configuration field set
253
+
254
+ ### Optional Phase 3 — Outbound escalation
255
+ - [ ] Correct connection block used: `customer_web_client:` for EmbeddedMessaging, `messaging:` for 3rd-party, `telephony:` for Voice, `service_email:` for Email-to-Case
256
+ - [ ] `outboundRouteName` and `outboundRouteType` present in the correct `<plannerSurfaces>` entry of the deployed bundle
257
+ - [ ] Agent status is Active after republish
258
+
259
+ ---
260
+
261
+ ## Reference file index
262
+
263
+ | File | When to read |
264
+ |---|---|
265
+ | `references/channel-types.md` | Phase 1 — determine SobjectType and routing branch |
266
+ | `references/queue-resolution.md` | Phase 1 — queue lookup, creation, and Id capture |
267
+ | `references/live-traffic-gate.md` | Phase 2 — detection queries, deferred-flow rules, and manual wiring copy for the live-traffic warning gate |
268
+ | `references/channel-branch-voice.md` | Branch B — full Voice inbound wiring: PstnVoice channel selection, RoutingFlow, MessagingChannel assignment, `modality voice:` republish |
269
+ | `references/channel-branch-email.md` | Branch C — full Email-to-Case wiring: CaseSettings flags, EmailRoutingAddress + read-modify-write patch, inbound RoutingFlow, mandatory outbound `connection service_email:`, BotEmailDefinition manual step |
270
+ | `references/routing-flow.md` | Branches B/C — inbound RoutingFlow XML template, deploy, verify |
271
+ | `references/agent-wiring.md` | Phase 3 (optional) — outbound escalation `connection messaging:` block |
@@ -0,0 +1,97 @@
1
+ # Agent wiring — outbound escalation (optional)
2
+
3
+ This step is optional and presented to the user after inbound routing is complete. It configures the agent to hand off to a human agent via outbound escalation.
4
+
5
+ > **Scope note:** This is distinct from inbound routing (which routes incoming work items *to* the agent). Outbound escalation adds a `connection {type}:` block to the agent's `.agent` YAML so the agent can transfer a conversation *to a queue* when the customer requests a human. The outbound routing flow used here is a different flow from the inbound one created in Phase 2.
6
+
7
+ ## Connection block by channel type
8
+
9
+ The connection block name depends on the channel type being wired:
10
+
11
+ | Channel type | Connection block | `outbound_route_type` |
12
+ |---|---|---|
13
+ | Enhanced Chat (EmbeddedMessaging) | `connection customer_web_client:` | `OmniChannelFlow` |
14
+ | Enhanced Messaging (3rd-party) | `connection messaging:` | `OmniChannelFlow` |
15
+ | Voice | `connection telephony:` | `OmniChannelFlow` |
16
+
17
+ ## Prerequisite
18
+
19
+ An outbound RoutingFlow (`routingType: QueueBased`, routes to the fallback queue) must already exist. If one doesn't exist, create it using the QueueBased template in `references/routing-flow.md` Part 2 before proceeding here.
20
+
21
+ Verify the outbound flow exists:
22
+ ```bash
23
+ sf data query --target-org $ORG --json \
24
+ --query "SELECT ApiName, ActiveVersionId FROM FlowDefinitionView WHERE ProcessType='RoutingFlow' AND ApiName='{OUTBOUND_FLOW_DEVELOPER_NAME}'"
25
+ ```
26
+ `ActiveVersionId` must be non-null.
27
+
28
+ ## Add the connection block to the agent
29
+
30
+ Retrieve the agent's authoring bundle:
31
+ ```bash
32
+ sf project retrieve start \
33
+ --metadata "GenAiPlannerBundle:{AGENT_DEVELOPER_NAME}" \
34
+ --target-org $ORG
35
+ ```
36
+
37
+ Add the appropriate block to the agent's `.agent` YAML. For **Enhanced Chat** (`connection customer_web_client:`):
38
+
39
+ ```yaml
40
+ connection customer_web_client:
41
+ outbound_route_type: "OmniChannelFlow"
42
+ outbound_route_name: "flow://{OUTBOUND_FLOW_DEVELOPER_NAME}"
43
+ escalation_message: "Transferring you to a live agent — please hold on a moment."
44
+ adaptive_response_allowed: True
45
+ ```
46
+
47
+ For **Enhanced Messaging** (`connection messaging:`):
48
+
49
+ ```yaml
50
+ connection messaging:
51
+ outbound_route_type: "OmniChannelFlow"
52
+ outbound_route_name: "flow://{OUTBOUND_FLOW_DEVELOPER_NAME}"
53
+ escalation_message: "Transferring you to a live agent — please hold on a moment."
54
+ adaptive_response_allowed: True
55
+ ```
56
+
57
+ For **Voice** (`connection telephony:` + `modality voice:`):
58
+
59
+ Voice requires two blocks. Add both if they are not already present:
60
+
61
+ ```yaml
62
+ modality voice:
63
+ voice_id: "UgBBYS2sOqTuMpoF3BR0"
64
+ outbound_speed: 1.0
65
+ outbound_stability: 0.65
66
+ outbound_similarity: 0.75
67
+
68
+ connection telephony:
69
+ outbound_route_type: "OmniChannelFlow"
70
+ outbound_route_name: "flow://{OUTBOUND_FLOW_DEVELOPER_NAME}"
71
+ escalation_message: "Finding an associate for you..."
72
+ adaptive_response_allowed: True
73
+ ```
74
+
75
+ If a block for the relevant connection type already exists in the file, **add the outbound fields to the existing block** rather than creating a duplicate. Do not overwrite fields that are already present. If `modality voice:` already exists, leave it as-is — do not overwrite existing voice tuning values.
76
+
77
+ ## Republish and activate the agent
78
+
79
+ ```bash
80
+ sf agent validate authoring-bundle --api-name {AGENT_DEVELOPER_NAME} --json
81
+ sf agent publish authoring-bundle --api-name {AGENT_DEVELOPER_NAME} --json
82
+ echo "Y" | sf agent activate --api-name {AGENT_DEVELOPER_NAME} --json
83
+ ```
84
+
85
+ ## Verify the wiring round-tripped
86
+
87
+ After publish, retrieve the bundle and check:
88
+ ```bash
89
+ grep -n "outboundRouteName\|outboundRouteType" \
90
+ force-app/main/default/genAiPlannerBundles/{AGENT_DEVELOPER_NAME}_v*/\*.genAiPlannerBundle
91
+ ```
92
+
93
+ Both `outboundRouteName` and `outboundRouteType` must be present in the correct `<plannerSurfaces>` entry. The compiled XML maps the connection blocks as:
94
+ - `connection customer_web_client:` → `<surfaceType>CustomerWebClient</surfaceType>`
95
+ - `connection messaging:` → `<surfaceType>Messaging</surfaceType>`
96
+
97
+ If absent, the connection block was not serialised correctly — re-retrieve the `.agent` file and confirm the YAML was written before publishing.
@@ -0,0 +1,145 @@
1
+ # Branch C — Email-to-Case inbound routing
2
+
3
+ Same inbound RoutingFlow shape as Branch B, but using the org-specific Case-based ServiceChannel. Also includes the mandatory outbound `connection service_email:` and a mandatory manual BotEmailDefinition step (Email Configuration in Setup).
4
+
5
+ ## Step 0 — Enable Email-to-Case
6
+
7
+ Ensure the two required CaseSettings flags are on. Read the current state:
8
+
9
+ ```bash
10
+ sf api request rest -o "$ORG" --method GET \
11
+ "/services/data/v67.0/tooling/query?q=SELECT+Metadata+FROM+CaseSettings+LIMIT+1"
12
+ ```
13
+
14
+ Check `metadata.emailToCase.enableEmailToCase` and `metadata.emailToCase.enableOnDemandEmailToCase`. If either is `false`, deploy a settings file that sets both to `true` (use the same safe-fields-only Metadata API deploy pattern used when patching routing addresses — include only the `emailToCase` block with known-safe fields). Verify they are `true` before continuing.
15
+
16
+ ---
17
+
18
+ ## Step 1 — Existing routing address or new one?
19
+
20
+ Query existing Email-to-Case routing addresses on the org:
21
+
22
+ ```bash
23
+ sf data query --target-org $ORG --json \
24
+ --query "SELECT Id, PersonalName, Address FROM EmailRoutingAddress ORDER BY PersonalName"
25
+ ```
26
+
27
+ Ask the user via `AskUserQuestion`:
28
+ - **One or more found** → present each as `{PersonalName} <{Address}>`, plus *"Create a new email routing address"*
29
+ - **Zero found** → skip the question; proceed directly to create a new routing address
30
+
31
+ ### If creating a new routing address
32
+
33
+ 1. Ask for the support email address:
34
+
35
+ > *"What email address should receive support emails? This is the address customers will email — e.g. `support@yourcompany.com`.*
36
+ > *Note: Salesforce will send a verification email to this address. You must click the verification link before inbound emails will be processed."*
37
+
38
+ 2. Create the `EmailRoutingAddress` record:
39
+ ```bash
40
+ sf data create record --target-org $ORG \
41
+ --sobject EmailRoutingAddress \
42
+ --values "PersonalName='{SUPPORT_EMAIL}' Address='{SUPPORT_EMAIL}'" \
43
+ --json
44
+ ```
45
+ Capture the new record `Id` as `ROUTING_ADDRESS_ID`.
46
+
47
+ 3. Set `CaseOrigin`, `SaveEmailHeaders`, and `AddressType` via CaseSettings read-modify-write:
48
+
49
+ a. Read current CaseSettings from the Tooling API:
50
+ ```bash
51
+ sf api request rest -o "$ORG" --method GET \
52
+ "/services/data/v67.0/tooling/query?q=SELECT+Metadata+FROM+CaseSettings+LIMIT+1"
53
+ ```
54
+
55
+ b. In the returned `Metadata.caseEmailRoutingAddresses` array, find the entry whose `emailAddress` matches `{SUPPORT_EMAIL}`. Patch that entry:
56
+ - `caseOrigin`: query `Case.Origin` picklist values and select `Email` if present, otherwise the closest match
57
+ - `saveEmailHeaders`: `true`
58
+ - `addressType`: `EmailToCase`
59
+
60
+ c. Deploy the patched Metadata back:
61
+ ```bash
62
+ sf api request rest -o "$ORG" --method PATCH \
63
+ "/services/data/v67.0/tooling/sobjects/CaseSettings/{CASE_SETTINGS_ID}" \
64
+ --body '{"Metadata": {<patched metadata object>}}'
65
+ ```
66
+ Run this from `/tmp/sfskills` (a valid SFDX project directory). If the Tooling API PATCH fails, fall back to Metadata API deploy via `sf project deploy start --metadata Settings:Case`.
67
+
68
+ 4. Inform the user about email verification — then continue without waiting:
69
+
70
+ > *"A verification email has been sent to `{SUPPORT_EMAIL}`. Click the link in that email when you get it — inbound mail won't be processed until the address is verified, but you can complete the rest of the setup now.*
71
+ >
72
+ > *If you don't receive the verification email, your domain may have email verification policies that block it:*
73
+ > *[Email Verification Requirements for Salesforce Orgs](https://help.salesforce.com/s/articleView?id=xcloud.security_email_verification_requirements.htm&type=5)*"*
74
+
75
+ Continue to the next step immediately — do not wait for the user to confirm.
76
+
77
+ ### If using an existing routing address
78
+
79
+ Set `ROUTING_ADDRESS_ID` to the selected record's `Id` and continue. No provisioning steps needed.
80
+
81
+ ---
82
+
83
+ ## Step 2 — Inbound RoutingFlow
84
+
85
+ 1. **Query the ServiceChannel** — see `channel-types.md`. Stop if zero rows; ask user if multiple rows.
86
+
87
+ 2. **Determine names:**
88
+ - Flow label: `{AgentLabel} Inbound Email Flow`
89
+ - DeveloperName: `{AgentDevName}_Inbound_Email_Flow`
90
+ - `SERVICE_CHANNEL_DEV_NAME` / `SERVICE_CHANNEL_LABEL` from the queried ServiceChannel
91
+
92
+ 3. **Write the RoutingFlow XML** to `force-app/main/default/flows/{AgentDevName}_Inbound_Email_Flow.flow-meta.xml` using the template in `routing-flow.md`. Substitute all tokens including `{QUEUE_ID}` from Phase 1.
93
+
94
+ 4. **Deploy and verify `ActiveVersionId` is non-null** (see `routing-flow.md`).
95
+
96
+ No agent file changes from inbound routing.
97
+
98
+ ---
99
+
100
+ ## Step 3 — Mandatory outbound escalation: `connection service_email:`
101
+
102
+ Unlike other channel types where outbound escalation is optional, Email-to-Case requires the `connection service_email:` block to be on the agent before the BotEmailDefinition (Email Configuration) can be created in Setup — the Setup UI requires the agent to already have this connection wired.
103
+
104
+ Do not offer this as optional or skip to Phase 3. Run these steps now:
105
+
106
+ 1. **Determine the outbound flow name:**
107
+ - Flow label: `{AgentLabel} Outbound Email Flow`
108
+ - DeveloperName: `{AgentDevName}_Outbound_Email_Flow`
109
+
110
+ 2. **Check if an active outbound flow already exists:**
111
+ ```bash
112
+ sf data query --target-org $ORG --json \
113
+ --query "SELECT ApiName, ActiveVersionId FROM FlowDefinitionView WHERE ApiName='{AgentDevName}_Outbound_Email_Flow' AND ProcessType='RoutingFlow'"
114
+ ```
115
+ - Row exists with non-null `ActiveVersionId` → reuse it; skip to step 3.
116
+ - Row missing or `ActiveVersionId` null → create using the QueueBased template in `routing-flow.md` Part 2, with the `SERVICE_CHANNEL_DEV_NAME` / `SERVICE_CHANNEL_LABEL` queried above and `QUEUE_DEVELOPER_NAME` from Phase 1. Deploy and verify `ActiveVersionId` is non-null.
117
+
118
+ 3. **Add `connection service_email:` to the agent and republish** — follow `agent-wiring.md`. Verify the connection block is present in the deployed bundle before continuing.
119
+
120
+ ---
121
+
122
+ ## Step 4 — Mandatory manual step: BotEmailDefinition (cannot be automated)
123
+
124
+ The `BotEmailDefinition` metadata type is not yet deployable via `sf project deploy`. Surface this step only after the outbound connection block is confirmed deployed:
125
+
126
+ > *"The inbound routing flow and outbound escalation are now configured. One final manual step is required: you must create an **Email Configuration for Agentforce Service Agent** in Setup.*
127
+ >
128
+ > *Go to: `{ORG_INSTANCE_URL}/lightning/setup/AsaForEmail/home` → New*
129
+ >
130
+ > *Fill in the following fields:*
131
+ > - *Label / DeveloperName: use the agent name for identification, e.g. `{AgentLabel} Email Configuration`*
132
+ > - *Agent: select **{AgentLabel}***
133
+ > - *Reply Template: an email template containing `[[[GENERATED_CONTENT]]]` (the agent's reply body) and `[[[LEGAL_DISCLOSURE]]]` (required legal footer placeholder)*
134
+ > - *Legal Disclaimer: the legal text shown at the bottom of every agent reply email (required)*
135
+ > - *Signature: the agent's sign-off text, e.g. agent name and title (required)*
136
+ >
137
+ > *If you don't have suitable email templates yet, open the App Launcher and search for **Email Templates** to create them. The reply template must include `[[[GENERATED_CONTENT]]]` and `[[[LEGAL_DISCLOSURE]]]` as literal placeholder strings.*
138
+ >
139
+ > *Once the Email Configuration is saved, open your Email-to-Case configuration (Setup → Feature Settings → Service → Email-to-Case → edit the relevant routing address) and set the **Agentforce Configuration** field to the configuration you just created.*
140
+ >
141
+ > *Reference: [Email Configurations for Agentforce Service Agent](https://help.salesforce.com/s/articleView?id=ai.service_agent_email_configuration.htm&type=5)*
142
+ >
143
+ > Please confirm when this setup step is complete."*
144
+
145
+ Branch C is complete once the user confirms. Phase 3 outbound escalation has already been handled above — skip Phase 3 for Email-to-Case.
@@ -0,0 +1,69 @@
1
+ # Branch B — Voice inbound routing
2
+
3
+ Wires an Agentforce agent to a `PstnVoice` MessagingChannel via an inbound RoutingFlow. The queue resolved in Phase 1 acts as the fallback when the agent is unavailable.
4
+
5
+ ## Step 0 — Existing channel or new number?
6
+
7
+ Query for existing `PstnVoice` MessagingChannels on the org:
8
+
9
+ ```bash
10
+ sf data query --target-org $ORG --json \
11
+ --query "SELECT DeveloperName, MasterLabel, MessagingPlatformKey FROM MessagingChannel WHERE MessageType='PstnVoice' AND IsActive=true"
12
+ ```
13
+
14
+ Ask the user via `AskUserQuestion`:
15
+ - **One or more found** → present each as an option (`{MasterLabel} — {MessagingPlatformKey}`), plus *"Provision a new phone number"*
16
+ - **Zero found** → skip the question; proceed directly to provision a new number
17
+
18
+ **If provisioning a new number:** phone number provisioning is handled upstream by `service-helpagent-coordinate` (its own `channel-voice.md` reference) before this skill is invoked. By the time Branch B runs, the `PstnVoice` MessagingChannel already exists — set `CHANNEL_DEVELOPER_NAME` to its `DeveloperName` and proceed.
19
+
20
+ **If using an existing channel:** set `CHANNEL_DEVELOPER_NAME` to the selected channel's `DeveloperName`.
21
+
22
+ > **Check native vs 3rd-party telephony before creating the RoutingFlow.** See `channel-types.md` — if the org uses a partner telephony provider, stop and surface the message there. Do not proceed with RoutingFlow creation.
23
+
24
+ ## Step 1 — Determine names
25
+
26
+ - Flow label: `{AgentLabel} Inbound Voice Flow`
27
+ - DeveloperName: `{AgentDevName}_Inbound_Voice_Flow`
28
+ - `SERVICE_CHANNEL_DEV_NAME`: `sfdc_phone`
29
+ - `SERVICE_CHANNEL_LABEL`: `Phone`
30
+
31
+ ## Step 2 — Write the RoutingFlow XML
32
+
33
+ Write to `force-app/main/default/flows/{FLOW_DEVELOPER_NAME}.flow-meta.xml` using the template in `routing-flow.md`. Substitute all tokens including `{QUEUE_ID}` from Phase 1.
34
+
35
+ ## Step 3 — Deploy and verify
36
+
37
+ Deploy and verify `ActiveVersionId` is non-null (see `routing-flow.md`).
38
+
39
+ ## Step 4 — Assign the flow to the MessagingChannel
40
+
41
+ Deploy a `MessagingChannel` metadata file for `{CHANNEL_DEVELOPER_NAME}` with `sessionHandlerType=Flow`, `sessionHandlerFlow={FLOW_DEVELOPER_NAME}`, and `sessionHandlerQueue={QUEUE_DEVELOPER_NAME}`. This sets the "Flow Definition" field in Setup — without this step the flow is deployed but never executed and calls hang up immediately.
42
+
43
+ ```xml
44
+ <MessagingChannel xmlns="http://soap.sforce.com/2006/04/metadata">
45
+ <masterLabel>{CHANNEL_LABEL}</masterLabel>
46
+ <messagingChannelType>PstnVoice</messagingChannelType>
47
+ <sessionHandlerFlow>{FLOW_DEVELOPER_NAME}</sessionHandlerFlow>
48
+ <sessionHandlerQueue>{QUEUE_DEVELOPER_NAME}</sessionHandlerQueue>
49
+ <sessionHandlerType>Flow</sessionHandlerType>
50
+ </MessagingChannel>
51
+ ```
52
+
53
+ Verify: query `MessagingChannel WHERE DeveloperName='{CHANNEL_DEVELOPER_NAME}'` and confirm `SessionHandlerId` starts with `300` (FlowDefinition prefix).
54
+
55
+ ## Step 5 — Add `modality voice:` to the agent and republish
56
+
57
+ Retrieve the agent's authoring bundle, then add the following block at the end of the `.agent` file if it is not already present:
58
+
59
+ ```yaml
60
+ modality voice:
61
+ voice_id: "UgBBYS2sOqTuMpoF3BR0"
62
+ outbound_speed: 1.0
63
+ outbound_stability: 0.65
64
+ outbound_similarity: 0.75
65
+ ```
66
+
67
+ Do not ask the user for a `voice_id` — always use the platform default above ("Mark", en_US). The user can customize the voice afterward in Agent Builder → Connections → Voice. Then validate, publish, and activate the agent per `agent-wiring.md`. Verify the block round-tripped by re-retrieving the bundle.
68
+
69
+ Proceed to Phase 3 (optional).
@@ -0,0 +1,61 @@
1
+ # Channel types reference
2
+
3
+ ## Channel type matrix
4
+
5
+ | Channel type | SobjectType (queue) | Routing branch | SERVICE_CHANNEL_DEV_NAME | SERVICE_CHANNEL_LABEL |
6
+ |---|---|---|---|---|
7
+ | Enhanced Chat | `MessagingSession` | Branch A — set `sessionHandlerAsa` on MessagingChannel | `sfdc_livemessage` | `Messaging` |
8
+ | Enhanced Messaging (3rd-party: WhatsApp, SMS, etc.) | `MessagingSession` | Branch A — set `sessionHandlerAsa` on MessagingChannel | `sfdc_livemessage` | `Messaging` |
9
+ | Voice | `VoiceCall` | Branch B — create inbound RoutingFlow (`routingType: Copilot`) | `sfdc_phone` | `Phone` |
10
+ | Email-to-Case | `Case` | Branch C — create inbound RoutingFlow (`routingType: Copilot`) | *(query required — see below)* | *(query required)* |
11
+
12
+ ## Email-to-Case: query the org-specific ServiceChannel
13
+
14
+ The Case-based ServiceChannel DeveloperName and Label are not system-generated and vary by org. Query before writing the RoutingFlow:
15
+
16
+ ```bash
17
+ sf data query --target-org $ORG --json \
18
+ --query "SELECT DeveloperName, MasterLabel FROM ServiceChannel WHERE RelatedEntityType='Case'"
19
+ ```
20
+
21
+ - **Zero rows** → stop; surface gap to user. The channel cannot be wired until a Case-based ServiceChannel exists.
22
+ - **One row** → use its `DeveloperName` as `SERVICE_CHANNEL_DEV_NAME` and `MasterLabel` as `SERVICE_CHANNEL_LABEL`.
23
+ - **Multiple rows** → ask user to choose via `AskUserQuestion`.
24
+
25
+ ## Voice: native vs partner — MUST CHECK before Branch B
26
+
27
+ Branch B only works with **native Service Cloud Voice**. Partner telephony providers (Amazon Connect, Genesys, Avaya, etc.) manage their own routing pipelines and do not honour Salesforce RoutingFlows — wiring the agent via `routingType: Copilot` on a partner channel will have no effect.
28
+
29
+ **Detection method: query `CommunicationChannelLine` via the Tooling API.**
30
+
31
+ `CommunicationChannelLine` is a Tooling API object (not SOQL-queryable). Native SCV phone numbers have a `CommunicationChannelLine` record whose `DeveloperName` follows the pattern `DEV_{digits}` (e.g. `DEV_13375909051`). Partner voice channels do not.
32
+
33
+ **Step 1 — Extract the digits from the MessagingChannel DeveloperName.**
34
+
35
+ `PstnVoice` channels follow the pattern `VOICE_PSTN_{digits}` (e.g. `VOICE_PSTN_13375909051`). Strip the `VOICE_PSTN_` prefix to get the digits (e.g. `13375909051`).
36
+
37
+ **Step 2 — Query `CommunicationChannelLine` via the Tooling API:**
38
+
39
+ ```bash
40
+ sf data query --target-org $ORG --json --use-tooling-api \
41
+ --query "SELECT Id, DeveloperName FROM CommunicationChannelLine WHERE DeveloperName='DEV_{DIGITS}' LIMIT 1"
42
+ ```
43
+
44
+ Interpret results:
45
+
46
+ | Result | Verdict |
47
+ |---|---|
48
+ | Query returns 1+ row | **Native SCV** — Branch B is supported |
49
+ | Query returns 0 rows | **Partner voice** — Branch B not supported |
50
+
51
+ **If partner voice:** stop and surface this to the user:
52
+
53
+ > *"This voice channel uses a partner telephony provider. Routing to an Agentforce agent via a Salesforce RoutingFlow is not supported — routing is managed by the partner's system. Contact your telephony provider for agent routing options."*
54
+
55
+ Do not proceed with RoutingFlow creation for partner voice channels.
56
+
57
+ ## Routing branch summary
58
+
59
+ - **Branch A (messaging channels)**: No RoutingFlow. Set `sessionHandlerAsa` + `sessionHandlerQueue` directly on the existing `MessagingChannel` metadata. No agent republish.
60
+ - **Branch B (Voice, native only)**: Detect native vs 3rd-party first (see above). If native, create an inbound RoutingFlow with `routingType: Copilot` pointing to the agent by label, with the queue as fallback. No agent file changes.
61
+ - **Branch C (Email-to-Case)**: Same inbound RoutingFlow shape as Branch B, but with the org-specific Case-based ServiceChannel. No agent file changes.