@salesforce/afv-skills 1.66.0 → 1.68.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.
- package/README.md +55 -5
- package/package.json +2 -4
- package/skills/agentforce-offline-experimentation-run/SKILL.md +26 -49
- package/skills/agentforce-offline-experimentation-run/scripts/bt_compare.py +81 -0
- package/skills/agentforce-offline-experimentation-run/scripts/bt_fetch.py +358 -0
- package/skills/agentforce-offline-experimentation-run/scripts/bt_patch_agent.py +110 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/__init__.py +34 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/agentpatch.py +483 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/agentsrc.py +565 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/cache.py +95 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/compare.py +617 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/fetch.py +1012 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/judge.py +148 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/messages.py +92 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/patch.py +327 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/redact.py +40 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/results.py +288 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/scoring.py +340 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/sfap.py +238 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/splits.py +136 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/stdm.py +98 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/tokens.py +173 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/units.py +199 -0
- package/skills/agentforce-offline-experimentation-run/scripts/btlib/versions.py +194 -0
- package/skills/agentforce-offline-experimentation-run/scripts/build_report.py +366 -378
- package/skills/agentforce-offline-experimentation-run/scripts/resolve-token.sh +14 -4
- package/skills/agentforce-offline-experimentation-run/scripts/sfap_replay.py +472 -796
- package/skills/commerce-react-storefront-create/SKILL.md +350 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +2 -2
- package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +28 -16
- package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +18 -1
- package/skills/dx-lifecycle-center/SKILL.md +5 -2
- package/skills/dx-lifecycle-center/assets/widgets/connect-connected/connect-connected.json +65 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-connected/schema.json +32 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-sign-in/connect-sign-in.json +57 -0
- package/skills/dx-lifecycle-center/assets/widgets/connect-sign-in/schema.json +21 -0
- package/skills/dx-lifecycle-center/examples/workflows.md +20 -6
- package/skills/dx-lifecycle-center/references/connect-org.md +21 -2
- package/skills/dx-lifecycle-center/references/deploy.md +2 -2
- package/skills/dx-lifecycle-center/references/list-orgs.md +1 -1
- package/skills/dx-lifecycle-center/scripts/card-policy.jq +71 -0
- package/skills/dx-lifecycle-center/scripts/fill-widget.jq +29 -0
- package/skills/dx-lifecycle-center/scripts/widget.sh +28 -0
- package/skills/dx-org-devhub-configure/SKILL.md +85 -84
- package/skills/dx-org-devhub-configure/examples/status-output.md +25 -2
- package/skills/dx-org-devhub-configure/scripts/devhub.sh +265 -140
- package/skills/dx-org-devhub-configure/scripts/test-devhub.sh +100 -15
- package/skills/dx-packaging-move-to-2gp-migrate/SKILL.md +89 -0
- package/skills/dx-packaging-move-to-2gp-migrate/references/api-operations.md +164 -0
- package/skills/dx-scratch-def-configure/SKILL.md +163 -0
- package/skills/dx-scratch-def-configure/examples/confirm-card.md +53 -0
- package/skills/dx-scratch-def-configure/examples/report-recipes.md +100 -0
- package/skills/dx-scratch-def-configure/references/features.json +3270 -0
- package/skills/dx-scratch-def-configure/references/project-scratch-def.schema.json +1841 -0
- package/skills/dx-scratch-def-configure/references/settings-map.json +682 -0
- package/skills/dx-scratch-def-configure/scripts/lib_scratch_def.py +1306 -0
- package/skills/dx-scratch-def-configure/scripts/requirements.txt +3 -0
- package/skills/dx-scratch-def-configure/scripts/scrape_config_values.py +848 -0
- package/skills/education-cloud-domain-configure/SKILL.md +22 -24
- package/skills/education-cloud-domain-configure/references/dependent-features.md +9 -0
- package/skills/education-cloud-domain-configure/references/domain-features.md +15 -0
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +8 -0
- package/skills/education-cloud-domain-configure/references/setup-widgets.md +123 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +1 -1
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +1 -1
- package/skills/experience-design-validate/SKILL.md +1 -1
- package/skills/experience-search-coordinate/SKILL.md +19 -13
- package/skills/experience-search-coordinate/references/content-route.md +79 -1
- package/skills/experience-search-coordinate/references/media-route.md +30 -4
- package/skills/experience-ui-bundle-features-generate/SKILL.md +1 -1
- package/skills/experience-ui-bundle-mfa-configure/SKILL.md +1 -1
- package/skills/field-service-data-capture-migrate/SKILL.md +1 -1
- package/skills/platform-apex-generate/SKILL.md +14 -11
- package/skills/platform-apex-test-generate/SKILL.md +2 -1
- package/skills/platform-datamask-run/SKILL.md +52 -71
- package/skills/platform-datamask-run/references/api-surface.md +10 -4
- package/skills/platform-datamask-run/references/policy-authoring.md +56 -7
- package/skills/platform-datamask-run/references/run-and-abort.md +17 -10
- package/skills/platform-datamask-run/scripts/poll-job.sh +15 -25
- package/skills/platform-dataspace-access-configure/SKILL.md +19 -1
- package/skills/platform-metadata-deploy/README.md +1 -1
- package/skills/platform-metadata-deploy/SKILL.md +114 -15
- package/skills/platform-metadata-deploy/references/agent-deployment-guide.md +3 -4
- package/skills/platform-metadata-deploy/references/orchestration.md +2 -3
- package/skills/platform-metadata-discovery-get/SKILL.md +185 -0
- package/skills/platform-metadata-discovery-get/references/api-map.md +25 -0
- package/skills/platform-metadata-discovery-get/references/h360-routes.md +30 -0
- package/skills/platform-metadata-discovery-get/references/scoped-soql.md +52 -0
- package/skills/platform-metadata-grounding-get/SKILL.md +170 -0
- package/skills/platform-policy-rule-generate/SKILL.md +84 -232
- package/skills/platform-policy-rule-generate/references/condition-model.md +47 -0
- package/skills/platform-policy-rule-generate/references/condition-templates.md +89 -0
- package/skills/platform-policy-rule-generate/references/conjunction-compiler.md +25 -0
- package/skills/platform-policy-rule-generate/references/conjunction-expression.md +22 -0
- package/skills/platform-policy-rule-generate/references/consumer-all.md +9 -0
- package/skills/platform-policy-rule-generate/references/consumer-datacloud-ui.md +91 -0
- package/skills/platform-policy-rule-generate/references/deploy-errors.md +24 -36
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/policyRuleDefinitionSets/ExistsJoinRLS.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/ExistsJoinRLS/policyRuleDefinitions/ExistsJoinRLS_Rule_1.policyRuleDefinition +91 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/policyRuleDefinitionSets/FieldReadDeny.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/FieldReadDeny/policyRuleDefinitions/FieldReadDeny_Rule_1.policyRuleDefinition +72 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/policyRuleDefinitionSets/LastCharactersFieldMasking.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/LastCharactersFieldMasking/policyRuleDefinitions/LastCharactersFieldMasking_Rule_1.policyRuleDefinition +77 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/policyRuleDefinitionSets/PrincipalFieldMatchRLS.policyRuleDefinitionSet +6 -0
- package/skills/platform-policy-rule-generate/references/examples/PrincipalFieldMatchRLS/policyRuleDefinitions/PrincipalFieldMatchRLS_Rule_1.policyRuleDefinition +77 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/package.xml +12 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/policyRuleDefinitionSets/TaggedObjectAccess.policyRuleDefinitionSet +4 -0
- package/skills/platform-policy-rule-generate/references/examples/TaggedObjectAccess/policyRuleDefinitions/TaggedObjectAccess_Rule_1.policyRuleDefinition +65 -0
- package/skills/platform-policy-rule-generate/references/headless-transport.md +87 -0
- package/skills/platform-policy-rule-generate/references/policy-schema-full.md +17 -10
- package/skills/platform-policy-rule-generate/references/policy-shapes.md +74 -0
- package/skills/platform-policy-rule-generate/references/principal-expression.md +31 -0
- package/skills/platform-policy-rule-generate/references/reference-resolution.md +51 -0
- package/skills/platform-policy-rule-generate/references/resource-expression.md +48 -0
- package/skills/platform-policy-rule-generate/references/runtime-context.md +9 -0
- package/skills/platform-policy-rule-generate/references/templates-access.md +11 -9
- package/skills/platform-policy-rule-generate/references/templates-advanced.md +4 -2
- package/skills/platform-policy-rule-generate/references/templates-record.md +37 -22
- package/skills/platform-policy-rule-generate/references/templates-transform.md +10 -8
- package/skills/platform-policy-rule-generate/references/templates.md +2 -2
- package/skills/platform-policy-rule-generate/references/ui-compatibility.md +35 -17
- package/skills/platform-report-generate/SKILL.md +9 -4
- package/skills/platform-report-generate/references/chart-types.md +26 -2
- package/skills/platform-report-generate/references/column-names.md +43 -0
- package/skills/platform-report-generate/references/errors-and-troubleshooting.md +1 -1
- package/skills/platform-report-generate/references/verification-checklist.md +10 -2
- package/skills/platform-value-set-generate/SKILL.md +19 -19
- package/skills/platform-widget-generate/SKILL.md +25 -51
- package/skills/platform-widget-generate/examples/formulas.json +19 -2
- package/skills/platform-widget-generate/examples/localized-labels.json +57 -0
- package/skills/platform-widget-generate/references/widget-actions.md +29 -0
- package/skills/platform-widget-generate/references/widget-bundle-validation.md +1 -0
- package/skills/platform-widget-generate/references/widget-formulas.md +24 -7
- package/skills/platform-widget-generate/references/widget-gotchas.md +10 -0
- package/skills/platform-widget-generate/references/widget-labels.md +78 -0
- package/skills/platform-widget-generate/references/widget-styling.md +12 -0
- package/skills/sales-call-scoring-configure/SKILL.md +17 -10
- package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +55 -33
- package/skills/service-digital-engagement-channel-configure/SKILL.md +11 -7
- package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml +33 -0
- package/skills/service-digital-engagement-channel-configure/references/channel_settings.md +123 -16
- package/skills/service-digital-engagement-deployment-configure/SKILL.md +37 -100
- package/skills/service-digital-engagement-deployment-configure/assets/esd_web_update_template.xml +83 -8
- package/skills/service-digital-engagement-deployment-configure/examples/esd_web_prechat_fields.xml +74 -0
- package/skills/service-digital-engagement-deployment-configure/references/connect_api_creation.md +13 -3
- package/skills/service-digital-engagement-deployment-configure/references/deployment_settings.md +13 -78
- package/skills/service-digital-engagement-deployment-configure/references/onboarding_contract.md +5 -6
- package/skills/service-digital-engagement-deployment-configure/references/prechat_forms.md +245 -0
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +164 -120
- package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +61 -37
- package/skills/service-itsm-agentic-setup-incident-management/references/audit-tracking.md +42 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/broadcast-communications.md +23 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/email-to-incident.md +23 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-dashboards.md +25 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +30 -146
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +32 -136
- package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +32 -155
- package/skills/service-itsm-agentic-setup-incident-management/references/manage-incidents-with-ai.md +45 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/priority-matrix.md +32 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +30 -140
- package/skills/service-itsm-agentic-setup-incident-management/references/sla-milestones.md +110 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Widget Localization with Custom Labels
|
|
2
|
+
|
|
3
|
+
A widget shows translated text by referencing a Salesforce Custom Label instead of a hardcoded string.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Syntax
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
{!$Label.c.<LabelName>}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
- `c` is the org's default namespace. Always write it.
|
|
14
|
+
- The label name is static. Never build it from data — `{!$Label.c.$attrs.key}` can't be validated when the widget is saved.
|
|
15
|
+
- A `$Label` reference is not a `$attrs` binding and has no entry in `schema.json`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## What to localize
|
|
20
|
+
|
|
21
|
+
Replace every static, user-visible string in an allowed attribute, unless the user limited the request to specific strings.
|
|
22
|
+
|
|
23
|
+
**Allowed**
|
|
24
|
+
|
|
25
|
+
- Display text: `text`, `label`, `placeholder`, `title`, and other free-form string attributes (per `getUiComponentSchemas`)
|
|
26
|
+
- Text results inside a formula, e.g. the branches of an `IF` or `CASE`
|
|
27
|
+
|
|
28
|
+
**Not allowed**
|
|
29
|
+
|
|
30
|
+
- `meta` directives (`if`, `forEach`, `forItem`)
|
|
31
|
+
- Enum-valued attributes (`variant`, `size`, `color`, `gap`, `align`, `justify`) and icon names
|
|
32
|
+
- Anything inside `actions` (`url`, `target`, `sendMessage` `content`)
|
|
33
|
+
- Data bound with `$attrs` / `$item` — payload values are not translated
|
|
34
|
+
- `schema.json` and the `-meta.xml`
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Label names
|
|
39
|
+
|
|
40
|
+
Reuse existing labels first. If the user names labels, or the project's CustomLabels file (`labels/CustomLabels.labels-meta.xml`) already has a label whose value matches the text, reference that label's `fullName` verbatim. Otherwise propose `<WidgetName>_<Role>`.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Combining labels with data
|
|
45
|
+
|
|
46
|
+
- Join a label and data with `&` (see `references/widget-formulas.md`):
|
|
47
|
+
`"text": "{!$Label.c.<LabelName> & ' ' & TEXT($attrs.<attrName>)}"`
|
|
48
|
+
- Choose between labels with `IF` / `CASE`:
|
|
49
|
+
`"label": "{!IF($attrs.<booleanAttr>, $Label.c.<LabelWhenTrue>, $Label.c.<LabelWhenFalse>)}"`
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Creating labels
|
|
54
|
+
|
|
55
|
+
This skill gives no guidance on authoring label metadata, and the widget is complete without it. Create labels only when the user asks you to. When you do, add them to the project's existing CustomLabels file instead of overwriting it, and never redefine a label that already exists. The user is responsible for checking the labels and any translations in the org and for deploying them with or before the widget.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Label report
|
|
60
|
+
|
|
61
|
+
End the response with this report:
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
### Custom Labels used by this widget
|
|
65
|
+
|
|
66
|
+
These labels must exist in the target org before you deploy — deploying a widget that references a missing label fails.
|
|
67
|
+
|
|
68
|
+
| Label name | Value (default language) | Status | Used in |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| OrderStatus_Heading | Order status | Existing | `tile/text` `text` (widget heading) |
|
|
71
|
+
| OrderStatus_TrackButton | Track order | To create | `tile/button` `label` |
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- List each distinct label once, in the order it first appears in the widget.
|
|
75
|
+
- **Label name** is the `fullName`, without the `c.` prefix.
|
|
76
|
+
- **Value** is the literal text the label replaced.
|
|
77
|
+
- **Status** is `Existing` (already in the project or named by the user), `Created` (you wrote it), or `To create` (the user must create it).
|
|
78
|
+
- **Used in** names the block definition and attribute.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Widget Styling Best Practices
|
|
2
|
+
|
|
3
|
+
Widgets express *intent*, not pixels. Each surface provides a default look and feel; brand/theme overrides apply automatically.
|
|
4
|
+
|
|
5
|
+
- **Style semantically.** Use `variant`, `size`, and other enum-typed attributes (`primary`, `destructive`, `success`, `warning`). Do not pin literal colors or pixel values.
|
|
6
|
+
- **One primary action per visible group.** At most one `tile/button` with `variant: primary`. Use `secondary` or `destructive` for additional actions (see the `tile/button` schema for the full variant enum).
|
|
7
|
+
- **Every `tile/button` needs a `click` action.** See SKILL.md *Actions* — an action-less button renders disabled.
|
|
8
|
+
- **One `h1` per widget.** Use `h2`/`h3` for sub-section headings, `body` for prose, `caption` for helper text.
|
|
9
|
+
- **Use semantic state variants on state-bearing blocks** (`tile/badge`, `tile/callout`).
|
|
10
|
+
- **Omit attributes that equal the schema default.** Check each property's `default` in the `getUiComponentSchemas` metadata (step 4). If the value you would write matches it — e.g. `gap`, `size`, or `action/openLink` `target: "_blank"` — leave the attribute out. Set an attribute only to change it.
|
|
11
|
+
- **Don't pin `width`** unless a content constraint requires it.
|
|
12
|
+
- **Use the Lucide icon set.** Pass the Lucide name (`"check"`, `"alert-circle"`); other icon libraries are not supported.
|
|
@@ -146,12 +146,19 @@ Classify the org into one of 4 states:
|
|
|
146
146
|
### Phase 3 — Prerequisite enablement (State 2 only)
|
|
147
147
|
|
|
148
148
|
- **License gate (checked first):** query `OrganizationSettingsDetail`
|
|
149
|
-
(Tooling API) for the `ECICallScoringAI` OrgPermission.
|
|
150
|
-
`
|
|
151
|
-
requires Agentforce for Sales license." Non-zero exit.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
**
|
|
149
|
+
(Tooling API) for the `ECICallScoringAI` OrgPermission. Only an **explicit
|
|
150
|
+
`false`** refuses — exit with: "AI call coaching is not available in this
|
|
151
|
+
org and org requires Agentforce for Sales license." (Non-zero exit.) If the
|
|
152
|
+
permission **can't be read** — the query is rejected with `INVALID_TYPE`
|
|
153
|
+
(some org editions, for example Developer Edition) or returns no row — treat
|
|
154
|
+
it as **unknown and proceed**; do NOT fail closed on an unreadable signal.
|
|
155
|
+
The Einstein GenAI `TYPE_UNAVAILABLE` pre-check catches most unlicensed
|
|
156
|
+
orgs; the enable `updateMetadata` write is the final check. This mirrors the Phase 0
|
|
157
|
+
`ConversationPilot` gate, which defers on any non-conclusive read.
|
|
158
|
+
This runs even when `enableCallCoaching`/`enableECICallScoring`
|
|
159
|
+
already read favorably, since those settings don't by themselves confirm the
|
|
160
|
+
org is licensed. **Must run before the ECI-off check below** — a genuinely
|
|
161
|
+
unlicensed org
|
|
155
162
|
and a licensed-but-toggled-off org both read `enableCallCoaching=false`,
|
|
156
163
|
so checking ECI first would misdiagnose a licensing gap as a self-serve
|
|
157
164
|
Setup toggle (the regression the `NoLicense` eval dataset guards against).
|
|
@@ -217,7 +224,7 @@ Re-read `enableECICallScoring`. Require `true`. Print SOAP response on failure.
|
|
|
217
224
|
is server-side read-only and `updateMetadata` returns
|
|
218
225
|
`INSUFFICIENT_ACCESS_OR_READONLY`. `enable-call-scoring.sh` maps this to a
|
|
219
226
|
transient "still finishing turning on — wait a few minutes and re-run"
|
|
220
|
-
message rather than a terminal failure
|
|
227
|
+
message rather than a terminal failure.
|
|
221
228
|
- **Every SOAP call is bounded by a 30s timeout** (`CURL_TIMEOUT` in
|
|
222
229
|
`enable-call-scoring.sh`, matching the only existing timeout precedent in
|
|
223
230
|
this repo — the Pipeline skill's `setup-all.sh`) and classified via
|
|
@@ -243,14 +250,14 @@ Re-read `enableECICallScoring`. Require `true`. Print SOAP response on failure.
|
|
|
243
250
|
- **SOAP helpers**: `scripts/shared/soap.sh` (copied from the Pipeline skill —
|
|
244
251
|
`redact_token`, `parse_soap_response`)
|
|
245
252
|
- **Server-side gate** (declarative access check):
|
|
246
|
-
`
|
|
253
|
+
`ConversationalIntelligence.accessChecks.xml`
|
|
247
254
|
— `orgHasCallScoring` = ECI arm OR River Rush arm; `orgHasECICallScoringWithAI`
|
|
248
255
|
adds Einstein GenAI + `ECICallScoringAI` license perm on top.
|
|
249
256
|
- **Pref declaration**:
|
|
250
|
-
`
|
|
257
|
+
`ConversationalIntelligence.settings.xml`
|
|
251
258
|
— `<orgPreference name="ECICallScoringEnabled" mdApiName="enableECICallScoring" ...>`
|
|
252
259
|
- **Java feature registration** (would be the entry point if a
|
|
253
|
-
SetupDiscoveryService REST/MCP wrapper existed): `
|
|
260
|
+
SetupDiscoveryService REST/MCP wrapper existed): `CoachingCompetenciesFeature.java`
|
|
254
261
|
|
|
255
262
|
## Competency CRUD workflow
|
|
256
263
|
|
|
@@ -61,14 +61,14 @@ resolve_org_auth_with_token "$ORG_ALIAS" || exit 1
|
|
|
61
61
|
# orgs) reject the OrganizationSettingsDetail query with INVALID_TYPE. That's
|
|
62
62
|
# not a licensing signal — it's a metadata-availability signal. Treat any
|
|
63
63
|
# non-conclusive result as "unknown, defer to SOAP" and only refuse when the
|
|
64
|
-
# query explicitly comes back "false"
|
|
64
|
+
# query explicitly comes back "false".
|
|
65
65
|
CONVERSATIONPILOT_ENABLED=""
|
|
66
66
|
if CONVERSATIONPILOT_RAW=$(sf data query --target-org "$ORG_ALIAS" --use-tooling-api \
|
|
67
67
|
--query "SELECT SettingValue FROM OrganizationSettingsDetail WHERE SettingName='ConversationPilot' AND DataType='OrgPermissionSettings'" \
|
|
68
68
|
--json 2>/dev/null); then
|
|
69
69
|
CONVERSATIONPILOT_JSON=$(echo "$CONVERSATIONPILOT_RAW" | awk '/^{/,EOF')
|
|
70
70
|
if echo "$CONVERSATIONPILOT_JSON" | jq -e '.status == 0' >/dev/null 2>&1; then
|
|
71
|
-
CONVERSATIONPILOT_ENABLED=$(echo "$CONVERSATIONPILOT_JSON" | jq -r '.result.records[0].SettingValue
|
|
71
|
+
CONVERSATIONPILOT_ENABLED=$(echo "$CONVERSATIONPILOT_JSON" | jq -r '.result.records[0].SettingValue | select(. != null)')
|
|
72
72
|
fi
|
|
73
73
|
fi
|
|
74
74
|
|
|
@@ -215,7 +215,6 @@ fi
|
|
|
215
215
|
# doing a write — Einstein GenAI Platform is a hard prerequisite for AI
|
|
216
216
|
# Call Scoring, so an org that can't even see that settings type won't be
|
|
217
217
|
# able to enable Call Coaching regardless of what the ECI toggle says.
|
|
218
|
-
# W-24026047.
|
|
219
218
|
#
|
|
220
219
|
# Not perfect: an org could have the GenAI platform present but still lack
|
|
221
220
|
# the specific Call Scoring license. State 2c's ECICallScoringAI
|
|
@@ -245,19 +244,33 @@ if ECICALLSCORINGAI_RAW=$(sf data query --target-org "$ORG_ALIAS" --use-tooling-
|
|
|
245
244
|
--json 2>/dev/null); then
|
|
246
245
|
ECICALLSCORINGAI_JSON=$(echo "$ECICALLSCORINGAI_RAW" | awk '/^{/,EOF')
|
|
247
246
|
if echo "$ECICALLSCORINGAI_JSON" | jq -e '.status == 0' >/dev/null 2>&1; then
|
|
248
|
-
|
|
247
|
+
# A missing row means "couldn't read it", NOT "license is off" — default
|
|
248
|
+
# to empty (unknown), never to "false". OrganizationSettingsDetail is not
|
|
249
|
+
# queryable (INVALID_TYPE) on some org editions (for example Developer
|
|
250
|
+
# Edition) and can return zero rows even when queryable; both are "can't
|
|
251
|
+
# tell", and collapsing them to "false" fails closed. Use select(), not
|
|
252
|
+
# `// empty`: SettingValue is a boolean and `//` drops an explicit false.
|
|
253
|
+
ECICALLSCORINGAI_ENABLED=$(echo "$ECICALLSCORINGAI_JSON" | jq -r '.result.records[0].SettingValue | select(. != null)')
|
|
249
254
|
fi
|
|
250
255
|
fi
|
|
251
256
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
257
|
+
# Only an EXPLICIT negative refuses. An unknown result — the query was
|
|
258
|
+
# rejected (INVALID_TYPE on this org shape) or returned no row — must NOT
|
|
259
|
+
# hard-fail: doing so blocks legitimately-licensed orgs where
|
|
260
|
+
# OrganizationSettingsDetail simply isn't queryable. This mirrors the Phase 0
|
|
261
|
+
# ConversationPilot gate, which defers to SOAP on any non-conclusive read. The
|
|
262
|
+
# 2a-pre GenAI TYPE_UNAVAILABLE gate above catches most unlicensed orgs, and
|
|
263
|
+
# the updateMetadata write below is the final check — a truly unlicensed org
|
|
264
|
+
# faults on the write. Closes the residual gap the earlier
|
|
265
|
+
# GenAI-proxy fix left behind.
|
|
266
|
+
if [[ "$ECICALLSCORINGAI_ENABLED" == "false" ]]; then
|
|
267
|
+
echo "AI call coaching is not available in this org and org requires Agentforce for Sales license."
|
|
255
268
|
exit 1
|
|
256
269
|
fi
|
|
257
270
|
|
|
258
|
-
if [[ "$ECICALLSCORINGAI_ENABLED"
|
|
259
|
-
echo "
|
|
260
|
-
|
|
271
|
+
if [[ -z "$ECICALLSCORINGAI_ENABLED" ]]; then
|
|
272
|
+
echo "Couldn't confirm the AI Call Scoring license on this org — continuing;"
|
|
273
|
+
echo " if the license is missing, the enable step will report it."
|
|
261
274
|
fi
|
|
262
275
|
|
|
263
276
|
# 2b. ECI must be enabled — this skill is ECI-only.
|
|
@@ -363,7 +376,7 @@ EOF
|
|
|
363
376
|
# read-only and updateMetadata returns INSUFFICIENT_ACCESS_OR_READONLY.
|
|
364
377
|
# This is a transient state that self-resolves in a few minutes, not a
|
|
365
378
|
# permanent failure — surface a wait-and-retry message instead of the
|
|
366
|
-
# generic error.
|
|
379
|
+
# generic error.
|
|
367
380
|
case "$CS_RESULT" in
|
|
368
381
|
WRITE_ERROR:INSUFFICIENT_ACCESS_OR_READONLY*)
|
|
369
382
|
echo " Einstein Conversation Insights is still finishing turning on."
|
|
@@ -388,31 +401,40 @@ CCR_LOOKUP=$(sf api request rest \
|
|
|
388
401
|
"services/data/v68.0/tooling/query/?q=SELECT+Id,SettingValue+FROM+OrganizationSettingsDetail+WHERE+SettingName='CallCoachingReady'+AND+DataType='OrgPermissionSettings'" \
|
|
389
402
|
--target-org "$ORG_ALIAS" 2>/dev/null) || true
|
|
390
403
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
404
|
+
# On some org editions (for example Developer Edition), OrganizationSettingsDetail
|
|
405
|
+
# isn't exposed at all (INVALID_TYPE) — the same unqueryable shape the Phase 3
|
|
406
|
+
# license gate tolerates. The authoritative enable (enableECICallScoring, flipped
|
|
407
|
+
# above and re-verified below) has already succeeded, so a CallCoachingReady
|
|
408
|
+
# lookup we physically cannot run must not fail the enable closed.
|
|
409
|
+
if echo "$CCR_LOOKUP" | grep -q '"errorCode"[[:space:]]*:[[:space:]]*"INVALID_TYPE"'; then
|
|
410
|
+
echo "CallCoachingReady OrgPermission isn't queryable on this org — skipping (Call Coaching is already enabled)."
|
|
411
|
+
else
|
|
412
|
+
CCR_COUNT=$(echo "$CCR_LOOKUP" | jq -r '.totalSize // 0' 2>/dev/null || echo 0)
|
|
413
|
+
if [[ "$CCR_COUNT" == "0" ]]; then
|
|
414
|
+
echo "Could not locate the CallCoachingReady OrgPermission record on this org."
|
|
415
|
+
exit 1
|
|
416
|
+
fi
|
|
396
417
|
|
|
397
|
-
CCR_ID=$(echo "$CCR_LOOKUP" | jq -r '.records[0].Id')
|
|
398
|
-
CCR_CURRENT=$(echo "$CCR_LOOKUP" | jq -r '.records[0].SettingValue')
|
|
418
|
+
CCR_ID=$(echo "$CCR_LOOKUP" | jq -r '.records[0].Id')
|
|
419
|
+
CCR_CURRENT=$(echo "$CCR_LOOKUP" | jq -r '.records[0].SettingValue')
|
|
399
420
|
|
|
400
|
-
if [[ "$CCR_CURRENT" == "true" ]]; then
|
|
401
|
-
|
|
402
|
-
else
|
|
403
|
-
echo "Enabling CallCoachingReady..."
|
|
404
|
-
if CCR_PATCH_RESP=$(sf api request rest \
|
|
405
|
-
"services/data/v68.0/tooling/sobjects/OrganizationSettingsDetail/${CCR_ID}" \
|
|
406
|
-
--target-org "$ORG_ALIAS" \
|
|
407
|
-
--method PATCH \
|
|
408
|
-
--header 'Content-Type: application/json' \
|
|
409
|
-
--body '{"SettingValue": true}' \
|
|
410
|
-
2>/dev/null); then
|
|
411
|
-
echo " CallCoachingReady enabled"
|
|
421
|
+
if [[ "$CCR_CURRENT" == "true" ]]; then
|
|
422
|
+
echo "CallCoachingReady is already enabled — skipping."
|
|
412
423
|
else
|
|
413
|
-
echo "
|
|
414
|
-
|
|
415
|
-
|
|
424
|
+
echo "Enabling CallCoachingReady..."
|
|
425
|
+
if CCR_PATCH_RESP=$(sf api request rest \
|
|
426
|
+
"services/data/v68.0/tooling/sobjects/OrganizationSettingsDetail/${CCR_ID}" \
|
|
427
|
+
--target-org "$ORG_ALIAS" \
|
|
428
|
+
--method PATCH \
|
|
429
|
+
--header 'Content-Type: application/json' \
|
|
430
|
+
--body '{"SettingValue": true}' \
|
|
431
|
+
2>/dev/null); then
|
|
432
|
+
echo " CallCoachingReady enabled"
|
|
433
|
+
else
|
|
434
|
+
echo " Failed to enable CallCoachingReady"
|
|
435
|
+
echo " $CCR_PATCH_RESP"
|
|
436
|
+
exit 1
|
|
437
|
+
fi
|
|
416
438
|
fi
|
|
417
439
|
fi
|
|
418
440
|
|
|
@@ -138,13 +138,15 @@ All steps are sequential. Do not skip or reorder.
|
|
|
138
138
|
- `isSaveTranscriptEnabled` — save conversation transcripts
|
|
139
139
|
- `maxFileSize` — maximum attachment size in MB
|
|
140
140
|
|
|
141
|
+
9a. **Configure session inactivity (optional)** — ask using the Setup labels and set the top-level fields per `references/channel_settings.md` → "Setup Prompts: Session Inactivity".
|
|
142
|
+
|
|
141
143
|
10. **Configure messaging keywords** — generate `<messagingKeywords>` elements:
|
|
142
144
|
- `OptOut` type with individual `<keyword>` elements: cancel, end, quit, stop, stopall, unsubscribe
|
|
143
145
|
- `Help` type with `<keyword>`: help
|
|
144
146
|
|
|
145
147
|
11. **Apply standard parameters** — if the user needs standard pre-chat fields, generate `<standardParameters>` elements with `parameterType`. If the channel uses Flow-based routing and the user specifies flow variable mappings, include `<actionParameterMappings>` with `actionParameterName` to map each parameter to a flow input variable.
|
|
146
148
|
|
|
147
|
-
12. **Apply custom parameters** — if the user needs pre-chat data collection, generate `<customParameters>` elements with `name`, `masterLabel`, `parameterDataType`, `externalParameterName`, and `maxLength`. If the channel uses Flow-based routing and the user specifies flow variable mappings, include `<actionParameterMappings>` with `actionParameterName` to map each parameter to a flow input variable.
|
|
149
|
+
12. **Apply custom parameters** — if the user needs pre-chat data collection, generate `<customParameters>` elements with `name`, `masterLabel`, `parameterDataType`, `externalParameterName`, and `maxLength`. Always set `parameterDataType` to `String` — the channel accepts no other value (the field's actual type, including Checkbox/Number/dropdown, is set at the deployment level via `formFieldType`, not here). If the channel uses Flow-based routing and the user specifies flow variable mappings, include `<actionParameterMappings>` with `actionParameterName` to map each parameter to a flow input variable.
|
|
148
150
|
|
|
149
151
|
13. **Generate the file** — produce the `.messagingChannel-meta.xml` file following the template structure. Place at the path the user specifies, or default to the project's metadata source path under `messagingChannels/`.
|
|
150
152
|
|
|
@@ -176,7 +178,7 @@ All steps are sequential. Do not skip or reorder.
|
|
|
176
178
|
17. **Report** — delegated: return the contract §5 result and stop. Standalone: continue.
|
|
177
179
|
|
|
178
180
|
18. **Present output** (standalone) — show the generated file to the user with a summary of configured settings and confirm activation status. Offer next steps:
|
|
179
|
-
- **Automated responses** — ask
|
|
181
|
+
- **Automated responses** — ask which messages the user wants using the Setup labels per `references/channel_settings.md` → "Setup Prompts: Automated Responses", then redeploy.
|
|
180
182
|
|
|
181
183
|
---
|
|
182
184
|
|
|
@@ -216,8 +218,10 @@ All steps are sequential. Do not skip or reorder.
|
|
|
216
218
|
| "Only active Agentforce Service Agents are supported" on deploy | Bot is inactive — run `sf agent activate` before deploying |
|
|
217
219
|
| Flow or ASA routing fails without fallback queue | `sessionHandlerQueue` is mandatory when `sessionHandlerType` is `Flow` or `AgentforceServiceAgent` |
|
|
218
220
|
| JWT verification not working | Connected app and certificate must be configured for the org |
|
|
219
|
-
| Custom parameters not collected | `name` must be unique per channel
|
|
220
|
-
|
|
|
221
|
+
| Custom parameters not collected | `name` must be unique per channel |
|
|
222
|
+
| `<customParameters>` deploy fails: "bad value for restricted picklist field" | `parameterDataType` was set to something other than `String`. Channel custom parameters are always `String`; set the field's actual type (Number, Checkbox, dropdown) at the deployment level, not here |
|
|
223
|
+
| Removing a custom parameter: "can't be deleted as it is referenced elsewhere" | **Check before deploying, not after.** Every deployment on this channel whose pre-chat form uses the param must first drop that field and be published (user-approved); remove the param's `actionParameterMappings` in a separate deploy first. See `references/channel_settings.md` §Removing a Custom Parameter |
|
|
224
|
+
| Automated response / session-inactivity deploy fails | See `references/channel_settings.md` → "Automated Responses", "Session Settings" |
|
|
221
225
|
| Channel deployed but messages not routing | Channel must be activated after deployment — it defaults to inactive |
|
|
222
226
|
| "You can't enable Session-Based Chat for verified users" | Set `isSynchronousChatEnabled` to `false` for Auth channels — session-based chat is only valid for UnAuth |
|
|
223
227
|
|
|
@@ -250,9 +254,8 @@ All steps are sequential. Do not skip or reorder.
|
|
|
250
254
|
- [ ] If UnAuth, is `anonymousUserJwtExpirationTime` set (default 360, range 60-4320)?
|
|
251
255
|
- [ ] If Auth, is `verifiedUserJwtExpirationTime` set (default 60, range 60-240)?
|
|
252
256
|
|
|
253
|
-
### Automated Response Checks (only if user requested)
|
|
254
|
-
- [ ]
|
|
255
|
-
- [ ] Are special characters XML-escaped in `response` text?
|
|
257
|
+
### Session Inactivity / Automated Response Checks (only if user requested)
|
|
258
|
+
- [ ] Checked against `references/channel_settings.md` (Session Settings, Automated Responses)?
|
|
256
259
|
|
|
257
260
|
### Keyword Checks
|
|
258
261
|
- [ ] Is there at least an `OptOut` keyword type defined?
|
|
@@ -281,6 +284,7 @@ File structure follows the template in `assets/messaging_channel_template.xml`.
|
|
|
281
284
|
| Creating the Omni-Channel Flow for routing | `automation-flow-generate` skill |
|
|
282
285
|
| Creating permission sets for messaging agents | `platform-permission-set-generate` skill |
|
|
283
286
|
| Creating the Embedded Service Deployment | `service-digital-engagement-deployment-configure` skill |
|
|
287
|
+
| Creating the `ConversationMessageDefinition` an automated response references | `conversation-message-definition-builder` skill |
|
|
284
288
|
|
|
285
289
|
---
|
|
286
290
|
|
package/skills/service-digital-engagement-channel-configure/assets/messaging_channel_template.xml
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<MessagingChannel xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
3
3
|
<!-- Automated Responses (optional, repeat per response) -->
|
|
4
|
+
<!-- Shape depends on type — see references/channel_settings.md "Automated Responses" -->
|
|
5
|
+
<!-- TextResponse shape: OptOutConfirmation, HelpResponse only -->
|
|
4
6
|
<!--
|
|
5
7
|
<automatedResponses>
|
|
6
8
|
<autoResponseContentType>TextResponse</autoResponseContentType>
|
|
@@ -10,6 +12,18 @@
|
|
|
10
12
|
</automatedResponses>
|
|
11
13
|
-->
|
|
12
14
|
|
|
15
|
+
<!-- MessageDefinition shape: InitialResponse, AgentEngagedResponse, AgentEndEngagementResponse, EndUserInactiveResponse, EndUserIdleResponse, RerouteResponse, RoutingUnavailableResponse -->
|
|
16
|
+
<!-- messageDefinitionName must reference an existing ConversationMessageDefinition (build via conversation-message-definition-builder first) -->
|
|
17
|
+
<!-- Do NOT include language or response on this shape -->
|
|
18
|
+
<!-- Optional responseTimeoutInMins (4-30): only for EndUserIdleResponse / EndUserInactiveResponse -->
|
|
19
|
+
<!--
|
|
20
|
+
<automatedResponses>
|
|
21
|
+
<autoResponseContentType>MessageDefinition</autoResponseContentType>
|
|
22
|
+
<messageDefinitionName>{CONVERSATION_MESSAGE_DEFINITION_DEV_NAME}</messageDefinitionName>
|
|
23
|
+
<type>{InitialResponse|AgentEngagedResponse|AgentEndEngagementResponse|EndUserInactiveResponse|EndUserIdleResponse|RerouteResponse|RoutingUnavailableResponse}</type>
|
|
24
|
+
</automatedResponses>
|
|
25
|
+
-->
|
|
26
|
+
|
|
13
27
|
<!-- Standard Parameters (optional, repeat per parameter) -->
|
|
14
28
|
<!-- actionParameterMappings is optional — include when using Flow routing to map to flow input variables -->
|
|
15
29
|
<!--
|
|
@@ -58,10 +72,29 @@
|
|
|
58
72
|
<isFileAttachmentExtUnrestricted>{true|false}</isFileAttachmentExtUnrestricted>
|
|
59
73
|
<isSaveTranscriptEnabled>{true|false}</isSaveTranscriptEnabled>
|
|
60
74
|
<maxFileSize>{SIZE_IN_MB}</maxFileSize>
|
|
75
|
+
|
|
76
|
+
<!-- Messaging Authorizations (only when authMode is Auth; omit entirely for UnAuth) -->
|
|
77
|
+
<!--
|
|
78
|
+
<messagingAuthorizations>
|
|
79
|
+
<authIdentifier>{AUTH_IDENTIFIER}</authIdentifier>
|
|
80
|
+
<authorizationType>PublicKeyCertificateSet</authorizationType>
|
|
81
|
+
<enabled>{true|false}</enabled>
|
|
82
|
+
<publicKeyCertificateSetName>{KEYSET_NAME}</publicKeyCertificateSetName>
|
|
83
|
+
</messagingAuthorizations>
|
|
84
|
+
-->
|
|
61
85
|
</embeddedConfig>
|
|
62
86
|
|
|
63
87
|
<!-- Session Settings -->
|
|
64
88
|
<endUserIdleTimeOut>{IDLE_TIMEOUT_MINUTES}</endUserIdleTimeOut>
|
|
89
|
+
|
|
90
|
+
<!-- Session Inactivity (optional) — top-level siblings of embeddedConfig, not nested inside it -->
|
|
91
|
+
<!-- endUserIdleAction must be Inactivate, End, or InactivateAndEnd -->
|
|
92
|
+
<!--
|
|
93
|
+
<endUserIdleAction>{Inactivate|End|InactivateAndEnd}</endUserIdleAction>
|
|
94
|
+
<endInactiveSessionTimeOut>{MINUTES_AFTER_IDLE_ACTION}</endInactiveSessionTimeOut>
|
|
95
|
+
<isAgentMessageResetInactivityEnabled>{true|false}</isAgentMessageResetInactivityEnabled>
|
|
96
|
+
-->
|
|
97
|
+
|
|
65
98
|
<isEstimatedWaitTimeEnabled>{true|false}</isEstimatedWaitTimeEnabled>
|
|
66
99
|
<isQueuePositionEnabled>{true|false}</isQueuePositionEnabled>
|
|
67
100
|
<isSynchronousChatEnabled>{true|false}</isSynchronousChatEnabled>
|
|
@@ -133,12 +133,24 @@ Configures the authorization settings for verified user identity in the messagin
|
|
|
133
133
|
|
|
134
134
|
| Field | Type | Default | Description |
|
|
135
135
|
|-------|------|---------|-------------|
|
|
136
|
-
| `endUserIdleTimeOut` | Integer | `5` | Minutes of user inactivity before idle warning |
|
|
136
|
+
| `endUserIdleTimeOut` | Integer | `5` | Minutes of user inactivity before idle warning (range 5-30) |
|
|
137
|
+
| `endUserIdleAction` | Enum | — | Action taken when the idle timeout elapses: `Inactivate`, `End`, or `InactivateAndEnd` |
|
|
138
|
+
| `endInactiveSessionTimeOut` | Integer | — | Minutes after `endUserIdleAction` fires before the inactive session itself ends |
|
|
139
|
+
| `isAgentMessageResetInactivityEnabled` | Boolean | — | Restart the customer's inactivity timer when a rep sends a message (Setup label: "Rep messages reset customer's inactivity timer"). Only takes effect when `endUserIdleTimeOut` is set; it is forced to `false` otherwise |
|
|
137
140
|
| `isEstimatedWaitTimeEnabled` | Boolean | `false` | Show estimated wait time |
|
|
138
141
|
| `isQueuePositionEnabled` | Boolean | `false` | Show queue position to user |
|
|
139
142
|
| `isSynchronousChatEnabled` | Boolean | `false` | Enable real-time synchronous chat |
|
|
140
143
|
| `isVoiceModeEnabled` | Boolean | `false` | Enable voice mode capability |
|
|
141
144
|
|
|
145
|
+
Setup UI (Customer Inactivity card): `endUserIdleTimeOut` is "Minutes to Inactivate Session" / "Minutes to End Session" (5-30); `endUserIdleAction` is "Choose action when customer is idle" with values "Inactivate Session" (`Inactivate`), "End Session" (`End`), and "Inactivate & End Session" (`InactivateAndEnd`); `endInactiveSessionTimeOut` is "Minutes to End Session After Inactivation" (5-30, only meaningful with `InactivateAndEnd`).
|
|
146
|
+
|
|
147
|
+
`endUserIdleTimeOut`, `endUserIdleAction`, `endInactiveSessionTimeOut`, and `isAgentMessageResetInactivityEnabled` are **MIAW (EmbeddedMessaging) only** — not applicable to SMS/WhatsApp/LINE. These can be deployed together with `isAbandonedChatsEnabled`/`chatAbandonmentTimeout` with no conflict.
|
|
148
|
+
|
|
149
|
+
```xml
|
|
150
|
+
<endUserIdleTimeOut>5</endUserIdleTimeOut>
|
|
151
|
+
<endUserIdleAction>InactivateAndEnd</endUserIdleAction>
|
|
152
|
+
<endInactiveSessionTimeOut>10</endInactiveSessionTimeOut>
|
|
153
|
+
```
|
|
142
154
|
|
|
143
155
|
---
|
|
144
156
|
|
|
@@ -196,11 +208,13 @@ Repeatable element — one block per pre-chat field for data collection.
|
|
|
196
208
|
|-------|------|----------|-------------|
|
|
197
209
|
| `name` | String | Yes | Unique API name for the parameter |
|
|
198
210
|
| `masterLabel` | String | Yes | Display label shown to agent/user |
|
|
199
|
-
| `parameterDataType` |
|
|
211
|
+
| `parameterDataType` | String | Yes | **Always `String`** — see note below |
|
|
200
212
|
| `externalParameterName` | String | Yes | External mapping name for the parameter |
|
|
201
|
-
| `maxLength` | Integer | No | Max chars
|
|
213
|
+
| `maxLength` | Integer | No | Max chars (default 255) |
|
|
202
214
|
| `actionParameterMappings` | Object | No | Maps this parameter to an Omni-Channel Flow action input variable |
|
|
203
215
|
|
|
216
|
+
> **`parameterDataType` is always `String`.** Every channel custom parameter deploys as `String`, regardless of the field's logical type. The metadata field's declared type is the broad `FlowDataType` enum (`Apex`, `Boolean`, `Currency`, `Date`, `DateTime`, `Multipicklist`, `Number`, `Picklist`, `SObject`, `String`, `Time`), but `MessagingChannel` restricts it at deploy time to `String` only — any other value fails with *"bad value for restricted picklist field."* The parameter's actual data type (Number, Checkbox/Boolean, dropdown, etc.) is not set on the channel; it is chosen at the **deployment** level in the pre-chat New Custom Parameter screen — i.e. via the Embedded Service form field's `formFieldType` (see `service-digital-engagement-deployment-configure`).
|
|
217
|
+
|
|
204
218
|
### Action Parameter Mappings
|
|
205
219
|
|
|
206
220
|
When the channel uses Flow-based routing, `actionParameterMappings` maps a custom parameter to a flow input variable so the value collected from the user is passed into the routing flow.
|
|
@@ -222,34 +236,89 @@ When the channel uses Flow-based routing, `actionParameterMappings` maps a custo
|
|
|
222
236
|
</customParameters>
|
|
223
237
|
```
|
|
224
238
|
|
|
239
|
+
### Removing a Custom Parameter
|
|
240
|
+
|
|
241
|
+
A parameter still used by a pre-chat form can't be deleted ("can't be deleted as it is referenced elsewhere"). Several deployments can share one channel, so **check every deployment before writing**: retrieve all `EmbeddedServiceConfig` and find each one whose `<messagingChannel>` is this channel and whose form has `<formField>` = the param `name`. Don't use a failed channel deploy to find them.
|
|
242
|
+
|
|
243
|
+
1. If another deployment the user didn't mention still uses the param, stop and ask; changing it is outside the request.
|
|
244
|
+
2. Each referencing deployment: remove the field (via `service-digital-engagement-deployment-configure`) and publish it after the user approves.
|
|
245
|
+
3. If the param has `actionParameterMappings`, deploy the channel with the mapping removed first.
|
|
246
|
+
4. Deploy the channel without that parameter's `<customParameters>` block; keep every other parameter.
|
|
247
|
+
|
|
225
248
|
---
|
|
226
249
|
|
|
227
250
|
## Automated Responses (`<automatedResponses>`)
|
|
228
251
|
|
|
229
|
-
Repeatable element — automated messages sent at specific events.
|
|
252
|
+
Repeatable element — automated messages sent at specific events. There are two mutually exclusive content shapes, and **which shape applies depends on the `type`** (EmbeddedMessaging channel).
|
|
253
|
+
|
|
254
|
+
### Shape 1 — `TextResponse` (inline text)
|
|
255
|
+
|
|
256
|
+
Applies only to `OptOutConfirmation` and `HelpResponse`.
|
|
230
257
|
|
|
231
258
|
| Field | Type | Required | Description |
|
|
232
259
|
|-------|------|----------|-------------|
|
|
233
|
-
| `autoResponseContentType` | Enum | Yes | `TextResponse`
|
|
260
|
+
| `autoResponseContentType` | Enum | Yes | `TextResponse` |
|
|
234
261
|
| `language` | String | Yes | Locale code (e.g., `en_US`) |
|
|
235
262
|
| `response` | String | Yes | The response message text (XML-escape special chars) |
|
|
236
|
-
| `type` | Enum | Yes |
|
|
263
|
+
| `type` | Enum | Yes | `OptOutConfirmation` or `HelpResponse` |
|
|
264
|
+
|
|
265
|
+
### Shape 2 — `MessageDefinition` (reference to a Messaging Component)
|
|
266
|
+
|
|
267
|
+
Applies to `InitialResponse`, `AgentEngagedResponse`, `AgentEndEngagementResponse`, `EndUserInactiveResponse`, `EndUserIdleResponse`, `RerouteResponse`, and `RoutingUnavailableResponse` — the "Conversation Acknowledgement," "Start Conversation," "End Conversation," "Inactive Conversation," "Warning Message," "Reroute Conversation," and "Routing Unavailable" fields in the Setup UI, all backed by a "Messaging Components" (`ConversationMessageDefinition`) picker.
|
|
268
|
+
|
|
269
|
+
| Field | Type | Required | Description |
|
|
270
|
+
|-------|------|----------|-------------|
|
|
271
|
+
| `autoResponseContentType` | Enum | Yes | `MessageDefinition` |
|
|
272
|
+
| `messageDefinitionName` | String | Yes | `DeveloperName` of an existing `ConversationMessageDefinition`. Must already exist in the org — build it with the `conversation-message-definition-builder` skill before deploying this reference (see Cross-Skill Integration in SKILL.md) |
|
|
273
|
+
| `type` | Enum | Yes | `InitialResponse`, `AgentEngagedResponse`, `AgentEndEngagementResponse`, `EndUserInactiveResponse`, `EndUserIdleResponse`, `RerouteResponse`, or `RoutingUnavailableResponse` |
|
|
274
|
+
| `responseTimeoutInMins` | Integer | No | **Only** on `EndUserIdleResponse` and `EndUserInactiveResponse` (range 4-30). Minutes before the idle action fires at which the message is shown (Setup label "Minutes to Show Warning"; Help: "select 4 to show the message 4 minutes before the session inactivates"). On `EndUserIdleResponse` it must be less than `endUserIdleTimeOut` (Setup caps it at `endUserIdleTimeOut` - 1). Rejected on every other type and on `TextResponse` |
|
|
275
|
+
|
|
276
|
+
**Do not include `<language>` or `<response>` on a `MessageDefinition`-shaped block.** The language comes from the referenced CMD's own `<language>` field. Including `<language>` here causes the deploy to fail — with `"unexpected metadata"` for `InitialResponse`/`AgentEngagedResponse`/`AgentEndEngagementResponse`, and with an internal server error for `EndUserInactiveResponse`. Omitting it is the fix, not a schema quirk to work around another way.
|
|
277
|
+
|
|
278
|
+
```xml
|
|
279
|
+
<!-- TextResponse shape -->
|
|
280
|
+
<automatedResponses>
|
|
281
|
+
<autoResponseContentType>TextResponse</autoResponseContentType>
|
|
282
|
+
<language>en_US</language>
|
|
283
|
+
<response>Text STOP to opt out of further messages.</response>
|
|
284
|
+
<type>HelpResponse</type>
|
|
285
|
+
</automatedResponses>
|
|
286
|
+
|
|
287
|
+
<!-- MessageDefinition shape -->
|
|
288
|
+
<automatedResponses>
|
|
289
|
+
<autoResponseContentType>MessageDefinition</autoResponseContentType>
|
|
290
|
+
<messageDefinitionName>Customer_Inactive_Message</messageDefinitionName>
|
|
291
|
+
<type>EndUserInactiveResponse</type>
|
|
292
|
+
</automatedResponses>
|
|
293
|
+
|
|
294
|
+
<!-- Idle warning with responseTimeoutInMins (only valid on EndUserIdleResponse / EndUserInactiveResponse) -->
|
|
295
|
+
<automatedResponses>
|
|
296
|
+
<autoResponseContentType>MessageDefinition</autoResponseContentType>
|
|
297
|
+
<messageDefinitionName>Idle_Warning_Message</messageDefinitionName>
|
|
298
|
+
<responseTimeoutInMins>4</responseTimeoutInMins>
|
|
299
|
+
<type>EndUserIdleResponse</type>
|
|
300
|
+
</automatedResponses>
|
|
301
|
+
```
|
|
237
302
|
|
|
238
303
|
### Response Types
|
|
239
304
|
|
|
240
|
-
| `type` Value | When Sent |
|
|
241
|
-
|
|
242
|
-
| `OptOutConfirmation` | When user opts out of receiving messages |
|
|
243
|
-
| `HelpResponse` | When user sends a help keyword |
|
|
244
|
-
| `InitialResponse` | Let a customer know that their initial message was received |
|
|
245
|
-
| `AgentEngagedResponse` | Let a customer know that their messaging session was accepted by a service rep |
|
|
246
|
-
| `AgentEndEngagementResponse` | Let a customer know that their messaging session ended, and optionally provide a post-chat URL.
|
|
247
|
-
| `EndUserInactiveResponse` | Let a customer know that their messaging conversation has ended because they stopped responding |
|
|
248
|
-
| `EndUserIdleResponse` |
|
|
305
|
+
| `type` Value | Content Shape | When Sent |
|
|
306
|
+
|-------------|---------------|-----------|
|
|
307
|
+
| `OptOutConfirmation` | `TextResponse` | When user opts out of receiving messages |
|
|
308
|
+
| `HelpResponse` | `TextResponse` | When user sends a help keyword |
|
|
309
|
+
| `InitialResponse` | `MessageDefinition` | Let a customer know that their initial message was received |
|
|
310
|
+
| `AgentEngagedResponse` | `MessageDefinition` | Let a customer know that their messaging session was accepted by a service rep |
|
|
311
|
+
| `AgentEndEngagementResponse` | `MessageDefinition` | Let a customer know that their messaging session ended, and optionally provide a post-chat URL. Sent when the service rep or end user ends the session |
|
|
312
|
+
| `EndUserInactiveResponse` | `MessageDefinition` | Let a customer know that their messaging conversation has ended because they stopped responding |
|
|
313
|
+
| `EndUserIdleResponse` | `MessageDefinition` | Warn a customer that their conversation will be inactivated or ended because they are idle. Set in the Customer Inactivity card ("Warning Message"); `responseTimeoutInMins` is how many minutes before the idle action it is shown |
|
|
314
|
+
| `RerouteResponse` | `MessageDefinition` | Sent when a conversation is rerouted to a different queue or agent ("Reroute Conversation") |
|
|
315
|
+
| `RoutingUnavailableResponse` | `MessageDefinition` | Sent when no routing target is available ("Routing Unavailable") |
|
|
316
|
+
|
|
317
|
+
Only `OptOutConfirmation` and `HelpResponse` use the `TextResponse` shape; every other type is `MessageDefinition`-only. `OptIn*` and `CustomResponse` types are not used for EmbeddedMessaging channels.
|
|
249
318
|
|
|
250
319
|
### XML Escaping
|
|
251
320
|
|
|
252
|
-
Special characters in `response` must be XML-escaped:
|
|
321
|
+
Special characters in a `TextResponse` block's `response` must be XML-escaped:
|
|
253
322
|
- `'` → `'`
|
|
254
323
|
- `"` → `"`
|
|
255
324
|
- `&` → `&`
|
|
@@ -292,3 +361,41 @@ Repeatable element — keyword groups that trigger automated responses. Each key
|
|
|
292
361
|
<language>en_US</language>
|
|
293
362
|
</messagingKeywords>
|
|
294
363
|
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Setup Prompts: Session Inactivity
|
|
368
|
+
|
|
369
|
+
Ask using the Setup labels (Customer Inactivity card), with the field in parentheses:
|
|
370
|
+
|
|
371
|
+
- "Inactivate or end a session after a period of customer inactivity?" If yes, "Minutes to Inactivate Session / End Session?" (`endUserIdleTimeOut`, 5-30).
|
|
372
|
+
- "Choose action when customer is idle": **Inactivate Session** (`Inactivate`), **End Session** (`End`), or **Inactivate & End Session** (`InactivateAndEnd`) (`endUserIdleAction` — no other values). **Validate before editing or deploying:** if the user names any other value (e.g. `EndChatSession`, "close", "terminate"), do not write it; say it is not an option, list the three, and ask which one. Never deploy to see whether it is accepted. For Inactivate & End Session also ask "Minutes to End Session After Inactivation?" (`endInactiveSessionTimeOut`, 5-30).
|
|
373
|
+
- "Should rep messages reset the customer's inactivity timer?" (`isAgentMessageResetInactivityEnabled`; needs `endUserIdleTimeOut`).
|
|
374
|
+
- Optional idle warning: the **Warning Message** prompt under Automated Responses below.
|
|
375
|
+
|
|
376
|
+
Set all of these as **top-level fields, siblings of `<embeddedConfig>`** (not nested inside it). MIAW (EmbeddedMessaging) only.
|
|
377
|
+
|
|
378
|
+
Checks:
|
|
379
|
+
- [ ] `endUserIdleAction`/`endInactiveSessionTimeOut` are top-level siblings of `<embeddedConfig>`, not nested inside it.
|
|
380
|
+
- [ ] `endUserIdleAction` is one of `Inactivate`, `End`, `InactivateAndEnd`, checked before the file is edited (free text such as `EndChatSession` fails with "not a valid value for the enum").
|
|
381
|
+
- [ ] `endUserIdleTimeOut` is in range 5-30.
|
|
382
|
+
|
|
383
|
+
## Setup Prompts: Automated Responses
|
|
384
|
+
|
|
385
|
+
Ask which messages the user wants, using the Setup labels (Automated Responses card), with the `type` in parentheses. Two content shapes, chosen by `type`:
|
|
386
|
+
|
|
387
|
+
- Consent text — **Opt-Out Confirmation** (`OptOutConfirmation`) and **Help Response** (`HelpResponse`): `TextResponse` shape; generate elements with `autoResponseContentType: TextResponse`, `language`, and XML-escaped `response` text.
|
|
388
|
+
- Messaging Components — `MessageDefinition` shape; the referenced `ConversationMessageDefinition` must exist first. If it doesn't, delegate to `conversation-message-definition-builder` to create it, then generate the element with `autoResponseContentType: MessageDefinition` and `messageDefinitionName` (no `language`, no `response`):
|
|
389
|
+
- **Conversation Acknowledgement** (`InitialResponse`), **Start Conversation** (`AgentEngagedResponse`), **End Conversation** (`AgentEndEngagementResponse`), **Inactive Conversation** (`EndUserInactiveResponse`), **Reroute Conversation** (`RerouteResponse`), **Routing Unavailable** (`RoutingUnavailableResponse`).
|
|
390
|
+
- **Warning Message** (`EndUserIdleResponse`) — the idle warning; ask "How many minutes before the session inactivates/ends should the warning show?" (Setup: "Minutes to Show Warning"; `responseTimeoutInMins`, 4-30, less than `endUserIdleTimeOut`). `responseTimeoutInMins` is allowed only on `EndUserIdleResponse` and `EndUserInactiveResponse`.
|
|
391
|
+
|
|
392
|
+
Offer **every** type above (nine in all), never a subset. A question tool that allows only four options means asking in several rounds; do not merge types into buckets or drop any. If the user says only "automated responses", ask round by round until each type is accepted or declined. Ask for the `TextResponse` wording (Opt-Out, Help) instead of inventing it. Create any missing component by **invoking the `conversation-message-definition-builder` skill** (Skill tool) and deploying what it produces. Never write, copy, or adapt a `ConversationMessageDefinition` by hand, including by copying the shape of an existing one: the builder owns the required layout, `AutoResponse` type, and `Title` constant. If the builder skill is not available, stop and tell the user; do not fall back to hand-writing.
|
|
393
|
+
|
|
394
|
+
When adding to an existing channel, retrieve it first and keep **one** `automatedResponses` block per `type`. A second block of the same type fails the deploy with `duplicate value found: MessagingChannelId`; the cause is the duplicate block, not the component.
|
|
395
|
+
|
|
396
|
+
Checks:
|
|
397
|
+
- [ ] Every type was offered, and each answer (accepted or declined) was recorded.
|
|
398
|
+
- [ ] `OptOutConfirmation`/`HelpResponse`: `TextResponse` shape with `language` + `response`, special characters XML-escaped.
|
|
399
|
+
- [ ] Every other type: `MessageDefinition` shape with `messageDefinitionName` set and `language`/`response` both absent.
|
|
400
|
+
- [ ] `messageDefinitionName` references a `ConversationMessageDefinition` that already exists in the org (otherwise: "reference not found" — build it with `conversation-message-definition-builder` first).
|
|
401
|
+
- [ ] `responseTimeoutInMins` (4-30) appears only on `EndUserIdleResponse`/`EndUserInactiveResponse`, and on `EndUserIdleResponse` is less than `endUserIdleTimeOut`.
|