@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,86 @@
1
+ # Live-traffic warning gate (Phase 2)
2
+
3
+ Runs once, before any branch, whenever Phase 2 begins. Prevents an unattended re-route of live traffic on a channel that already has active inbound routing.
4
+
5
+ ## Detect existing routing
6
+
7
+ - **Branch A (Enhanced Chat / Enhanced Messaging):** retrieve the MessagingChannel and inspect `SessionHandlerType`. If it is non-empty, routing is live.
8
+ - **Branches B/C (Voice / Email-to-Case):** query `FlowDefinitionView WHERE ProcessType='RoutingFlow'` for any flow assigned to this service channel with a non-null `ActiveVersionId`.
9
+
10
+ If the channel has no existing routing, skip this gate entirely and proceed directly to the branch.
11
+
12
+ ## Infer from the user's prompt before asking
13
+
14
+ Before raising `AskUserQuestion`, re-read the user's original prompt. If it already resolves the timing choice unambiguously, honor it silently — do NOT ask.
15
+
16
+ - **Defer intent already stated** — treat as if the user picked **"Set up, then wire manually"**. Set `DEFER_INBOUND_ROUTING=true` and proceed to the deferred path (below) without raising the question. Non-exhaustive trigger phrases: "do not cut over", "don't cut over", "do not cut live traffic over", "don't switch live traffic yet", "wire manually", "wire it manually when I'm ready", "review first", "let me review", "hold off on activating", "set up but don't activate", "prepare but don't route", "leave live traffic alone".
17
+ - **Cutover intent already stated** — treat as if the user picked **"Re-route now"**. Leave `DEFER_INBOUND_ROUTING` unset and proceed with immediate re-routing without raising the question. Non-exhaustive trigger phrases: "go ahead and cut over now", "re-route immediately", "cut over now", "switch live traffic now", "activate immediately", "just do it now".
18
+
19
+ Only fall through to `AskUserQuestion` when the prompt is silent or genuinely ambiguous about timing.
20
+
21
+ ## If existing routing detected and prompt is silent, ask
22
+
23
+ ```yaml
24
+ AskUserQuestion:
25
+ question: "'{CHANNEL_MASTER_LABEL}' already has active inbound routing configured.
26
+ Deploying will re-route live traffic immediately — any in-progress
27
+ conversations or calls on this channel will be affected.
28
+ How would you like to proceed?"
29
+ header: "Live traffic"
30
+ options:
31
+ - label: "Re-route now"
32
+ description: "Deploy immediately. Live traffic will be affected."
33
+ - label: "Set up, then wire manually"
34
+ description: "Create the queue and RoutingFlow (Voice/Email) now, but skip activating
35
+ inbound routing. Manual wiring instructions will be provided at the end."
36
+ ```
37
+
38
+ ### Safe default on ambiguous / no-selection response
39
+
40
+ If `AskUserQuestion` returns without a clear selection — timeout, empty answer, unrecognized reply, or any headless-run auto-resolution — default to **"Set up, then wire manually"** (set `DEFER_INBOUND_ROUTING=true`). Never default to a live re-route: the deferred path is non-destructive and recoverable; an unintended cutover is not.
41
+
42
+ ## If the user chooses "Set up, then wire manually"
43
+
44
+ Set `DEFER_INBOUND_ROUTING=true` and continue:
45
+
46
+ - **Branch A:** create the queue normally. Skip the `sf project deploy start` for the MessagingChannel entirely.
47
+ - **Branches B/C:** create the queue and write + deploy the RoutingFlow normally (the flow is safe to deploy — it only becomes live when assigned to the channel). Skip any step that assigns the flow as the active routing flow for the channel.
48
+
49
+ After Phase 2 completes, if `DEFER_INBOUND_ROUTING=true`, print manual wiring instructions before the Phase 3 prompt.
50
+
51
+ ### Branch A — activate when ready
52
+
53
+ `sessionHandlerAsa` is not accepted by the Metadata API at v67 — deploy `sessionHandlerType` + `sessionHandlerQueue` only, then bind the bot via a Data API PATCH. The bot must be Active before the PATCH ("Only active Agentforce Service Agents are supported" otherwise).
54
+
55
+ ```bash
56
+ sf project retrieve start --metadata "MessagingChannel:{CHANNEL_DEVELOPER_NAME}" --target-org {ORG}
57
+ # In the retrieved XML, set ONLY:
58
+ # <sessionHandlerType>AgentforceServiceAgent</sessionHandlerType>
59
+ # <sessionHandlerQueue>{QUEUE_DEVELOPER_NAME}</sessionHandlerQueue>
60
+ # Do NOT add <sessionHandlerAsa> — the Metadata API silently rejects it at v67.
61
+ sf project deploy start --metadata "MessagingChannel:{CHANNEL_DEVELOPER_NAME}" --target-org {ORG}
62
+
63
+ # Resolve Ids, then bind the bot via Data API PATCH:
64
+ CHAN_ID=$(sf data query -o {ORG} --json \
65
+ -q "SELECT Id FROM MessagingChannel WHERE DeveloperName='{CHANNEL_DEVELOPER_NAME}'" \
66
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
67
+ BOT_ID=$(sf data query -o {ORG} --json \
68
+ -q "SELECT Id FROM BotDefinition WHERE DeveloperName='{AGENT_DEVELOPER_NAME}'" \
69
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
70
+ QUEUE_ID=$(sf data query -o {ORG} --json \
71
+ -q "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='{QUEUE_DEVELOPER_NAME}'" \
72
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
73
+
74
+ sf api request rest --method PATCH -o {ORG} \
75
+ "/services/data/v67.0/sobjects/MessagingChannel/${CHAN_ID}" \
76
+ --body "{\"SessionHandlerId\":\"${BOT_ID}\",\"FallbackQueueId\":\"${QUEUE_ID}\"}"
77
+ # Expected: HTTP 204
78
+
79
+ # Verify — both must be non-null:
80
+ sf data query -o {ORG} --json \
81
+ -q "SELECT SessionHandlerId, FallbackQueueId FROM MessagingChannel WHERE Id='${CHAN_ID}'"
82
+ ```
83
+
84
+ ### Branches B/C — activate when ready
85
+
86
+ > The RoutingFlow `{FLOW_DEVELOPER_NAME}` is deployed and active. To assign it as the inbound routing flow, go to **Setup → Omni-Channel → Service Channels** and point the channel at this flow — or re-run this skill against the same channel; the existing flow will be detected and reused, and only the channel assignment step will run.
@@ -0,0 +1,135 @@
1
+ # Queue resolution
2
+
3
+ Run this before any channel wiring. The fallback queue must exist and have the correct `QueueSobject` record for the channel type's SobjectType.
4
+
5
+ ## Step 1 — Query existing compatible queues
6
+
7
+ Determine the SobjectType from the channel type (see `references/channel-types.md`), then query:
8
+
9
+ ```bash
10
+ sf data query --target-org $ORG --json \
11
+ --query "SELECT Queue.Name, Queue.DeveloperName, Queue.Id
12
+ FROM QueueSobject
13
+ WHERE SobjectType='{SOBJECT_TYPE}'"
14
+ ```
15
+
16
+ ## Step 2 — Present to user via AskUserQuestion
17
+
18
+ - **One or more found** → present each as an option: `{Queue.Name} ({Queue.DeveloperName})`, plus a final option *"Create a new queue"*. If the user picks an existing queue, capture its `DeveloperName` and `Id` and skip queue creation.
19
+ - **Zero found** → inform the user no compatible queue exists; proceed directly to create one.
20
+
21
+ ## Step 3 — Create a new queue (if needed)
22
+
23
+ **Naming:** `{ChannelTypeLabel} Queue` / DeveloperName `{Channel_Type_Label}_Queue`
24
+
25
+ Examples:
26
+ - Voice → `Voice Queue` / `Voice_Queue`
27
+ - Enhanced Chat → `Enhanced Chat Queue` / `Enhanced_Chat_Queue`
28
+ - Email → `Email Queue` / `Email_Queue`
29
+
30
+ ### 1. Create the Group record
31
+ ```bash
32
+ QUEUE_ID=$(sf data create record --target-org $ORG \
33
+ --sobject Group \
34
+ --values "Type='Queue' Name='{QUEUE_NAME}' DeveloperName='{QUEUE_DEVELOPER_NAME}'" \
35
+ --json | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['id'])")
36
+ ```
37
+
38
+ ### 2. Grant queue access to the correct SobjectType
39
+ ```bash
40
+ sf data create record --target-org $ORG \
41
+ --sobject QueueSobject \
42
+ --values "QueueId='$QUEUE_ID' SobjectType='{SOBJECT_TYPE}'"
43
+ ```
44
+
45
+ ### 3. Add the running user as a queue member
46
+ ```bash
47
+ ORG_USERNAME=$(sf org display --target-org $ORG --json \
48
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['username'])")
49
+ RUNNING_USER_ID=$(sf data query --target-org $ORG --json \
50
+ --query "SELECT Id FROM User WHERE Username='$ORG_USERNAME'" \
51
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
52
+ sf data create record --target-org $ORG \
53
+ --sobject GroupMember \
54
+ --values "GroupId='$QUEUE_ID' UserOrGroupId='$RUNNING_USER_ID'"
55
+ ```
56
+
57
+ ## Step 4 — Resolve or create a Routing Configuration
58
+
59
+ The queue must have a `QueueRoutingConfig` so Omni-Channel knows how to handle capacity. Query first:
60
+
61
+ ```bash
62
+ sf data query --target-org $ORG --json \
63
+ --query "SELECT Id, DeveloperName, CapacityPercentage, RoutingModel FROM QueueRoutingConfig WHERE QueueId='{QUEUE_ID}'"
64
+ ```
65
+
66
+ - **Found** → use it as-is; skip creation.
67
+ - **Not found** → create one using the capacity percentage for the channel type:
68
+
69
+ | Channel type | `CapacityPercentage` |
70
+ |---|---|
71
+ | Enhanced Chat / Enhanced Messaging | `50` |
72
+ | Voice | `100` |
73
+ | Email-to-Case | `25` |
74
+
75
+ All use `RoutingModel: LeastActive`.
76
+
77
+ ```bash
78
+ sf data create record --target-org $ORG \
79
+ --sobject QueueRoutingConfig \
80
+ --values "Name='{QUEUE_NAME} Routing' DeveloperName='{QUEUE_DEVELOPER_NAME}_Routing' QueueId='{QUEUE_ID}' CapacityPercentage={CAPACITY_PERCENTAGE} RoutingModel='LeastActive' IsAttributeBased=false"
81
+ ```
82
+
83
+ Verify the record was created:
84
+ ```bash
85
+ sf data query --target-org $ORG --json \
86
+ --query "SELECT Id, CapacityPercentage FROM QueueRoutingConfig WHERE QueueId='{QUEUE_ID}'"
87
+ ```
88
+
89
+ ## Step 5 — Capture for use in Phase 2
90
+
91
+ Store:
92
+ - `QUEUE_DEVELOPER_NAME` — used in the MessagingChannel XML (Branch A) or RoutingFlow `queueId` lookup (Branches B/C)
93
+ - `QUEUE_NAME` (the `Name` field, e.g. `Voice Queue`) — used as `queueLabel` in the RoutingFlow XML
94
+ - `QUEUE_ID` (18-char record Id) — used as `queueId` in the RoutingFlow XML
95
+
96
+ If an existing queue was chosen, query its Id if not already available:
97
+ ```bash
98
+ QUEUE_ID=$(sf data query --target-org $ORG --json \
99
+ --query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='{QUEUE_DEVELOPER_NAME}'" \
100
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Step 6 — Escalation queue resolution (Phase 3 only)
106
+
107
+ Run this step when the user opts into outbound escalation (Branches A/B). The escalation queue is the human queue that receives escalated conversations — it may be the same as the inbound fallback queue, or a different one.
108
+
109
+ ### Check whether other compatible queues exist
110
+
111
+ Query for queues with the correct SobjectType, excluding the inbound fallback queue already selected:
112
+
113
+ ```bash
114
+ sf data query --target-org $ORG --json \
115
+ --query "SELECT Queue.Name, Queue.DeveloperName, Queue.Id
116
+ FROM QueueSobject
117
+ WHERE SobjectType='{SOBJECT_TYPE}'
118
+ AND Queue.DeveloperName != '{QUEUE_DEVELOPER_NAME}'"
119
+ ```
120
+
121
+ ### Branch on results
122
+
123
+ **Zero other queues exist** → no choice to offer; reuse the inbound fallback queue. Set `ESCALATION_QUEUE_DEVELOPER_NAME = QUEUE_DEVELOPER_NAME` and `ESCALATION_QUEUE_ID = QUEUE_ID`. Continue without asking.
124
+
125
+ **One or more other queues exist** → ask the user via `AskUserQuestion`:
126
+
127
+ > *"Which queue should receive escalated conversations from the agent?"*
128
+ > - *Use the same queue as inbound fallback: `{QUEUE_NAME}` ({QUEUE_DEVELOPER_NAME})* **(Recommended)**
129
+ > - *{OtherQueue.Name} ({OtherQueue.DeveloperName})* — one option per additional compatible queue
130
+
131
+ If the user picks the fallback: `ESCALATION_QUEUE_DEVELOPER_NAME = QUEUE_DEVELOPER_NAME`, `ESCALATION_QUEUE_ID = QUEUE_ID`.
132
+
133
+ If the user picks a different queue: capture its `DeveloperName` and `Id` as `ESCALATION_QUEUE_DEVELOPER_NAME` and `ESCALATION_QUEUE_ID`.
134
+
135
+ Use `ESCALATION_QUEUE_DEVELOPER_NAME` (not `QUEUE_DEVELOPER_NAME`) when writing the outbound RoutingFlow XML in Phase 3.
@@ -0,0 +1,384 @@
1
+ # RoutingFlows — inbound and outbound
2
+
3
+ Two distinct RoutingFlows are used when wiring an agent to a channel:
4
+
5
+ | Flow | `processType` | `routingType` | Purpose |
6
+ |---|---|---|---|
7
+ | Inbound | `RoutingFlow` | `Copilot` | Routes arriving work items *to* the agent; queue is fallback when agent unavailable |
8
+ | Outbound | `RoutingFlow` | `QueueBased` | Routes *from* the agent to a human queue when the customer requests escalation |
9
+
10
+ Both flows reference the same fallback queue resolved in Phase 1. The inbound flow is created in Phase 2 (Branches B/C only — Branch A uses `sessionHandlerAsa` instead). The outbound flow is created in Phase 3 if the user opts into outbound escalation.
11
+
12
+ ---
13
+
14
+ ## Part 1 — Inbound RoutingFlow (Copilot routing)
15
+
16
+ Used for Voice (Branch B) and Email-to-Case (Branch C). When a work item arrives on the channel, it routes directly to the Agentforce Agent, with the fallback queue used when the agent is unavailable.
17
+
18
+ The `routingType` is `Copilot` (the platform token for Agentforce Agent routing). The agent is referenced by its **label** (`copilotLabel`), not its DeveloperName. The queue fallback is expressed via `queueLabel` (the queue's `Name` field) and `queueId` (the queue's 18-char record Id).
19
+
20
+ ## Naming convention
21
+
22
+ | Channel | Flow Label | DeveloperName |
23
+ |---|---|---|
24
+ | Voice | `{AgentLabel} Inbound Voice Flow` | `{AgentDevName}_Inbound_Voice_Flow` |
25
+ | Email-to-Case | `{AgentLabel} Inbound Email Flow` | `{AgentDevName}_Inbound_Email_Flow` |
26
+
27
+ ## Lookup the queue Id before writing the XML
28
+
29
+ The `queueId` parameter must be a hardcoded 18-char Id in the XML. Query it from the `QUEUE_DEVELOPER_NAME` resolved in Phase 1:
30
+
31
+ ```bash
32
+ QUEUE_ID=$(sf data query --target-org $ORG --json \
33
+ --query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='{QUEUE_DEVELOPER_NAME}'" \
34
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])")
35
+ ```
36
+
37
+ ## XML template
38
+
39
+ Substitute: `{FLOW_LABEL}`, `{FLOW_DEVELOPER_NAME}`, `{AGENT_LABEL}`, `{AGENT_DEV_NAME}` (BotDefinition DeveloperName), `{QUEUE_LABEL}` (the queue's `Name`, e.g. `Voice Queue`), `{QUEUE_ID}` (18-char Id), `{SERVICE_CHANNEL_DEV_NAME}`, `{SERVICE_CHANNEL_LABEL}`.
40
+
41
+ > **`copilotId` is required.** Without it the platform cannot resolve the agent at runtime and routes to the fallback queue instead. Use a `<setupReference>` pointing to the `BotDefinition` by DeveloperName — do not use a hardcoded Salesforce Id.
42
+
43
+ ```xml
44
+ <?xml version="1.0" encoding="UTF-8"?>
45
+ <Flow xmlns="http://soap.sforce.com/2006/04/metadata">
46
+ <actionCalls>
47
+ <name>Route_to_Agent</name>
48
+ <label>Route to Agent</label>
49
+ <locationX>0</locationX>
50
+ <locationY>0</locationY>
51
+ <actionName>routeWork</actionName>
52
+ <actionType>routeWork</actionType>
53
+ <flowTransactionModel>CurrentTransaction</flowTransactionModel>
54
+ <inputParameters>
55
+ <name>recordId</name>
56
+ <value><elementReference>recordId</elementReference></value>
57
+ </inputParameters>
58
+ <inputParameters>
59
+ <name>serviceChannelLabel</name>
60
+ <value><stringValue>{SERVICE_CHANNEL_LABEL}</stringValue></value>
61
+ </inputParameters>
62
+ <inputParameters>
63
+ <name>serviceChannelDevName</name>
64
+ <value><stringValue>{SERVICE_CHANNEL_DEV_NAME}</stringValue></value>
65
+ </inputParameters>
66
+ <inputParameters>
67
+ <name>routingType</name>
68
+ <value><stringValue>Copilot</stringValue></value>
69
+ </inputParameters>
70
+ <inputParameters>
71
+ <name>copilotLabel</name>
72
+ <value><stringValue>{AGENT_LABEL}</stringValue></value>
73
+ </inputParameters>
74
+ <inputParameters>
75
+ <name>copilotId</name>
76
+ <value>
77
+ <setupReference>{AGENT_DEV_NAME}</setupReference>
78
+ <setupReferenceType>BotDefinition</setupReferenceType>
79
+ </value>
80
+ </inputParameters>
81
+ <inputParameters>
82
+ <name>queueLabel</name>
83
+ <value><stringValue>{QUEUE_LABEL}</stringValue></value>
84
+ </inputParameters>
85
+ <inputParameters>
86
+ <name>queueId</name>
87
+ <value><stringValue>{QUEUE_ID}</stringValue></value>
88
+ </inputParameters>
89
+ <inputParameters>
90
+ <name>serviceChannelId</name>
91
+ <value>
92
+ <setupReference>{SERVICE_CHANNEL_DEV_NAME}</setupReference>
93
+ <setupReferenceType>ServiceChannel</setupReferenceType>
94
+ </value>
95
+ </inputParameters>
96
+ <nameSegment>routeWork</nameSegment>
97
+ <offset>0</offset>
98
+ <versionString>2.0.0</versionString>
99
+ </actionCalls>
100
+ <apiVersion>67.0</apiVersion>
101
+ <areMetricsLoggedToDataCloud>false</areMetricsLoggedToDataCloud>
102
+ <environments>Default</environments>
103
+ <interviewLabel>{FLOW_DEVELOPER_NAME} {!$Flow.CurrentDateTime}</interviewLabel>
104
+ <label>{FLOW_LABEL}</label>
105
+ <processMetadataValues>
106
+ <name>BuilderType</name>
107
+ <value><stringValue>LightningFlowBuilder</stringValue></value>
108
+ </processMetadataValues>
109
+ <processMetadataValues>
110
+ <name>CanvasMode</name>
111
+ <value><stringValue>AUTO_LAYOUT_CANVAS</stringValue></value>
112
+ </processMetadataValues>
113
+ <processMetadataValues>
114
+ <name>OriginBuilderType</name>
115
+ <value><stringValue>LightningFlowBuilder</stringValue></value>
116
+ </processMetadataValues>
117
+ <processType>RoutingFlow</processType>
118
+ <start>
119
+ <locationX>50</locationX>
120
+ <locationY>0</locationY>
121
+ <connector><targetReference>Route_to_Agent</targetReference></connector>
122
+ </start>
123
+ <status>Active</status>
124
+ <variables>
125
+ <name>recordId</name>
126
+ <dataType>String</dataType>
127
+ <isCollection>false</isCollection>
128
+ <isInput>true</isInput>
129
+ <isOutput>false</isOutput>
130
+ </variables>
131
+ </Flow>
132
+ ```
133
+
134
+ ## Deploy and verify
135
+
136
+ Write the XML to `force-app/main/default/flows/{FLOW_DEVELOPER_NAME}.flow-meta.xml`, then deploy:
137
+
138
+ ```bash
139
+ sf project deploy start -m "Flow:{FLOW_DEVELOPER_NAME}" --target-org $ORG
140
+ ```
141
+
142
+ Verify the flow is active:
143
+ ```bash
144
+ sf data query --target-org $ORG --json \
145
+ --query "SELECT ApiName, ActiveVersionId FROM FlowDefinitionView WHERE ApiName='{FLOW_DEVELOPER_NAME}'"
146
+ ```
147
+
148
+ `ActiveVersionId` must be non-null. If it is null, the deploy did not produce an active version — check the deploy report for errors.
149
+
150
+ ## Common failures (inbound)
151
+
152
+ | Symptom | Cause |
153
+ |---|---|
154
+ | `ActiveVersionId` is null after deploy | Flow saved as inactive draft — check for XML validation errors in the deploy report |
155
+ | Work items route to queue instead of agent | `copilotId` is missing (most common), `routingType` is `QueueBased` instead of `Copilot`, or `copilotLabel` doesn't match the agent's exact label — all three must be present and correct |
156
+ | Flow deploys but doesn't appear in Omni-Channel routing config | The flow is not yet referenced in a routing config — this skill doesn't create the routing config; the channel's own routing config must reference this flow |
157
+
158
+ ---
159
+
160
+ ## Part 2 — Outbound RoutingFlow (QueueBased escalation)
161
+
162
+ Used in Phase 3 for all channel types. When the agent escalates to a human, this flow routes the conversation to the fallback queue resolved in Phase 1.
163
+
164
+ ### Naming convention
165
+
166
+ | Channel | Flow Label | DeveloperName |
167
+ |---|---|---|
168
+ | Enhanced Chat | `{AgentLabel} Outbound Enhanced Chat Flow` | `{AgentDevName}_Outbound_Enhanced_Chat_Flow` |
169
+ | Enhanced Messaging | `{AgentLabel} Outbound Messaging Flow` | `{AgentDevName}_Outbound_Messaging_Flow` |
170
+ | Voice | `{AgentLabel} Outbound Voice Flow` | `{AgentDevName}_Outbound_Voice_Flow` |
171
+
172
+ ### Check before creating
173
+
174
+ ```bash
175
+ sf data query --target-org $ORG --json \
176
+ --query "SELECT ApiName, ActiveVersionId FROM FlowDefinitionView WHERE ApiName='{FLOW_DEVELOPER_NAME}' AND ProcessType='RoutingFlow'"
177
+ ```
178
+
179
+ If a row exists with non-null `ActiveVersionId`, reuse it — capture the `ApiName` and skip creation. If `ActiveVersionId` is null (inactive draft / OOB platform flow), create a new flow anyway — do not attempt to activate an existing draft.
180
+
181
+ ### Service channel values by channel type
182
+
183
+ | Channel | `SERVICE_CHANNEL_DEV_NAME` | `SERVICE_CHANNEL_LABEL` |
184
+ |---|---|---|
185
+ | Enhanced Chat / Enhanced Messaging | `sfdc_livemessage` | `Messaging` |
186
+ | Voice | `sfdc_phone` | `Phone` |
187
+
188
+ ### XML template
189
+
190
+ Substitute: `{FLOW_LABEL}`, `{FLOW_DEVELOPER_NAME}`, `{QUEUE_DEVELOPER_NAME}` (from Phase 1), `{SERVICE_CHANNEL_DEV_NAME}`, `{SERVICE_CHANNEL_LABEL}`.
191
+
192
+ ```xml
193
+ <?xml version="1.0" encoding="UTF-8"?>
194
+ <Flow xmlns="http://soap.sforce.com/2006/04/metadata">
195
+ <actionCalls>
196
+ <name>Check_Availability</name>
197
+ <label>Check Availability for Routing</label>
198
+ <locationX>0</locationX>
199
+ <locationY>0</locationY>
200
+ <actionName>checkAvailabilityForRouting</actionName>
201
+ <actionType>checkAvailabilityForRouting</actionType>
202
+ <connector>
203
+ <targetReference>Are_Reps_Available</targetReference>
204
+ </connector>
205
+ <flowTransactionModel>CurrentTransaction</flowTransactionModel>
206
+ <inputParameters>
207
+ <name>serviceChannelId</name>
208
+ <value>
209
+ <setupReference>{SERVICE_CHANNEL_DEV_NAME}</setupReference>
210
+ <setupReferenceType>ServiceChannel</setupReferenceType>
211
+ </value>
212
+ </inputParameters>
213
+ <inputParameters>
214
+ <name>serviceChannelLabel</name>
215
+ <value><stringValue>{SERVICE_CHANNEL_LABEL}</stringValue></value>
216
+ </inputParameters>
217
+ <inputParameters>
218
+ <name>serviceChannelDevName</name>
219
+ <value><stringValue>{SERVICE_CHANNEL_DEV_NAME}</stringValue></value>
220
+ </inputParameters>
221
+ <inputParameters>
222
+ <name>routingType</name>
223
+ <value><stringValue>QueueBased</stringValue></value>
224
+ </inputParameters>
225
+ <inputParameters>
226
+ <name>queueId</name>
227
+ <value><elementReference>Lookup_Queue_by_Name.Id</elementReference></value>
228
+ </inputParameters>
229
+ <inputParameters>
230
+ <name>isQueueVariable</name>
231
+ <value><booleanValue>true</booleanValue></value>
232
+ </inputParameters>
233
+ <inputParameters>
234
+ <name>selectedOutputs</name>
235
+ <value><stringValue>GET_AVAILABILITY</stringValue></value>
236
+ </inputParameters>
237
+ <nameSegment>checkAvailabilityForRouting</nameSegment>
238
+ <outputParameters>
239
+ <assignToReference>onlineAgentsCount</assignToReference>
240
+ <name>onlineAgentsCount</name>
241
+ </outputParameters>
242
+ <versionString>2.0.0</versionString>
243
+ </actionCalls>
244
+ <actionCalls>
245
+ <name>Route_to_Queue</name>
246
+ <label>Route to Queue</label>
247
+ <locationX>0</locationX>
248
+ <locationY>0</locationY>
249
+ <actionName>routeWork</actionName>
250
+ <actionType>routeWork</actionType>
251
+ <flowTransactionModel>CurrentTransaction</flowTransactionModel>
252
+ <inputParameters>
253
+ <name>recordId</name>
254
+ <value><elementReference>recordId</elementReference></value>
255
+ </inputParameters>
256
+ <inputParameters>
257
+ <name>serviceChannelLabel</name>
258
+ <value><stringValue>{SERVICE_CHANNEL_LABEL}</stringValue></value>
259
+ </inputParameters>
260
+ <inputParameters>
261
+ <name>serviceChannelDevName</name>
262
+ <value><stringValue>{SERVICE_CHANNEL_DEV_NAME}</stringValue></value>
263
+ </inputParameters>
264
+ <inputParameters>
265
+ <name>routingType</name>
266
+ <value><stringValue>QueueBased</stringValue></value>
267
+ </inputParameters>
268
+ <inputParameters>
269
+ <name>serviceChannelId</name>
270
+ <value>
271
+ <setupReference>{SERVICE_CHANNEL_DEV_NAME}</setupReference>
272
+ <setupReferenceType>ServiceChannel</setupReferenceType>
273
+ </value>
274
+ </inputParameters>
275
+ <inputParameters>
276
+ <name>queueId</name>
277
+ <value><elementReference>Lookup_Queue_by_Name.Id</elementReference></value>
278
+ </inputParameters>
279
+ <inputParameters>
280
+ <name>isQueueVariable</name>
281
+ <value><booleanValue>true</booleanValue></value>
282
+ </inputParameters>
283
+ <nameSegment>routeWork</nameSegment>
284
+ <versionString>2.0.0</versionString>
285
+ </actionCalls>
286
+ <apiVersion>67.0</apiVersion>
287
+ <areMetricsLoggedToDataCloud>false</areMetricsLoggedToDataCloud>
288
+ <decisions>
289
+ <name>Are_Reps_Available</name>
290
+ <label>Are Reps Available?</label>
291
+ <locationX>0</locationX>
292
+ <locationY>0</locationY>
293
+ <defaultConnectorLabel>No</defaultConnectorLabel>
294
+ <rules>
295
+ <name>Reps_Available</name>
296
+ <conditionLogic>and</conditionLogic>
297
+ <conditions>
298
+ <leftValueReference>onlineAgentsCount</leftValueReference>
299
+ <operator>GreaterThan</operator>
300
+ <rightValue><numberValue>0.0</numberValue></rightValue>
301
+ </conditions>
302
+ <connector><targetReference>Route_to_Queue</targetReference></connector>
303
+ <label>Yes</label>
304
+ </rules>
305
+ </decisions>
306
+ <environments>Default</environments>
307
+ <interviewLabel>{FLOW_DEVELOPER_NAME} {!$Flow.CurrentDateTime}</interviewLabel>
308
+ <label>{FLOW_LABEL}</label>
309
+ <processMetadataValues>
310
+ <name>BuilderType</name>
311
+ <value><stringValue>LightningFlowBuilder</stringValue></value>
312
+ </processMetadataValues>
313
+ <processMetadataValues>
314
+ <name>CanvasMode</name>
315
+ <value><stringValue>AUTO_LAYOUT_CANVAS</stringValue></value>
316
+ </processMetadataValues>
317
+ <processMetadataValues>
318
+ <name>OriginBuilderType</name>
319
+ <value><stringValue>LightningFlowBuilder</stringValue></value>
320
+ </processMetadataValues>
321
+ <processType>RoutingFlow</processType>
322
+ <recordLookups>
323
+ <name>Lookup_Queue_by_Name</name>
324
+ <label>Lookup Queue by Name</label>
325
+ <locationX>0</locationX>
326
+ <locationY>0</locationY>
327
+ <assignNullValuesIfNoRecordsFound>false</assignNullValuesIfNoRecordsFound>
328
+ <connector><targetReference>Check_Availability</targetReference></connector>
329
+ <filterLogic>and</filterLogic>
330
+ <filters>
331
+ <field>DeveloperName</field>
332
+ <operator>EqualTo</operator>
333
+ <value><stringValue>{QUEUE_DEVELOPER_NAME}</stringValue></value>
334
+ </filters>
335
+ <filters>
336
+ <field>Type</field>
337
+ <operator>EqualTo</operator>
338
+ <value><stringValue>Queue</stringValue></value>
339
+ </filters>
340
+ <getFirstRecordOnly>true</getFirstRecordOnly>
341
+ <object>Group</object>
342
+ <storeOutputAutomatically>true</storeOutputAutomatically>
343
+ </recordLookups>
344
+ <start>
345
+ <locationX>0</locationX>
346
+ <locationY>0</locationY>
347
+ <connector><targetReference>Lookup_Queue_by_Name</targetReference></connector>
348
+ </start>
349
+ <status>Active</status>
350
+ <variables>
351
+ <name>onlineAgentsCount</name>
352
+ <dataType>Number</dataType>
353
+ <isCollection>false</isCollection>
354
+ <isInput>false</isInput>
355
+ <isOutput>false</isOutput>
356
+ <scale>0</scale>
357
+ </variables>
358
+ <variables>
359
+ <name>recordId</name>
360
+ <dataType>String</dataType>
361
+ <isCollection>false</isCollection>
362
+ <isInput>true</isInput>
363
+ <isOutput>false</isOutput>
364
+ </variables>
365
+ </Flow>
366
+ ```
367
+
368
+ ### Deploy and verify
369
+
370
+ ```bash
371
+ sf project deploy start -m "Flow:{FLOW_DEVELOPER_NAME}" --target-org $ORG
372
+ sf data query --target-org $ORG --json \
373
+ --query "SELECT ApiName, ActiveVersionId FROM FlowDefinitionView WHERE ApiName='{FLOW_DEVELOPER_NAME}'"
374
+ ```
375
+
376
+ `ActiveVersionId` must be non-null. Capture `{FLOW_DEVELOPER_NAME}` for use in the agent's connection block (`outbound_route_name: "flow://{FLOW_DEVELOPER_NAME}"`).
377
+
378
+ ## Common failures (outbound)
379
+
380
+ | Symptom | Cause |
381
+ |---|---|
382
+ | `ActiveVersionId` is null after deploy | Flow saved as inactive draft — check XML for validation errors |
383
+ | Escalation goes nowhere / agent hangs | Connection block uses wrong key (`messaging:` instead of `customer_web_client:` for EmbeddedMessaging, etc.) — see `agent-wiring.md` |
384
+ | No agents available — queue not receiving work | Queue lacks a `QueueSobject` for the correct SobjectType — recheck Phase 1 |