@salesforce/afv-skills 1.41.0 → 1.43.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 +2 -6
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +3 -0
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +4 -0
- package/skills/design-systems-slds-validate/SKILL.md +2 -2
- package/skills/dx-app-analytics-query/SKILL.md +1 -3
- package/skills/dx-devops-conflict-resolve/SKILL.md +205 -0
- package/skills/dx-devops-conflict-resolve/examples/conflict-workflows.md +165 -0
- package/skills/dx-devops-conflict-resolve/references/deploy-failure-resolution.md +75 -0
- package/skills/dx-devops-conflict-resolve/references/git-conflict-resolution.md +124 -0
- package/skills/dx-devops-conflict-resolve/scripts/detect-conflicts.sh +91 -0
- package/skills/dx-devops-conflict-resolve/scripts/diagnose-deploy-failure.sh +156 -0
- package/skills/dx-devops-request-status/SKILL.md +160 -0
- package/skills/dx-devops-request-status/examples/polling-workflows.md +101 -0
- package/skills/dx-devops-request-status/references/cli-commands.md +176 -0
- package/skills/dx-devops-request-status/scripts/poll-status.sh +134 -0
- package/skills/dx-devops-test-failures-analyze/SKILL.md +6 -6
- package/skills/dx-devops-test-pipeline-configure/SKILL.md +7 -7
- package/skills/dx-devops-test-suite-assignments-configure/SKILL.md +6 -6
- package/skills/dx-devops-test-suite-run/SKILL.md +6 -6
- package/skills/dx-devops-work-item-manage/SKILL.md +2 -0
- package/skills/dx-org-manage/references/creating-scratch-org.md +5 -2
- package/skills/dx-org-manage/references/creating-snapshot.md +1 -0
- package/skills/dx-org-shape-manage/SKILL.md +152 -0
- package/skills/dx-org-shape-manage/examples/create_error_output.json +9 -0
- package/skills/dx-org-shape-manage/examples/create_success_output.json +9 -0
- package/skills/dx-org-shape-manage/examples/delete_output.json +11 -0
- package/skills/dx-org-shape-manage/examples/list_inactive_output.json +32 -0
- package/skills/dx-org-shape-manage/examples/list_output.json +24 -0
- package/skills/dx-org-shape-manage/references/cli_flags.md +135 -0
- package/skills/dx-org-switch/SKILL.md +2 -2
- package/skills/dx-org-trial-expiration-check/SKILL.md +2 -0
- package/skills/dx-pkg-post-install-configure/SKILL.md +3 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +211 -0
- package/skills/education-cloud-multi-campus-configure/examples/hierarchy_visualization.md +174 -0
- package/skills/education-cloud-multi-campus-configure/examples/output_examples.md +54 -0
- package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input.csv +29 -0
- package/skills/education-cloud-multi-campus-configure/examples/sample_hierarchy_input_edgecases.csv +16 -0
- package/skills/education-cloud-multi-campus-configure/references/account_recordtype_prerequisite.md +44 -0
- package/skills/education-cloud-multi-campus-configure/references/delta_computation.md +33 -0
- package/skills/education-cloud-multi-campus-configure/references/error_handling.md +198 -0
- package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +54 -0
- package/skills/education-cloud-multi-campus-configure/references/gotchas.md +16 -0
- package/skills/education-cloud-multi-campus-configure/references/hierarchy_parsing_rules.md +133 -0
- package/skills/education-cloud-multi-campus-configure/references/mcp-invocation.md +75 -0
- package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/SKILL.md +1 -1
- package/skills/experience-cms-brand-apply/SKILL.md +4 -1
- package/skills/experience-cms-brand-create/SKILL.md +197 -0
- package/skills/experience-cms-brand-create/assets/brand-template.json +329 -0
- package/skills/experience-cms-brand-create/references/brand-anatomy.md +120 -0
- package/skills/experience-cms-brand-create/references/disk-contract.md +84 -0
- package/skills/experience-cms-content-generate/SKILL.md +190 -0
- package/skills/experience-cms-content-generate/assets/display-formats.md +84 -0
- package/skills/experience-cms-content-generate/assets/payloads/create-content-bulk.json +11 -0
- package/skills/experience-cms-content-generate/assets/payloads/create-content-single.json +11 -0
- package/skills/experience-cms-content-generate/assets/payloads/publish-content.json +4 -0
- package/skills/experience-cms-content-generate/assets/payloads/update-content.json +9 -0
- package/skills/experience-cms-content-generate/assets/questions.md +241 -0
- package/skills/experience-cms-content-generate/examples/create-content-call.md +81 -0
- package/skills/experience-cms-content-generate/references/bulk-batching.md +56 -0
- package/skills/experience-cms-content-generate/references/content-type-classification.md +88 -0
- package/skills/experience-cms-content-generate/references/content-write-tool.md +95 -0
- package/skills/experience-cms-content-generate/references/delegation-protocol.md +37 -0
- package/skills/experience-cms-content-generate/references/edit-publish-workflow.md +63 -0
- package/skills/experience-cms-content-generate/references/error-recovery.md +72 -0
- package/skills/experience-cms-content-generate/references/identifier-resolution.md +26 -0
- package/skills/experience-cms-content-generate/references/intent-routing.md +45 -0
- package/skills/experience-cms-content-generate/references/principles.md +19 -0
- package/skills/experience-cms-content-generate/references/ux-rules.md +68 -0
- package/skills/experience-cms-content-generate/references/workspace-resolution.md +33 -0
- package/skills/experience-cms-content-type-generate/SKILL.md +449 -0
- package/skills/experience-cms-content-type-generate/assets/discovery-prompts.md +79 -0
- package/skills/experience-cms-content-type-generate/assets/schema-example.json +70 -0
- package/skills/experience-cms-content-type-generate/references/agent-checklist.md +50 -0
- package/skills/experience-cms-content-type-generate/references/anti-patterns.md +39 -0
- package/skills/experience-cms-content-type-generate/references/deployment-errors.md +27 -0
- package/skills/experience-cms-content-type-generate/references/discovery-details.md +106 -0
- package/skills/experience-cms-content-type-generate/references/discovery-query-rules.md +85 -0
- package/skills/experience-cms-content-type-generate/references/edit-fields-loop.md +48 -0
- package/skills/experience-cms-content-type-generate/references/pre-deploy-checklist.md +21 -0
- package/skills/experience-cms-content-type-generate/references/retrieve-and-reconcile.md +105 -0
- package/skills/experience-cms-content-type-generate/references/schema-rules.md +51 -0
- package/skills/experience-cms-content-type-generate/references/schema-summary-format.md +60 -0
- package/skills/experience-lds-graphql-generate/SKILL.md +4 -0
- package/skills/experience-lwc-accessibility-jest-run/SKILL.md +79 -0
- package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +205 -0
- package/skills/experience-lwc-design-generate/SKILL.md +5 -4
- package/skills/experience-lwc-generate/SKILL.md +10 -9
- package/skills/experience-ui-bundle-deploy/references/dev-preview.md +21 -0
- package/skills/experience-ui-bundle-deploy/references/social-login.md +1 -0
- package/skills/experience-ui-bundle-file-upload-generate/SKILL.md +6 -6
- package/skills/experience-ui-bundle-localize/SKILL.md +30 -37
- package/skills/experience-ui-bundle-localize/references/gotchas.md +23 -7
- package/skills/experience-ui-bundle-localize/references/i18n-setup.md +48 -4
- package/skills/experience-ui-bundle-localize/references/label-xml.md +22 -8
- package/skills/experience-ui-bundle-localize/references/verifying.md +39 -11
- package/skills/experience-ui-bundle-localize/scripts/detect-bundle-type.sh +118 -15
- package/skills/experience-ui-bundle-localize/scripts/tests/test-detect-bundle-type.sh +187 -0
- package/skills/experience-ui-bundle-mfa-configure/SKILL.md +13 -2
- package/skills/experience-ui-bundle-mfa-configure/references/social-login.md +1 -0
- package/skills/experience-ui-bundle-project-generate/SKILL.md +2 -2
- package/skills/integration-connectivity-generate/SKILL.md +11 -10
- package/skills/integration-eventing-cdc-configure/SKILL.md +6 -6
- package/skills/integration-eventing-subscription-configure/SKILL.md +6 -5
- package/skills/mobile-platform-native-capabilities-integrate/SKILL.md +2 -2
- package/skills/mobile-platform-offline-validate/scripts/package.json +1 -1
- package/skills/platform-agentexchange-partner-offers-configure/SKILL.md +8 -8
- package/skills/platform-custom-application-generate/SKILL.md +2 -0
- package/skills/platform-custom-field-generate/SKILL.md +8 -6
- package/skills/platform-custom-metadata-type-generate/SKILL.md +460 -0
- package/skills/platform-custom-metadata-type-generate/references/cmdt-records.md +251 -0
- package/skills/platform-custom-metadata-type-generate/scripts/sanitize-developer-name.sh +46 -0
- package/skills/platform-custom-setting-generate/SKILL.md +419 -0
- package/skills/platform-dataspace-access-configure/SKILL.md +3 -3
- package/skills/platform-sharing-owd-configure/SKILL.md +3 -0
- package/skills/platform-value-set-generate/SKILL.md +2 -0
- package/skills/service-agentforce-channel-configure/SKILL.md +29 -20
- package/skills/service-agentforce-channel-configure/assets/BotEmailDefinition.botEmailDefinition-meta.xml +36 -0
- package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email +17 -0
- package/skills/service-agentforce-channel-configure/assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email-meta.xml +29 -0
- package/skills/service-agentforce-channel-configure/assets/mdapi-package.xml +25 -0
- package/skills/service-agentforce-channel-configure/assets/settings-mdapi-package.xml +30 -0
- package/skills/service-agentforce-channel-configure/references/agent-wiring.md +20 -0
- package/skills/service-agentforce-channel-configure/references/botemaildefinition.md +107 -0
- package/skills/service-agentforce-channel-configure/references/channel-branch-email.md +203 -50
- package/skills/service-agentforce-channel-configure/references/channel-types.md +30 -3
- package/skills/service-agentforce-channel-configure/references/queue-resolution.md +17 -8
- package/skills/service-agentforce-channel-configure/references/routing-flow.md +14 -3
- package/skills/service-agentforce-channel-configure/scripts/validate-botemaildefinition.py +126 -0
- package/skills/service-agentforce-channel-configure/scripts/validate-emailtemplate.py +133 -0
- package/skills/service-de-channel-activate/SKILL.md +271 -0
- package/skills/service-de-channel-activate/references/gotchas.md +31 -0
- package/skills/service-de-channel-activate/references/phone-verification.md +96 -0
- package/skills/service-de-channel-activate/references/worked-examples.md +14 -0
- package/skills/service-de-channel-consent-configure/SKILL.md +230 -0
- package/skills/service-de-channel-consent-configure/references/gotchas.md +41 -0
- package/skills/service-de-channel-consent-configure/references/language-keywords.md +84 -0
- package/skills/service-de-channel-consent-configure/references/worked-examples.md +134 -0
- package/skills/service-de-channel-create/SKILL.md +369 -0
- package/skills/service-de-channel-create/references/apple.md +59 -0
- package/skills/service-de-channel-create/references/connect-insert.md +84 -0
- package/skills/service-de-channel-create/references/facebook.md +154 -0
- package/skills/service-de-channel-create/references/line.md +66 -0
- package/skills/service-de-channel-create/references/sms.md +98 -0
- package/skills/service-de-channel-create/references/whatsapp.md +98 -0
- package/skills/service-de-channel-create/references/worked-examples.md +70 -0
- package/skills/service-de-channel-routing-configure/SKILL.md +345 -0
- package/skills/service-de-channel-routing-configure/references/asa-routing.md +90 -0
- package/skills/service-de-channel-routing-configure/references/gotchas.md +27 -0
- package/skills/service-de-channel-routing-configure/references/queue-creation.md +123 -0
- package/skills/service-de-channel-routing-configure/references/target-locate.md +98 -0
- package/skills/service-de-channel-routing-configure/references/worked-examples.md +174 -0
- package/skills/service-de-headless-channel-configure/SKILL.md +305 -0
- package/skills/service-de-headless-channel-configure/references/gotchas.md +27 -0
- package/skills/service-de-headless-channel-configure/references/inputs.md +49 -0
- package/skills/service-de-headless-channel-configure/references/output-envelopes.md +53 -0
- package/skills/service-de-headless-channel-configure/references/partial-success.md +24 -0
- package/skills/service-de-headless-channel-configure/references/terms-and-conditions.md +54 -0
- package/skills/service-de-headless-channel-configure/references/worked-examples.md +108 -0
- package/skills/service-de-waba-integrate/SKILL.md +227 -0
- package/skills/service-digital-engagement-channel-configure/scripts/check-api-version.sh +29 -0
- package/skills/service-digital-engagement-messaging-site-integrate/SKILL.md +10 -9
- package/skills/service-digital-engagement-messaging-site-integrate/references/lwr_patch.md +39 -21
- package/skills/service-digital-engagement-messaging-site-integrate/scripts/patch_lwr_bundle.sh +157 -96
- package/skills/service-email-to-case-configure/SKILL.md +190 -0
- package/skills/service-email-to-case-configure/assets/CaseSettings.settings-meta.xml +45 -0
- package/skills/service-email-to-case-configure/examples/CaseSettings-two-addresses.settings-meta.xml +36 -0
- package/skills/service-email-to-case-configure/references/apply-mechanics.md +73 -0
- package/skills/service-email-to-case-configure/references/routing_address_reference.md +73 -0
- package/skills/service-email-to-case-configure/references/troubleshooting.md +25 -0
- package/skills/service-email-to-case-configure/scripts/apply-casesettings.py +1315 -0
- package/skills/service-email-to-case-configure/scripts/check-agent-email-capability.sh +26 -0
- package/skills/service-email-to-case-configure/scripts/tests/__init__.py +0 -0
- package/skills/service-email-to-case-configure/scripts/tests/_bootstrap.py +45 -0
- package/skills/service-email-to-case-configure/scripts/tests/_fakeorg.py +366 -0
- package/skills/service-email-to-case-configure/scripts/tests/_run.py +84 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_apply_org_scenarios.py +655 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_get_session.py +134 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_new_capabilities.py +193 -0
- package/skills/service-email-to-case-configure/scripts/tests/test_validate_casesettings.py +170 -0
- package/skills/service-email-to-case-configure/scripts/validate-casesettings.py +229 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +33 -15
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -47
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +17 -12
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/references/cli-invocation.md +5 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/scripts/classify-enable-plan.mjs +11 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/SKILL.md +8 -6
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/references/cli-invocation.md +3 -3
- package/skills/service-itsm-agentic-setup-agentforce-studio-validate/scripts/classify-readiness.mjs +11 -3
- package/skills/service-itsm-agentic-setup-configure/SKILL.md +5 -5
- package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +5 -5
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +2 -2
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +11 -7
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +20 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +10 -6
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/action-availability.md +7 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +11 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/build-create-body.mjs +24 -17
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-action-availability.mjs +98 -58
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +20 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/strip-release-management.mjs +176 -0
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/SKILL.md +19 -19
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/cli-invocation.md +3 -4
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/helper-contracts.md +6 -6
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/references/permset-topology.md +3 -10
- package/skills/service-itsm-agentic-setup-itsm-agentforce-permset-assign/scripts/classify-permset-availability.mjs +7 -9
- package/skills/service-itsm-incident-mgmt-configure/SKILL.md +2 -0
- package/skills/service-itsm-incident-priority-configure/SKILL.md +15 -12
- package/skills/service-itsm-incident-priority-configure/examples/matrix-operations.md +27 -1
- package/skills/service-itsm-incident-priority-configure/references/sf-cli-invocation.md +37 -6
- package/skills/service-native-voice-recording-transcription-configure/SKILL.md +146 -0
- package/skills/service-native-voice-recording-transcription-configure/assets/confirmation-output.json +16 -0
- package/skills/service-native-voice-recording-transcription-configure/assets/package.xml +22 -0
- package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +101 -0
- package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +181 -0
- package/skills/data360-activate/README.md +0 -38
- package/skills/data360-activate/SKILL.md +0 -127
- package/skills/data360-connect/README.md +0 -57
- package/skills/data360-connect/SKILL.md +0 -163
- package/skills/data360-connect/examples/connections/heroku-postgres.json +0 -15
- package/skills/data360-connect/examples/connections/ingest-api-connection.json +0 -5
- package/skills/data360-connect/examples/connections/ingest-api-schema.json +0 -31
- package/skills/data360-connect/examples/connections/redshift.json +0 -16
- package/skills/data360-connect/examples/connections/sharepoint-unstructured.json +0 -20
- package/skills/data360-connect/examples/connections/snowflake-connection.json +0 -42
- package/skills/data360-harmonize/README.md +0 -31
- package/skills/data360-harmonize/SKILL.md +0 -126
- package/skills/data360-orchestrate/README.md +0 -120
- package/skills/data360-orchestrate/SKILL.md +0 -263
- package/skills/data360-orchestrate/assets/definitions/activation-target.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/activation.template.json +0 -7
- package/skills/data360-orchestrate/assets/definitions/calculated-insight.template.json +0 -7
- package/skills/data360-orchestrate/assets/definitions/data-action-target.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/data-action.template.json +0 -5
- package/skills/data360-orchestrate/assets/definitions/data-graph.template.json +0 -21
- package/skills/data360-orchestrate/assets/definitions/data-stream.template.json +0 -55
- package/skills/data360-orchestrate/assets/definitions/dmo.template.json +0 -17
- package/skills/data360-orchestrate/assets/definitions/identity-resolution.template.json +0 -30
- package/skills/data360-orchestrate/assets/definitions/mapping.template.json +0 -14
- package/skills/data360-orchestrate/assets/definitions/relationship.template.json +0 -12
- package/skills/data360-orchestrate/assets/definitions/search-index.template.json +0 -9
- package/skills/data360-orchestrate/assets/definitions/segment.template.json +0 -16
- package/skills/data360-orchestrate/references/feature-readiness.md +0 -157
- package/skills/data360-orchestrate/references/plugin-setup.md +0 -138
- package/skills/data360-orchestrate/scripts/bootstrap-plugin.sh +0 -53
- package/skills/data360-orchestrate/scripts/diagnose-org.mjs +0 -511
- package/skills/data360-orchestrate/scripts/generate-manifest.mjs +0 -68
- package/skills/data360-orchestrate/scripts/verify-plugin.sh +0 -58
- package/skills/data360-prepare/README.md +0 -50
- package/skills/data360-prepare/SKILL.md +0 -203
- package/skills/data360-prepare/examples/ingestion-api/.env.example +0 -8
- package/skills/data360-prepare/examples/ingestion-api/README.md +0 -48
- package/skills/data360-prepare/examples/ingestion-api/send-data.py +0 -144
- package/skills/data360-query/README.md +0 -43
- package/skills/data360-query/SKILL.md +0 -128
- package/skills/data360-query/examples/search-indexes/hybrid-structured.json +0 -44
- package/skills/data360-query/examples/search-indexes/vector-knowledge.json +0 -43
- package/skills/data360-segment/README.md +0 -35
- package/skills/data360-segment/SKILL.md +0 -123
- package/skills/service-helpagent-coordinate/references/channel-help-portal.md +0 -22
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-1-1-non-text-content.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-i-lists.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-ii-tables.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iii-form-labels.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-iv-regions.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-1-v-groups.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-3-5-identify-input.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-1-4-3-contrast.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-1-1-keyboard.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-4-link-purpose.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-4-6-headings-labels.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-3-label-in-name.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-2-5-7-dragging-movement.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-1-on-focus.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-2-2-on-input.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-1-error-identification.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-2-labels-instructions.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-3-3-3-error-suggestion.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-i-name.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-ii-role.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/reviewers/sc-4-1-2-iii-value.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-1-1-non-text-content.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-1-use-of-color.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-10-resize-reflow.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-11-non-text-contrast.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/references/vision/sc-1-4-3-contrast.md +0 -0
- /package/skills/{experience-lwc-accessibility-validate → experience-accessibility-validate}/scripts/contrast-ratio.py +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Facebook Messenger — OAuth, page selection, request body, gotchas
|
|
2
|
+
|
|
3
|
+
`MESSAGE_TYPE=Facebook`. Platform key is the **Facebook Page ID** (numeric, ~15 digits). Unlike the
|
|
4
|
+
other types, Facebook resolves its platform key via a browser-based OAuth flow when `{PAGE_ID}` isn't
|
|
5
|
+
supplied.
|
|
6
|
+
|
|
7
|
+
## Inputs
|
|
8
|
+
|
|
9
|
+
- `{PAGE_ID}` — **optional.** If absent, run OAuth → fetch pages → prompt for selection.
|
|
10
|
+
- `{CHANNEL_NAME}` — **optional.** If absent, prompt after page selection.
|
|
11
|
+
|
|
12
|
+
Most callers will NOT provide `PAGE_ID` upfront.
|
|
13
|
+
|
|
14
|
+
## Stage 1 preflight caveat
|
|
15
|
+
|
|
16
|
+
Only run the Stage 1 preflight if `{PAGE_ID}` was provided. If not, skip it — the page id isn't known
|
|
17
|
+
until OAuth + page selection completes. Run the preflight (two-query FK form) after the page is chosen,
|
|
18
|
+
before the insert.
|
|
19
|
+
|
|
20
|
+
## Stage 2-3: browser-based OAuth + page selection
|
|
21
|
+
|
|
22
|
+
Facebook requires OAuth authorization to access the customer's pages. This is an interactive,
|
|
23
|
+
browser-based flow — but it **is** headless-driveable end to end: the skill hands the admin the
|
|
24
|
+
exact authorize URL and fetches the page list over Connect REST. It is **not** UI-bootstrap-only.
|
|
25
|
+
|
|
26
|
+
**Step 1 — get `{AUTH_PROVIDER_ID}` AND the kickoff URL in one query.** The `OauthKickoffUrl` field
|
|
27
|
+
on the AuthProvider is the load-bearing piece — it is the feature-specific Facebook OAuth entry
|
|
28
|
+
point:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
sf data query --target-org '{ORG_ALIAS}' \
|
|
32
|
+
--query "SELECT Id, OauthKickoffUrl FROM AuthProvider WHERE DeveloperName = 'LiveMessageSetup' AND ProviderType = 'Facebook' ORDER BY CreatedDate DESC LIMIT 1" \
|
|
33
|
+
--json > "${SCRATCH_DIR}/fb-authprovider.json"
|
|
34
|
+
```
|
|
35
|
+
Record `{AUTH_PROVIDER_ID}` = `records[0].Id` and `{OAUTH_KICKOFF_URL}` = `records[0].OauthKickoffUrl`
|
|
36
|
+
(e.g. `https://<myDomain>/services/auth/oauth/LiveMessageSetup`). If no record →
|
|
37
|
+
`{ok:false, kind:"missing-authprovider", hint:"LiveMessageSetup AuthProvider not found — org may not have Facebook Messenger enabled"}`.
|
|
38
|
+
|
|
39
|
+
> **Use `OauthKickoffUrl`, NOT the generic `/services/auth/sso/<orgId>/LiveMessageSetup` SSO URL.**
|
|
40
|
+
> That SSO door runs the AuthProvider's Apex *registration handler* to log a user in; `LiveMessageSetup`
|
|
41
|
+
> has no registration handler (`RegistrationHandlerId=000000000000000`), so the SSO URL dead-ends at
|
|
42
|
+
> `NO_REGISTRATION_HANDLER` — "authentication error." The `/services/auth/oauth/...` kickoff URL is the
|
|
43
|
+
> service-token flow and is the only one that works here. (Verified live on sdb6, 2026-08-26.)
|
|
44
|
+
|
|
45
|
+
**Step 2 — best-effort token probe / page fetch (same endpoint).** A GET returns the page list when
|
|
46
|
+
the token is valid:
|
|
47
|
+
```bash
|
|
48
|
+
sf api request rest \
|
|
49
|
+
"/services/data/v{API_VERSION}/connect/livemessage/channels?messageType=Facebook&authProviderId={AUTH_PROVIDER_ID}" \
|
|
50
|
+
--target-org '{ORG_ALIAS}' > "${SCRATCH_DIR}/fb-pages.json"
|
|
51
|
+
```
|
|
52
|
+
- Body has a `channels[]` array → token *appears* valid; you already have the page list.
|
|
53
|
+
- Body has `errorCode:"AUTH_PROVIDER_NEEDS_AUTH"` → token missing/expired; go to Step 3.
|
|
54
|
+
|
|
55
|
+
> **The GET is NOT authoritative (gotcha #5).** It serves a *cached* page-list snapshot that can
|
|
56
|
+
> survive the underlying Facebook token expiring — a green GET does not guarantee the Stage 4 POST
|
|
57
|
+
> will succeed. Only the POST validates the token at submit time. If Stage 4 returns
|
|
58
|
+
> `AUTH_PROVIDER_NEEDS_AUTH` despite a passing GET, re-run Step 3 (don't blame the SF session).
|
|
59
|
+
|
|
60
|
+
**Step 3 — open the authorize URL in a browser.** Append the window-close callback so the flow ends
|
|
61
|
+
on a clean blank page rather than a confusing redirect:
|
|
62
|
+
```bash
|
|
63
|
+
OAUTH_URL="${OAUTH_KICKOFF_URL}?startURL=%2Fpage%2Fwindowclose.jsp"
|
|
64
|
+
case "$(uname -s)" in
|
|
65
|
+
Darwin) open "${OAUTH_URL}" ;;
|
|
66
|
+
Linux) xdg-open "${OAUTH_URL}" ;;
|
|
67
|
+
MINGW*|MSYS*|CYGWIN*) start "" "${OAUTH_URL}" ;;
|
|
68
|
+
*) echo "Open this URL to authorize Facebook: ${OAUTH_URL}" ;;
|
|
69
|
+
esac
|
|
70
|
+
```
|
|
71
|
+
Open it automatically; only fall back to printing the URL if no opener exists. Tell the admin: log
|
|
72
|
+
in to the Facebook account that administers the target Page(s), grant access, and **a blank white
|
|
73
|
+
page means success** — close that tab. Then wait for their confirmation (or poll the Step-2 GET
|
|
74
|
+
until `channels[]` appears; ~60 × 3s).
|
|
75
|
+
|
|
76
|
+
**Step 4 — fetch the page list** (re-run the Step-2 GET now that the token is fresh). Each entry has
|
|
77
|
+
`developerName`, `masterLabel`, `messageType`, `messagingPlatformKey`; entries whose page is already
|
|
78
|
+
wired to a channel **also** carry `id` and `isActive`.
|
|
79
|
+
|
|
80
|
+
Failure kinds from this stage: `oauth-not-complete` (authorization missing/expired),
|
|
81
|
+
`oauth-failed` (authorization failed or cancelled), `missing-authprovider` (no LiveMessageSetup FB
|
|
82
|
+
AuthProvider on the org).
|
|
83
|
+
|
|
84
|
+
**Page selection (if `{PAGE_ID}` not supplied):** render **every** page — sorted alphabetically by
|
|
85
|
+
`masterLabel`, annotated with already-connected status, **never truncated** (real orgs have 56+
|
|
86
|
+
pages). Use the write-to-file-plus-render-inline strategy to defeat Bash stdout collapse. Read the
|
|
87
|
+
reply, trim, record `{PAGE_ID}`.
|
|
88
|
+
|
|
89
|
+
**Channel name (if not supplied):** prompt `Enter a display name for this channel (e.g., "Customer
|
|
90
|
+
Support")`. Empty after trim → re-prompt once; second empty →
|
|
91
|
+
`{ok:false, kind:"missing-input", hint:"CHANNEL_NAME is required"}`.
|
|
92
|
+
|
|
93
|
+
Failure kinds from this stage: `oauth-not-complete` (authorization missing/expired),
|
|
94
|
+
`oauth-failed` (authorization failed or cancelled).
|
|
95
|
+
|
|
96
|
+
## Stage 4.2: request body
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
jq -n --arg pageId "${PAGE_ID}" --arg channelName "${CHANNEL_NAME}" \
|
|
100
|
+
'{messageType:"Facebook", platformType:"Enhanced",
|
|
101
|
+
messagingPlatformKey:$pageId, messagingChannelName:$channelName, authDetails:{}}' \
|
|
102
|
+
> "${SCRATCH_DIR}/body.json"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
(`${SCRATCH_DIR}` is the per-run scratch dir established in SKILL.md Stage 0.2 — under
|
|
106
|
+
`${outputDir}`/`${TMPDIR}`, never a bare `/tmp` path.)
|
|
107
|
+
|
|
108
|
+
`authDetails: {}` — empty; the OAuth token lives in the AuthProvider, not the body. `authProviderId`
|
|
109
|
+
is a URL query parameter, never a body field.
|
|
110
|
+
|
|
111
|
+
**Response classification — classify by `errorCode` first, status second.** The Connect endpoint is
|
|
112
|
+
inconsistent about which HTTP status it pairs with `AUTH_PROVIDER_NEEDS_AUTH` (observed at 401, docs
|
|
113
|
+
imply 400). Always inspect `response[0].errorCode` (or `.errorCode` if the body is an object) before
|
|
114
|
+
status-based classification:
|
|
115
|
+
|
|
116
|
+
| `errorCode` (any status) | Handling |
|
|
117
|
+
| --- | --- |
|
|
118
|
+
| `AUTH_PROVIDER_NEEDS_AUTH` | `{ok:false, kind:"oauth-not-complete", hint:"Facebook OAuth authorization is missing or expired — re-run Stage 2 to refresh the FB token"}`. |
|
|
119
|
+
| `DUPLICATE_VALUE` | Re-run Stage 1 preflight; emit success `created:false, path:"connect-duplicate"`. |
|
|
120
|
+
|
|
121
|
+
Then the two 401 flavors (disambiguate by errorCode, NOT status):
|
|
122
|
+
- `AUTH_PROVIDER_NEEDS_AUTH` → `oauth-not-complete` (re-run OAuth; SF session is fine).
|
|
123
|
+
- empty body / `INVALID_SESSION_ID` → `{ok:false, kind:"auth", hint:"SF session token invalid — run 'sf org login web'"}`.
|
|
124
|
+
|
|
125
|
+
Telling the user to run `sf org login web` when the FB token is the problem sends them down a dead
|
|
126
|
+
end — the errorCode is what distinguishes the two.
|
|
127
|
+
|
|
128
|
+
## Gotchas
|
|
129
|
+
|
|
130
|
+
1. **The 401 is usually NOT an SF token problem.** `AUTH_PROVIDER_NEEDS_AUTH` at 401 means the
|
|
131
|
+
AuthProvider's stored Facebook token is stale — re-run OAuth, not `sf org login web`. Classify by
|
|
132
|
+
errorCode first.
|
|
133
|
+
2. **Never truncate the page list.** 56+ pages is normal; write-to-file-plus-render-inline defeats
|
|
134
|
+
Bash stdout collapse.
|
|
135
|
+
3. **MCU lands as `DeploymentStatus=New` for Facebook** (WhatsApp lands as `Disabled`). Both are
|
|
136
|
+
valid `→ Provisioning` sources — don't assert a specific starting status in Stage 5. (Verified:
|
|
137
|
+
fresh FB insert → `MessagingChannelUsage.DeploymentStatus=New`, `DeploymentType=Conversation`.)
|
|
138
|
+
4. **POST-response projection is not authoritative** for `masterLabel` / `developerName` — trust the
|
|
139
|
+
Stage 5 verify SOQL. Verified: POST returned `developerName:"Facebook_988507654355940"` /
|
|
140
|
+
`masterLabel:"988507654355940"`, but SOQL showed `FACEBOOK_US_988507654355940` (uppercase +
|
|
141
|
+
country-code suffix) / the real `messagingChannelName` as `MasterLabel`.
|
|
142
|
+
5. **The page-list GET is a cached snapshot, not a live token check.** `GET
|
|
143
|
+
/connect/livemessage/channels?messageType=Facebook&authProviderId=...` can return 200 with the
|
|
144
|
+
full page list even after the underlying Facebook token has expired; only the Stage 4 POST
|
|
145
|
+
validates the token at submit time. Use the GET for the page list, never as proof the POST will
|
|
146
|
+
succeed. If the POST returns `AUTH_PROVIDER_NEEDS_AUTH`, re-open `OauthKickoffUrl` (Stage 2-3),
|
|
147
|
+
don't run `sf org login web`.
|
|
148
|
+
6. **Consent is auto-seeded on insert — do NOT assume the channel lands consent-blank.** A fresh
|
|
149
|
+
Connect insert comes back with `ConsentType=ImplicitOptIn` already set and a default `en_US`
|
|
150
|
+
`MsgChannelLanguageKeyword` already created (opt-out keywords `cancel,stopall,stop,unsubscribe,
|
|
151
|
+
end,quit` + a canned confirmation, plus a `help` keyword). The downstream consent step is
|
|
152
|
+
therefore often a **no-op** on a fresh channel (or an *upgrade* if the caller wants
|
|
153
|
+
Explicit/DoubleOptIn), not a guaranteed write. (Verified live on sdb6, 2026-08-26, channel
|
|
154
|
+
`0MjSG000000TXdJ0AW`.)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# LINE — token verify, request body, gotchas
|
|
2
|
+
|
|
3
|
+
`MESSAGE_TYPE=Line`. Platform key is the **LINE channel id** (numeric, from the LINE Developers
|
|
4
|
+
Console — not the LINE user id). Channel secret + access token go in `authDetails`.
|
|
5
|
+
|
|
6
|
+
## Inputs
|
|
7
|
+
|
|
8
|
+
- `{LINE_CHANNEL_ID}` — LINE channel id. Numeric string. Sent as `messagingPlatformKey`.
|
|
9
|
+
- `{LINE_CHANNEL_SECRET}` — LINE channel secret (webhook verification secret). Sent in
|
|
10
|
+
`authDetails.client_secret`.
|
|
11
|
+
- `{LINE_ACCESS_TOKEN}` — LINE long-lived channel access token. Sent in `authDetails.access_token`.
|
|
12
|
+
- `{CHANNEL_NAME}` — optional. Defaults to `LINE_{LINE_CHANNEL_ID}` if not provided.
|
|
13
|
+
- `{VERIFY_TOKEN_FIRST}` — optional boolean, default `true`. When `true`, validate the token against
|
|
14
|
+
LINE's public API before insert.
|
|
15
|
+
|
|
16
|
+
## Stage 2-3: optional token preflight
|
|
17
|
+
|
|
18
|
+
If `{VERIFY_TOKEN_FIRST}` is `true`, validate the token before paying the full insert cost. This is
|
|
19
|
+
a **third-party** call to LINE, so it uses `curl` (not `sf api request rest`) — the LINE token is
|
|
20
|
+
not a Salesforce credential:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
curl -sS -o "${SCRATCH_DIR}/line-token.json" -w '\n%{http_code}' \
|
|
24
|
+
-H "Authorization: Bearer ${LINE_ACCESS_TOKEN}" \
|
|
25
|
+
"https://api.line.me/v2/bot/info"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- HTTP 200 → token valid, proceed.
|
|
29
|
+
- HTTP 401 / non-200 → `{ok:false, kind:"line-token-invalid", hint:"LINE access token rejected — regenerate in LINE Developers Console and retry"}`.
|
|
30
|
+
|
|
31
|
+
If `VERIFY_TOKEN_FIRST=false`, skip — the Connect POST will surface a token error later, with less
|
|
32
|
+
clear signal.
|
|
33
|
+
|
|
34
|
+
(`${SCRATCH_DIR}` is the per-run scratch dir established in SKILL.md Stage 0.2 — under
|
|
35
|
+
`${outputDir}`/`${TMPDIR}`, never a bare `/tmp` path.)
|
|
36
|
+
|
|
37
|
+
## Stage 4.2: request body
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{"messageType":"Line","platformType":"Enhanced",
|
|
41
|
+
"messagingPlatformKey":"{LINE_CHANNEL_ID}",
|
|
42
|
+
"messagingChannelName":"{CHANNEL_NAME}",
|
|
43
|
+
"authDetails":{"client_secret":"{LINE_CHANNEL_SECRET}","access_token":"{LINE_ACCESS_TOKEN}"}}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Write the body to a file** — the access token is long and can contain shell-hostile characters.
|
|
47
|
+
|
|
48
|
+
Response classification: same as the shared table (see `connect-insert.md`), plus — on `400` whose
|
|
49
|
+
message contains "access token" / "channel secret" / "Line" — emit
|
|
50
|
+
`{ok:false, kind:"line-token-invalid", message, hint:"LINE creds rejected — verify channel secret + access token in LINE Developers Console"}`.
|
|
51
|
+
|
|
52
|
+
## Gotchas
|
|
53
|
+
|
|
54
|
+
1. **`messagingPlatformKey` is the LINE channel id**, not the LINE user id — the numeric id shown in
|
|
55
|
+
the Developers Console for the Messaging API channel.
|
|
56
|
+
2. **`authDetails` keys are exactly `client_secret` + `access_token`.** Don't rename them;
|
|
57
|
+
`LiveMessageSetupServiceImpl.addChannel` looks for exactly those strings.
|
|
58
|
+
3. **Long-lived vs short-lived tokens.** The Setup wizard assumes long-lived (Developers Console).
|
|
59
|
+
Short-lived tokens (Channel Access Token v2.1 API) insert fine but expire, silently stopping the
|
|
60
|
+
channel. Use long-lived for production.
|
|
61
|
+
4. **No third-party registration at activation.** Unlike WhatsApp, LINE has no `/register` call —
|
|
62
|
+
`service-de-channel-activate` transitions MCU→Active without any external callout, so
|
|
63
|
+
`Provisioning` is essentially invisible (~1s).
|
|
64
|
+
5. **`sf api request rest` manages the SF OAuth session** — no `ACCESS_TOKEN`/`INSTANCE_URL` shell
|
|
65
|
+
variables. The LINE token is the only credential handled by `curl`, and only for the Stage 2-3
|
|
66
|
+
verify.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# SMS (Text) — phone-number platform key, accepted-but-ignored smsProvider, gotchas
|
|
2
|
+
|
|
3
|
+
`MESSAGE_TYPE=Text`. There is **no `"SMS"` enum value** — SMS channels are `Text` everywhere in the
|
|
4
|
+
platform (the `MessageTypeEnum` API value is `"Text"`; the DB value is `0`). Send `"messageType":"Text"`.
|
|
5
|
+
|
|
6
|
+
Platform key is the **phone number / SMS code itself** — the literal long code, toll-free number, or
|
|
7
|
+
short code string the caller wants to send from (e.g. `18005551234`). It is stored verbatim into
|
|
8
|
+
`MessagingChannel.MessagingPlatformKey` and used as-is for the activation-time ESP lookup, so it must
|
|
9
|
+
match exactly what was provisioned for that code. Don't reformat it; send whatever the caller gives.
|
|
10
|
+
|
|
11
|
+
**Prerequisite (caller's responsibility, NOT handled by this skill):** the phone number / code must
|
|
12
|
+
already be provisioned to the org through the SMS code-request flow. This skill does **not** allocate a
|
|
13
|
+
number, request a short code, or run any code-provisioning step — it only inserts the channel record for
|
|
14
|
+
a number the caller already has. If the number isn't provisioned yet, the insert may still succeed (the
|
|
15
|
+
record is created inactive) but activation will later fail at the ESP registration step.
|
|
16
|
+
|
|
17
|
+
## Inputs
|
|
18
|
+
|
|
19
|
+
- `{SMS_NUMBER}` — the phone number / short code / toll-free number, as a plain string. Sent as
|
|
20
|
+
`messagingPlatformKey`. **Required.**
|
|
21
|
+
- `{SMS_PROVIDER}` — the code-provider identifier for this number (the "messaging provider" / SMS
|
|
22
|
+
provider). Sent as `smsProvider`. The `smsProvider` **key must be present in the body**, but the
|
|
23
|
+
Connect endpoint only checks that the field *exists* — it does not check the **value** against any
|
|
24
|
+
provider registry, and it does not persist the value anywhere. Sending an **empty string**
|
|
25
|
+
(`"smsProvider":""`) inserts the channel successfully; **omitting the key entirely** fails with
|
|
26
|
+
errorCode `ILLEGAL_QUERY_PARAMETER_VALUE`, message `"SMS provider is missing "`. Tested against
|
|
27
|
+
`sdb6` (API v69.0): an empty-provider channel and a real-provider channel are byte-identical across
|
|
28
|
+
every queryable `MessagingChannel` field — there is no `ExternalChannelConfigJson` /
|
|
29
|
+
`codeProviderDetails` field on the object (the only provider/config-adjacent fields are
|
|
30
|
+
`IsoCountryCode` and `RoutingConfigurationId`), so the value has no storage location and leaves no
|
|
31
|
+
observable trace. Pass the real provider when the caller knows it, else default to `""` — never omit
|
|
32
|
+
the key.
|
|
33
|
+
- `{CHANNEL_NAME}` — display name (`messagingChannelName`). Recommended; falls back to the number if
|
|
34
|
+
omitted, but supplying it keeps the Setup UI label meaningful. Note: the insert **response** echoes
|
|
35
|
+
`masterLabel` as the bare number, but the **persisted** `MessagingChannel.MasterLabel` holds the
|
|
36
|
+
supplied `messagingChannelName` (tested against `sdb6`, API v69.0). Read the stored record — not the
|
|
37
|
+
POST response — if you need the display label back.
|
|
38
|
+
- `{ISO_COUNTRY_CODE}` — optional, default `US`. Participates in the dedupe query and the generated
|
|
39
|
+
`DeveloperName`, so pass the real country if the number is non-US.
|
|
40
|
+
|
|
41
|
+
## Stage 2-3: none
|
|
42
|
+
|
|
43
|
+
SMS has no insert-time third-party prerequisite that this skill performs. The number-provisioning /
|
|
44
|
+
code-request step is upstream and out of scope (see the prerequisite note above). The ESP registration
|
|
45
|
+
(`registerCsotSms` → Admin API ESP-ID lookup keyed by the platform key) runs at **activation**, not
|
|
46
|
+
insert — so an unprovisioned number surfaces as an activation-time `provisioning-error`, not an insert
|
|
47
|
+
failure.
|
|
48
|
+
|
|
49
|
+
## Stage 4.2: request body
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{"messageType":"Text","platformType":"Enhanced",
|
|
53
|
+
"messagingPlatformKey":"{SMS_NUMBER}",
|
|
54
|
+
"messagingChannelName":"{CHANNEL_NAME}",
|
|
55
|
+
"smsProvider":"{SMS_PROVIDER}",
|
|
56
|
+
"isoCountryCode":"{ISO_COUNTRY_CODE}"}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**`smsProvider` is the Text-specific field the body must always carry** — no other type sends it, and
|
|
60
|
+
Text cannot be inserted if the key is missing. Its value is not validated or stored (see Inputs), so
|
|
61
|
+
default to `""` when the caller didn't supply a provider — but **always include the key**. **No
|
|
62
|
+
`authDetails` / `externalAccountId` / auth tokens** — Text uses none of those (`authDetails` is read
|
|
63
|
+
only by MsCopilot / GoogleChat / Slack / Line). `authProviderId` in the URL query string is **optional
|
|
64
|
+
for Text** (the v258 Connect signature added a Text-only path that doesn't require it) — this is the
|
|
65
|
+
whole reason Stage 4.1 treats a missing `LiveMessageSetup` AuthProvider as terminal for every other type
|
|
66
|
+
but non-fatal for `Text`. Send `authProviderId` only when Stage 4.1 actually resolved one (harmless for
|
|
67
|
+
Text); when it didn't, `Text` proceeds and the POST omits the parameter entirely. **Do not append an
|
|
68
|
+
empty `?authProviderId=`** — a blank value is rejected with `ILLEGAL_QUERY_PARAMETER_VALUE`, so a Text
|
|
69
|
+
insert on an org with no LiveMessage setup must hit the bare endpoint.
|
|
70
|
+
|
|
71
|
+
Response classification: same as the shared table (see `connect-insert.md`), plus — on an error whose
|
|
72
|
+
message mentions "SMS provider" / "provider is missing" (observed errorCode
|
|
73
|
+
`ILLEGAL_QUERY_PARAMETER_VALUE`) — the body dropped the `smsProvider` key entirely; re-send with the
|
|
74
|
+
key present (an empty string `""` is fine). This shouldn't happen if the body is built from the shape
|
|
75
|
+
above, which always includes the key.
|
|
76
|
+
|
|
77
|
+
## Gotchas
|
|
78
|
+
|
|
79
|
+
1. **The enum is `Text`, not `SMS`.** `"messageType":"SMS"` is rejected — the picklist / SOQL / Connect
|
|
80
|
+
enum value is `Text`. The user-facing concept "SMS" maps to `Text` in every API surface.
|
|
81
|
+
2. **`smsProvider` key is mandatory; its value is not.** The Connect endpoint checks only that the
|
|
82
|
+
field is present — omitting it fails with errorCode `ILLEGAL_QUERY_PARAMETER_VALUE`, message
|
|
83
|
+
`"SMS provider is missing "`, but an empty string (`"smsProvider":""`) inserts fine, and the
|
|
84
|
+
endpoint neither checks the value against a provider registry nor stores it anywhere (no
|
|
85
|
+
`ExternalChannelConfigJson`/`codeProviderDetails` field exists on `MessagingChannel`; tested
|
|
86
|
+
against `sdb6`, API v69.0). Always send the key; default the value to `""` when unknown. It is a
|
|
87
|
+
code-provider label, not an auth secret.
|
|
88
|
+
3. **`MessagingPlatformKey` is the number/code string itself**, stored verbatim. There's no separate
|
|
89
|
+
phone-number ID (contrast WhatsApp, where the platform key is a Phone Number ID distinct from the
|
|
90
|
+
WABA ID). Send the exact provisioned code string; this skill doesn't normalize to E.164.
|
|
91
|
+
4. **This skill doesn't provision the number.** It inserts a channel record for a number the caller
|
|
92
|
+
already has. Number allocation / short-code requests are a separate upstream flow, intentionally out
|
|
93
|
+
of scope here — the caller must already know their number and its provider.
|
|
94
|
+
5. **Activation, not insert, is where an unprovisioned number bites.** `registerCsotSms` does the Admin
|
|
95
|
+
API ESP-ID lookup keyed by the platform key at activation time. Insert only creates the inactive
|
|
96
|
+
record + its MCU.
|
|
97
|
+
6. **Fresh MCUs start in `DeploymentStatus=New`** (`Disabled` is the post-deactivation state) — same as
|
|
98
|
+
every other type. Don't assert a specific starting status in Stage 5.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# WhatsApp — prerequisites, request body, gotchas
|
|
2
|
+
|
|
3
|
+
`MESSAGE_TYPE=WhatsApp`. Platform key is the **Phone Number ID** (not the WABA ID, not the display
|
|
4
|
+
number). WABA ID is sent separately as `externalAccountId`.
|
|
5
|
+
|
|
6
|
+
## Inputs
|
|
7
|
+
|
|
8
|
+
- `{WABA_ID}` — WhatsApp Business Account ID. Numeric string, ~15 digits. Sent as
|
|
9
|
+
`externalAccountId`. **NOT the same as Phone Number ID** — a WABA can contain multiple phone
|
|
10
|
+
numbers. Meta Business Manager → WhatsApp Accounts → (your account) → Account ID at top.
|
|
11
|
+
- `{PHONE_NUMBER_ID}` — Meta phone number ID. Numeric string, ~15 digits. Sent as
|
|
12
|
+
`messagingPlatformKey`. (NOT the display phone number like `+1 650-555-0199`.) **Must differ from
|
|
13
|
+
WABA_ID.** Meta Business Manager → WhatsApp Accounts → (your WABA) → Phone Numbers tab → Phone
|
|
14
|
+
number ID column.
|
|
15
|
+
- `{CHANNEL_NAME}` — display name (`messagingChannelName`), shown as "Channel Name" in Setup →
|
|
16
|
+
Messaging Settings. Required — prompt if not supplied. Never auto-default to the phone number id:
|
|
17
|
+
the id is opaque and produces a confusing UI (both columns show the same digits).
|
|
18
|
+
- `{ISO_COUNTRY_CODE}` — optional, two-letter ISO-3166 alpha-2 (e.g. `US`). Default `US`. Passed as
|
|
19
|
+
`isoCountryCode`.
|
|
20
|
+
|
|
21
|
+
## Stage 2-3: WABA partnership + SF-side management (prereq)
|
|
22
|
+
|
|
23
|
+
Runs only when Stage 1 preflight found no existing channel. Execution order on a fresh run:
|
|
24
|
+
Stage 1 → Stage 2 (linking) → Stage 3 (manage-WABA) → Stage 4 (insert). On a preflight-hit resume,
|
|
25
|
+
these never run — the partnership and the SF-side webhook/credit-line share are both in place by
|
|
26
|
+
definition (the prior insert couldn't have succeeded otherwise).
|
|
27
|
+
|
|
28
|
+
**Stage 2 — customer-side partnership.** Confirm the WABA is shared with Salesforce in Meta Business
|
|
29
|
+
Suite. There's no Graph API to probe this without a customer Meta token, so invoke
|
|
30
|
+
`service-de-waba-integrate` and handle its envelope:
|
|
31
|
+
- success → proceed to Stage 3
|
|
32
|
+
- `{ok:false, kind:"partnership-blocked"}` → propagate; resolve on Meta side and retry
|
|
33
|
+
- `{ok:false, kind:"user-declined"}` → propagate; re-run when ready
|
|
34
|
+
|
|
35
|
+
**Stage 3 — SF-side management.** The customer-side share from Stage 2 alone does not subscribe SF's
|
|
36
|
+
webhook or share SF's Meta line of credit. Call the sanctioned Connect endpoint. **The WABA id (and
|
|
37
|
+
phone id) go in the URL query string, NOT the JSON body** — the endpoint reads `wabaId`/`phoneId`
|
|
38
|
+
from the query and ignores a body `externalAccountId`. Send an empty body:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
sf api request rest \
|
|
42
|
+
"/services/data/v{API_VERSION}/connect/livemessage/whatsapp/business-account?authProviderId=${AUTH_PROVIDER_ID}&wabaId=${WABA_ID}&phoneId=${PHONE_NUMBER_ID}" \
|
|
43
|
+
--method POST --target-org '{ORG_ALIAS}' \
|
|
44
|
+
--header 'Content-Type: application/json' --header 'Accept: application/json' \
|
|
45
|
+
--include
|
|
46
|
+
```
|
|
47
|
+
On failure emit
|
|
48
|
+
`{ok:false, kind:"waba-manage-failed", hint:"manageWhatsAppBusinessAccount failed — SF could not subscribe its webhook / share credit line with this WABA. Most likely: WABA not actually shared yet (partnership landed Meta-side but hasn't propagated), or the WABA id is wrong.", message:"..."}`.
|
|
49
|
+
|
|
50
|
+
> **Do NOT put the WABA id in the body** (gotcha #6). A body of `{"externalAccountId":"<WABA_ID>"}` —
|
|
51
|
+
> or even `{"wabaId":"<WABA_ID>"}` — returns `400 INVALID_API_INPUT "wabaId is required"`, because the
|
|
52
|
+
> endpoint only reads `wabaId`/`phoneId` from the query string. Pass both as query params with an empty
|
|
53
|
+
> body. (Verified live: documented body shape → `"wabaId is required"` on sdb6; query-param shape → 201
|
|
54
|
+
> on projectCodeyDemo, 2026-08-26.)
|
|
55
|
+
|
|
56
|
+
Together Stage 2 + Stage 3 produce a WABA fully ready for the Stage 4 channel insert.
|
|
57
|
+
|
|
58
|
+
## Stage 4.2: request body
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{"messageType":"WhatsApp","platformType":"Enhanced",
|
|
62
|
+
"messagingPlatformKey":"{PHONE_NUMBER_ID}",
|
|
63
|
+
"messagingChannelName":"{CHANNEL_NAME}",
|
|
64
|
+
"externalAccountId":"{WABA_ID}",
|
|
65
|
+
"isoCountryCode":"{ISO_COUNTRY_CODE}"}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The MCU lands in a pre-activation `DeploymentStatus` (observed as both `Disabled` and `New` on fresh
|
|
69
|
+
WhatsApp inserts across orgs; Facebook lands as `New`). Any pre-activation value is a valid
|
|
70
|
+
`→ Provisioning` source state — don't assert a specific one; just confirm the MCU exists.
|
|
71
|
+
|
|
72
|
+
## Type-specific failure kinds
|
|
73
|
+
|
|
74
|
+
- `partnership-blocked` — from Stage 2 (`service-de-waba-integrate`).
|
|
75
|
+
- `user-declined` — user cancelled the WABA-linking prompt.
|
|
76
|
+
- `waba-manage-failed` — from Stage 3 (SF-side `manageWhatsAppBusinessAccount`).
|
|
77
|
+
- `meta-precondition` — Connect rejected the insert (WABA not shared, phone not OTP'd on Meta side,
|
|
78
|
+
etc.); hint `"Connect API rejected the request — WABA not shared, phone not OTP'd on Meta side"`.
|
|
79
|
+
|
|
80
|
+
## Gotchas
|
|
81
|
+
|
|
82
|
+
1. **WABA_ID ≠ PHONE_NUMBER_ID.** A WABA can contain multiple phone numbers. Same value for both →
|
|
83
|
+
cryptic activation failures ("WhatsApp number registration failed"). Stage 0.1 asserts they differ.
|
|
84
|
+
2. **PATCH activation is synchronous with Meta `/register`** — WhatsApp channels take 15-30s to
|
|
85
|
+
activate (vs ~1s for Apple/LINE, which have no external callout). Not this skill's concern, but
|
|
86
|
+
explains the downstream latency difference in `service-de-channel-activate`.
|
|
87
|
+
3. **`developerName` follows the server-side format** (e.g. `WHATSAPP_US_<phoneNumberId>`), NOT the
|
|
88
|
+
Connect response's pre-DB projection. Trust the DB (Stage 5 verify), not the 201 body.
|
|
89
|
+
4. **Fresh-insert MCU `DeploymentStatus` varies** — observed as both `Disabled` and `New` on WhatsApp
|
|
90
|
+
across orgs (`New` for Facebook). Don't assert a specific starting status in Stage 5 — just that the
|
|
91
|
+
MCU exists; any pre-activation value is a valid `→ Provisioning` source.
|
|
92
|
+
5. **Field/relationship-name variance across orgs.** Use the two-query FK form (never the
|
|
93
|
+
`MessagingChannelUsages` child subquery), and the trimmed universal field set — `ExternalAccountId`
|
|
94
|
+
and `MessagingPlatform` are absent on some orgs (`INVALID_FIELD` on `wadtesting`).
|
|
95
|
+
6. **WABA-management call takes `wabaId`/`phoneId` in the URL query, not the body.** The documented
|
|
96
|
+
body shape `{"externalAccountId":"<WABA_ID>"}` returns `400 INVALID_API_INPUT "wabaId is required"`
|
|
97
|
+
(as does `{"wabaId":...}` in the body). Pass `?...&wabaId=<WABA_ID>&phoneId=<PHONE_NUMBER_ID>` with an
|
|
98
|
+
empty body — see Stage 3.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: service-de-channel-create-worked-examples
|
|
3
|
+
description: "Load for end-to-end traces of a channel insert per type — a fresh Connect-path insert (Apple, verified on wadtesting), a preflight short-circuit re-run, and the Facebook interactive OAuth → page-selection path. Illustrative only; the authoritative flow is the parent SKILL.md stages."
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0"
|
|
6
|
+
related-skills: service-de-channel-create
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Worked examples (per type)
|
|
10
|
+
|
|
11
|
+
## Apple Business Chat — fresh insert (real trace, wadtesting 2026-04-30)
|
|
12
|
+
|
|
13
|
+
`messagingcore-wadtesting2.test1.my.pc-rnd.salesforce.com`. Inputs:
|
|
14
|
+
`APPLE_BC_ID=c02e9350-f526-42dc-9e8d-cec2edf59487`, `CHANNEL_NAME=Apple Channel`.
|
|
15
|
+
|
|
16
|
+
- **Stage 1** — preflight SOQL (two-query FK form) returns 0 rows. Proceed.
|
|
17
|
+
- **Stage 4.1** — `SELECT Id FROM AuthProvider WHERE DeveloperName='LiveMessageSetup'` → one row,
|
|
18
|
+
captured as `{AUTH_PROVIDER_ID}` (org-specific).
|
|
19
|
+
- **Stage 4.2** — body `{"messageType":"AppleBusinessChat","platformType":"Enhanced","messagingPlatformKey":"c02e9350-...","messagingChannelName":"Apple Channel"}`;
|
|
20
|
+
POST to `.../connect/livemessage/channels?authProviderId=${AUTH_PROVIDER_ID}`. Response 201:
|
|
21
|
+
```json
|
|
22
|
+
{"id":"0MjSG000000MNUD0A4","developerName":"AppleBusinessChat_c02e9350_...",
|
|
23
|
+
"isActive":false,"masterLabel":"c02e9350-...","messageType":"AppleBusinessChat",
|
|
24
|
+
"messagingPlatformKey":"c02e9350-..."}
|
|
25
|
+
```
|
|
26
|
+
The `masterLabel`/`developerName` in the body are **stale input-rep projections** — the DB row uses
|
|
27
|
+
`MasterLabel="Apple Channel"` and the canonical `APPLEBUSINESSCHAT_US_c02e9350_...`.
|
|
28
|
+
- **Stage 5** — verify SOQL confirms `MasterLabel="Apple Channel"`,
|
|
29
|
+
`DeveloperName="APPLEBUSINESSCHAT_US_c02e9350_..."`, `IsActive=false`; MCU `0gLSG0000003Kjl2AE`,
|
|
30
|
+
`DeploymentType=Conversation`, `DeploymentStatus=New`.
|
|
31
|
+
- **Stage 6** — success envelope, `path:"connect"`, `created:true`.
|
|
32
|
+
|
|
33
|
+
Downstream chain ran immediately after: routing PATCH → 204; activation PATCH
|
|
34
|
+
(`DeploymentStatus="Provisioning"`) → 204 in ~1s (Apple hits the observer's `default` branch — no
|
|
35
|
+
external callout).
|
|
36
|
+
|
|
37
|
+
**Gotcha surfaced:** the first POST omitted `?authProviderId=` (based on an older skill version
|
|
38
|
+
claiming "Apple doesn't use authProviderId") → `400 ILLEGAL_QUERY_PARAMETER_VALUE`. Corrected:
|
|
39
|
+
`authProviderId` is universally required.
|
|
40
|
+
|
|
41
|
+
## LINE — fresh insert (illustrative)
|
|
42
|
+
|
|
43
|
+
Inputs: `LINE_CHANNEL_ID=2001234567`, secret + long-lived token, `CHANNEL_NAME=Support LINE Channel`.
|
|
44
|
+
|
|
45
|
+
- **Stage 1** preflight → 0 rows.
|
|
46
|
+
- **Stage 2-3** (optional token verify) → `GET https://api.line.me/v2/bot/info` returns 200. Valid.
|
|
47
|
+
- **Stage 4.2** body includes `authDetails:{client_secret, access_token}`. Response 201 →
|
|
48
|
+
`{id:"0MjSG000000Fd2m0AD", developerName:"LINE_2001234567", ...}`.
|
|
49
|
+
- **Stage 5** verify → channel + one MCU `DeploymentType=Conversation`. Success `path:"connect"`.
|
|
50
|
+
|
|
51
|
+
## Preflight short-circuit (any type)
|
|
52
|
+
|
|
53
|
+
Re-running an insert for a channel that already exists:
|
|
54
|
+
- **Stage 1** preflight SOQL finds `records.length === 1`. Records `{CHANNEL_ID}`, `{DEVELOPER_NAME}`,
|
|
55
|
+
`{IS_ACTIVE}`; second query picks up `{MCU_ID}`.
|
|
56
|
+
- Emits success envelope with `path:"preflight", created:false`. Stages 2-5 never run. This is the
|
|
57
|
+
idempotency guard (`MessagingChannel` rows aren't deletable via standard means).
|
|
58
|
+
|
|
59
|
+
## Facebook — interactive OAuth → page selection (illustrative)
|
|
60
|
+
|
|
61
|
+
`PAGE_ID` not supplied.
|
|
62
|
+
- **Stage 1** skipped (no page id yet).
|
|
63
|
+
- **Stage 2-3** — look up `{AUTH_PROVIDER_ID}`; the stored FB token is stale, so open the OAuth URL
|
|
64
|
+
in a browser, wait for the user to authorize, then fetch the page list. Render all pages sorted by
|
|
65
|
+
`masterLabel`, annotated with connected status, untruncated. User selects one → `{PAGE_ID}`. Prompt
|
|
66
|
+
for `{CHANNEL_NAME}`. Now run the Stage 1 preflight for the chosen page id.
|
|
67
|
+
- **Stage 4.2** body `{..., messagingPlatformKey:"{PAGE_ID}", authDetails:{}}`. If the response
|
|
68
|
+
errorCode is `AUTH_PROVIDER_NEEDS_AUTH` (may arrive as 400 OR 401), emit `oauth-not-complete` and
|
|
69
|
+
re-run OAuth — do NOT tell the user to run `sf org login web` (the SF session is fine).
|
|
70
|
+
- **Stage 5** verify → MCU `DeploymentStatus=New` (Facebook lands as `New`, not `Disabled`). Success.
|