@salesforce/afv-skills 1.59.0 → 1.61.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/package.json +1 -1
- package/skills/agentforce-architecture-analyze/SKILL.md +66 -17
- package/skills/agentforce-architecture-analyze/assets/cli/show_access_token.yaml +4 -7
- package/skills/agentforce-architecture-analyze/references/contract.json +1 -1
- package/skills/agentforce-architecture-analyze/scripts/emit_env.py +2 -2
- package/skills/agentforce-architecture-analyze/scripts/main.py +40 -44
- package/skills/agentforce-architecture-analyze/scripts/rest_client.py +11 -3
- package/skills/agentforce-architecture-analyze/scripts/sf_cli.py +77 -10
- package/skills/agentforce-architecture-analyze/scripts/tests/test_end_to_end_fixture.py +1 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_flow_children_inflation.py +1 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_main_pipeline.py +53 -2
- package/skills/agentforce-architecture-analyze/scripts/tests/test_resolve_creds.py +184 -36
- package/skills/agentforce-architecture-analyze/scripts/tests/test_rest_client.py +17 -0
- package/skills/agentforce-architecture-analyze/scripts/tests/test_sf_cli.py +165 -11
- package/skills/agentforce-architecture-analyze/scripts/tests/test_skill_md_pipeline_block.py +319 -0
- package/skills/agentforce-d360-analyze/SKILL.md +28 -10
- package/skills/agentforce-d360-analyze/scripts/dc.py +200 -50
- package/skills/agentforce-d360-analyze/scripts/discover_sessions.py +10 -6
- package/skills/agentforce-d360-analyze/scripts/fetch_dc.py +22 -6
- package/skills/agentforce-d360-analyze/scripts/resolve_session.py +21 -13
- package/skills/agentforce-d360-analyze/scripts/tests/test_dc_and_resolve_session.py +298 -76
- package/skills/agentforce-d360-analyze/scripts/tests/test_default_target_org.py +432 -0
- package/skills/agentforce-d360-analyze/scripts/tests/test_discover_sessions.py +1 -1
- package/skills/agentforce-d360-analyze/scripts/tests/test_resolve_session_main.py +9 -3
- package/skills/agentforce-d360-analyze/scripts/tests/test_skill_md_prefix_block.py +176 -0
- package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +17 -27
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +7 -17
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +47 -63
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +10 -13
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -46
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +4 -21
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +58 -82
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +16 -315
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +9 -24
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -44
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +11 -63
- package/skills/consumer-goods-rtr-datacloud-export-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-dashboard-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/SKILL.md +2 -1
- package/skills/consumer-goods-tpe-datakit-deploy/SKILL.md +2 -1
- package/skills/data360-schema-get/SKILL.md +3 -3
- package/skills/design-systems-slds-validate/references/report-format.md +1 -1
- package/skills/dx-org-manage/SKILL.md +1 -0
- package/skills/dx-org-shape-manage/SKILL.md +1 -0
- package/skills/dx-org-snapshot-manage/SKILL.md +172 -0
- package/skills/dx-org-snapshot-manage/examples/create_error_output.json +16 -0
- package/skills/dx-org-snapshot-manage/examples/create_success_output.json +19 -0
- package/skills/dx-org-snapshot-manage/examples/delete_output.json +9 -0
- package/skills/dx-org-snapshot-manage/examples/get_output.json +19 -0
- package/skills/dx-org-snapshot-manage/examples/list_output.json +36 -0
- package/skills/dx-org-snapshot-manage/references/cli_flags.md +179 -0
- package/skills/dx-org-snapshot-manage/references/snapshot_usage.md +55 -0
- package/skills/dx-org-trial-expiration-check/SKILL.md +1 -1
- package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +2 -2
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +7 -5
- package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +11 -11
- package/skills/experience-content-media-image-generate/SKILL.md +83 -0
- package/skills/experience-content-media-image-generate/scripts/download-image.sh +84 -0
- package/skills/external-diagram-mermaid-generate/SKILL.md +12 -12
- package/skills/field-service-data-capture-migrate/references/component-mapping.md +1 -1
- package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +1 -2
- package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +1 -0
- package/skills/field-service-data-capture-migrate/references/transformer-rules.md +1 -1
- package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +12 -1
- package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +4 -1
- package/skills/field-service-setup-orchestrator-get/SKILL.md +0 -1
- package/skills/insurance-brokerage-agency-billing-configure/SKILL.md +233 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/accounting-setup.md +117 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/billing-rules-config.md +237 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/billing-settings.md +271 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/demo-policy-config.md +138 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/org-defaults.md +64 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/permissions-config.md +226 -0
- package/skills/insurance-brokerage-agency-billing-configure/references/prerequisites.md +142 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +3 -2
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +3 -3
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +68 -45
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +17 -18
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +16 -3
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +16 -13
- package/skills/marketing-message-test/SKILL.md +194 -0
- package/skills/marketing-message-test/references/api-contract.md +333 -0
- package/skills/omnistudio-callable-apex-generate/SKILL.md +3 -3
- package/skills/omnistudio-datamapper-generate/SKILL.md +6 -6
- package/skills/omnistudio-datapacks-deploy/SKILL.md +11 -11
- package/skills/omnistudio-dependencies-analyze/SKILL.md +5 -5
- package/skills/omnistudio-epc-catalog-generate/SKILL.md +6 -6
- package/skills/omnistudio-flexcard-generate/SKILL.md +6 -6
- package/skills/omnistudio-integration-procedure-generate/SKILL.md +6 -6
- package/skills/omnistudio-omniscript-generate/SKILL.md +6 -5
- package/skills/platform-apex-logs-debug/SKILL.md +1 -0
- package/skills/platform-metadata-deploy/SKILL.md +1 -0
- package/skills/platform-models-api-configure/SKILL.md +5 -5
- package/skills/platform-soql-query/SKILL.md +1 -0
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +17 -6
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +107 -192
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone-action.json +6 -6
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +49 -20
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +4 -4
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +224 -290
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/workflow.md +295 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +1 -1
- package/skills/service-itsm-slack-itservice-configure/SKILL.md +2 -1
- package/skills/service-itsm-slack-itservice-configure/references/manage-slack-connection.md +2 -2
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +20 -13
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +5 -55
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +0 -38
- package/skills/service-omni-command-center-analyze/SKILL.md +2 -3
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
- package/skills/tableau-next-asset-create/README.md +65 -0
- package/skills/tableau-next-asset-create/SKILL.md +409 -0
- package/skills/tableau-next-asset-create/references/admin-users.md +149 -0
- package/skills/tableau-next-asset-create/references/ai-readiness.md +355 -0
- package/skills/tableau-next-asset-create/references/alerts.md +111 -0
- package/skills/tableau-next-asset-create/references/build-workflow.md +819 -0
- package/skills/tableau-next-asset-create/references/dashboard-authoring.md +302 -0
- package/skills/tableau-next-asset-create/references/dashboard-design-principles.md +352 -0
- package/skills/tableau-next-asset-create/references/data-transform-gotchas.md +210 -0
- package/skills/tableau-next-asset-create/references/data-understanding.md +387 -0
- package/skills/tableau-next-asset-create/references/deep-reference-index.md +74 -0
- package/skills/tableau-next-asset-create/references/destructive-operations.md +62 -0
- package/skills/tableau-next-asset-create/references/edit-dashboard.md +273 -0
- package/skills/tableau-next-asset-create/references/edit-visualization.md +529 -0
- package/skills/tableau-next-asset-create/references/empty-source-handling.md +104 -0
- package/skills/tableau-next-asset-create/references/ingest-and-metric-gotchas.md +638 -0
- package/skills/tableau-next-asset-create/references/insight-bundle.md +69 -0
- package/skills/tableau-next-asset-create/references/large-flat-file-handling.md +331 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_envelope.json +54 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/_shared-widget-fields.json +122 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/add_page.json +29 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/delete_page.json +27 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/discard_dashboard.json +11 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/move_widget_to_page.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/place_widget_on_page.json +30 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_dashboard.json +16 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/remove_widget_from_page.json +26 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/rename_page.json +28 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/save_dashboard.json +18 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/undo.json +11 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_button_widget.json +69 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_container_widget.json +88 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_filter_widget.json +146 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_metric_widget.json +78 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_navigation_widget.json +80 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_parameter_widget.json +160 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_text_widget.json +103 -0
- package/skills/tableau-next-asset-create/references/schemas/edit-dashboard/upsert_visualization_widget.json +68 -0
- package/skills/tableau-next-asset-create/references/sdm-tool-reference.md +721 -0
- package/skills/tableau-next-asset-create/references/semantic-query-and-enrichment.md +355 -0
- package/skills/tableau-next-asset-create/references/shared-gates.md +322 -0
- package/skills/tableau-next-asset-create/references/sharing-and-promotion.md +306 -0
- package/skills/tableau-next-asset-create/references/tasks/ai-readiness-audit.md +51 -0
- package/skills/tableau-next-asset-create/references/tasks/analyze-data.md +48 -0
- package/skills/tableau-next-asset-create/references/tasks/build-dashboard.md +66 -0
- package/skills/tableau-next-asset-create/references/tasks/build-end-to-end.md +73 -0
- package/skills/tableau-next-asset-create/references/tasks/create-data-transform.md +51 -0
- package/skills/tableau-next-asset-create/references/tasks/create-viz.md +58 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-dashboard.md +80 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-sdm.md +106 -0
- package/skills/tableau-next-asset-create/references/tasks/edit-viz.md +40 -0
- package/skills/tableau-next-asset-create/references/tasks/enrich-model.md +68 -0
- package/skills/tableau-next-asset-create/references/tasks/ingest-flat-file.md +68 -0
- package/skills/tableau-next-asset-create/references/tasks/manage-alert.md +35 -0
- package/skills/tableau-next-asset-create/references/tasks/profile-dataset.md +47 -0
- package/skills/tableau-next-asset-create/references/tasks/promote-or-reuse.md +46 -0
- package/skills/tableau-next-asset-create/references/tasks/provision-user.md +39 -0
- package/skills/tableau-next-asset-create/references/tasks/query-model.md +92 -0
- package/skills/tableau-next-asset-create/references/tasks/review-verified-questions.md +42 -0
- package/skills/tableau-next-asset-create/references/tasks/share-asset.md +37 -0
- package/skills/tableau-next-asset-create/references/verified-questions.md +125 -0
- package/skills/tableau-next-asset-create/references/viz-authoring.md +992 -0
- package/skills/service-de-channel-consent-configure/SKILL.md +0 -230
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +0 -102
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: service-de-channel-consent-configure
|
|
3
|
-
description: "Configure consent (opt-in/opt-out) on an Enhanced `MessagingChannel` so activation will accept it. Given a `{CHANNEL_ID}`, sets the channel's `ConsentType` (ImplicitOptIn / ExplicitOptIn / DoubleOptIn) and the `OptInPrompt` / `DoubleOptInPrompt` prompt fields, then creates or updates one `MsgChannelLanguageKeyword` record per language holding the opt-in / double-opt-in / opt-out / help / custom keywords and confirmation messages. Use between channel insertion and activation — activation fails the consent-readiness check unless a valid ConsentType and at least one matching language-keyword record exist."
|
|
4
|
-
metadata:
|
|
5
|
-
version: "1.0"
|
|
6
|
-
minApiVersion: "67.0"
|
|
7
|
-
domains: ["Service"]
|
|
8
|
-
cliTools:
|
|
9
|
-
- tool: ["sf"]
|
|
10
|
-
semver: ">=2.0.0"
|
|
11
|
-
relatedSkills:
|
|
12
|
-
- "service-de-channel-activate"
|
|
13
|
-
- "service-de-channel-routing-configure"
|
|
14
|
-
- "service-de-headless-channel-configure"
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
# Configuring Channel Consent
|
|
18
|
-
|
|
19
|
-
## What this skill does
|
|
20
|
-
|
|
21
|
-
Ensures an Enhanced `MessagingChannel` has valid **consent** configured before activation. Consent has two parts, and both are checked by the server-side activation-readiness gate (`MessagingChannelReadinessChecker.isConsentConfiguredForChannel`):
|
|
22
|
-
|
|
23
|
-
1. **Channel-level fields** on `MessagingChannel`:
|
|
24
|
-
- `ConsentType` — static enum: `ImplicitOptIn`, `ExplicitOptIn`, or `DoubleOptIn`.
|
|
25
|
-
- `OptInPrompt` — message sent when an end-user reply doesn't match an opt-in keyword (required for ExplicitOptIn/DoubleOptIn, except on Unified SMS / WhatsApp / RCS where it's optional).
|
|
26
|
-
- `DoubleOptInPrompt` — message sent when a reply doesn't match a double-opt-in keyword (required for DoubleOptIn).
|
|
27
|
-
- `IsRequireDoubleOptIn` — boolean flag; set true alongside `ConsentType=DoubleOptIn`.
|
|
28
|
-
|
|
29
|
-
2. **Per-language keyword records** — one or more `MsgChannelLanguageKeyword` child rows (master-detail to `MessagingChannel`, key prefix `3Or`). Each holds the keywords an end-user sends (opt-in, double-opt-in, opt-out, help, custom) and the confirmation replies, **for one language**. Keyword fields are **comma-separated strings** (e.g. `"STOP,UNSUBSCRIBE,CANCEL"`).
|
|
30
|
-
|
|
31
|
-
**Consent is never a no-op for activation.** Even `ImplicitOptIn` requires at least one `MsgChannelLanguageKeyword` with an opt-out keyword + opt-out confirmation. (The one exception is an outbound-only channel, which the readiness check passes automatically.)
|
|
32
|
-
|
|
33
|
-
Consent settings apply only to **Enhanced** channels (`PlatformType=Enhanced`) of a supported message type. On a Standard channel these fields aren't used; this skill only touches Enhanced channels.
|
|
34
|
-
|
|
35
|
-
## Where this fits
|
|
36
|
-
|
|
37
|
-
This skill runs between routing and activation in the Enhanced-channel setup pipeline. `service-de-channel-routing-configure` sets the channel's `SessionHandler`; this skill configures consent; then `service-de-channel-activate` flips the channel live. The activation readiness check requires **both** routing and consent, so run this before activating. The `service-de-headless-channel-configure` orchestrator sequences all three automatically — invoke this skill directly only when you want to configure consent on its own.
|
|
38
|
-
|
|
39
|
-
## Reference File Index
|
|
40
|
-
|
|
41
|
-
| Reference file | Load when |
|
|
42
|
-
| --- | --- |
|
|
43
|
-
| `references/language-keywords.md` | Creating or updating the per-language `MsgChannelLanguageKeyword` records — full field list, CSV keyword semantics, create-vs-update logic, and the Unified-SMS help/custom-keyword rules. |
|
|
44
|
-
| `references/gotchas.md` | Troubleshooting an unexpected result, or before modifying this skill. |
|
|
45
|
-
| `references/worked-examples.md` | You want a reference run of the ImplicitOptIn, ExplicitOptIn, or DoubleOptIn paths. |
|
|
46
|
-
|
|
47
|
-
## When NOT to use this skill
|
|
48
|
-
|
|
49
|
-
- **The channel isn't Enhanced.** Consent fields apply to Enhanced channels only. This skill confirms `PlatformType=Enhanced` and stops otherwise.
|
|
50
|
-
- **The channel is outbound-only.** Outbound-only channels pass the consent-readiness check automatically; there's nothing to configure.
|
|
51
|
-
- **The channel doesn't exist yet.** Run the insertion skill first; this skill expects a real `MessagingChannel.Id`.
|
|
52
|
-
|
|
53
|
-
## Inputs (from caller)
|
|
54
|
-
|
|
55
|
-
- `{CHANNEL_ID}` — a 15- or 18-char `MessagingChannel.Id` (prefix `0Mj`). Must already exist and be Enhanced.
|
|
56
|
-
- `{CONSENT_TYPE}` — optional; one of `ImplicitOptIn` | `ExplicitOptIn` | `DoubleOptIn`. If omitted, the skill prompts.
|
|
57
|
-
- `{LANGUAGE}` — optional; the `MasterLanguage` for the keyword record (e.g. `en_US`). Defaults to `en_US` if not provided.
|
|
58
|
-
- `{ORG_ALIAS}` — optional; `sf` CLI target-org alias. Default: whatever `sf config get target-org` returns.
|
|
59
|
-
|
|
60
|
-
The individual keyword/confirmation/prompt values are collected interactively in Stage 3–4 (or accepted from the caller if pre-supplied).
|
|
61
|
-
|
|
62
|
-
## Output (to caller)
|
|
63
|
-
|
|
64
|
-
**Success — no change needed:**
|
|
65
|
-
```json
|
|
66
|
-
{"ok": true, "noop": true, "consentType": "ImplicitOptIn|ExplicitOptIn|DoubleOptIn", "languageKeywordIds": ["3Or..."], "message": "Consent already configured and activation-ready"}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
**Success — consent configured:**
|
|
70
|
-
```json
|
|
71
|
-
{"ok": true, "consentType": "ExplicitOptIn", "channelFieldsSet": ["ConsentType","OptInPrompt"],
|
|
72
|
-
"languageKeywordId": "3Or...", "language": "en_US", "created": true|false, "activationReady": true}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**Precondition / validation not met:**
|
|
76
|
-
```json
|
|
77
|
-
{"ok": false, "kind": "not-enhanced", "hint": "consent fields apply to Enhanced channels only; this channel is PlatformType=<x>"}
|
|
78
|
-
{"ok": false, "kind": "missing-consent-input", "hint": "<which required keyword/prompt for the chosen ConsentType is missing>"}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Failure:**
|
|
82
|
-
```json
|
|
83
|
-
{"ok": false, "kind": "channel-patch-failed", "message": "..."}
|
|
84
|
-
{"ok": false, "kind": "keyword-record-failed", "message": "..."}
|
|
85
|
-
{"ok": false, "kind": "verify-failed", "hint": "writes returned success but a re-read shows the channel is still not consent-ready"}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Stage 1: Read current consent state
|
|
91
|
-
|
|
92
|
-
Read the channel's consent fields and any existing language-keyword records.
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
sf data query --target-org '{ORG_ALIAS}' \
|
|
96
|
-
--query "SELECT Id, DeveloperName, PlatformType, MessageType, MessagingPlatformKey, ConsentType, OptInPrompt, DoubleOptInPrompt, IsRequireDoubleOptIn FROM MessagingChannel WHERE Id = '{CHANNEL_ID}'" \
|
|
97
|
-
--json > /tmp/cc-channel.json
|
|
98
|
-
|
|
99
|
-
sf data query --target-org '{ORG_ALIAS}' \
|
|
100
|
-
--query "SELECT Id, MasterLanguage, OptInKeywords, DoubleOptInKeywords, OptInConfirmation, OptOutKeywords, OptOutConfirmation, HelpKeywords, HelpResponse, CustomKeywords, CustomResponse FROM MsgChannelLanguageKeyword WHERE MessagingChannelId = '{CHANNEL_ID}'" \
|
|
101
|
-
--json > /tmp/cc-keywords.json
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
If the channel record is missing — halt with `Error: Channel {CHANNEL_ID} not found — check the id, or run the insertion skill first.`
|
|
105
|
-
|
|
106
|
-
If `PlatformType != 'Enhanced'` — emit `{ok:false, kind:"not-enhanced", ...}` and stop.
|
|
107
|
-
|
|
108
|
-
**No-op check:** if `ConsentType` is non-null AND the existing language-keyword records already satisfy the readiness matrix for that ConsentType (see Stage 5), emit the `noop:true` envelope and return. Don't re-prompt or overwrite a channel that is already activation-ready.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## Stage 2: Choose the ConsentType
|
|
113
|
-
|
|
114
|
-
If `{CONSENT_TYPE}` wasn't supplied, prompt (do NOT auto-pick):
|
|
115
|
-
|
|
116
|
-
```text
|
|
117
|
-
Channel '{developerName}' ({CHANNEL_ID}) — choose a consent model:
|
|
118
|
-
|
|
119
|
-
1) ImplicitOptIn — end users are opted in by default; you only handle opt-OUT (STOP) keywords.
|
|
120
|
-
2) ExplicitOptIn — end users must send an opt-in keyword before you can message them.
|
|
121
|
-
3) DoubleOptIn — explicit opt-in plus a second confirming keyword.
|
|
122
|
-
|
|
123
|
-
Pick [1-3]:
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Record `{CONSENT_TYPE}`. Note the field checks that follow (this is the exact server-side activation-readiness contract — see `references/gotchas.md` for the source):
|
|
127
|
-
|
|
128
|
-
| ConsentType | MessagingChannel fields | `MsgChannelLanguageKeyword` (≥1 record) |
|
|
129
|
-
| --- | --- | --- |
|
|
130
|
-
| ImplicitOptIn | (none required) | `OptOutKeywords` + `OptOutConfirmation` |
|
|
131
|
-
| ExplicitOptIn | `OptInPrompt`¹ | above + `OptInKeywords` |
|
|
132
|
-
| DoubleOptIn | `OptInPrompt`¹ + `DoubleOptInPrompt` + `IsRequireDoubleOptIn=true` | above + `DoubleOptInKeywords` |
|
|
133
|
-
|
|
134
|
-
¹ `OptInPrompt` is optional (not required for readiness) on Unified SMS / WhatsApp / RCS channels — detect via `MessageType IN ('Text','WhatsApp','Rcs')` on an Enhanced channel (the queryable proxy for the server's `isUnifiedSMSOrWhatsappOrRCS`). Still recommend setting it for a good end-user experience.
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Stage 3: Collect channel-level prompt values
|
|
139
|
-
|
|
140
|
-
Only prompt for the fields the chosen ConsentType requires (see the matrix above). Skip this stage entirely for `ImplicitOptIn` — it needs no channel-level prompt fields.
|
|
141
|
-
|
|
142
|
-
For `ExplicitOptIn` / `DoubleOptIn`:
|
|
143
|
-
|
|
144
|
-
```text
|
|
145
|
-
Opt-in prompt (sent when a reply doesn't match an opt-in keyword):
|
|
146
|
-
```
|
|
147
|
-
For `DoubleOptIn`, also:
|
|
148
|
-
```text
|
|
149
|
-
Double-opt-in prompt (sent when a reply doesn't match a double-opt-in keyword):
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Trim whitespace. If a required prompt is empty after trimming, re-prompt once; on a second empty, emit `{ok:false, kind:"missing-consent-input", hint:"..."}`.
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## Stage 4: Configure the per-language keyword record
|
|
157
|
-
|
|
158
|
-
Collect the keyword lists and confirmation replies for `{LANGUAGE}` (default `en_US`), then create or update the `MsgChannelLanguageKeyword` record.
|
|
159
|
-
|
|
160
|
-
**Load `references/language-keywords.md` and follow it** — it holds the full field list, the comma-separated-keyword semantics, the create-vs-update decision (reuse an existing record for the same language rather than duplicating), and the Unified-SMS help/custom-keyword rules.
|
|
161
|
-
|
|
162
|
-
The minimum per ConsentType (again, from the readiness contract):
|
|
163
|
-
- **ImplicitOptIn:** `OptOutKeywords` (e.g. `STOP,UNSUBSCRIBE`) + `OptOutConfirmation`.
|
|
164
|
-
- **ExplicitOptIn:** the above + `OptInKeywords` (e.g. `START,YES`).
|
|
165
|
-
- **DoubleOptIn:** the above + `DoubleOptInKeywords` (e.g. `CONFIRM`).
|
|
166
|
-
|
|
167
|
-
`OptInConfirmation`, `HelpKeywords`/`HelpResponse`, and `CustomKeywords`/`CustomResponse` are optional for the base readiness check (help/custom are only *required* on Unified SMS — see the reference), but collect them if the user wants them.
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Stage 5: Write channel fields + keyword record
|
|
172
|
-
|
|
173
|
-
Write the channel-level fields in one PATCH (only the fields the ConsentType requires).
|
|
174
|
-
|
|
175
|
-
**Quoting rule (load-bearing):** `sf data update record --values` splits on spaces, so any value containing a space **must be wrapped in single quotes inside the double-quoted `--values` string** — e.g. `OptInPrompt='Reply YES to receive messages'`. An unquoted `OptInPrompt=Reply YES ...` fails with `Malformed key=value pair` (verified live on sdb6c). Prompts almost always contain spaces, so always quote them.
|
|
176
|
-
|
|
177
|
-
```bash
|
|
178
|
-
# ImplicitOptIn — ConsentType only
|
|
179
|
-
sf data update record --target-org '{ORG_ALIAS}' --sobject MessagingChannel \
|
|
180
|
-
--record-id '{CHANNEL_ID}' --values "ConsentType=ImplicitOptIn" --json > /tmp/cc-patch.json
|
|
181
|
-
|
|
182
|
-
# ExplicitOptIn
|
|
183
|
-
sf data update record --target-org '{ORG_ALIAS}' --sobject MessagingChannel \
|
|
184
|
-
--record-id '{CHANNEL_ID}' --values "ConsentType=ExplicitOptIn OptInPrompt='{OPT_IN_PROMPT}'" --json > /tmp/cc-patch.json
|
|
185
|
-
|
|
186
|
-
# DoubleOptIn
|
|
187
|
-
sf data update record --target-org '{ORG_ALIAS}' --sobject MessagingChannel \
|
|
188
|
-
--record-id '{CHANNEL_ID}' \
|
|
189
|
-
--values "ConsentType=DoubleOptIn OptInPrompt='{OPT_IN_PROMPT}' DoubleOptInPrompt='{DBL_PROMPT}' IsRequireDoubleOptIn=true" --json > /tmp/cc-patch.json
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
If `status !== 0`: emit `{ok:false, kind:"channel-patch-failed", message: ...}` and return.
|
|
193
|
-
|
|
194
|
-
Then create or update the `MsgChannelLanguageKeyword` record per `references/language-keywords.md`. If it fails: `{ok:false, kind:"keyword-record-failed", message: ...}`.
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
## Stage 6: Verify activation readiness
|
|
199
|
-
|
|
200
|
-
Re-read both the channel and its keyword records (same two queries as Stage 1). Confirm, per the chosen ConsentType's row in the Stage 2 matrix, that every required field is now non-null on the channel AND on at least one keyword record for the configured language.
|
|
201
|
-
|
|
202
|
-
If any required field is still null: emit `{ok:false, kind:"verify-failed", hint:"<which requirement is unmet>"}`.
|
|
203
|
-
|
|
204
|
-
Otherwise emit the success envelope with `activationReady: true`.
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## Stage 7: Report to caller
|
|
209
|
-
|
|
210
|
-
Report the JSON envelope. If this skill is the leaf (user invoked it directly), render:
|
|
211
|
-
|
|
212
|
-
- `Success — Consent configured — channel {CHANNEL_ID} is now {CONSENT_TYPE} with a {LANGUAGE} keyword record. Activation-ready.`
|
|
213
|
-
- `Info: Consent already configured — {CONSENT_TYPE}, {N} language record(s). No changes.` (no-op path)
|
|
214
|
-
- `Warning: This channel is PlatformType={x}, not Enhanced — consent fields don't apply here.` (not-enhanced)
|
|
215
|
-
- `Warning: Missing required consent input for {CONSENT_TYPE}: {what}. Re-run and provide it.` (missing-consent-input)
|
|
216
|
-
- `Error: {kind}: {message}` (other failures)
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## Worked examples
|
|
221
|
-
|
|
222
|
-
For reference runs of the ImplicitOptIn (opt-out only), ExplicitOptIn, and DoubleOptIn paths, see `references/worked-examples.md`.
|
|
223
|
-
|
|
224
|
-
---
|
|
225
|
-
|
|
226
|
-
## Gotchas
|
|
227
|
-
|
|
228
|
-
Known gotchas — the exact per-ConsentType activation-readiness contract (and its source), comma-separated keyword storage, the "ImplicitOptIn still needs a keyword record" trap, one-record-per-language uniqueness, the Unified-SMS help/French-custom rules, and the OptInPrompt Unified-SMS/WhatsApp/RCS exemption.
|
|
229
|
-
|
|
230
|
-
**When troubleshooting an unexpected result, or before modifying this skill, load `references/gotchas.md` and follow it.**
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_comment": "Out-of-box 'Standard Support for Incidents' predefined SLA policy — a faithful replica of what Salesforce ITSM seeds when a customer clicks the Incident checkbox under 'Create Predefined Policies' in Setup (Incident process type only). Source of truth for Phase 2-OOB. This is a DATA template, not a ready-to-POST body: substitute <businessHoursId> / <AccountId> at runtime and translate the criteria per the recipe in references/mcp-invocation.md (Predefined Incident Policy). Byte-for-byte modeled on core service-itsm-impl default-sla-policies/incident.json (the resource DefaultSlaServiceImpl reads and seeds) + shared_core_ui_labels/incident-management.xml (DefaultSeededSla): 6 milestones — Critical (30/120) and High (60/240) each Priority Equals, plus a MERGED Moderate-or-Low tier (240/960) whose ACTIVE criterion is a Priority OR (filterLogic '1 OR 2' over two Equals rows, Moderate + Low). NOTE: the core template also carries a per-tier CANCEL criterion, but the public /connect/sla-management route has NO 'CANCEL' milestoneState (valid states: ACTIVE, COMPLETE, PAUSE, UNPAUSE) — so this replica OMITS cancelWhen. The ACTIVE Priority criterion alone gates engagement (an off-tier Incident never matches), making CANCEL redundant. Every milestone uses startTimeBasedOn MILESTONE_CRITERIA (the OOB timer starts when the milestone criteria first match, NOT from the SLA-process created date). WHY REPLICATE INSTEAD OF CALLING THE UI'S OWN API: the checkbox invokes DefaultSlaPolicyController.saveSelectedOptions, an @AuraEnabled controller (core/ui-service-itsm-components) whose only caller of DefaultSlaService.createDefaultSlaPolicies is that Aura action — there is NO public REST/Connect wrapper, so the headless MCP (which dispatches REST/Connect) cannot invoke the seeder directly; it reproduces the seeder's exact output via the public /connect/sla-management routes.",
|
|
3
|
-
|
|
4
|
-
"policy": {
|
|
5
|
-
"name": "Standard Support for Incidents",
|
|
6
|
-
"description": "Standard Support for Incidents",
|
|
7
|
-
"processType": "Incident",
|
|
8
|
-
"businessHourId": "<default active BusinessHours Id>",
|
|
9
|
-
"createdDateEntryCriteria": true,
|
|
10
|
-
"closedExitCriteria": true,
|
|
11
|
-
"versionDefault": true,
|
|
12
|
-
"active": true,
|
|
13
|
-
"_recordTypeApplied": false,
|
|
14
|
-
"_slaType": "SLA",
|
|
15
|
-
"_activeNote": "The OOB backend creates the SlaProcess with active:false, then flips it active:true during auto-entitlement activation. When replicating via the public /connect/sla-management/sla-policies POST, create it directly with active:true (same as the custom Phase 2 flow) to avoid the Connect activate PATCH, which can 500 headless."
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
"_milestoneTypesNote": "DETECT BEFORE CREATE. Enabling the SLA Management feature pre-seeds a default MilestoneType catalog (commonly First Response, Follow Up, Periodic Update, and Resolve Within). A blind POST for a name that already exists returns HTTP 500 ('already exists') and half-seeds the policy. First read the catalog (SOQL SELECT Id, Name FROM MilestoneType WHERE Name IN ('Acknowledge Within','Resolve Within'), or GET .../milestone-types), reuse any match by id, and POST only the missing name(s). See references/mcp-invocation.md (Predefined Incident Policy, seed step 1).",
|
|
19
|
-
"milestoneTypes": [
|
|
20
|
-
{ "name": "Acknowledge Within", "description": "Acknowledge Within", "recurrenceType": "OneTime" },
|
|
21
|
-
{ "name": "Resolve Within", "description": "Resolve Within", "recurrenceType": "OneTime" }
|
|
22
|
-
],
|
|
23
|
-
|
|
24
|
-
"milestones": [
|
|
25
|
-
{
|
|
26
|
-
"order": 1,
|
|
27
|
-
"milestoneType": "Acknowledge Within",
|
|
28
|
-
"timeTrigger": 30,
|
|
29
|
-
"priorityTier": "Critical",
|
|
30
|
-
"startTimeBasedOn": "MILESTONE_CRITERIA",
|
|
31
|
-
"activeWhen": { "field": "Priority", "operator": "Equals", "value": "Critical" },
|
|
32
|
-
"completeWhen": { "field": "Status", "operator": "NotEqual", "value": "New" }
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"order": 2,
|
|
36
|
-
"milestoneType": "Resolve Within",
|
|
37
|
-
"timeTrigger": 120,
|
|
38
|
-
"priorityTier": "Critical",
|
|
39
|
-
"startTimeBasedOn": "MILESTONE_CRITERIA",
|
|
40
|
-
"activeWhen": { "field": "Priority", "operator": "Equals", "value": "Critical" },
|
|
41
|
-
"completeWhen": { "field": "Status", "filterLogic": "1 OR 2 OR 3", "rows": [ { "operator": "Equals", "value": "Resolved" }, { "operator": "Equals", "value": "Completed" }, { "operator": "Equals", "value": "Closed" } ] }
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"order": 3,
|
|
45
|
-
"milestoneType": "Acknowledge Within",
|
|
46
|
-
"timeTrigger": 60,
|
|
47
|
-
"priorityTier": "High",
|
|
48
|
-
"startTimeBasedOn": "MILESTONE_CRITERIA",
|
|
49
|
-
"activeWhen": { "field": "Priority", "operator": "Equals", "value": "High" },
|
|
50
|
-
"completeWhen": { "field": "Status", "operator": "NotEqual", "value": "New" }
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"order": 4,
|
|
54
|
-
"milestoneType": "Resolve Within",
|
|
55
|
-
"timeTrigger": 240,
|
|
56
|
-
"priorityTier": "High",
|
|
57
|
-
"startTimeBasedOn": "MILESTONE_CRITERIA",
|
|
58
|
-
"activeWhen": { "field": "Priority", "operator": "Equals", "value": "High" },
|
|
59
|
-
"completeWhen": { "field": "Status", "filterLogic": "1 OR 2 OR 3", "rows": [ { "operator": "Equals", "value": "Resolved" }, { "operator": "Equals", "value": "Completed" }, { "operator": "Equals", "value": "Closed" } ] }
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
"order": 5,
|
|
63
|
-
"milestoneType": "Acknowledge Within",
|
|
64
|
-
"timeTrigger": 240,
|
|
65
|
-
"priorityTier": "Moderate or Low",
|
|
66
|
-
"startTimeBasedOn": "MILESTONE_CRITERIA",
|
|
67
|
-
"activeWhen": { "field": "Priority", "filterLogic": "1 OR 2", "rows": [ { "operator": "Equals", "value": "Moderate" }, { "operator": "Equals", "value": "Low" } ] },
|
|
68
|
-
"completeWhen": { "field": "Status", "operator": "NotEqual", "value": "New" }
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"order": 6,
|
|
72
|
-
"milestoneType": "Resolve Within",
|
|
73
|
-
"timeTrigger": 960,
|
|
74
|
-
"priorityTier": "Moderate or Low",
|
|
75
|
-
"startTimeBasedOn": "MILESTONE_CRITERIA",
|
|
76
|
-
"activeWhen": { "field": "Priority", "filterLogic": "1 OR 2", "rows": [ { "operator": "Equals", "value": "Moderate" }, { "operator": "Equals", "value": "Low" } ] },
|
|
77
|
-
"completeWhen": { "field": "Status", "filterLogic": "1 OR 2 OR 3", "rows": [ { "operator": "Equals", "value": "Resolved" }, { "operator": "Equals", "value": "Completed" }, { "operator": "Equals", "value": "Closed" } ] }
|
|
78
|
-
}
|
|
79
|
-
],
|
|
80
|
-
|
|
81
|
-
"entitlement": {
|
|
82
|
-
"_note": "The OOB backend auto-creates the Entitlement during activation. When replicating headless, create it via POST /sobjects/Entitlement on the resolved Account (same as the custom Phase 2 flow), SlaProcessId = the seeded policy, backdated StartDate for immediate engagement.",
|
|
83
|
-
"name": "Standard Support for Incidents",
|
|
84
|
-
"matchAllCriterion": {
|
|
85
|
-
"_note": "The OOB seeds an always-true entitlement criterion so every Incident matches automatically. ATTEMPT to replicate it via POST /connect/sla-management/entitlement-criteria: `describe` the route FIRST and send its exact input fields — it rejects `filterType`, and a wrong body returns a 400 (a wrong-payload error, NOT a platform gap). Only if the create still 400s after using the described schema, fall back to the date-windowed Entitlement alone and REPORT only the engagement-scope consequence: the policy then engages on Incidents wired to this Entitlement (EntitlementId set), not automatically on every Incident. Do NOT tell the user the route is 'unreachable' or 'undiscoverable' — it works; the body just needs its correct fields. The date-windowed Entitlement + the milestone criteria above are still sufficient to engage the Phase 3 test Incident.",
|
|
86
|
-
"field": "Subject",
|
|
87
|
-
"operator": "NotEqual",
|
|
88
|
-
"value": "!iw6vnffW1Pt:CQbS/0cwh!17G,Gj##H",
|
|
89
|
-
"priorityOrder": 98,
|
|
90
|
-
"criteriaType": "AND"
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
"_replicationNotes": {
|
|
95
|
-
"table": "Every criterion filters the Incident table (filterItems[].table = \"Incident\").",
|
|
96
|
-
"activeCriterion": "The public Attach-Milestone route's milestoneCriteria carries the ACTIVE criterion — filterType RuleFilter, milestoneState ACTIVE (UPPERCASE — the server matches this case-sensitively; a wrong-case 'Active' returns 201 but silently drops the criterion, collapsing every Incident onto the lowest-order/Critical tier), milestoneAgreementType SLA (customer-facing; OLA is the internal alternative — W-23959162). The priority-tier row IS this active criterion; it is what tiers the policy.",
|
|
97
|
-
"completion": "The OOB completion (Status In resolved-set) criterion uses milestoneState COMPLETE (UPPERCASE). There is NO CANCEL state on the public route (valid: ACTIVE, COMPLETE, PAUSE, UNPAUSE), so no cancel criterion is sent — the ACTIVE Priority criterion alone gates engagement (matches examples/milestone-patterns.md Pattern 3). Verify tiering by runtime: create a Moderate/Low test Incident and confirm its EntityMilestone lands on the 240/960 tier, not 30/120 (the create response always echoes milestoneCriteria:[] regardless of success, so it cannot confirm persistence).",
|
|
98
|
-
"orClause": "The core OOB template groups Moderate+Low into ONE tier via an ACTIVE filterLogic '1 OR 2' over two Priority Equals rows (Moderate, Low) — see incident.json orders 5-6. This template mirrors that exactly: orders 5-6 carry activeWhen.filterLogic '1 OR 2' with rows [Priority Equals Moderate, Priority Equals Low]. The public milestone-criteria route accepts this OR via customLogicExpression (the same MilestoneCriteriaInputRepresentation the /connect/sla-management milestones route consumes), so it need NOT be split into separate Equals milestones. Seed 6 milestones as listed. If the live route rejects the OR filterLogic, fall back to two separate Priority Equals milestones (Moderate, Low) with the same timeTriggers — behavior-equivalent. The merged tier has NO cancelWhen, matching the core template (orders 5-6 have ACTIVE + COMPLETE only).",
|
|
99
|
-
"statusIn": "Status 'In [Resolved, Completed, Closed]' has no single-row In operator, so each completeWhen above is already PRE-SPLIT into a filterLogic ('1 OR 2 OR 3') across three Status Equals rows — the data file never carries a route-rejected In operator. If the route rejects filterLogic, split into one Status Equals row per value (behavior-equivalent). Validate each Status/Priority value against the live Incident picklist before seeding.",
|
|
100
|
-
"midTier": "Map the mid tier to the org's ACTUAL mid-priority label — 'Moderate' on the standard ITSM picklist, but many orgs label it 'Medium'. In the merged orders 5-6 activeWhen.rows, use whichever label the live Incident.Priority picklist carries in place of 'Moderate' (keep the 'Low' row as-is). Drop a row from the OR only when its value is genuinely absent from the picklist, and note any dropped/relabeled tier in the report."
|
|
101
|
-
}
|
|
102
|
-
}
|