@salesforce/afv-skills 1.65.0 → 1.65.1
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/field-service-data-capture-form-deployer-configure/SKILL.md +2 -23
- package/skills/field-service-data-capture-form-designer-configure/SKILL.md +3 -13
- package/skills/field-service-mobile-branding-configure/SKILL.md +3 -17
- package/skills/field-service-objective-designer-configure/SKILL.md +379 -72
- package/skills/field-service-prework-brief-deployer-configure/SKILL.md +537 -10
- package/skills/field-service-scheduling-policy-designer-query/SKILL.md +1093 -65
- package/skills/field-service-sobject-create-configure/SKILL.md +213 -13
- package/skills/field-service-voice-to-form-configure/SKILL.md +11 -40
- package/skills/field-service-work-rule-designer-configure/SKILL.md +95 -121
- package/skills/agentforce-gpt-email-generation-configure/SKILL.md +0 -312
- package/skills/agentforce-wizard-ui-forecasting-analytics-components-configure/SKILL.md +0 -64
- package/skills/agentforce-wizard-ui-sales-einstein-components-configure/SKILL.md +0 -46
- package/skills/automation-company-profile-info-query/SKILL.md +0 -51
- package/skills/automation-digital-wallet-configure/SKILL.md +0 -689
- package/skills/automation-flow-coordinate/SKILL.md +0 -95
- package/skills/automation-flow-coordinate/references/elements/action-call/action-call.md +0 -1569
- package/skills/automation-flow-coordinate/references/elements/action-call/conversation-messaging.md +0 -96
- package/skills/automation-flow-coordinate/references/elements/action-call/examples/send-sms-message.json +0 -23
- package/skills/automation-flow-coordinate/references/elements/action-call/examples/send-to-journey-no-fields.json +0 -31
- package/skills/automation-flow-coordinate/references/elements/action-call/send-to-journey.md +0 -179
- package/skills/automation-flow-coordinate/references/elements/exit-rule/examples/event-email-link-click.json +0 -13
- package/skills/automation-flow-coordinate/references/elements/exit-rule/exit-rule.md +0 -83
- package/skills/automation-flow-coordinate/references/elements/forward-to-bot-or-agent/examples/forward-to-bot-or-agent.json +0 -69
- package/skills/automation-flow-coordinate/references/elements/forward-to-bot-or-agent/forward-to-bot-or-agent.md +0 -274
- package/skills/automation-flow-coordinate/references/elements/start/audience-common.md +0 -192
- package/skills/automation-flow-coordinate/references/elements/start/automation-event-triggered.md +0 -130
- package/skills/automation-flow-coordinate/references/elements/start/data-cloud-data-change-triggered.md +0 -92
- package/skills/automation-flow-coordinate/references/elements/start/form-submission-triggered.md +0 -88
- package/skills/automation-flow-coordinate/references/elements/start/segment-triggered.md +0 -152
- package/skills/automation-flow-coordinate/references/elements/start/start.md +0 -539
- package/skills/automation-flow-coordinate/references/elements/subflow/subflow.md +0 -152
- package/skills/automation-flow-coordinate/references/elements/wait/wait.md +0 -497
- package/skills/automation-flow-coordinate/references/recipes/author/author.md +0 -868
- package/skills/automation-flow-coordinate/references/recipes/summarize/element-generic.md +0 -300
- package/skills/automation-flow-coordinate/references/recipes/summarize/reference-resolution.md +0 -292
- package/skills/automation-flow-coordinate/references/recipes/summarize/summarize.md +0 -323
- package/skills/automation-flow-coordinate/references/recipes/testing/examples/debug-output-template.md +0 -109
- package/skills/automation-flow-coordinate/references/recipes/testing/shape.md +0 -219
- package/skills/automation-flow-coordinate/references/recipes/testing/shared-stages/intent-analyzer.md +0 -180
- package/skills/automation-flow-coordinate/references/recipes/testing/workflows/debug.md +0 -175
- package/skills/automation-flow-coordinate/references/recipes/testing/workflows/promote.md +0 -255
- package/skills/automation-flow-coordinate/references/recipes/testing/workflows/save-debug.md +0 -212
- package/skills/automation-flow-coordinate/references/resources/variable/variable.md +0 -171
- package/skills/automation-flow-coordinate/references/shared/anti-patterns.md +0 -786
- package/skills/automation-flow-coordinate/references/shared/end/end.md +0 -267
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/eval/README.md +0 -69
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/eval/predictions.jsonl +0 -80
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/eval/prompts.jsonl +0 -116
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/flow-type-resolver.md +0 -321
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/taxonomy.json +0 -320
- package/skills/automation-flow-coordinate/references/shared/server-functions.md +0 -597
- package/skills/automotive-cloud-appraisal-management-settings-configure/SKILL.md +0 -69
- package/skills/automotive-cloud-dealer-essentials-configure/SKILL.md +0 -78
- package/skills/automotive-cloud-ground-agent-data-pipelines-configure/SKILL.md +0 -373
- package/skills/automotive-cloud-ground-mfg-agent-data-pipelines-configure/SKILL.md +0 -273
- package/skills/automotive-cloud-mfg-agent-data-pipelines-configure/SKILL.md +0 -259
- package/skills/automotive-cloud-mfg-sales-concierge-agent-create/SKILL.md +0 -369
- package/skills/automotive-cloud-mfg-sales-concierge-foundation-configure/SKILL.md +0 -542
- package/skills/automotive-cloud-mfg-sales-concierge-foundation-coordinate/SKILL.md +0 -159
- package/skills/automotive-cloud-mfg-sales-concierge-orchestrator-agent-create/SKILL.md +0 -349
- package/skills/automotive-cloud-mfg-sales-concierge-orchestrator-configure/SKILL.md +0 -505
- package/skills/automotive-cloud-sales-concierge-agent-create/SKILL.md +0 -380
- package/skills/automotive-cloud-sales-concierge-foundation-configure/SKILL.md +0 -567
- package/skills/automotive-cloud-sales-concierge-foundation-coordinate/SKILL.md +0 -159
- package/skills/automotive-cloud-sales-concierge-orchestrator-agent-create/SKILL.md +0 -360
- package/skills/automotive-cloud-sales-concierge-orchestrator-configure/SKILL.md +0 -539
- package/skills/automotive-cloud-sales-concierge-search-grounding-configure/SKILL.md +0 -358
- package/skills/commerce-b2b-merchant-quote-configure/SKILL.md +0 -602
- package/skills/commerce-b2b-store-configure/SKILL.md +0 -251
- package/skills/commerce-credit-memo-create/SKILL.md +0 -139
- package/skills/commerce-delivery-business-hours-configure/SKILL.md +0 -277
- package/skills/commerce-delivery-estimation-apply/SKILL.md +0 -155
- package/skills/commerce-delivery-estimation-configure/SKILL.md +0 -377
- package/skills/commerce-delivery-routing-specs-integrate/SKILL.md +0 -174
- package/skills/commerce-estimate-bopis-query/SKILL.md +0 -279
- package/skills/commerce-estimate-delivery-date-query/SKILL.md +0 -349
- package/skills/commerce-fees-apply/SKILL.md +0 -227
- package/skills/commerce-fulfillment-routing-analyze/SKILL.md +0 -200
- package/skills/commerce-guest-buyer-create/SKILL.md +0 -173
- package/skills/commerce-location-bopis-configure/SKILL.md +0 -378
- package/skills/commerce-location-business-hours-configure/SKILL.md +0 -235
- package/skills/commerce-location-delivery-processing-time-configure/SKILL.md +0 -309
- package/skills/commerce-location-graph-integrate/SKILL.md +0 -131
- package/skills/commerce-location-shipping-carrier-method-configure/SKILL.md +0 -755
- package/skills/commerce-location-temporary-operating-hours-configure/SKILL.md +0 -331
- package/skills/commerce-merchant-buyer-groups-configure/SKILL.md +0 -579
- package/skills/commerce-merchant-buyer-user-onboarding-create/SKILL.md +0 -626
- package/skills/commerce-merchant-catalog-configure/SKILL.md +0 -614
- package/skills/commerce-merchant-extension-provider-configure/SKILL.md +0 -368
- package/skills/commerce-merchant-insights-account-health-churn-analyze/SKILL.md +0 -118
- package/skills/commerce-merchant-insights-inventory-returns-analyze/SKILL.md +0 -65
- package/skills/commerce-merchant-insights-order-shopper-get/SKILL.md +0 -90
- package/skills/commerce-merchant-insights-product-performance-analyze/SKILL.md +0 -72
- package/skills/commerce-merchant-insights-query/SKILL.md +0 -279
- package/skills/commerce-merchant-storefront-guest-access-configure/SKILL.md +0 -656
- package/skills/commerce-order-summary-change-apply/SKILL.md +0 -375
- package/skills/commerce-product-details-get/SKILL.md +0 -363
- package/skills/commerce-product-search/SKILL.md +0 -563
- package/skills/commerce-react-storefront-create/SKILL.md +0 -350
- package/skills/commerce-return-order-summary-create/SKILL.md +0 -513
- package/skills/commerce-search-relevance-analyze/SKILL.md +0 -757
- package/skills/commerce-temporary-processing-time-override-create/SKILL.md +0 -274
- package/skills/communications-initial-setup-configure/SKILL.md +0 -630
- package/skills/communications-multisite-configure/SKILL.md +0 -571
- package/skills/communications-revenue-cloud-settings-configure/SKILL.md +0 -74
- package/skills/communications-smb-fiber-catalog-create/SKILL.md +0 -413
- package/skills/communications-tmf-integrate/SKILL.md +0 -1368
- package/skills/consumer-goods-visit-activity-act4-questions-assign/SKILL.md +0 -448
- package/skills/consumer-goods-visit-activity-act5-standard-create/SKILL.md +0 -269
- package/skills/consumer-goods-visit-activity-act6-assortment-configure/SKILL.md +0 -271
- package/skills/consumer-goods-visit-activity-act7-account-scoping-create/SKILL.md +0 -382
- package/skills/consumer-goods-visit-activity-act8-plan-attach-create/SKILL.md +0 -373
- package/skills/consumer-goods-visit-activity-act9-proof-validate/SKILL.md +0 -389
- package/skills/consumer-goods-visit-and-activity-act1-specification-create/SKILL.md +0 -338
- package/skills/consumer-goods-visit-and-activity-act2-template-create/SKILL.md +0 -547
- package/skills/consumer-goods-visit-and-activity-act3-definition-create/SKILL.md +0 -346
- package/skills/consumer-goods-visit-and-activity-configure/SKILL.md +0 -1110
- package/skills/crm-analytics-adoption-insights-configure/SKILL.md +0 -224
- package/skills/crm-analytics-custom-report-type-lightning-configure/SKILL.md +0 -418
- package/skills/crm-analytics-dashboards-configure/SKILL.md +0 -731
- package/skills/crm-analytics-operational-analytics-metadata-bridge-migrate/SKILL.md +0 -233
- package/skills/crm-analytics-report-notifications-ui-configure/SKILL.md +0 -184
- package/skills/crm-analytics-sharing-inheritance-coverage-analyze/SKILL.md +0 -167
- package/skills/crm-analytics-sonic-getting-started-configure/SKILL.md +0 -55
- package/skills/crm-analytics-tableau-next-app-deploy/SKILL.md +0 -1350
- package/skills/crm-analytics-tableau-next-c360-basemodel-validate/SKILL.md +0 -1862
- package/skills/crm-analytics-tableau-next-datacloud-validate/SKILL.md +0 -83
- package/skills/crm-analytics-tableau-next-provisioning-validate/SKILL.md +0 -81
- package/skills/data360-activation-create/SKILL.md +0 -104
- package/skills/data360-activation-external-platform-get/SKILL.md +0 -49
- package/skills/data360-activation-target-create/SKILL.md +0 -93
- package/skills/data360-activation-v2-create/SKILL.md +0 -456
- package/skills/data360-audience-dmo-get/SKILL.md +0 -38
- package/skills/data360-calculated-affinity-create/SKILL.md +0 -82
- package/skills/data360-calculated-insight-create/SKILL.md +0 -148
- package/skills/data360-catalog-metadata-create/SKILL.md +0 -183
- package/skills/data360-code-extension-create/SKILL.md +0 -115
- package/skills/data360-communication-capping-create/SKILL.md +0 -227
- package/skills/data360-connection-create/SKILL.md +0 -491
- package/skills/data360-content-lens-create/SKILL.md +0 -181
- package/skills/data360-data-action-create/SKILL.md +0 -126
- package/skills/data360-data-action-target-create/SKILL.md +0 -181
- package/skills/data360-data-clean-room-create/SKILL.md +0 -238
- package/skills/data360-data-governance-create/SKILL.md +0 -746
- package/skills/data360-data-graph-create/SKILL.md +0 -82
- package/skills/data360-data-harmonized-model-object-reference-create/SKILL.md +0 -38
- package/skills/data360-data-lake-object-create/SKILL.md +0 -207
- package/skills/data360-data-model-object-catalog-get/SKILL.md +0 -49
- package/skills/data360-data-model-object-create/SKILL.md +0 -128
- package/skills/data360-data-model-object-mapping-create/SKILL.md +0 -106
- package/skills/data360-data-space-create/SKILL.md +0 -161
- package/skills/data360-data-streams-create/SKILL.md +0 -324
- package/skills/data360-engagement-signal-get/SKILL.md +0 -38
- package/skills/data360-experiment-create/SKILL.md +0 -82
- package/skills/data360-goal-based-campaign-create/SKILL.md +0 -192
- package/skills/data360-harmonization-process-history-get/SKILL.md +0 -38
- package/skills/data360-harmonized-unstructured-dmo-create/SKILL.md +0 -84
- package/skills/data360-identity-resolution-create/SKILL.md +0 -115
- package/skills/data360-intelligent-document-processing-create/SKILL.md +0 -148
- package/skills/data360-knowledge-graph-construction-create/SKILL.md +0 -93
- package/skills/data360-knowledge-graph-create/SKILL.md +0 -216
- package/skills/data360-knowledge-space-mcp-configure/SKILL.md +0 -475
- package/skills/data360-machine-learning-mcp-configure/SKILL.md +0 -697
- package/skills/data360-multi-org-mcp-configure/SKILL.md +0 -117
- package/skills/data360-secondary-index-mcp-configure/SKILL.md +0 -126
- package/skills/data360-segment-mcp-configure/SKILL.md +0 -159
- package/skills/data360-semantic-calculated-dimension-mcp-configure/SKILL.md +0 -93
- package/skills/data360-semantic-calculated-measurement-mcp-configure/SKILL.md +0 -93
- package/skills/data360-semantic-data-object-mcp-configure/SKILL.md +0 -93
- package/skills/data360-semantic-dimension-mcp-configure/SKILL.md +0 -38
- package/skills/data360-semantic-engine-mcp-configure/SKILL.md +0 -62
- package/skills/data360-semantic-measurement-mcp-configure/SKILL.md +0 -38
- package/skills/data360-semantic-metric-mcp-configure/SKILL.md +0 -93
- package/skills/data360-semantic-model-mcp-configure/SKILL.md +0 -115
- package/skills/data360-standard-mapping-mcp-configure/SKILL.md +0 -38
- package/skills/data360-tenant-lifecycle-mcp-configure/SKILL.md +0 -73
- package/skills/experience-afv-query/SKILL.md +0 -234
- package/skills/experience-agentforce-vibes-in-react-configure/SKILL.md +0 -63
- package/skills/experience-apex-components-configure/SKILL.md +0 -69
- package/skills/experience-apex-pages-configure/SKILL.md +0 -107
- package/skills/experience-app-home-configure/SKILL.md +0 -76
- package/skills/experience-aura-lightning-out-access-configure/SKILL.md +0 -58
- package/skills/experience-briefcase-configure/SKILL.md +0 -287
- package/skills/experience-community-flexi-page-list-create/SKILL.md +0 -74
- package/skills/experience-community-template-definition-list-query/SKILL.md +0 -48
- package/skills/experience-community-theme-definition-list-query/SKILL.md +0 -38
- package/skills/experience-content-assets-configure/SKILL.md +0 -86
- package/skills/experience-custom-domain-create/SKILL.md +0 -727
- package/skills/experience-defer-rendering-workspace-page-setup-configure/SKILL.md +0 -41
- package/skills/experience-field-service-app-builder-configure/SKILL.md +0 -187
- package/skills/experience-flow-category-configure/SKILL.md +0 -117
- package/skills/experience-formula-configure/SKILL.md +0 -358
- package/skills/experience-global-actions-configure/SKILL.md +0 -69
- package/skills/experience-global-publisher-layouts-configure/SKILL.md +0 -79
- package/skills/experience-instrumentation-configure/SKILL.md +0 -64
- package/skills/experience-lex-engagement-configure/SKILL.md +0 -50
- package/skills/experience-lightning-bolt-open/SKILL.md +0 -12
- package/skills/experience-lightning-out-configure/SKILL.md +0 -129
- package/skills/experience-lightning-preview-configure/SKILL.md +0 -67
- package/skills/experience-lightning-types-query/SKILL.md +0 -98
- package/skills/experience-malware-scan-configure/SKILL.md +0 -71
- package/skills/experience-my-salesforce-configure/SKILL.md +0 -126
- package/skills/experience-navigation-menus-configure/SKILL.md +0 -235
- package/skills/experience-notification-types-configure/SKILL.md +0 -206
- package/skills/experience-notifications-configure/SKILL.md +0 -75
- package/skills/experience-record-discovery-query/SKILL.md +0 -227
- package/skills/experience-regenerate-previews-open/SKILL.md +0 -94
- package/skills/experience-sales-cloud-mab-configure/SKILL.md +0 -254
- package/skills/experience-schema-builder-open/SKILL.md +0 -38
- package/skills/experience-simple-record-home-configure/SKILL.md +0 -110
- package/skills/experience-static-resources-configure/SKILL.md +0 -74
- package/skills/field-service-setup-coordinate/SKILL.md +0 -62
- package/skills/field-service-work-plan-configure/SKILL.md +0 -253
- package/skills/fsc-actionable-segmentation-settings-configure/SKILL.md +0 -180
- package/skills/fsc-digital-origination-bre-decision-matrix-foundation-create/SKILL.md +0 -196
- package/skills/fsc-digital-origination-bre-disclosures-consent-configure/SKILL.md +0 -106
- package/skills/fsc-digital-origination-bre-document-upload-configure/SKILL.md +0 -96
- package/skills/fsc-digital-origination-bre-permissions-assign/SKILL.md +0 -111
- package/skills/fsc-digital-origination-bre-setup-coordinate/SKILL.md +0 -250
- package/skills/fsc-digital-origination-bre-stp-eligibility-configure/SKILL.md +0 -122
- package/skills/fsc-digital-origination-coordinate/SKILL.md +0 -653
- package/skills/fsc-digital-origination-demo-run/SKILL.md +0 -225
- package/skills/fsc-digital-origination-execution-guardrails-validate/SKILL.md +0 -112
- package/skills/fsc-digital-origination-initial-setup-configure/SKILL.md +0 -396
- package/skills/fsc-digital-origination-pricing-setup-coordinate/SKILL.md +0 -336
- package/skills/fsc-digital-origination-pricing-setup-data-foundation-create/SKILL.md +0 -208
- package/skills/fsc-digital-origination-pricing-setup-procedure-create/SKILL.md +0 -375
- package/skills/fsc-digital-origination-product-setup-act1-permissions-assign/SKILL.md +0 -83
- package/skills/fsc-digital-origination-product-setup-coordinate/SKILL.md +0 -248
- package/skills/fsc-digital-origination-sample-data-create/SKILL.md +0 -206
- package/skills/fsc-document-checklist-settings-configure/SKILL.md +0 -57
- package/skills/fsc-flexible-hierarchy-configure/SKILL.md +0 -148
- package/skills/fsc-flexible-hierarchy-foundation-configure/SKILL.md +0 -1430
- package/skills/fsc-flexible-hierarchy-graph-config-create/SKILL.md +0 -471
- package/skills/fsc-flexible-hierarchy-rule-based-graph-deploy/SKILL.md +0 -429
- package/skills/fsc-pricing-product-configurator-configure/SKILL.md +0 -150
- package/skills/fsc-pricing-salesforce-omnistudio-switch/SKILL.md +0 -123
- package/skills/fsc-product-act2-catalog-categories-create/SKILL.md +0 -82
- package/skills/fsc-product-act3-attributes-create/SKILL.md +0 -249
- package/skills/fsc-product-act4-classification-assignment-create/SKILL.md +0 -196
- package/skills/fsc-product-act5-considerations-get/SKILL.md +0 -44
- package/skills/fsc-stage-management-apex-flow-deploy/SKILL.md +0 -384
- package/skills/fsc-stage-management-compliant-data-sharing-configure/SKILL.md +0 -144
- package/skills/fsc-stage-management-decision-matrices-create/SKILL.md +0 -107
- package/skills/fsc-stage-management-definition-assignments-create/SKILL.md +0 -189
- package/skills/fsc-stage-management-definition-create/SKILL.md +0 -108
- package/skills/fsc-stage-management-permissions-assign/SKILL.md +0 -143
- package/skills/fsc-stage-management-transitions-configure/SKILL.md +0 -139
- package/skills/health-cloud-appt-booking-config-configure/SKILL.md +0 -135
- package/skills/health-cloud-appt-booking-url-config-configure/SKILL.md +0 -134
- package/skills/health-cloud-care-provider-affl-role-config-configure/SKILL.md +0 -136
- package/skills/health-cloud-care-provider-search-config-configure/SKILL.md +0 -134
- package/skills/health-cloud-care-requests-create/SKILL.md +0 -178
- package/skills/health-cloud-initial-configure/SKILL.md +0 -511
- package/skills/health-cloud-patient-appointment-scheduling-configure/SKILL.md +0 -1374
- package/skills/health-cloud-provider-search-settings-configure/SKILL.md +0 -924
- package/skills/health-cloud-referral-management-coordinate/SKILL.md +0 -513
- package/skills/health-cloud-timeline-configure/SKILL.md +0 -622
- package/skills/health-cloud-virtual-visit-config-configure/SKILL.md +0 -135
- package/skills/industries-account-score-settings-query/SKILL.md +0 -78
- package/skills/industries-actionable-list-data-sources-dmo-configure/SKILL.md +0 -177
- package/skills/industries-ad-product-availability-search/SKILL.md +0 -399
- package/skills/industries-advanced-account-forecast-settings-configure/SKILL.md +0 -628
- package/skills/industries-advanced-therapy-management-settings-configure/SKILL.md +0 -73
- package/skills/industries-atm-settings-starter-configure/SKILL.md +0 -76
- package/skills/industries-batch-document-ai-configure/SKILL.md +0 -196
- package/skills/industries-behavioral-health-app-settings-configure/SKILL.md +0 -71
- package/skills/industries-branch-management-settings-configure/SKILL.md +0 -89
- package/skills/industries-bre-decision-table-access-configure/SKILL.md +0 -367
- package/skills/industries-brokerage-settings-configure/SKILL.md +0 -41
- package/skills/industries-calendar-sync-settings-configure/SKILL.md +0 -89
- package/skills/industries-care-request-settings-configure/SKILL.md +0 -218
- package/skills/industries-case-management-intelligence-settings-configure/SKILL.md +0 -54
- package/skills/industries-catalog-process-attributes-products-configure/SKILL.md +0 -380
- package/skills/industries-catalog-process-fulfillment-configure/SKILL.md +0 -216
- package/skills/industries-catalog-process-intake-configure/SKILL.md +0 -219
- package/skills/industries-catalog-process-knowledge-configure/SKILL.md +0 -153
- package/skills/industries-catalog-process-preprocessor-configure/SKILL.md +0 -168
- package/skills/industries-cds-general-settings-configure/SKILL.md +0 -69
- package/skills/industries-claim-financial-settings-configure/SKILL.md +0 -169
- package/skills/industries-clinical-data-model-settings-configure/SKILL.md +0 -136
- package/skills/industries-clinical-data-model-settings-starter-configure/SKILL.md +0 -105
- package/skills/industries-collection-plan-settings-configure/SKILL.md +0 -132
- package/skills/industries-comms-service-console-settings-configure/SKILL.md +0 -159
- package/skills/industries-compliance-configure/SKILL.md +0 -102
- package/skills/industries-compliance-document-extraction-setup-configure/SKILL.md +0 -76
- package/skills/industries-contact-center-app-layout-configure/SKILL.md +0 -88
- package/skills/industries-contact-center-components-configure/SKILL.md +0 -96
- package/skills/industries-contact-center-path-knowledge-configure/SKILL.md +0 -95
- package/skills/industries-contact-center-user-access-assign/SKILL.md +0 -96
- package/skills/industries-course-waitlist-config-configure/SKILL.md +0 -162
- package/skills/industries-crisis-center-settings-configure/SKILL.md +0 -84
- package/skills/industries-custom-object-settings-configure/SKILL.md +0 -94
- package/skills/industries-data-cloud-integration-configure/SKILL.md +0 -88
- package/skills/industries-data-space-feature-mappings-configure/SKILL.md +0 -245
- package/skills/industries-decision-matrix-builder-configure/SKILL.md +0 -78
- package/skills/industries-decision-table-hbase-configure/SKILL.md +0 -87
- package/skills/industries-decision-table-version-configure/SKILL.md +0 -74
- package/skills/industries-decision-tables-builder-configure/SKILL.md +0 -253
- package/skills/industries-decision-tables-configure/SKILL.md +0 -439
- package/skills/industries-energy-utilities-configure/SKILL.md +0 -251
- package/skills/industries-eu-cloud-multisite-configure/SKILL.md +0 -1008
- package/skills/industries-eu-new-connections-configure/SKILL.md +0 -30
- package/skills/industries-explainability-msg-template-configure/SKILL.md +0 -135
- package/skills/industries-expression-set-message-token-configure/SKILL.md +0 -135
- package/skills/industries-field-service-settings-configure/SKILL.md +0 -82
- package/skills/industries-form-framework-settings-configure/SKILL.md +0 -30
- package/skills/industries-fsc-ai-settings-configure/SKILL.md +0 -57
- package/skills/industries-fsc-association-engine-settings-configure/SKILL.md +0 -172
- package/skills/industries-fsc-b2b-settings-configure/SKILL.md +0 -61
- package/skills/industries-fsc-insurance-settings-configure/SKILL.md +0 -58
- package/skills/industries-fsc-visa-fulfillment-setup-configure/SKILL.md +0 -103
- package/skills/industries-fsc-wealth-agent-settings-configure/SKILL.md +0 -117
- package/skills/industries-fsc-wealth-settings-configure/SKILL.md +0 -99
- package/skills/industries-fundraising-gift-entry-settings-configure/SKILL.md +0 -120
- package/skills/industries-fundraising-rfm-configure/SKILL.md +0 -128
- package/skills/industries-fundraising-settings-configure/SKILL.md +0 -145
- package/skills/industries-fundraising-source-code-gen-configure/SKILL.md +0 -299
- package/skills/industries-google-maps-api-key-settings-configure/SKILL.md +0 -87
- package/skills/industries-grantmaking-intelligence-settings-open/SKILL.md +0 -58
- package/skills/industries-hc-score-category-settings-configure/SKILL.md +0 -167
- package/skills/industries-health-engagement-settings-configure/SKILL.md +0 -218
- package/skills/industries-home-health-agentforce-setup-configure/SKILL.md +0 -131
- package/skills/industries-home-health-bundling-policy-create/SKILL.md +0 -50
- package/skills/industries-home-health-entity-labels-configure/SKILL.md +0 -29
- package/skills/industries-home-health-fsl-package-deploy/SKILL.md +0 -71
- package/skills/industries-home-health-fsl-settings-validate/SKILL.md +0 -27
- package/skills/industries-home-health-guided-setup-care-and-skill-get/SKILL.md +0 -80
- package/skills/industries-home-health-guided-setup-configure/SKILL.md +0 -836
- package/skills/industries-home-health-guided-setup-enable-org-fsl-get/SKILL.md +0 -55
- package/skills/industries-home-health-guided-setup-get-org-ready-get/SKILL.md +0 -61
- package/skills/industries-home-health-licenses-assign/SKILL.md +0 -27
- package/skills/industries-home-health-operating-hours-create/SKILL.md +0 -40
- package/skills/industries-home-health-scheduling-policy-create/SKILL.md +0 -41
- package/skills/industries-home-health-service-objective-create/SKILL.md +0 -22
- package/skills/industries-home-health-skills-create/SKILL.md +0 -31
- package/skills/industries-home-health-users-create/SKILL.md +0 -29
- package/skills/industries-icm-act3-toggles-configure/SKILL.md +0 -198
- package/skills/industries-icm-act5-genai-suggested-assessments-configure/SKILL.md +0 -361
- package/skills/industries-icm-act6-mcg-integration-configure/SKILL.md +0 -550
- package/skills/industries-integrated-care-management-configure/SKILL.md +0 -168
- package/skills/industries-object-enablement-configure/SKILL.md +0 -86
- package/skills/industries-tpm-system-processing-service-configure/SKILL.md +0 -64
- package/skills/integration-apex-settings-configure/SKILL.md +0 -61
- package/skills/marketing-e360-email-archiving-configure/SKILL.md +0 -73
- package/skills/platform-custom-permissions-configure/SKILL.md +0 -687
- package/skills/platform-label-workbench-import-create/SKILL.md +0 -67
- package/skills/platform-privacy-agent-settings-configure/SKILL.md +0 -752
|
@@ -1,1569 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: flow-element-action-call
|
|
3
|
-
license: LICENSE.txt has complete terms
|
|
4
|
-
description: "Use this skill when creating, editing, or troubleshooting Flow Action elements — invocable actions including Apex methods, External Services, Quick Actions, REST callouts, Email Alerts, LWC local actions (toasts, navigation), and other invocable actions. TRIGGER when: user asks to call an Apex action, invoke an external service, add an action call, configure an Email Alert, show a toast/notification message, navigate or open a page/URL/record, or use any invocable action in a flow. DO NOT TRIGGER when the user only needs a subflow call (use flow-element-subflow)."
|
|
5
|
-
metadata:
|
|
6
|
-
version: "1.0"
|
|
7
|
-
related-skills: flow-output-assignments, flow-fault-paths
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Action Element (Invocable Actions)
|
|
11
|
-
|
|
12
|
-
## Reference File Index
|
|
13
|
-
|
|
14
|
-
| File | Purpose |
|
|
15
|
-
|---|---|
|
|
16
|
-
| `examples/inline-transform-input.json` | `actionCalls[]` entry with an inline-Transform Apex input and a `setupReference` connection input |
|
|
17
|
-
| `examples/push-notification.json` | E360 "Send Mobile App Message" (push) — verified worked example |
|
|
18
|
-
| `examples/in-app-message.json` | E360 "Send Mobile App In-App Message" — verified worked example |
|
|
19
|
-
| `examples/send-conversation-messages.json` | "Send Conversation Messages" (Enhanced Messaging / Digital Engagement) — verified worked example |
|
|
20
|
-
| `conversation-messaging.md` | Send Conversation Messages action build guide — MUST load before authoring a `sendConversationMessages` action call (trait differences vs. E360 mobile, input parameters, consent cross-validation, anti-patterns) |
|
|
21
|
-
| `../forward-to-bot-or-agent/forward-to-bot-or-agent.md` | Forward to Bot/Agent build guide — MUST load before authoring a `forwardToBotOrAgent` action call. Covers the mandatory WaitUntilEvent companion, `associatedWaitConfiguration` cross-reference, channel and event-type scoping, processType constraints, and fault-path requirement. |
|
|
22
|
-
| `examples/send-sms-message.json` | E360 "Send SMS Message" (`sendSmsMessage`) — verified worked example; load before authoring a `sendSmsMessage` action call (see [Send SMS Message Action](#send-sms-message-action-e360)) |
|
|
23
|
-
| `examples/send-email-message.json` | E360 "Send Email Message" — source-derived worked example (`senderId` + `communicationSubscriptionId` + `commSubscriptionChannelTypeId`); load before authoring a `sendEmailMessage` action call (see [Send Email Message](#send-email-message-e360)) |
|
|
24
|
-
| `examples/exit-from-flow.json` | Exit an Individual from one selected marketing flow, across one or all running versions |
|
|
25
|
-
| `examples/send-to-journey-no-fields.json` | Verified persisted `sendToJourney` action shape when the Journey schema has no required field mappings |
|
|
26
|
-
| `send-to-journey.md` | Send to Journey action build guide — MUST load before authoring a `sendToJourney` action call |
|
|
27
|
-
| `validators.md` | Save/activation validation rules for action elements |
|
|
28
|
-
|
|
29
|
-
## Overview
|
|
30
|
-
|
|
31
|
-
The Action element is the most versatile callout element in Flow Builder. It covers every invocable action registered with Salesforce: Apex-annotated methods (`@InvocableMethod`), External Services (OpenAPI-backed REST callouts), Quick Actions, Email Alerts, outbound messages, and platform-supplied actions (Einstein, journeys, etc.). In the metadata they all share the same `ActionCall` container — only the `actionType` field distinguishes them.
|
|
32
|
-
|
|
33
|
-
## When to Use
|
|
34
|
-
|
|
35
|
-
Use an Action element when a flow needs to:
|
|
36
|
-
- Call a custom Apex method marked `@InvocableMethod`
|
|
37
|
-
- Call an External Service (REST or MuleSoft)
|
|
38
|
-
- Send an Email Alert via a predefined email alert record
|
|
39
|
-
- Run any other registered invocable action
|
|
40
|
-
|
|
41
|
-
For calling another flow, use a Subflow element.
|
|
42
|
-
|
|
43
|
-
## Action Discovery — One Combined Catalog
|
|
44
|
-
|
|
45
|
-
Before authoring an `actionCalls[]` entry, locate the action with `GET /services/data/vXX.0/flowbuilder/action/invocable-actions`. A wrong `processType`/`triggerType` filter, or a stale action name, both surface as "Action not found" at save time even though the action exists.
|
|
46
|
-
|
|
47
|
-
`GET /services/data/vXX.0/flowbuilder/action/invocable-actions` returns a **single combined catalog** covering both action sources (Core collapsed the former separate standard/dynamic catalogs into this one operation). **Transform actions are excluded** — the server filters them out and no MCP tool exposes the transform-action catalog (author Transform elements from the target type schema instead; see the flow-element-transform skill):
|
|
48
|
-
|
|
49
|
-
| Action source | How it appears in `GET /services/data/vXX.0/flowbuilder/action/invocable-actions` | Notes |
|
|
50
|
-
|---|---|---|
|
|
51
|
-
| Platform built-ins | Included in the combined result (filter with `actionType`/`namePattern`) | Stock platform invocables (email, Chatter, approval, outbound message, etc.). ~36 on a stock org. |
|
|
52
|
-
| Managed packages, custom `@InvocableMethod`, External Connectors, External Services, ESR-backed actions | Included in the combined result; `dataSpace`/`flowDefinitionId` scope the dynamic portion (they don't yield a dynamic-only list) | Anything installed or namespaced. 3500+ entries on orgs with integrations — FILTER WITH `namePattern`/`actionType`/`limit` (or jq) AS THE COMBINED RESULT IS USUALLY TOO LONG. |
|
|
53
|
-
|
|
54
|
-
Rule of thumb: there is one catalog. Narrow it — pass `actionType` (e.g. `apex`, `flow`, `emailSimple`) and/or `namePattern` (case-insensitive substring on API name + label) to find third-party/managed/custom actions; `dataSpace`/`flowDefinitionId` scope the **dynamic portion** of that combined result. There is no standard-only or dynamic-only MCP variant — Core always calls `getAllowedActions` with `includeStandard=true, includeDynamic=true`.
|
|
55
|
-
|
|
56
|
-
Always pass the flow's exact `processType` (required) and `triggerType` (optional) to `GET /services/data/vXX.0/flowbuilder/action/invocable-actions`. Same action name can be filtered out by trigger type (e.g. callout actions blocked on `RecordBeforeSave`).
|
|
57
|
-
|
|
58
|
-
Once the target action is identified, always drill in with `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` (`actionName` + `actionType`, both required; optional `builderType`/`expand`) to get the authoritative parameter schema before authoring metadata. This call does not take `processType`/`triggerType`.
|
|
59
|
-
|
|
60
|
-
## Required Properties
|
|
61
|
-
|
|
62
|
-
| Property | Description | Constraints |
|
|
63
|
-
|---|---|---|
|
|
64
|
-
| Label | Human-readable name shown on the canvas | Cannot be blank |
|
|
65
|
-
| API Name | Unique developer name within the flow | Must be alphanumeric and start with a letter |
|
|
66
|
-
| Action | The specific invocable action to execute | Must resolve to an action registered for this flow's process type and trigger type; cannot be null |
|
|
67
|
-
|
|
68
|
-
## Optional Properties
|
|
69
|
-
|
|
70
|
-
| Property | Description | Default |
|
|
71
|
-
|---|---|---|
|
|
72
|
-
| Description | Free-text documentation | None |
|
|
73
|
-
| Manually Assign Variables | When enabled, exposes output parameters for explicit assignment instead of using automatic output handling | Disabled (automatic output enabled where supported) |
|
|
74
|
-
| Transaction Control | On supported process types, controls whether the action runs in the current, new, or automatic transaction | Automatic (when supported) |
|
|
75
|
-
| Store Output Automatically | Whether the action output is stored as a typed auto-output variable | true (where process type supports it) |
|
|
76
|
-
|
|
77
|
-
## Input Parameters
|
|
78
|
-
|
|
79
|
-
Input parameters are driven entirely by the action's describe metadata. The Flow Builder UI:
|
|
80
|
-
|
|
81
|
-
1. Fetches all declared input parameters from the server when an action is selected.
|
|
82
|
-
2. Merges them with any values already saved in the flow, preserving prior assignments.
|
|
83
|
-
3. Displays required parameters with a validation error if left blank.
|
|
84
|
-
4. Hides parameters containing the internal prefix `__` (double-underscore) — these are system-generated and not customer-facing.
|
|
85
|
-
5. Parameters can have a "controlling field" that drives conditional visibility: if parameter A controls parameter B, clearing A's value automatically clears B's value.
|
|
86
|
-
6. Some parameters have enumerated values that are loaded dynamically based on the values of other parameters (dependency chains).
|
|
87
|
-
|
|
88
|
-
### How to bind an input parameter's value
|
|
89
|
-
|
|
90
|
-
Every entry in `inputParameters[].value` is one of **five** shapes. Pick by what the value actually is — not by habit.
|
|
91
|
-
|
|
92
|
-
| Shape | Use when | Example |
|
|
93
|
-
|---|---|---|
|
|
94
|
-
| `{ "stringValue": "X" }` / `{ "numberValue": N }` / `{ "booleanValue": ... }` | Value is a **literal known at design time**. This includes any value chosen from an enumerated-values response when the parameter is a primitive. | `{ "name": "connection", "value": { "stringValue": "Quickbooks1t2" } }` |
|
|
95
|
-
| `{ "setupReference": "<devName>", "setupReferenceType": "<TypeName>" }` | Value is a **named setup record** referenced by developer name — ExternalServiceRegistration (named connection), NamedCredential, Permission Set, Recipient Group, etc. Emitted when the parameter is typed as a setup reference rather than a primitive enum. | `{ "name": "connection", "value": { "setupReference": "Quickbooks1t2", "setupReferenceType": "ExternalServiceRegistration" } }` |
|
|
96
|
-
| `{ "elementReference": "$Record.Field" }` or `{ "elementReference": "<TransformName>" }` or `{ "elementReference": "<RecordLookupName>.Id" }` | Value comes from **another flow element at runtime** — record trigger field, prior lookup, prior transform, prior action output, formula. | `{ "name": "createCustomerRequest", "value": { "elementReference": "Build_Request" } }` |
|
|
97
|
-
| `{ "elementReference": "<VariableName>" }` | Value must vary per invocation (caller passes it in as `isInput: true`) **or** is genuinely reused by multiple elements **or** is computed at runtime via Assignment. | `{ "name": "approverId", "value": { "elementReference": "User_Selected_Approver" } }` |
|
|
98
|
-
| `{ "transform": { ... } }` — **inline Transform** | Parameter is typed `Apex` / `SObject` / `schemaUri` AND there is no existing upstream Transform / variable / element to point at. Builds the typed wrapper object **inline** inside the action's input. See [Inline Transform Inputs](#inline-transform-inputs) below. | `{ "name": "createCustomerRequest", "value": { "transform": { "dataType": "Apex", "apexClass": "StdExtConnect__Quickbooks_Tx5fCustomerCreateRequest", "isCollection": false, "transformValues": [ ... ] } } }` |
|
|
99
|
-
|
|
100
|
-
**Picking between a standalone Transform vs. an inline Transform** for an `Apex` / `SObject` / `schemaUri` input:
|
|
101
|
-
|
|
102
|
-
| Situation | Use |
|
|
103
|
-
|---|---|
|
|
104
|
-
| The shaped object is consumed by **one action**, isn't reused, and doesn't need to appear as its own canvas node. | **Inline transform** — `value.transform: { ... }` directly on the action input. |
|
|
105
|
-
| The shaped object is consumed by **multiple downstream elements**, the user wants it visible on the canvas, or downstream logic needs to reference it by name. | **Standalone Transform** element in `transforms[]`, then `elementReference` to that Transform's name on the action input. |
|
|
106
|
-
|
|
107
|
-
**Anti-pattern — DO NOT do this:** wrapping a known-at-design-time literal in a `String` variable just to indirect through `elementReference`.
|
|
108
|
-
|
|
109
|
-
```json
|
|
110
|
-
// WRONG — literal hidden behind a variable
|
|
111
|
-
"variables": [{ "name": "QB_Connection_Id", "dataType": "String",
|
|
112
|
-
"value": { "stringValue": "Quickbooks1t2" }, "isInput": true }],
|
|
113
|
-
"inputParameters": [{ "name": "connection",
|
|
114
|
-
"value": { "elementReference": "QB_Connection_Id" } }]
|
|
115
|
-
|
|
116
|
-
// RIGHT — literal bound directly
|
|
117
|
-
"variables": [],
|
|
118
|
-
"inputParameters": [{ "name": "connection",
|
|
119
|
-
"value": { "stringValue": "Quickbooks1t2" } }]
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Why it's wrong: the variable adds no behavior, and if `isInput: true` it lets callers pass a value the action's enum/type constraint would otherwise reject at design time. Variables earn their keep only when the value (a) is computed, (b) varies per caller, or (c) is reused across multiple elements.
|
|
123
|
-
|
|
124
|
-
### Inline Transform Inputs
|
|
125
|
-
|
|
126
|
-
When an action declares an input parameter typed `Apex` / `SObject` / `schemaUri` and **no existing flow element** (variable, prior lookup, standalone Transform, prior action output) holds a suitable value, build the wrapper **inline** at the action's input using a `transform` value. This keeps the metadata local to the action instead of dropping a standalone Transform on the canvas.
|
|
127
|
-
|
|
128
|
-
**Wire shape.** The `value` becomes `{ "transform": { ...transform-body... } }`. The inner `transform` body is **identical** in shape to a standalone Transform element body (same `transformValues[]`, same `transformValueActions[]`, same `transformType: "Map"` semantics) — minus the canvas-level fields. See the **flow-element-transform skill** (`transform.md` § Inline Transform, § transformValues Structure, § TransformValueAction Shapes) for the full body shape; the action-call skill does not duplicate those rules.
|
|
129
|
-
|
|
130
|
-
**Required fields on the inline transform body:**
|
|
131
|
-
|
|
132
|
-
| Field | Required | Notes |
|
|
133
|
-
|---|---|---|
|
|
134
|
-
| `dataType` | yes | `"Apex"`, `"SObject"`, or matching the parameter's declared type |
|
|
135
|
-
| `apexClass` / `objectType` / `schemaUri` | yes (one) | Exactly one — pick by `dataType` |
|
|
136
|
-
| `isCollection` | yes | Mirror the parameter's `maxOccurs` (false for singular, true when the param is a list) |
|
|
137
|
-
| `transformValues` | yes | One outer entry containing `transformValueActions[]` |
|
|
138
|
-
|
|
139
|
-
**Fields OMITTED from an inline transform** (canvas-only on a standalone Transform):
|
|
140
|
-
- `name`, `label`, `locationX`, `locationY` — not a canvas node
|
|
141
|
-
- `connector` — flow continues from the host action, not the inline transform
|
|
142
|
-
- `storeOutputAutomatically` — the wrapper is consumed inline; no separate output resource
|
|
143
|
-
|
|
144
|
-
**TransformValueAction value shapes** (same as standalone Transform; cross-link to transform skill for full rules):
|
|
145
|
-
|
|
146
|
-
```jsonc
|
|
147
|
-
// Literal scalar
|
|
148
|
-
{ "transformType": "Map", "outputFieldApiName": "GivenName",
|
|
149
|
-
"value": { "stringValue": "John Doe", "inputConfiguratorMode": "Resource" } }
|
|
150
|
-
|
|
151
|
-
// Enum-resolved scalar (Custom mode signals a picked enum literal)
|
|
152
|
-
{ "transformType": "Map", "outputFieldApiName": "PreferredDeliveryMethod",
|
|
153
|
-
"value": { "stringValue": "Email", "inputConfiguratorMode": "Custom" } }
|
|
154
|
-
|
|
155
|
-
// Element reference (from $Record, prior lookup, prior action output)
|
|
156
|
-
{ "transformType": "Map", "outputFieldApiName": "ShipAddr.PostalCode",
|
|
157
|
-
"value": { "elementReference": "Get_Records_1.MailingPostalCode",
|
|
158
|
-
"inputConfiguratorMode": "Resource" } }
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**Nested fields** (e.g. `ShipAddr.PostalCode`, `PrimaryEmailAddr.Address`) use the **dot-path** form of `outputFieldApiName`. The Transform editor recurses into the parent Apex sub-object automatically; the inline transform body does the same. The dot-path rule is owned by the transform skill — see `transform.md` § Required-on-Save Rules.
|
|
162
|
-
|
|
163
|
-
**Don't:** create a standalone Transform with `transformValues` that contains only one mapping action, then `elementReference` it from a single action input. That's the inline-transform case in disguise — collapse it.
|
|
164
|
-
|
|
165
|
-
**Do:** when the user later asks to reuse the shaped wrapper from a second action or expose it on the canvas, promote the inline transform to `transforms[]` and switch the action input to `elementReference`.
|
|
166
|
-
|
|
167
|
-
**Reference example:** `examples/inline-transform-input.json` — full `actionCalls[]` entry combining an inline-Transform Apex input, a `setupReference` connection input, three mapping styles (literal, enum-resolved, element reference), and a nested dot-path field.
|
|
168
|
-
|
|
169
|
-
### Dynamic Type Mappings (Generic Types)
|
|
170
|
-
|
|
171
|
-
**Decision gate — run this before writing any `actionCalls[]` entry.** Inspect `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details`'s `genericTypes[]`:
|
|
172
|
-
|
|
173
|
-
- **Empty `genericTypes[]`** → the action is non-generic; emit **no** `dataTypeMappings` (a stray entry is rejected — see [Save-time rejections](#save-time-rejections)).
|
|
174
|
-
- **Non-empty `genericTypes[]`** → for **each non-`NamedAutomationSchema` placeholder**, run the Resolution workflow in [Generic-Type Placeholders](#generic-type-placeholders-u__-t__) and emit one `dataTypeMappings[]` entry (`typeName` = the placeholder's `genericTypes[].name`; plus exactly one concrete `typeValue`/`apexClass`/`schemaUri`). `NamedAutomationSchema` placeholders (e.g. `ContentSchema`) are optional and may be left unmapped.
|
|
175
|
-
|
|
176
|
-
Actions can declare generic parameters (e.g., "T extends SObject"). Flow Builder presents a type mapping row for each generic type, and the user must choose a concrete Salesforce object or Apex type before parameters that depend on it are shown. Rules:
|
|
177
|
-
|
|
178
|
-
- Each generic type mapping must have a non-blank, valid value — except `NamedAutomationSchema` type mappings, which are optional and can be left unmapped.
|
|
179
|
-
- Changing a type mapping reloads dependent input/output parameters.
|
|
180
|
-
- **The metadata field is `dataTypeMappings`, despite this section's name.** `dynamicTypeMappings` is not a real field — the server won't flag it as unknown, it just fails the whole save with a generic top-level rejection (see "Save-time rejections" below). Same trap applies to any action with generic types, not just this one.
|
|
181
|
-
- **Resolve every non-`NamedAutomationSchema` `genericTypes[]` entry, even one the flow's design doesn't actively use.** This includes `SCHEMAURI` (`schemaUri`) placeholders — only `NamedAutomationSchema` is exempt. A generic placeholder blocks validation regardless of whether the flow reads that specific generic-typed parameter — e.g. a flow that only assigns a sibling String/primitive output still fails `DYNAMIC_TYPE_MAPPING_MISSING` if an unrelated Apex-typed generic sibling parameter is left unmapped. Check `genericTypes[]` on every action drill-down and resolve all of it, not just the placeholder(s) feeding the parameter you plan to use.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
## Output Parameters
|
|
185
|
-
|
|
186
|
-
There are two modes:
|
|
187
|
-
|
|
188
|
-
**Automatic output handling (default where supported)**
|
|
189
|
-
- Output is stored as a single, typed Flow resource named after the action element.
|
|
190
|
-
- The data type is either `ActionOutput` (generic) or a specific Apex/SObject type if the action declares a system-generated output.
|
|
191
|
-
- No individual output parameters appear in the editor.
|
|
192
|
-
|
|
193
|
-
**Manual assignment (advanced)**
|
|
194
|
-
- The user switches the toggle to manually assign variables.
|
|
195
|
-
- Each output parameter from the action descriptor becomes an assignable row.
|
|
196
|
-
- Outputs that are blank (unassigned) are stripped before saving to metadata.
|
|
197
|
-
- Empty string values on output rows are treated as null (no assignment).
|
|
198
|
-
- Parameters marked as `NOT_AVAILABLE` (removed from the action definition) show a warning badge "Will Cause Errors" and are disabled.
|
|
199
|
-
|
|
200
|
-
## Fault Path
|
|
201
|
-
|
|
202
|
-
Fault-capable Action elements have a fault path (connector type `FAULT`). This path is taken when the action throws an exception at runtime. Apply the action-specific persisted shape before this generic rule.
|
|
203
|
-
|
|
204
|
-
**Marketing flows: fault path only when asked.** In a marketing flow, add a `faultConnector` to an action only if the user asks for error handling. A marketing flow is one whose `start.triggerType` is on the list in `shared/fault-paths/fault-paths.md` § Marketing Flows — Fault Paths Only When Asked. This covers every marketing action below (Send Email Message, Send SMS, Send RCS, push, in-app, and Exit From Flow). In any other flow type, including a plain Autolaunched Flow with no `triggerType`, the fault-path rules in this file apply as written.
|
|
205
|
-
|
|
206
|
-
- Default available connections: one regular path + one fault path.
|
|
207
|
-
- `maxConnections` is 2 for non-branching actions.
|
|
208
|
-
|
|
209
|
-
## Async Actions (Wait Until Completed)
|
|
210
|
-
|
|
211
|
-
Some actions declare `isAsync = true`. When the flow is configured to wait for completion (`isWaitUntilCompleted = true`), the element gains two child branches:
|
|
212
|
-
|
|
213
|
-
- **Default path** — taken when the action completes successfully.
|
|
214
|
-
- **Timeout path** — taken if the action does not complete within the configured window. The timeout path can be hidden/disabled via `timeoutPathUsage`. In auto-layout canvas, the timeout path defaults to disabled; in free-form canvas it defaults to enabled.
|
|
215
|
-
|
|
216
|
-
Timeout configuration:
|
|
217
|
-
- `offset` must be a number between 1 and 365 (inclusive).
|
|
218
|
-
- `offsetUnit` can be `Minutes`, `Hours`, `Days`, `Weeks`, or `Months`; it must not be blank.
|
|
219
|
-
- Changing a branching async action triggers the `ACTION_CALL_WITH_MODIFIED_AND_DELETED_PATHS` element type to signal path cleanup.
|
|
220
|
-
|
|
221
|
-
**Authoring an async action call — required field set.** When `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` reports `isAsync: true` for the target action, always emit all three together on the `actionCalls[]` entry, even if the user's request only mentions waiting for the result:
|
|
222
|
-
|
|
223
|
-
```json
|
|
224
|
-
"isWaitUntilCompleted": true,
|
|
225
|
-
"offset": 1,
|
|
226
|
-
"offsetUnit": "Hours"
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
Omitting `isWaitUntilCompleted` fails validation with `ACTIONCALL_INVALID_ISWAITUNTILCOMPLETED` ("you must set isWaitUntilCompleted to true"). Omitting `offset`/`offsetUnit` fails/warns with `ACTIONCALL_MISSING_OFFSET`. Both are cheap to preempt: check `isAsync` on every action drill-down before authoring, not after the first validation round-trip flags it.
|
|
230
|
-
|
|
231
|
-
## Actions With Outcome Paths (Branching Actions)
|
|
232
|
-
|
|
233
|
-
Certain action types (e.g., `INDV_PREFERRED_RECORD_DECISION`, some orchestration steps) return a list of named outcome paths instead of a single result. These are called "dependent outcomes". The flow editor:
|
|
234
|
-
|
|
235
|
-
1. Fetches available outcomes from the server using the action name, type, and current input parameter values.
|
|
236
|
-
2. Presents each outcome as a selectable path.
|
|
237
|
-
3. Creates an `ActionCallPath` child element per outcome, plus a hidden default path in metadata.
|
|
238
|
-
4. Path names come from the action descriptor; path labels are auto-generated or localized.
|
|
239
|
-
|
|
240
|
-
Child paths use the naming convention `<elementName>:<pathName>` to ensure uniqueness in nested contexts.
|
|
241
|
-
|
|
242
|
-
## Versioned Actions
|
|
243
|
-
|
|
244
|
-
Actions can declare multiple versions via a `versionList`. When an action is versioned:
|
|
245
|
-
- The editor shows a version picker.
|
|
246
|
-
- Switching versions re-fetches parameters and merges them with the current element state.
|
|
247
|
-
- Parameters that existed in the old version but not the new version are flagged with warnings; required or populated ones are retained with an error; optional unset ones are dropped.
|
|
248
|
-
- If the action also has a Custom Property Editor (CPE), all parameters with warnings are purged before the CPE is rendered (to avoid presenting invalid parameters to the CPE).
|
|
249
|
-
|
|
250
|
-
## Configuration Editors (Custom Property Editors)
|
|
251
|
-
|
|
252
|
-
An action can declare a `configurationEditor` — a custom Lightning component that replaces the standard parameter list UI. When present:
|
|
253
|
-
- The CPE receives the flow state, input variables, and type mappings.
|
|
254
|
-
- Changes from the CPE are handled via `ConfigurationEditorChangeEvent` and `ConfigurationEditorPropertyDeleteEvent`.
|
|
255
|
-
- Mini-CPEs are detected when any input parameter has a `cpeName` attribute.
|
|
256
|
-
|
|
257
|
-
## Warnings During Merge
|
|
258
|
-
|
|
259
|
-
When the saved flow metadata is merged with the latest action describe, parameters can carry these warnings:
|
|
260
|
-
|
|
261
|
-
| Warning Code | Meaning | Visual |
|
|
262
|
-
|---|---|---|
|
|
263
|
-
| `NOT_AVAILABLE` | Parameter was removed from the action | Badge: "Will Cause Errors"; input disabled |
|
|
264
|
-
| `DATA_TYPE_CHANGED` | Parameter data type changed between versions | Warning icon |
|
|
265
|
-
| `DUPLICATE` | Same parameter name assigned more than once (CFD edit) | Marked for deletion |
|
|
266
|
-
|
|
267
|
-
## Validation Rules and Constraints
|
|
268
|
-
|
|
269
|
-
- Action must be selected and non-null before saving.
|
|
270
|
-
- All required input parameters must have a value (not null, not blank).
|
|
271
|
-
- Resource picker values are validated for correct format and reference.
|
|
272
|
-
- Generic type mappings must be filled (except `NamedAutomationSchema`).
|
|
273
|
-
- For async actions: `offset` is required, numeric, range 1–365; `offsetUnit` is required.
|
|
274
|
-
- Email-sending actions (Send Email) have cross-parameter validation: template vs. subject/body choice fields must be consistently set; recipient ID is required when a template is used. See [Send Email Actions](#send-email-actions) for the verified `sendEmailMessage`/`emailSimple` shapes and a note on which of these checks reproduced at `validate_flow` time.
|
|
275
|
-
- Parameters with `__` in their name are internal and excluded from the customer-facing UI.
|
|
276
|
-
- **RecordBeforeSave flows cannot use actions with external callouts at all** — before-save flows have no scheduled path; deployment or activation is blocked. **RecordAfterSave flows** with `hasCallout: true` must place the action on a **scheduled path** (`scheduledPaths[]` on the Start element), not the immediate path. Save succeeds; activation is blocked with `WARNING_BLOCK_ACTIVATION` if the action sits on the immediate path.
|
|
277
|
-
|
|
278
|
-
## Common Patterns
|
|
279
|
-
|
|
280
|
-
- To pass a record ID into an action, map an input parameter to the record ID variable from the triggering record or a lookup result.
|
|
281
|
-
- To use an action's output in a subsequent element, reference the auto-output variable `{!ElementApiName.OutputFieldName}` (automatic mode) or the manually assigned variable.
|
|
282
|
-
- Actions that modify records should use the fault path to handle errors gracefully (in a marketing flow, only when the user asks for error handling; see [Fault Path](#fault-path)).
|
|
283
|
-
- For actions with generic types (`genericTypes[]` non-empty on the describe — placeholder names like `T__body`, `U__output`, `sObjectType`), resolve the placeholder(s) first and emit `dataTypeMappings[]` on the action call. Parameters typed against an unresolved placeholder won't accept concrete values until the mapping is set. See [Generic-Type Placeholders](#generic-type-placeholders-u__-t__) below.
|
|
284
|
-
- When an action version list is present, always confirm the desired version before configuring parameters, because switching versions resets parameters.
|
|
285
|
-
|
|
286
|
-
## MCP Tools for Action Discovery
|
|
287
|
-
|
|
288
|
-
Agents call these flow MCP tools, not the raw Aura functions.
|
|
289
|
-
|
|
290
|
-
| Tool | Use when |
|
|
291
|
-
|---|---|
|
|
292
|
-
| `GET /services/data/vXX.0/flowbuilder/action/invocable-actions` | Single discovery tool for BOTH platform built-ins (`emailSimple`, `chatterPost`, `submitForApproval` — ~36 on a stock org) AND dynamic actions (managed-package, External Connector, External Service, ESR-backed, custom `@InvocableMethod` — 3500+ on orgs with integrations). Core collapsed the former separate standard/dynamic catalogs into this one operation, which returns the **combined** list (transform actions are excluded — no MCP tool lists them). Required `processType`; optional `triggerType`, `builderType`, `actionType` (filter by type, e.g. `apex`/`flow`), `namePattern` (case-insensitive substring on API name + label), `limit`, and `dataSpace`/`flowDefinitionId` (scope the dynamic portion of the combined result — ignored for standard built-ins; they don't produce a dynamic-only list). **CRITICAL: on orgs with integrations the combined payload is extremely large (multiple MB from dynamic actions). Always narrow with `namePattern`/`actionType`/`limit` (or filter with jq) before reading.** |
|
|
293
|
-
| `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` | Full schema for ONE action — required inputs, generic types, output shape. **Mandatory** before authoring any `actionCalls[]` element. Params: `actionType`, `actionName` (both required); optional `builderType` and `expand` (pass `expand=SchemaParameters` to fold schema-backed params' nested fields inline, one level, avoiding a separate `GET /services/data/vXX.0/flowbuilder/action/schema-uri-parameters` call). There is no `processType`/`triggerType`/`flowProcessType`/`flowTriggerType` param. |
|
|
294
|
-
| `GET /services/data/vXX.0/flowbuilder/action/invocable-action-generic-type-enum-values` | Resolve generic-type placeholders — any `genericTypes[].name` starting with `U__` (uniformly-typed param) or `T__` (per-action typed param like `T__body`). Call only when `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` returned non-empty `genericTypes[]` AND every path listed under each placeholder's `typeProviders.dependsOn` has a resolved upstream value. Required params: `actionType`, `actionName`, `requestedGenericTypes` (a **JSON array of placeholder-name strings**, e.g. `["T__body"]` — the OAS schema is `type: array, items: {type: string}`, so send an array even for one placeholder, not a bare string), and `inputParamsJson` (a **JSON-encoded string** of `[{path, value}]` objects); optional `processType`, `triggerType`, `builderType`. Each `value` inside `inputParamsJson` must be an **object** holding a **literal** (`{stringValue: "..."}` / `{numberValue: 1}`) — the resolver reads only `stringValue`/`numberValue`, so an `elementReference` or other FEROV variant resolves to null and is dropped; resolve the driving input to a literal first. |
|
|
295
|
-
| `GET /services/data/vXX.0/flowbuilder/action/invocable-action-parameter-enum-values` | Resolve dynamic picklist / dependent-enum values on one or more parameters. Call when `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` returned a parameter (or `subfieldEnums[]` entry) with `status: "NOT_ENOUGH_INFO"` AND the upstream `dependsOn` inputs are now known. Required params: `actionType`, `actionName`, `requestedParamsJson` (a **JSON-encoded string** of the list-of-paths, e.g. `[["param"],["wrapper","subfield"]]`), and `inputParamsJson` (a **JSON-encoded string** of `[{path, value}]` objects supplying every `dependsOn` path); optional `processType`, `triggerType`, `builderType`. Returns `List<InvocableActionParameterDescriptor>` with the populated enum value set. |
|
|
296
|
-
| `GET /services/data/vXX.0/flowbuilder/resource/apex-types` | Browse Apex request/response classes by namespace + name. Required when an action input has `dataType: apex`. **Must pass `processType`** (required); optional `builderType`, `namePattern`, `limit`. There is no trigger-type param. |
|
|
297
|
-
|
|
298
|
-
Naming convention for raw Aura references in Salesforce docs (mapping if you read upstream code):
|
|
299
|
-
|
|
300
|
-
| Aura function | MCP tool |
|
|
301
|
-
|---|---|
|
|
302
|
-
| `getAllInvocableActionsForType` | `GET /services/data/vXX.0/flowbuilder/action/invocable-actions` (returns standard + dynamic combined) |
|
|
303
|
-
| `getStandardInvocableActionsForType` | `GET /services/data/vXX.0/flowbuilder/action/invocable-actions` (standard actions are included in the combined result; filter with `actionType`/`namePattern`) |
|
|
304
|
-
| `getDynamicInvocableActionsForType` | `GET /services/data/vXX.0/flowbuilder/action/invocable-actions` (`dataSpace`/`flowDefinitionId` scope the dynamic portion of the combined result — there is no dynamic-only MCP variant) |
|
|
305
|
-
| `getInvocableActionDetails` | `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` |
|
|
306
|
-
| `getInvocableActionParameterWithEnumeratedValues` | `GET /services/data/vXX.0/flowbuilder/action/invocable-action-parameter-enum-values` |
|
|
307
|
-
| `getInvocableActionGenericTypesWithEnumeratedValues` | `GET /services/data/vXX.0/flowbuilder/action/invocable-action-generic-type-enum-values` |
|
|
308
|
-
| `getDependentOutcomes` | `GET /services/data/vXX.0/flowbuilder/action/dependent-outcomes` (dedicated tool; params `actionType`, `actionName`, `paramValuesJson`) |
|
|
309
|
-
|
|
310
|
-
## Apex-Typed Input Parameters
|
|
311
|
-
|
|
312
|
-
When `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` returns a parameter with `dataType: "Apex"` (or a non-null `apexClass` field), the action expects a typed Apex object — not a flat set of scalar inputs. This is true across ALL actions.
|
|
313
|
-
|
|
314
|
-
**Workflow:**
|
|
315
|
-
|
|
316
|
-
1. From the parameter descriptor, capture the `apexClass` value.
|
|
317
|
-
2. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/resource/apex-types", queryParams: { processType })` (optionally `namePattern` to narrow by class name, `limit`) and locate the class by matching `apexClass` against `apexTypes[].name`. Each entry returns `properties[]` listing `{ name, dataType, objectType, apexClass, isCollection }` and an `innerTypes[]` array holding the nested Apex types referenced by this class.
|
|
318
|
-
3. Recurse into any property whose `dataType: "Apex"` — resolve its nested shape by looking up its `apexClass` in `innerTypes[]` (or the top-level `apexTypes[]` list) to enumerate nested children.
|
|
319
|
-
4. Author a **Transform element** (`transforms[]`) whose `apexClass` / `objectType` matches the request class. Map scalar children directly; use dot-path `outputFieldApiName` for nested children (e.g. `"BillAddr.City"`). See the flow-element-transform skill.
|
|
320
|
-
5. Pass the Transform as the action's input via `value: { elementReference: "<TransformName>" }`.
|
|
321
|
-
|
|
322
|
-
Do not pass flat scalar fields directly as top-level `inputParameters[]` when the action signature is a single Apex wrapper — the save will succeed but the action will fail at runtime because the wrapper is unset.
|
|
323
|
-
|
|
324
|
-
## Generic-Type Placeholders (`U__*`, `T__*`)
|
|
325
|
-
|
|
326
|
-
Some invocable actions don't have a static input/output type — the type is computed per upstream binding (e.g. for `JiraV2.createIssue` the request body shape depends on which `project` + `issueType` was chosen; for `extractDataFromDocument` the output shape depends on the document configuration). These actions surface as `genericTypes[]` entries on the action describe.
|
|
327
|
-
|
|
328
|
-
**Recognition.** `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` returns:
|
|
329
|
-
|
|
330
|
-
```json
|
|
331
|
-
"genericTypes": [
|
|
332
|
-
{
|
|
333
|
-
"name": "T__body", // or "U__input" / "U__output" / "T__<param>"
|
|
334
|
-
"superType": "APEXTYPE", // or "SOBJECT" / "SCHEMAURI"
|
|
335
|
-
"typeProviders": { // Type providers is optional, when not including select the type based on the input/output values
|
|
336
|
-
"dependsOn": [["issueType"], ["project"], ["connection"]],
|
|
337
|
-
"values": [],
|
|
338
|
-
"status": "NOT_ENOUGH_INFO"
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
]
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
AND one or more `parameters[]` entries whose `apexClass` / `sobjectType` / `schemaUri` equals the placeholder name (e.g. `"apexClass": "T__body"`). Those parameters get their concrete shape from the resolved placeholder.
|
|
345
|
-
|
|
346
|
-
**`superType` picks the `dataTypeMappings` field — don't guess, don't default to `typeValue`.** Match directly, no exceptions:
|
|
347
|
-
|
|
348
|
-
| `genericTypes[].superType` | `dataTypeMappings` field to emit |
|
|
349
|
-
|---|---|
|
|
350
|
-
| `APEXTYPE` | `apexClass` |
|
|
351
|
-
| `SOBJECT` | `typeValue` |
|
|
352
|
-
| `SCHEMAURI` | `schemaUri` |
|
|
353
|
-
| `NAMED_AUTOMATION_SCHEMA` | `schemaUri`, never `typeValue` (the mapping is optional, see [Key rules](#key-rules); `send-to-journey.md` emits one) |
|
|
354
|
-
|
|
355
|
-
`extractDataFromDocument`'s `U__output` is `superType: "APEXTYPE"` — the resolved value (e.g. `DocumentProcessing__invoiceconfig_invoiceconfig`) goes in `apexClass`. Emitting it as `typeValue` passes the "is it resolved" check but fails a second round with `TYPE_MAPPING_NOT_SUPPORTED`.
|
|
356
|
-
|
|
357
|
-
**Check `genericTypes[]` before the first `validate_flow` call, not after an error.** Same cheap-to-preempt pattern as the `isAsync` check in [Validation Rules and Constraints](#validation-rules-and-constraints): read `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details`'s `genericTypes[]` up front. Non-empty means resolve every entry via `GET /services/data/vXX.0/flowbuilder/action/invocable-action-generic-type-enum-values` and emit `dataTypeMappings[]` in the very first payload — don't build the action call, validate, and let `DYNAMIC_TYPE_MAPPING_MISSING` tell you what the describe already told you.
|
|
358
|
-
|
|
359
|
-
**Naming.**
|
|
360
|
-
- `U__<name>` — generic placeholder shared across multiple params with the same type (uniform).
|
|
361
|
-
- `T__<name>` — per-parameter typed placeholder (typically request bodies on External Connector actions).
|
|
362
|
-
|
|
363
|
-
Both resolve through the same tool; the prefix is a hint about scope, not a different mechanism.
|
|
364
|
-
|
|
365
|
-
**Resolution.**
|
|
366
|
-
|
|
367
|
-
1. Bind every `dependsOn[]` path with a concrete upstream value.
|
|
368
|
-
2. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/action/invocable-action-generic-type-enum-values")`:
|
|
369
|
-
|
|
370
|
-
```json
|
|
371
|
-
{
|
|
372
|
-
"actionType": "<actionType>",
|
|
373
|
-
"actionName": "<actionName>",
|
|
374
|
-
"processType": "AutoLaunchedFlow",
|
|
375
|
-
"triggerType": "RecordAfterSave",
|
|
376
|
-
"requestedGenericTypes": ["T__body"],
|
|
377
|
-
"inputParamsJson": "[{\"path\":[\"connection\"],\"value\":{\"stringValue\":\"<ESR_DeveloperName>\"}},{\"path\":[\"project\"],\"value\":{\"stringValue\":\"<projectKey>\"}},{\"path\":[\"issueType\"],\"value\":{\"stringValue\":\"<issueTypeId>\"}}]"
|
|
378
|
-
}
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
`inputParams[].value` is a FEROV object — `{stringValue: ...}` / `{numberValue: ...}` / `{booleanValue: ...}` — NOT a bare string. Only these three literal keys are supported here (no `elementReference`, no date variants); the resolver needs a design-time literal, not a runtime reference. The server returns `400` with `Expected object, received string` if you pass a bare string.
|
|
382
|
-
|
|
383
|
-
WRONG — bare string, fails with 400 "Expected object, received string":
|
|
384
|
-
```json
|
|
385
|
-
{ "path": ["<paramName>"], "value": "<value>" }
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
RIGHT — wrapped in a FEROV literal:
|
|
389
|
-
```json
|
|
390
|
-
[
|
|
391
|
-
{ "path": ["<paramName>"], "value": { "stringValue": "<value>" } },
|
|
392
|
-
{ "path": ["<paramName>"], "value": { "numberValue": 42 } },
|
|
393
|
-
{ "path": ["<paramName>"], "value": { "booleanValue": true } }
|
|
394
|
-
]
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
Same rule applies to `flowbuilder_get_invocable_action_parameter_with_enumerated_values`'s `inputParams[]` — both enum-resolution tools share this shape.
|
|
398
|
-
The tool params match the Connect OAS contract: `actionType` + `actionName` are required; `processType`/`triggerType`/`builderType` are optional (note: `processType`/`triggerType`, **not** `flowProcessType`/`flowTriggerType`). `requestedGenericTypes` is a **JSON array of placeholder-name strings** (schema `type: array, items: {type: string}`) — send `["T__body"]`, not the bare string `"T__body"`, even for a single placeholder. `inputParamsJson` is a **JSON-encoded string** (not a structured array) whose decoded form is `[{path, value}]`. Inside it, each `value` is an OBJECT holding a **literal** (`{stringValue: ...}` / `{numberValue: ...}`), NOT a bare string — the server returns `400` with `Expected object, received string` if you pass a bare string. Note this resolver reads only `stringValue`/`numberValue`; an `elementReference` (or any other FEROV variant) resolves to null and is dropped, so a `dependsOn` input pointed at a variable won't resolve — bind it to a concrete literal first.
|
|
399
|
-
|
|
400
|
-
3. Read the response's resolved `apexClass` / `objectType` / `schemaUri` for each requested placeholder.
|
|
401
|
-
4. Emit `dataTypeMappings[]` on the action call (see "Metadata Shape" below).
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
## Dynamic-Picklist Parameters (Dependent Enums)
|
|
405
|
-
|
|
406
|
-
Some parameters have enum value sets that cannot be resolved until upstream input parameters are known. The mechanism is the same regardless of `actionType`.
|
|
407
|
-
|
|
408
|
-
**Recognition.** `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` returns descriptors of this shape:
|
|
409
|
-
|
|
410
|
-
```json
|
|
411
|
-
{
|
|
412
|
-
"name": "<paramName>",
|
|
413
|
-
"subfieldEnums": [
|
|
414
|
-
{
|
|
415
|
-
"path": ["<paramName>", "<subfield>"],
|
|
416
|
-
"enums": {
|
|
417
|
-
"dependsOn": [["<upstreamParam>"]],
|
|
418
|
-
"values": [],
|
|
419
|
-
"status": "NOT_ENOUGH_INFO"
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
]
|
|
423
|
-
}
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
Or at the parameter level itself:
|
|
427
|
-
|
|
428
|
-
```json
|
|
429
|
-
{ "name": "<paramName>", "enums": { "dependsOn": [["<other>"]], "status": "NOT_ENOUGH_INFO" } }
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
`status: "NOT_ENOUGH_INFO"` + non-empty `dependsOn` ⇒ needs resolution.
|
|
433
|
-
|
|
434
|
-
**Resolution.** Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/action/invocable-action-parameter-enum-values")`:
|
|
435
|
-
|
|
436
|
-
```json
|
|
437
|
-
{
|
|
438
|
-
"actionType": "<actionType>",
|
|
439
|
-
"actionName": "<actionName>",
|
|
440
|
-
"processType": "AutoLaunchedFlow",
|
|
441
|
-
"triggerType": "RecordAfterSave",
|
|
442
|
-
"requestedParamsJson": "[[\"<paramName>\",\"<subfield>\"]]",
|
|
443
|
-
"inputParamsJson": "[{\"path\":[\"<upstreamParam>\"],\"value\":{\"stringValue\":\"<resolvedValue>\"}}]"
|
|
444
|
-
}
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
`actionType` + `actionName` are required; `processType`/`triggerType`/`builderType` are optional (note: `processType`/`triggerType`, **not** `flowProcessType`/`flowTriggerType`). `requestedParamsJson` is a **JSON-encoded string** whose decoded form is a list of paths (single-element for top-level params, multi-element for nested subfields). `inputParamsJson` is a **JSON-encoded string** whose decoded form is `[{path, value}]` and must supply every path listed in the target's `dependsOn[]`. Returns `List<InvocableActionParameterDescriptor>` with `enums.values[]` now filled.
|
|
448
|
-
|
|
449
|
-
### Picking the value to assign
|
|
450
|
-
|
|
451
|
-
**Rule (bind-as-literal).** For any parameter or subfield whose `enums.values[]` was resolved by `GET /services/data/vXX.0/flowbuilder/action/invocable-action-parameter-enum-values`:
|
|
452
|
-
|
|
453
|
-
> Bind the chosen `value` **directly** at the action's `inputParameters[].value` (or the Transform's mapped value, for an Apex wrapper subfield) as a `{ "stringValue": "..." }` literal. **Do not** wrap it in a flow variable, formula, or constant first.
|
|
454
|
-
|
|
455
|
-
The enum's `value` field (not its `label`) is what gets written. Pick exactly one entry from the resolved set.
|
|
456
|
-
|
|
457
|
-
#### Right vs. wrong
|
|
458
|
-
|
|
459
|
-
```json
|
|
460
|
-
// RIGHT — enum value pinned as a literal at the action input
|
|
461
|
-
"variables": [],
|
|
462
|
-
"inputParameters": [
|
|
463
|
-
{ "name": "connection", "value": { "stringValue": "Quickbooks1t2" } }
|
|
464
|
-
]
|
|
465
|
-
|
|
466
|
-
// WRONG #1 — variable indirection for a value known at design time
|
|
467
|
-
"variables": [{ "name": "QB_Connection_Id", "dataType": "String",
|
|
468
|
-
"value": { "stringValue": "Quickbooks1t2" }, "isInput": true }],
|
|
469
|
-
"inputParameters": [
|
|
470
|
-
{ "name": "connection", "value": { "elementReference": "QB_Connection_Id" } }
|
|
471
|
-
]
|
|
472
|
-
|
|
473
|
-
// WRONG #2 — picking the label instead of the value
|
|
474
|
-
"inputParameters": [
|
|
475
|
-
{ "name": "connection", "value": { "stringValue": "t2" } } // label, not value
|
|
476
|
-
]
|
|
477
|
-
|
|
478
|
-
// WRONG #3 — hard-coded from documentation when the live tool returned a set
|
|
479
|
-
"inputParameters": [
|
|
480
|
-
{ "name": "connection", "value": { "stringValue": "QBO_PROD_TROPICAL_2" } }
|
|
481
|
-
]
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
#### Workflow
|
|
485
|
-
|
|
486
|
-
1. After `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` flags a parameter/subfield with `dependsOn[]` and `status: "NOT_ENOUGH_INFO"`, resolve any upstream paths first.
|
|
487
|
-
2. Call the enumerated-values tool with the resolved values in `inputParamsJson` and the target path in `requestedParamsJson` (both JSON-encoded strings).
|
|
488
|
-
3. From the returned descriptor, read `enums.values[]` (top-level) or the matching `subfieldEnums[i].enums.values[]`.
|
|
489
|
-
4. Choose **exactly one entry's `value`** (not `label`) and bind it per the rule above.
|
|
490
|
-
5. If multiple entries are returned and the user has not specified which to use, pick the first entry and note the choice in your output so the user can override.
|
|
491
|
-
|
|
492
|
-
#### When the rule does NOT apply
|
|
493
|
-
|
|
494
|
-
- **User specifies a literal not in the set.** Trust the user's value. Still call the enumerated-values tool if you need to verify the value is in the set before binding.
|
|
495
|
-
- **Value must vary at runtime.** If the value genuinely depends on caller input, prior flow data, or a computed expression, use `elementReference` to a variable, formula, or upstream element output. The rule only forbids indirection for *known-at-design-time* literals.
|
|
496
|
-
- **Upstream dependency unresolvable.** If the upstream input itself is a flow variable whose value isn't known at design time, skip enum resolution for the dependent subfield — leave it unset. `subfieldEnums` validation is design-time guidance, not a save-time requirement.
|
|
497
|
-
|
|
498
|
-
#### Why this matters
|
|
499
|
-
|
|
500
|
-
- The enum set is **org-specific** (named-connection IDs, dependent record types, configured options). Only the live tool reflects what this org accepts.
|
|
501
|
-
- Indirection adds noise to the metadata and obscures the design intent: a literal pinned at the input documents itself.
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
## Metadata Shape
|
|
505
|
-
|
|
506
|
-
Elements of this type live in `metadata.actionCalls[]`. Each entry:
|
|
507
|
-
|
|
508
|
-
| Field | Type | Required | Notes |
|
|
509
|
-
|---|---|---|---|
|
|
510
|
-
| `name` | string | yes | dev-name; unique; ≤ 80 chars |
|
|
511
|
-
| `label` | string | yes | display label |
|
|
512
|
-
| `actionName` | string | yes | action API name (`emailSimple`, `<MyApexClass>`, etc.) |
|
|
513
|
-
| `actionType` | string | yes | one of ~70 enum values (e.g. `apex`, `emailSimple`, `emailAlert`, `flow`, `chatterPost`, `submitForApproval`) |
|
|
514
|
-
| `nameSegment` | string | derived | mirrors `actionName` |
|
|
515
|
-
| `inputParameters` | array | yes | resolved from `getInvocableActionDetails` |
|
|
516
|
-
| `outputParameters` | array | conditional | `[]` when `storeOutputAutomatically: true` |
|
|
517
|
-
| `storeOutputAutomatically` | boolean | no | omit when the org doesn't support automatic output handling |
|
|
518
|
-
| `connector` | Connector | yes | single outgoing edge |
|
|
519
|
-
| `faultConnector` | Connector | conditional | Mandatory for fault-capable actions, except in a marketing flow (only when the user asks for error handling); apply the action-specific persisted shape first |
|
|
520
|
-
| `timeoutConnector` | Connector | conditional | async-with-timeout actions only |
|
|
521
|
-
| `flowTransactionModel` | string | yes | `"Automatic"`, `"CurrentTransaction"`, or `"NewTransaction"` — always emitted; no default |
|
|
522
|
-
| `actionCallPaths` | array | conditional | multi-path actions (e.g. `EinsteinDecidePath`) |
|
|
523
|
-
| `timeoutPathUsage` | string | conditional | `"EnableTimeoutPath"` for async-with-timeout |
|
|
524
|
-
| `dataTypeMappings` | array | conditional | One entry per generic placeholder; emit only when the action describe returns non-empty `genericTypes[]` |
|
|
525
|
-
|
|
526
|
-
### `dataTypeMappings` Entry Shape
|
|
527
|
-
|
|
528
|
-
| Field | Type | Required | Notes |
|
|
529
|
-
|---|---|---|---|
|
|
530
|
-
| `typeName` | string | conditional | placeholder name from `genericTypes[].name`; required unless `valueMappingKey` is set (XOR) |
|
|
531
|
-
| `typeValue` | string | conditional | concrete sObject API name (`Account`, `Custom__c`); one-of {`typeValue`, `apexClass`, `schemaUri`} |
|
|
532
|
-
| `apexClass` | string | conditional | concrete Apex class API name; one-of {`typeValue`, `apexClass`, `schemaUri`} |
|
|
533
|
-
| `schemaUri` | string | conditional | remote schema URI; one-of {`typeValue`, `apexClass`, `schemaUri`} |
|
|
534
|
-
| `valueMappingKey` | string | conditional | value-mapping variant; XOR with `typeName` |
|
|
535
|
-
| `valueMappingTarget` | string | conditional | required when `valueMappingKey` is set; must not equal `valueMappingKey` |
|
|
536
|
-
| `valueMappingTransformType` | `FlowValueMappingType` | conditional | required when `valueMappingKey` is set |
|
|
537
|
-
|
|
538
|
-
### `dataTypeMappings` Examples
|
|
539
|
-
|
|
540
|
-
One entry per placeholder from `genericTypes[]`. Pick the value field by what the resolved type actually is — never guess, always resolve via `GET /services/data/vXX.0/flowbuilder/action/invocable-action-generic-type-enum-values` first (see [Generic-Type Placeholders](#generic-type-placeholders-u__-t__)).
|
|
541
|
-
|
|
542
|
-
```json
|
|
543
|
-
// Apex class resolved — use apexClass
|
|
544
|
-
"dataTypeMappings": [
|
|
545
|
-
{ "typeName": "U__output", "apexClass": "MyNamespace__SomeApexWrapper" }
|
|
546
|
-
]
|
|
547
|
-
|
|
548
|
-
// sObject resolved — use typeValue
|
|
549
|
-
"dataTypeMappings": [
|
|
550
|
-
{ "typeName": "T__body", "typeValue": "Account" }
|
|
551
|
-
]
|
|
552
|
-
|
|
553
|
-
// remote schema resolved — use schemaUri
|
|
554
|
-
"dataTypeMappings": [
|
|
555
|
-
{ "typeName": "T__request", "schemaUri": "AutomationSchema:SchemaAction/schemaType" }
|
|
556
|
-
]
|
|
557
|
-
|
|
558
|
-
// multiple placeholders on one action — resolve and emit every one
|
|
559
|
-
"dataTypeMappings": [
|
|
560
|
-
{ "typeName": "T__issueType", "apexClass": "JiraV2__IssueTypeWrapper" },
|
|
561
|
-
{ "typeName": "T__project", "typeValue": "Custom_Project__c" }
|
|
562
|
-
]
|
|
563
|
-
|
|
564
|
-
// value-mapping variant — valueMappingKey XOR typeName
|
|
565
|
-
"dataTypeMappings": [
|
|
566
|
-
{
|
|
567
|
-
"valueMappingKey": "SourceField__c",
|
|
568
|
-
"valueMappingTarget": "TargetField__c",
|
|
569
|
-
"valueMappingTransformType": "DirectMap"
|
|
570
|
-
}
|
|
571
|
-
]
|
|
572
|
-
```
|
|
573
|
-
|
|
574
|
-
Wrong vs. right — the two mistakes that produce the vague top-level rejection or a silent generic-placeholder leak:
|
|
575
|
-
|
|
576
|
-
```jsonc
|
|
577
|
-
// WRONG — field name typo'd; server rejects the whole flow generically
|
|
578
|
-
"dynamicTypeMappings": [{ "typeName": "U__output", "apexClass": "MyClass" }]
|
|
579
|
-
|
|
580
|
-
// WRONG — two value variants set at once (must be exactly one)
|
|
581
|
-
{ "typeName": "U__output", "apexClass": "MyClass", "typeValue": "Account" }
|
|
582
|
-
|
|
583
|
-
// WRONG — unresolved placeholder string left as the value
|
|
584
|
-
{ "typeName": "U__output", "apexClass": "U__output" }
|
|
585
|
-
|
|
586
|
-
// RIGHT — one field name, one value variant, concrete resolved value
|
|
587
|
-
{ "typeName": "U__output", "apexClass": "MyNamespace__SomeApexWrapper" }
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
### Key rules
|
|
591
|
-
|
|
592
|
-
- **`faultConnector` is mandatory for fault-capable actions.** Action calls can fail at runtime (DML, callout, governor limits). Apply the action-specific persisted shape before this generic rule. In a marketing flow, emit it only when the user asks for error handling (see [Fault Path](#fault-path)).
|
|
593
|
-
- **`actionType: "flow"` is forbidden** — calling a subflow via `actionCalls` with `actionType: "flow"` has subtly different semantics. Always use top-level `subflows[]` instead.
|
|
594
|
-
- **`storeOutputAutomatically: true` ⇒ `outputParameters: []`.** If the org does not support automatic output handling, omit `storeOutputAutomatically` entirely and populate `outputParameters` manually.
|
|
595
|
-
- **`actionType: "emailAlert"` forces `storeOutputAutomatically: false** regardless of org settings.
|
|
596
|
-
- **Generic types** (placeholders starting with `U__` or `T__`): if `genericTypes[]` from the action drill-down is non-empty, EVERY entry must be resolved to a concrete type and emitted as a `dataTypeMappings[]` row before saving. The placeholder `name` (e.g. `T__body`, `U__output`) goes verbatim into `dataTypeMappings[].typeName`; the resolved concrete value goes into exactly one of `typeValue` (sObject) / `apexClass` / `schemaUri`. Parameters whose `apexClass`, `sobjectType`, or `schemaUri` field equals the placeholder name are pointing at that mapping — their input shape comes from the resolved class/sObject/schema. Leaving any `U__*` / `T__*` string in saved metadata causes a server rejection. Resolve via `GET /services/data/vXX.0/flowbuilder/action/invocable-action-generic-type-enum-values`; if its `typeProviders.status` is `ERROR` (managed-package / external-system failure on this org), fall back to the static apex catalog (`GET /services/data/vXX.0/flowbuilder/resource/apex-types`) to find the corresponding per-ESR materialized class (e.g. `ExternalConnect.<ESR>_<action>MetadataProvider...` for External Connector actions).
|
|
597
|
-
- **Enum-resolved values bind as literals.** When a value comes from `GET /services/data/vXX.0/flowbuilder/action/invocable-action-parameter-enum-values`, write it directly at `inputParameters[].value` as `{ "stringValue": "..." }`. Do not introduce a `String` variable just to hold the enum value and reference it via `elementReference` — see "Picking the value to assign" above for the right/wrong examples.
|
|
598
|
-
- **Async-with-timeout** actions emit `connector` + `timeoutConnector` + `timeoutPathUsage: "EnableTimeoutPath"`.
|
|
599
|
-
- **Multi-path actions** (e.g. `EinsteinDecidePath`) emit `actionCallPaths[]`. The `pathName === "DEFAULT"` entry corresponds to the regular `connector`; non-default paths live only in `actionCallPaths[]`.
|
|
600
|
-
- **`dataTypeMappings` only on generic actions.** When `genericTypes[]` is empty, omit the field (or emit `[]`); a stray entry is rejected. One entry per non-`NamedAutomationSchema` placeholder; `NamedAutomationSchema` is the only optional case. **Every emitted `typeName` MUST equal one of the action's `genericTypes[].name` placeholder strings verbatim — never an output- or param-name (e.g. `SuccessMessage`); a name that matches no declared placeholder is rejected at save (see § Save-time rejections).**
|
|
601
|
-
- **One value variant per `dataTypeMappings` entry.** Exactly one of `typeValue` / `apexClass` / `schemaUri`; values must be concrete (no `U__*` / `T__*` strings).
|
|
602
|
-
- **`typeName` XOR `valueMappingKey`.** Value-mapping entries also require `valueMappingTarget` + `valueMappingTransformType` and `key != target`.
|
|
603
|
-
- **Dynamic types require process-type support and API version ≥ 48.0.**
|
|
604
|
-
|
|
605
|
-
### `flowTransactionModel` is action-specific
|
|
606
|
-
|
|
607
|
-
`flowTransactionModel` is always emitted. For the actions below specifically,
|
|
608
|
-
**do not copy a value across actions** — each rejects one of the two values,
|
|
609
|
-
and copying the wrong one fails validation with
|
|
610
|
-
`ACTIONCALL_TRANSACTION_MODEL_NOT_ALLOWED`. Check the target action before
|
|
611
|
-
binding:
|
|
612
|
-
|
|
613
|
-
| Action | Allowed `flowTransactionModel` |
|
|
614
|
-
|---|---|
|
|
615
|
-
| `sendEmailMessage` (UMS email) | `Automatic` |
|
|
616
|
-
| `emailSimple` (stock Send Email) | `CurrentTransaction` only (rejects `Automatic`) |
|
|
617
|
-
| `sendSmsMessage` (E360) | `CurrentTransaction` (supports `Automatic` too) |
|
|
618
|
-
| `exitIndividualsFromFlow` | `CurrentTransaction` (rejects `Automatic`) |
|
|
619
|
-
| LWC local actions (`lwcComponent`) | `CurrentTransaction` |
|
|
620
|
-
|
|
621
|
-
Extend this table as new actions are verified. For any action not listed
|
|
622
|
-
here, check the describe's `allowsTransactionControl`: when `true`, either
|
|
623
|
-
`Automatic` or `CurrentTransaction` is generally accepted (verify against the
|
|
624
|
-
specific action); when `false`, **omit `flowTransactionModel` entirely** —
|
|
625
|
-
emitting it against an action that doesn't support transaction control produces invalid
|
|
626
|
-
action metadata (e.g. `sendConversationMessages`, see
|
|
627
|
-
[Conversation Messaging Action](#conversation-messaging-action)).
|
|
628
|
-
|
|
629
|
-
### Save-time rejections
|
|
630
|
-
|
|
631
|
-
- `Required input parameter '<name>' is missing`
|
|
632
|
-
- `Output parameter '<name>' is not valid for this action when storeOutputAutomatically is true`
|
|
633
|
-
- `Action '<actionName>' of type '<actionType>' not found`
|
|
634
|
-
- Unresolved `U__input` / `U__output` placeholders in saved metadata
|
|
635
|
-
- `Connector '<name>' not found` (HTTP Callout / named credential)
|
|
636
|
-
- `dataTypeMappings` entry missing `typeName` / `valueMappingKey`, or with both set
|
|
637
|
-
- `dataTypeMappings` entry with multiple of `typeValue` / `apexClass` / `schemaUri`
|
|
638
|
-
- `dataTypeMappings` `typeValue` / `apexClass` / `schemaUri` not resolvable in this org
|
|
639
|
-
- `valueMappingKey` set without `valueMappingTarget` or `valueMappingTransformType`, or `key == target`
|
|
640
|
-
- Dynamic types not supported by this process type, or API version < 48.0
|
|
641
|
-
- **Generic top-level `{"errorCode":"ILLEGAL_QUERY_PARAMETER_VALUE","message":"The flow property is not a valid flow definition."}`** — unlike the specific errors above, this gives no field name or reason. Seen when an `actionCalls[]` entry uses a wrong/misspelled top-level field name (e.g. `dynamicTypeMappings` instead of `dataTypeMappings`) — the payload isn't recognized as a valid flow shape at all, so it fails generically instead of naming the bad field. If a save rejects with this vague error and everything else looks right, binary-search the payload (trim elements down via `saveType: "createNewFlow"` on a minimal copy) to isolate which top-level field name is wrong, rather than guessing at content-level fixes.
|
|
642
|
-
|
|
643
|
-
### Fixing repeated validation failures — resolve, don't retry blind
|
|
644
|
-
|
|
645
|
-
When `validate_flow`/`POST /services/data/vXX.0/flowbuilder/flow/actions/save` returns an error tied to a specific element, resolve it with the matching MCP discovery tool before re-submitting the same payload:
|
|
646
|
-
|
|
647
|
-
| Error signals | Fix by calling |
|
|
648
|
-
|---|---|
|
|
649
|
-
| `DYNAMIC_TYPE_MAPPING_MISSING` | `GET /services/data/vXX.0/flowbuilder/action/invocable-action-generic-type-enum-values` — resolve the named placeholder to a concrete `apexClass`/`typeValue`/`schemaUri`, emit `dataTypeMappings[]` |
|
|
650
|
-
| `ACTIONCALL_INVALID_ISWAITUNTILCOMPLETED` / `ACTIONCALL_MISSING_OFFSET` | No lookup needed — the action's `isAsync: true` from `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` already told you to add `isWaitUntilCompleted`/`offset`/`offsetUnit` |
|
|
651
|
-
| Unresolved dependent enum (`NOT_ENOUGH_INFO` on a param) | `GET /services/data/vXX.0/flowbuilder/action/invocable-action-parameter-enum-values` |
|
|
652
|
-
| `Action '<name>' of type '<type>' not found` | Re-run `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/action/invocable-actions")` with the flow's exact `processType`/`triggerType` — the action may be filtered out for this context |
|
|
653
|
-
|
|
654
|
-
Re-validate after each targeted fix rather than changing multiple guessed fields at once — each error usually names exactly one field or one missing declaration.
|
|
655
|
-
|
|
656
|
-
**Stray / mismatched `dataTypeMappings` value — verbatim platform errors.** Both fire on an action-call carrying a `dataTypeMappings[]` entry whose `typeName` is not a real `genericTypes[].name` placeholder — most often an output- or param-like name (e.g. `SuccessMessage`) emitted on a **non-generic** action (empty `genericTypes[]`):
|
|
657
|
-
|
|
658
|
-
| Platform error (verbatim) | Cause | Fix |
|
|
659
|
-
|---|---|---|
|
|
660
|
-
| `In Apex action "<label>", type mapping "<X>" is not a supported type.` | Value `<X>` doesn't resolve to a real type (stray / placeholder-looking). | Remove the mapping if the action is non-generic; else set a concrete value for the matching generic param. |
|
|
661
|
-
| `Data type mapping "<X>" isn't referenced in action "<apiName>".` | `typeName` matches no generic param (e.g. a mapping on a non-generic action). | Remove the stray mapping; only map declared `genericTypes[].name`. |
|
|
662
|
-
|
|
663
|
-
Either string can fire depending on the stray value: an unresolvable value trips *is not a supported type*; a resolvable-but-unreferenced value trips *isn't referenced in action*. See § Key rules (the `dataTypeMappings` hard guard) and `validators.md`.
|
|
664
|
-
|
|
665
|
-
**Missing mapping when the action IS generic — the inverse failure.** The mapping is not merely optional-when-present: when `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` returns a **non-empty `genericTypes[]`**, a `dataTypeMappings[]` entry is **required** for every non-`NamedAutomationSchema` placeholder, and the flow will **not save** until each is set to a concrete type. This is the "generic type wasn't set when it should have been" case:
|
|
666
|
-
|
|
667
|
-
| Platform error | Cause | Fix |
|
|
668
|
-
|---|---|---|
|
|
669
|
-
| `Enter a value for data type mapping "<placeholder>" in Apex action "<label>".` (Core label `ActionCallDataTypeMappingMissing`; the generic **Data type mapping required** validator in `validators.md` — *"The action requires a data type mapping."* — covers the same save-blocking condition). | The action's describe has a non-empty `genericTypes[]`, but the action call emits no matching `dataTypeMappings[]` entry — or leaves an unresolved `U__*` / `T__*` placeholder string in the saved metadata (see the *Unresolved `U__input` / `U__output` placeholders* entry above). | Emit one `dataTypeMappings[]` entry per placeholder: set `typeName` to the `genericTypes[].name`, and exactly one of `typeValue` (sObject) / `apexClass` (Apex class) / `schemaUri` to the concrete type resolved via `GET /services/data/vXX.0/flowbuilder/action/invocable-action-generic-type-enum-values`. |
|
|
670
|
-
|
|
671
|
-
Rule of thumb (both directions): `dataTypeMappings` presence tracks `genericTypes[]` — **each non-`NamedAutomationSchema` placeholder in a non-empty `genericTypes[]` requires a mapping; `NamedAutomationSchema` placeholders (e.g. `ContentSchema`) stay optional and may be omitted; empty `genericTypes[]` ⇒ no mapping (a stray one is rejected).**
|
|
672
|
-
|
|
673
|
-
### Activation-time rejections (save succeeds, activate fails)
|
|
674
|
-
|
|
675
|
-
- `WARNING_BLOCK_ACTIVATION: <elementName> (Action) — A record-triggered flow can't execute actions that make external callouts in a path that runs immediately. Remove this element from the flow, or move it to a scheduled path.` — emitted when `hasCallout: true` action sits on the immediate path of a record-triggered flow. Move the action under a `scheduledPaths[]` entry on the Start element to clear.
|
|
676
|
-
|
|
677
|
-
## JSON Example
|
|
678
|
-
|
|
679
|
-
```json
|
|
680
|
-
{
|
|
681
|
-
"name": "Send_Welcome_Email",
|
|
682
|
-
"label": "Send Welcome Email",
|
|
683
|
-
"locationX": 200,
|
|
684
|
-
"locationY": 100,
|
|
685
|
-
"actionType": "emailSimple",
|
|
686
|
-
"actionName": "emailSimple",
|
|
687
|
-
"nameSegment": "emailSimple",
|
|
688
|
-
"flowTransactionModel": "CurrentTransaction",
|
|
689
|
-
"storeOutputAutomatically": true,
|
|
690
|
-
"inputParameters": [
|
|
691
|
-
{ "name": "emailAddresses", "value": { "elementReference": "varRecipient" } },
|
|
692
|
-
{ "name": "emailSubject", "value": { "stringValue": "Welcome" } },
|
|
693
|
-
{ "name": "emailBody", "value": { "elementReference": "tplWelcome" } }
|
|
694
|
-
],
|
|
695
|
-
"outputParameters": [],
|
|
696
|
-
"connector": { "targetReference": "end_path", "isGoTo": false },
|
|
697
|
-
"faultConnector": { "targetReference": "Log_Error", "isGoTo": false }
|
|
698
|
-
}
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
## Exit from a Flow (`exitIndividualsFromFlow`)
|
|
702
|
-
|
|
703
|
-
Add this element to `metadata.actionCalls[]`. Never add it to `metadata.subflows[]`.
|
|
704
|
-
|
|
705
|
-
This action is supported only in a Segment-triggered marketing flow. Load `../start/segment-triggered.md` and follow its process-type, segment-binding, schedule, data-space, timezone, and data-graph rules before authoring this action. Do not reuse the Exit action's target flow as the authoring segment unless the user explicitly asked for that configuration.
|
|
706
|
-
|
|
707
|
-
1. If no resource containing the Data Cloud Individual ID is named, ask for that resource and stop. Do not perform discovery, author an action, validate, or save until the answer identifies a real flow resource.
|
|
708
|
-
2. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/action/invocable-action-details", queryParams: { actionName: "exitIndividualsFromFlow", actionType: "exitIndividualsFromFlow" })` before emitting metadata. This special action may not appear in the generic invocable-action catalog, so do not treat catalog omission as proof that it is unsupported.
|
|
709
|
-
3. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/flow/subflows", queryParams: { subflowFilterType: "MARKETING" })` to discover eligible targets. Match a named target by `fullName` or `label`; when the user did not name one, ask them to choose from the filtered results. Never select a record-triggered, screen, or scheduled flow. Treat running-version status as unverified until the action describe, save, activation, or runtime response confirms it.
|
|
710
|
-
4. Bind `inputParameters[].value.elementReference` for `IndividualId` to the confirmed real flow resource. Never emit a placeholder value.
|
|
711
|
-
5. Add a `faultConnector` only if the user asks for error handling; a Segment flow is a marketing flow (see [Fault Path](#fault-path)). When asked, route it to a real named handler, such as a `Capture_Exit_Fault` Assignment that stores `$Flow.FaultMessage` in a Text variable; no bare end element exists. Because a Segment flow is headless, a bare capture is in-memory-only — for observability, follow it with a persistence/notification step (advisory; see `shared/fault-paths/fault-paths.md` § Observable vs. In-Memory-Only Fault Handling). Handle failures caused by an unsupported target type, no running target version, or missing user access.
|
|
712
|
-
|
|
713
|
-
Ask which target flow to exit when it is not named. Ask whether to exit one running version or all running versions of that target. Ask for the resource that contains the Data Cloud Individual ID when no existing resource is named.
|
|
714
|
-
|
|
715
|
-
**Required-input preflight:** if the target flow is named but no `IndividualId` source is named, ask only: "Which flow resource contains the Data Cloud Individual ID for the customer?" Stop and wait for that answer. Never invent a literal, use `PLACEHOLDER`, or substitute a CRM User, Contact, or Account ID.
|
|
716
|
-
|
|
717
|
-
Never emit `exitFromFlow`, `exitJourney`, `removeFromFlow`, `exitFlowParticipant`, or a `FlowInterview` query/delete. Emit only `actionType: "exitIndividualsFromFlow"` for this behavior.
|
|
718
|
-
|
|
719
|
-
Never place this action after Create, Update, or Delete Records in the same transaction: the action rejects pending DML. Put the exit on a process-type-supported separate transaction boundary, then confirm the resulting flow structure. `flowTransactionModel: "CurrentTransaction"` does not create a boundary.
|
|
720
|
-
|
|
721
|
-
| Version scope | `actionName` | `FlowVersionId` |
|
|
722
|
-
|---|---|---|
|
|
723
|
-
| All running versions | Selected target flow API name | Leave unset or empty |
|
|
724
|
-
| One running version | Selected target flow API name | Set to a running version ID returned for that target |
|
|
725
|
-
|
|
726
|
-
Set `actionType: "exitIndividualsFromFlow"`. Set `actionName` to the selected target flow API name. Set `flowTransactionModel: "CurrentTransaction"`; this action rejects `"Automatic"`. Do not persist `FlowApiName` or `flowApiName`; the editor uses it only as a synthetic selector. Do not use `nameSegment` as target-flow identity.
|
|
727
|
-
|
|
728
|
-
Set `storeOutputAutomatically: true` and `outputParameters: []` when automatic output handling is available. Otherwise, resolve the live types before assigning `ExitStatuses`, `FlowVersionId`, `isSuccess`, or `IndividualId` manually.
|
|
729
|
-
|
|
730
|
-
Treat a successful draft-save as insufficient evidence of activation or runtime support. Report feature-gate, target-flow-type, and user-permission failures from the describe, save, activation, or runtime response.
|
|
731
|
-
|
|
732
|
-
Use `examples/exit-from-flow.json` as an `actionCalls[]` fragment. Add the referenced `IndividualId` resource and `connector.targetReference` success target to the complete flow. The fragment has no `faultConnector`; add one and its handler only when the user asks for error handling. Replace the example target names with real elements in the authored flow.
|
|
733
|
-
|
|
734
|
-
## Send to Journey (`sendToJourney`)
|
|
735
|
-
|
|
736
|
-
Before authoring this action, load `send-to-journey.md` and follow it. That file
|
|
737
|
-
owns business-unit and Journey selection, Journey Builder-context DE schema
|
|
738
|
-
resolution, required-field mapping, and the persisted action shape.
|
|
739
|
-
|
|
740
|
-
## LWC Local Actions (`actionType: "lwcComponent"`)
|
|
741
|
-
|
|
742
|
-
A handful of stock actions run **client-side in the browser** rather than as a server callout. In the metadata they are still `actionCalls[]` entries, distinguished by `actionType: "lwcComponent"`. The two most common are:
|
|
743
|
-
|
|
744
|
-
| Action (`actionName` / `nameSegment`) | What it does |
|
|
745
|
-
|---|---|
|
|
746
|
-
| `flowruntime:showToastMessage` | Pops a Lightning **toast** notification (the "show a success/error message" pattern). |
|
|
747
|
-
| `flowruntime:openAPage` | **Navigates** the browser. Opening an external URL (`pageType: "WebPage"`) is verified live; the action also supports other page targets (record, list view, etc.) that are documented but not verified here. |
|
|
748
|
-
|
|
749
|
-
These are the correct answer when a screen flow needs to *tell the user something* (toast) or *send them somewhere* (open a page) as a step on the canvas — not a screen field. They only work at runtime in a Lightning context (Lightning app/console, a community, the mobile app); they are inert in other runtimes.
|
|
750
|
-
|
|
751
|
-
### How local actions differ from server actions
|
|
752
|
-
|
|
753
|
-
- **No `faultConnector`.** They run in the browser with no callout/DML, so there is no fault path — omit it entirely. The server neither requires nor auto-adds one; verified live.
|
|
754
|
-
- **No output.** Always `storeOutputAutomatically: false` and `outputParameters: []` — nothing comes back into the flow.
|
|
755
|
-
- `flowTransactionModel: "CurrentTransaction"`, `isWaitUntilCompleted: false`.
|
|
756
|
-
- The component must exist in the org. `flowruntime:showToastMessage` and `flowruntime:openAPage` are stock and surface via `getDynamicInvocableActionsForType` (type `lwcComponent`), so they are available in Screen flows without any deploy.
|
|
757
|
-
- Input values accept literals or merge fields exactly like any other action — e.g. a toast body of `"Hello {!userName}, your flow ran successfully."` interpolates a screen input at runtime.
|
|
758
|
-
|
|
759
|
-
### `flowruntime:showToastMessage` inputs
|
|
760
|
-
|
|
761
|
-
| Param | Type | Notes |
|
|
762
|
-
|---|---|---|
|
|
763
|
-
| `toastMessageTitle` | string | Bold heading of the toast. Optional. |
|
|
764
|
-
| `toastMessageBody` | string | Body text; supports merge fields. Optional. |
|
|
765
|
-
| `dismissalMethod` | string | `"Auto"` (auto-fades) or `"Manual"` (user must close). |
|
|
766
|
-
| `toastMessageStyle` | string | `"Information"`, `"Success"`, `"Warning"`, or `"Error"` — drives icon/color (all four verified live). The value is enforced by the component, not at save/activate, so stick to these four. |
|
|
767
|
-
| `toastMessageBodyLinks` | Apex | Optional embedded links (advanced; usually omitted). |
|
|
768
|
-
|
|
769
|
-
> The builder's CPE may add `"inputConfiguratorMode": "Custom"` onto the `toastMessageStyle` value object when you edit it in the UI. It is **not required** — a plain `{ "stringValue": "Success" }` saves and activates fine.
|
|
770
|
-
|
|
771
|
-
### `flowruntime:openAPage` inputs
|
|
772
|
-
|
|
773
|
-
| Param | Type | Notes |
|
|
774
|
-
|---|---|---|
|
|
775
|
-
| `pageType` | string | The navigation target kind. Only `"WebPage"` is verified here; other kinds (record, list view, etc.) exist but were not probed and likely take their own companion params — confirm against `getInvocableActionDetails` before relying on them. |
|
|
776
|
-
| `webPageUrl` | string | The URL to open when `pageType` is `"WebPage"` (verified). |
|
|
777
|
-
|
|
778
|
-
### JSON Example (verified: saves AND activates)
|
|
779
|
-
|
|
780
|
-
Chained on a screen flow — `Start → Screen → Show_Toast → Open_Page → End`:
|
|
781
|
-
|
|
782
|
-
```jsonc
|
|
783
|
-
{
|
|
784
|
-
"name": "Show_Toast",
|
|
785
|
-
"label": "Show Toast",
|
|
786
|
-
"actionType": "lwcComponent",
|
|
787
|
-
"actionName": "flowruntime:showToastMessage",
|
|
788
|
-
"nameSegment": "flowruntime:showToastMessage",
|
|
789
|
-
"flowTransactionModel": "CurrentTransaction",
|
|
790
|
-
"storeOutputAutomatically": false,
|
|
791
|
-
"isWaitUntilCompleted": false,
|
|
792
|
-
"inputParameters": [
|
|
793
|
-
{ "name": "toastMessageTitle", "value": { "stringValue": "Welcome!" } },
|
|
794
|
-
{ "name": "toastMessageBody", "value": { "stringValue": "Hello {!userName}, your flow ran successfully." } },
|
|
795
|
-
{ "name": "dismissalMethod", "value": { "stringValue": "Auto" } },
|
|
796
|
-
{ "name": "toastMessageStyle", "value": { "stringValue": "Success" } }
|
|
797
|
-
],
|
|
798
|
-
"outputParameters": [],
|
|
799
|
-
"connector": { "targetReference": "Open_Page" }
|
|
800
|
-
// no faultConnector — client-side action
|
|
801
|
-
}
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
```jsonc
|
|
805
|
-
{
|
|
806
|
-
"name": "Open_Page",
|
|
807
|
-
"label": "Open Page",
|
|
808
|
-
"actionType": "lwcComponent",
|
|
809
|
-
"actionName": "flowruntime:openAPage",
|
|
810
|
-
"nameSegment": "flowruntime:openAPage",
|
|
811
|
-
"flowTransactionModel": "CurrentTransaction",
|
|
812
|
-
"storeOutputAutomatically": false,
|
|
813
|
-
"isWaitUntilCompleted": false,
|
|
814
|
-
"inputParameters": [
|
|
815
|
-
{ "name": "pageType", "value": { "stringValue": "WebPage" } },
|
|
816
|
-
{ "name": "webPageUrl", "value": { "stringValue": "https://www.salesforce.com" } }
|
|
817
|
-
],
|
|
818
|
-
"outputParameters": [],
|
|
819
|
-
"connector": { "targetReference": "END_Flow" }
|
|
820
|
-
}
|
|
821
|
-
```
|
|
822
|
-
|
|
823
|
-
## `contentId` Rule (Marketing Messaging Actions)
|
|
824
|
-
|
|
825
|
-
Applies to `sendEmailMessage`, `sendMobileAppMessage`, `sendMobileAppInAppMessage`, `sendRcsMessage`, `sendSmsMessage`, `sendWhatsAppMessage`.
|
|
826
|
-
|
|
827
|
-
- **Never fabricate or guess a `contentId`.** An unresolvable value hard-fails the save (`Invalid Managed Content Key!`).
|
|
828
|
-
- **Discover SMS, RCS, and email content before omitting `contentId`.** Follow the CMS workflow below whenever `dispatch_readonly` is available (all CMS reads route through it). For `sendEmailMessage`, see [CMS discovery for Email](#cms-discovery-for-email-sendemailmessage).
|
|
829
|
-
- **Bind only a resolved FQN.** Pass the selected CMS row's `managedContentId` to `GET /services/data/vXX.0/flowbuilder/messaging/content-fqn`, then bind its non-empty `contentFqn` as `{ "stringValue": "<contentFqn>" }`.
|
|
830
|
-
- **Omit unresolved content.** Omit `contentId` only when CMS discovery is unavailable, returns no eligible row, or `GET /services/data/vXX.0/flowbuilder/messaging/content-fqn` returns no FQN. State that activation remains blocked; never substitute the CMS content key, variant ID, title, URL name, or raw `managedContentId`.
|
|
831
|
-
|
|
832
|
-
### CMS discovery for SMS and RCS
|
|
833
|
-
|
|
834
|
-
All CMS reads go through `dispatch_readonly`
|
|
835
|
-
against the CMS Connect API (`/connect/cms/...`) and SOQL (`/query`). There is no
|
|
836
|
-
`content-readonly` server. Steps 1, 3, and 4 issue the `dispatch_readonly` reads that replace it
|
|
837
|
-
(steps 2 and 5 are decision/filter steps with no tool call); the channel-delivery
|
|
838
|
-
read in step 4 is the authoritative **channel-publication** proof.
|
|
839
|
-
|
|
840
|
-
1. Select the Marketing **content space (workspace)**. SOQL is the fast path:
|
|
841
|
-
`dispatch_readonly({ url: "/services/data/vXX.0/query", method: "GET", queryParams: { q: "SELECT Id, Name FROM ManagedContentSpace" } })` →
|
|
842
|
-
`records[]`, each `{Id, Name}` (e.g. `"Content Workspace for Marketing Cloud"`).
|
|
843
|
-
(Equivalent Connect read: `GET /connect/cms/spaces`.) Ask the user to choose
|
|
844
|
-
when multiple marketing workspaces match and the request does not identify one.
|
|
845
|
-
2. Pick the content-type FQN matching your action's channel — **do not hardcode
|
|
846
|
-
blindly:** `sfdc_cms__sms` for SMS; `sfdc_cms__multiChannelContent` (RCS) for
|
|
847
|
-
RCS; `sfdc_cms__email` for email (`sendEmailMessage`). It becomes the
|
|
848
|
-
`contentTypeFQN` filter in step 4; if no content of that type surfaces in the
|
|
849
|
-
step-4 delivery read, stop — the workspace has none (this is where the old
|
|
850
|
-
"content type absent" fail-fast now surfaces).
|
|
851
|
-
3. Resolve the messaging **delivery channel**:
|
|
852
|
-
`dispatch_readonly({ url: "/services/data/vXX.0/connect/cms/spaces/<0Zu spaceId>/channels", method: "GET" })` →
|
|
853
|
-
`spaceChannels[]`, each `{channelSummary: {id (0ap…), name, type}}`. Select the
|
|
854
|
-
channel whose `name` is exactly `Marketing Messages`. If no channel or multiple
|
|
855
|
-
channels match, ask the user to select one by channel name and ID.
|
|
856
|
-
4. Read **published content from the delivery channel** — this is the
|
|
857
|
-
publication proof:
|
|
858
|
-
`dispatch_readonly({ url: "/services/data/vXX.0/connect/cms/delivery/channels/<0ap channelId>/contents", method: "GET", queryParams: { contentTypeFQN: "<type>", page: "0", pageSize: "250" } })` →
|
|
859
|
-
`contents[]`, each `{managedContentId, contentKey, contentType.fullyQualifiedName, publishedDate, title, urlName}`. A row here **is** channel-published (it carries a `publishedDate`).
|
|
860
|
-
- When the user names content or supplies keywords, filter these results by
|
|
861
|
-
`title`, or use the channel search route
|
|
862
|
-
`GET /connect/cms/delivery/channels/<channelId>/contents/search` (or
|
|
863
|
-
`/query`) with the same `contentTypeFQN`.
|
|
864
|
-
- A `ManagedContent` SOQL lookup (`SELECT Id, Name, ContentKey, ContentTypeFullyQualifiedName FROM ManagedContent WHERE ContentTypeFullyQualifiedName = '<type>' AND Name = '<title>'`) is a fast name→`managedContentId` path, but `ManagedContent` carries **no publication status** — never bind a row that does not also appear in this channel `contents[]`.
|
|
865
|
-
- Page with `page` from `0` and `pageSize` `1`–`250`. Stop after the first
|
|
866
|
-
empty `contents` collection; do not rely on `nextPageUrl` alone (it can stay
|
|
867
|
-
populated after an empty page).
|
|
868
|
-
5. Require published content. Match a requested title exactly; select one exact
|
|
869
|
-
match automatically, ask among multiple eligible rows, and stop when none
|
|
870
|
-
match. For enumeration, ask the user to choose from the published rows.
|
|
871
|
-
6. Read `managedContentId` from the selected row. Do not use its
|
|
872
|
-
`contentKey`, `id` (`9Ps...` variant), `title`, or `urlName` as `contentId`.
|
|
873
|
-
7. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/messaging/content-fqn")` with that `managedContentId`. Require
|
|
874
|
-
a non-empty `contentFqn`, then bind it to the messaging action's `contentId`.
|
|
875
|
-
Make this call for every content item; don't build the FQN yourself from the
|
|
876
|
-
space name and `contentKey`. The last segment is the item's API name, which is
|
|
877
|
-
often the content key for email but not for SMS (for example
|
|
878
|
-
`…sfdc_cms__sms--Welcome_Drip_1`). The org rejects a guessed FQN
|
|
879
|
-
that doesn't exist, even in a Draft flow: `Failed to get content key by FQN: …`
|
|
880
|
-
on save, `We couldn't find the selected content.` on activation.
|
|
881
|
-
|
|
882
|
-
The Connect routes, SOQL objects, and field names above were verified against a
|
|
883
|
-
live org: `ManagedContentSpace`/`ManagedContent` SOQL, `spaceChannels[]` with
|
|
884
|
-
`channelSummary.{id,name,type}`, and delivery `contents[]` with `managedContentId`,
|
|
885
|
-
`contentKey`, `contentType.fullyQualifiedName`, and `publishedDate`.
|
|
886
|
-
|
|
887
|
-
Read authored CMS content rather than electronic media: SMS and RCS message
|
|
888
|
-
definitions are non-media managed content. Re-run the selected lookup path
|
|
889
|
-
immediately before save and reject a row that is no longer Published.
|
|
890
|
-
|
|
891
|
-
### CMS discovery for Email (`sendEmailMessage`)
|
|
892
|
-
|
|
893
|
-
`sendEmailMessage` (UMS marketing email) needs an **email** CMS content item
|
|
894
|
-
(`sfdc_cms__email`) — not `sfdc_cms__sms` / `sfdc_cms__multiChannelContent`. The
|
|
895
|
-
discovery path mirrors the SMS/RCS workflow above, with two differences:
|
|
896
|
-
|
|
897
|
-
1. In step 2, require `sfdc_cms__email` as the `contentTypeFQN`.
|
|
898
|
-
2. In steps 3–4, do **not** assume a channel name for email — the channel that
|
|
899
|
-
delivers `sfdc_cms__email` varies by org. Identify it by **which channel's
|
|
900
|
-
delivery `contents[]` actually returns `sfdc_cms__email` rows** for the
|
|
901
|
-
step-3 `spaceChannels[]`: run the step-4 read against a candidate channel and
|
|
902
|
-
keep the one whose results include published `sfdc_cms__email` items. (On the
|
|
903
|
-
test org the email items happened to live on the same `Marketing Messages`
|
|
904
|
-
channel as SMS/RCS — treat that as one org's layout, not a default; a distinct
|
|
905
|
-
email channel is equally valid.) If the space-scoped channels read fails, fall
|
|
906
|
-
back to `GET /connect/cms/channels` and filter client-side, still selecting by
|
|
907
|
-
the content-type the channel actually delivers rather than by name.
|
|
908
|
-
|
|
909
|
-
Everything else is identical: page the delivery-channel `contents[]` from `0`,
|
|
910
|
-
require the selected row's `managedContentId` there (its `publishedDate` is the
|
|
911
|
-
publication proof), then resolve it with `GET /services/data/vXX.0/flowbuilder/messaging/content-fqn` and bind the
|
|
912
|
-
returned `contentFqn` to `contentId`.
|
|
913
|
-
|
|
914
|
-
A real published `sfdc_cms__email` item resolves to
|
|
915
|
-
`marketing--Default_Content_Workspace.sfdc_cms__email--<CONTENT_KEY>` and, once
|
|
916
|
-
bound, clears both Content-ID validation warnings on `sendEmailMessage`. Never
|
|
917
|
-
fabricate this value; omit `contentId` (activation stays blocked) when no
|
|
918
|
-
published email content exists.
|
|
919
|
-
|
|
920
|
-
## Mobile App Messaging Actions (E360)
|
|
921
|
-
|
|
922
|
-
Two standard platform invocable actions owned by **E360 Messaging Mobile Push** deliver messages to a mobile app. They are ordinary `actionCalls[]` entries; the agent selects between them by `actionName` alone — there is **no shared action name and no disambiguation logic required**.
|
|
923
|
-
|
|
924
|
-
| Action | `actionName` (emit verbatim) | Enum (`InvocableActionType`) | Min API | Delivery |
|
|
925
|
-
|---|---|---|---|---|
|
|
926
|
-
| **Send Mobile App Message** (push notification) | `sendMobileAppMessage` | `SEND_MOBILE_APP_MESSAGE` | 256 | Push |
|
|
927
|
-
| **Send Mobile App In-App Message** | `sendMobileAppInAppMessage` | `SEND_MOBILE_APP_IN_APP_MESSAGE` | 262 | In-App |
|
|
928
|
-
|
|
929
|
-
> Historic confusion: an earlier note claimed `sendMobileAppMessage` was shared between push and in-app. It is not — the two are distinct registered actions with distinct `actionName` strings. Emit the exact name for the channel you want.
|
|
930
|
-
|
|
931
|
-
### Shared metadata characteristics (both actions)
|
|
932
|
-
|
|
933
|
-
Both actions are registered with identical builder traits, so the same rules apply to each:
|
|
934
|
-
|
|
935
|
-
- **Fault path: only when asked in a marketing flow.** Both declare `hasCallout: true` in the action describe, and both can throw at runtime (record operations, callouts, or governor limits). In a marketing flow, add a `faultConnector` only if the user asks for error handling; in any other flow type, always wire one (see [Fault Path](#fault-path)).
|
|
936
|
-
- **No output.** Both run in the high-scale flow runtime (not core) and return no data. Emit `storeOutputAutomatically: false` with `outputParameters: []` — do not attempt automatic output handling.
|
|
937
|
-
- **Transaction control is supported.** `allowsTransactionControl: true`, `doRollbackOnError: false` — always emit `flowTransactionModel` (no default).
|
|
938
|
-
- **Synchronous.** Neither is async; do **not** emit `timeoutConnector` / `timeoutPathUsage`.
|
|
939
|
-
- **Custom Property Editor.** Each declares a `configurationEditor`
|
|
940
|
-
(`builder_e360_journeys-send-mobile-app-message-editor` /
|
|
941
|
-
`builder_e360_journeys-send-mobile-app-in-app-message-editor`). In the builder UI the CPE
|
|
942
|
-
replaces the standard parameter list — see [Configuration Editors](#configuration-editors-custom-property-editors). When authoring metadata directly, still resolve parameters from `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details`; the CPE does not change the saved `inputParameters[]` shape.
|
|
943
|
-
- **Generic type — `ContentSchema`.** As of core-264 the describe returns a non-empty
|
|
944
|
-
`genericTypes[]` carrying a `ContentSchema` entry, plus an optional `contentSchema` input
|
|
945
|
-
parameter. It is a **design-time authoring aid** for binding values into the selected
|
|
946
|
-
content's variables (merge fields); it is **not consumed by the runtime send path**, so the
|
|
947
|
-
action sends whether or not you map it. Follow the
|
|
948
|
-
[Dynamic Type Mappings](#dynamic-type-mappings-generic-types) rules: resolve it and emit a
|
|
949
|
-
`dataTypeMappings[]` row **if** you want to bind content variables in-flow; otherwise omit it.
|
|
950
|
-
`ContentSchema` resolves to a `NamedAutomationSchema`-typed placeholder in the describe output — it therefore falls under the existing exemption in [Key Rules](#key-rules) ("One entry per non-`NamedAutomationSchema` placeholder; `NamedAutomationSchema` is the only optional case"). You may omit the `dataTypeMappings[]` row for `ContentSchema` without save or activation errors.
|
|
951
|
-
- **Callout + record-triggered flows.** Because `hasCallout: true`: these actions **cannot be used in `RecordBeforeSave` flows** (before-save flows have no scheduled path; deployment or activation is blocked). In **`RecordAfterSave` flows**, they must sit on a **scheduled path** (`scheduledPaths[]` on the Start element), not the immediate path — see [Validation Rules and Constraints](#validation-rules-and-constraints).
|
|
952
|
-
|
|
953
|
-
### Input parameters
|
|
954
|
-
|
|
955
|
-
Parameters are describe-driven — always fetch the live set with
|
|
956
|
-
`GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` before authoring. The core-264 shapes:
|
|
957
|
-
|
|
958
|
-
**`sendMobileAppMessage` (push)**
|
|
959
|
-
|
|
960
|
-
| Param | Type | Required |
|
|
961
|
-
|---|---|---|
|
|
962
|
-
| `mobileAppId` | String | yes |
|
|
963
|
-
| `contentId` | String | yes¹ |
|
|
964
|
-
| `categoryName` | String | no |
|
|
965
|
-
| `contentSchema` | (generic — `ContentSchema`) | no |
|
|
966
|
-
|
|
967
|
-
¹ Required for activation, not draft save — omit when unknown. See the [`contentId` Rule](#contentid-rule-marketing-messaging-actions) above.
|
|
968
|
-
|
|
969
|
-
**`sendMobileAppInAppMessage` (in-app)**
|
|
970
|
-
|
|
971
|
-
| Param | Type | Required |
|
|
972
|
-
|---|---|---|
|
|
973
|
-
| `mobileAppId` | String | yes |
|
|
974
|
-
| `contentId` | String | yes¹ |
|
|
975
|
-
| `messageExpirationType` | String | yes |
|
|
976
|
-
| `messageTrigger` | String | yes |
|
|
977
|
-
| `displayStartDatetime` | String | no |
|
|
978
|
-
| `displayEndDatetime` | String | no |
|
|
979
|
-
| `displayTimezone` | String | no |
|
|
980
|
-
| `displayTimezoneOffset` | Double | no |
|
|
981
|
-
| `dynamicTimeframe` | Integer | no |
|
|
982
|
-
| `dynamicTimeframeUnit` | String | no |
|
|
983
|
-
| `priority` | Integer | no |
|
|
984
|
-
| `messageDelayDisplay` | Integer | no |
|
|
985
|
-
| `messageDelayDisplayUnit` | String | no |
|
|
986
|
-
| `displayControl` | String | no |
|
|
987
|
-
| `displayRepeatFrequency` | String | no |
|
|
988
|
-
| `displayMessageLimit` | Integer | no |
|
|
989
|
-
| `messageSuppressionActions` | String | no |
|
|
990
|
-
| `contentSchema` | (generic — `ContentSchema`) | no |
|
|
991
|
-
|
|
992
|
-
### Worked examples
|
|
993
|
-
|
|
994
|
-
Full `actionCalls[]` entries for both actions live in the example files:
|
|
995
|
-
|
|
996
|
-
- **Push notification:** `examples/push-notification.json` — `sendMobileAppMessage` with `mobileAppId` / `contentId` / `categoryName`, no output, no `faultConnector` (the marketing-flow default).
|
|
997
|
-
- **In-app message:** `examples/in-app-message.json` — `sendMobileAppInAppMessage` adding the required `messageExpirationType` / `messageTrigger`, no output, no `faultConnector` (the marketing-flow default).
|
|
998
|
-
|
|
999
|
-
> **Note:** These are `actionCalls[]` entry fragments, not complete flows. They reference upstream elements (`Get_Push_Content`, `Get_InApp_Content`) that must exist elsewhere in the flow. Do not paste them verbatim as a standalone flow — supply the matching Get Records element to produce a deployable whole. Add a `faultConnector` and its handler (for example `Log_Send_Error`) only when the user asks for error handling or the flow is not a marketing flow.
|
|
1000
|
-
|
|
1001
|
-
### Anti-patterns (agent should reject / flag)
|
|
1002
|
-
|
|
1003
|
-
```jsonc
|
|
1004
|
-
// WRONG #1 (non-marketing flow, or the user asked for error handling) — no fault path. Both actions can throw at runtime.
|
|
1005
|
-
{ "actionName": "sendMobileAppMessage", "connector": { "targetReference": "END_Flow" } }
|
|
1006
|
-
// (missing faultConnector)
|
|
1007
|
-
|
|
1008
|
-
// WRONG #2 — automatic output on an action that returns nothing.
|
|
1009
|
-
{ "actionName": "sendMobileAppInAppMessage", "storeOutputAutomatically": true }
|
|
1010
|
-
// Correct: storeOutputAutomatically: false, outputParameters: []
|
|
1011
|
-
|
|
1012
|
-
// WRONG #3 — timeout path on a synchronous action.
|
|
1013
|
-
{ "actionName": "sendMobileAppMessage",
|
|
1014
|
-
"timeoutConnector": { "targetReference": "On_Timeout" },
|
|
1015
|
-
"timeoutPathUsage": "EnableTimeoutPath" }
|
|
1016
|
-
// Neither action is async — omit timeout entirely.
|
|
1017
|
-
|
|
1018
|
-
// WRONG #4 — inventing a shared/generic name to "cover both channels".
|
|
1019
|
-
{ "actionName": "sendMobileMessage" } // no such action; use the exact channel name
|
|
1020
|
-
```
|
|
1021
|
-
|
|
1022
|
-
> **Verification note.** Metadata above verified against `InvocableActionType.java`,
|
|
1023
|
-
> `MobileAppParameterUtils.java`, `MobileAppInAppParameterUtils.java`, and the two action
|
|
1024
|
-
> classes (`InvocableSendMobileAppMessageAction.java`, `InvocableSendMobileAppInAppMessageAction.java`)
|
|
1025
|
-
> on **core-264** (`p4/264-main`) as of 2026-07. The `ContentSchema` generic type is fully
|
|
1026
|
-
> wired on both actions (each overrides `getInvocableActionGenericTypeEnumeratedValues()`, with
|
|
1027
|
-
> unit-test coverage). Per-org, confirm the concrete `ContentSchema` shape and each action's
|
|
1028
|
-
> available process/trigger types live via `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` before
|
|
1029
|
-
> relying on them.
|
|
1030
|
-
|
|
1031
|
-
## Send Email Message (E360)
|
|
1032
|
-
|
|
1033
|
-
The standard platform invocable action **Send Email Message** (`actionName: sendEmailMessage`) is owned by **E360 Messaging Email** and delivers a marketing/engagement email through the E360 send pipeline. It is an ordinary `actionCalls[]` entry — `actionType`, `actionName`, and `nameSegment` are all the literal string `sendEmailMessage`. Minimum API version **242**. In the builder UI a Custom Property Editor (`configurationEditor: "builder_e360_journeys-send-email-editor"`) replaces the standard parameter list.
|
|
1034
|
-
|
|
1035
|
-
### ⚠️ The two fields agents get wrong most often
|
|
1036
|
-
|
|
1037
|
-
Both failures are **wrong parameter names**. The product concepts "from address" and "communication subscription" do **not** map to input parameters called `fromAddress` / `communicationSubscription`:
|
|
1038
|
-
|
|
1039
|
-
| Product concept | ❌ Name agents wrongly emit | ✅ Real describe parameter(s) | Value shape |
|
|
1040
|
-
|---|---|---|---|
|
|
1041
|
-
| Sender / From | `fromAddress` | **`senderId`** | Literal **record Id** — `{ "stringValue": "<Id>" }` only (no references) |
|
|
1042
|
-
| Consent / subscription | `communicationSubscription` | **`communicationSubscriptionId`** + mandatory **`commSubscriptionChannelTypeId`** | Two literal **record Ids** — both `{ "stringValue": "<Id>" }` |
|
|
1043
|
-
|
|
1044
|
-
Three rules that follow from this — internalize them before authoring:
|
|
1045
|
-
|
|
1046
|
-
1. **The sender is `senderId`, a record Id — not a free-text email.** `senderId` takes the Id of a configured sender record (see the deep dive below). `fromAddress` **is** a real parameter, but it is a *separate, optional, dynamic-from override* that is **not read on the standard send path** — setting it does not set the sender. `fromAddress`/`fromName`/`replyToAddress`/`replyToName` are only consumed by the E360 dynamic-from/reply feature.
|
|
1047
|
-
2. **`communicationSubscriptionId` never travels alone.** If you set it you MUST also set `commSubscriptionChannelTypeId`, or activation fails (`COMMUNICATION_SUBSCRIPTION_CHANNEL_TYPE_ID_MISSING`). Both are **record Ids**, not developer names. The bare `communicationSubscription` (no `Id`) is a Flow *Start* parameter and does not exist on this action.
|
|
1048
|
-
3. **These Ids are NOT in the action describe — look them up.** `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` returns **no** enumerated values / `dependsOn` for `senderId`, `communicationSubscriptionId`, or `commSubscriptionChannelTypeId` — the builder's picklists come from the CPE, not describe. Bind an Id the user supplies; when the user names the sender or the subscription instead, resolve the name with the reads in [Resolve names to Ids](#resolve-names-to-ids). All three are **literal `{stringValue}` record Ids** — **never fabricate an Id**, and **never** bind them via `elementReference`, including to a Get Records lookup in the flow (see anti-pattern WRONG #2). Omit an unknown one to save a draft (they gate *activation*, not draft save — except `senderId`, see below).
|
|
1049
|
-
|
|
1050
|
-
### Shared metadata characteristics
|
|
1051
|
-
|
|
1052
|
-
- **Fault path: only when asked in a marketing flow.** The describe reports `hasCallout: true`; the action performs record work + callouts and throws on validation failures. In a marketing flow, add a `faultConnector` only if the user asks for error handling; in any other flow type (for example a record-triggered flow's scheduled path), always wire one (see [Fault Path](#fault-path)).
|
|
1053
|
-
- **Output.** The action declares a single `messageId` (String) output (populated per recipient). Automatic output handling is therefore available: emit `storeOutputAutomatically: true` with `outputParameters: []`, or switch to manual and assign the `messageId` row. **This differs from the E360 mobile actions, which return nothing.** *(Confirm the org's flow runtime accepts automatic output for this action live via `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` / a save test — see Verification note.)*
|
|
1054
|
-
- **Transaction control is supported.** `allowsTransactionControl: true`, `doRollbackOnError: false` — always emit `flowTransactionModel` (no default).
|
|
1055
|
-
- **Not async.** There is no async trait. The action implements execution *delay* for Send-Time Optimization (`useSto` / `stoTimeFrame`), which is scheduling, not an async wait-for-completion. Do **not** emit `timeoutConnector` / `timeoutPathUsage`.
|
|
1056
|
-
- **Custom Property Editor.** `builder_e360_journeys-send-email-editor`. As with the mobile actions, the CPE only changes the builder UI — when authoring metadata directly, still resolve parameters from `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details`; the CPE does not change the saved `inputParameters[]` shape.
|
|
1057
|
-
- **Generic type — `ContentSchema`.** The describe returns a non-empty `genericTypes[]` carrying one `ContentSchema` entry (schema-URI-typed) whose enumerated values depend on `contentId` and start at `status: NOT_ENOUGH_INFO`. It is a **design-time aid** for binding values into the selected content's merge variables; it is **not required to send**. Resolve it (and emit a `dataTypeMappings[]` row) only if you want to bind content variables in-flow; otherwise omit it — the send works without it. `contentId` must be set before the content schema can resolve.
|
|
1058
|
-
- **Callout + record-triggered flows.** Because `hasCallout: true`: cannot be used in `RecordBeforeSave` flows; in `RecordAfterSave` flows it must sit on a **scheduled path** (`scheduledPaths[]` on Start), not the immediate path — see [Validation Rules and Constraints](#validation-rules-and-constraints).
|
|
1059
|
-
|
|
1060
|
-
### Input parameters (describe-driven — always fetch the live set)
|
|
1061
|
-
|
|
1062
|
-
Only `contentId` is describe-*required*. Several others are effectively required by **save/activation validation** (flagged below). Full list comes from `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details`; the load-bearing subset:
|
|
1063
|
-
|
|
1064
|
-
| Param | Type | Binding | Effectively required? | Notes |
|
|
1065
|
-
|---|---|---|---|---|
|
|
1066
|
-
| `contentId` | String | `{stringValue}` literal | **Yes (save)** | Managed Content **FQN** (`marketing--…sfdc_cms__email--<KEY>`), **not** a bare CMS key. Subject/body/template all come from the content record — they are **not** action inputs. See the [`contentId` Rule](#contentid-rule-marketing-messaging-actions). |
|
|
1067
|
-
| `senderId` | String | `{stringValue}` literal **only** | **Yes (save/activation)** — omitting → `FROM_USER_EMPTY` | The From/sender. Record Id (see deep dive). |
|
|
1068
|
-
| `communicationSubscriptionId` | String | `{stringValue}` literal | Conditional (see deep dive) | CommSubscription record Id. |
|
|
1069
|
-
| `commSubscriptionChannelTypeId` | String | `{stringValue}` literal | Required **iff** `communicationSubscriptionId` is set | CommSubscriptionChannelType record Id. |
|
|
1070
|
-
| `fromAddress` / `fromName` | String | `{stringValue}` **or** `{elementReference}` / merge field | No | Dynamic-from override (feature-gated); **not** the standard sender. |
|
|
1071
|
-
| `replyToAddress` / `replyToName` | String | reference/merge allowed | No | Dynamic reply-to override. |
|
|
1072
|
-
| `clickTracking` / `openTracking` | Boolean | literal | No | Tracking toggles. |
|
|
1073
|
-
| `ccRecipientAddresses` / `isCcEnabled` | String / Boolean | ref allowed / literal | No | CC addresses + toggle. |
|
|
1074
|
-
| `useSto` / `stoTimeFrame` | Boolean / Integer | literal | No | Send-Time Optimization (delayed execution); `stoTimeFrame` in hours. |
|
|
1075
|
-
| `isTemplate` | Boolean | literal | No | Distributed Marketing: treat content as template. |
|
|
1076
|
-
| `locale` | String | Custom/Resource | No | Locale. |
|
|
1077
|
-
| `timeToLive` | Integer | literal (1–1440 min) | No | **Gated** — only present when the email-TTL gate is on. |
|
|
1078
|
-
| `contentSchemaParameter` | (generic `ContentSchema`) | nested schema | No | Hidden content merge-variable schema; resolves after `contentId`. |
|
|
1079
|
-
|
|
1080
|
-
> Implicit inputs (`individualMember`, `idempotencyKey`, `flowId`, `elementName`, `segmentId`, …) are set by the Flow runtime, not the author — do not emit them.
|
|
1081
|
-
|
|
1082
|
-
### `senderId` — the sender (deep dive)
|
|
1083
|
-
|
|
1084
|
-
`senderId` is a **literal String record Id** (`{ "stringValue": "<Id>" }`; references are not accepted — it is a configuration parameter). Accepted Id kinds, resolved in this order:
|
|
1085
|
-
|
|
1086
|
-
1. **OrgWideEmailAddress (OWEA)** Id — must be **verified** (`OWEA_NOT_VERIFIED` otherwise) and accessible to the user.
|
|
1087
|
-
2. **SenderEmailAddress** Id — must have an **active EmailDomainKey** (`SENDER_EMAIL_NOT_ACTIVE` otherwise).
|
|
1088
|
-
3. **User** Id (`005…`) — must be active (`USER_NOT_ACTIVE` otherwise).
|
|
1089
|
-
4. The **DefaultFromAddress sentinel** string.
|
|
1090
|
-
5. *(Legacy fallback only)* a raw email string that matches an email regex; anything else → `FROM_USER_UNKNOWN_ERROR` ("Invalid format for from address"). Discouraged — prefer a record Id.
|
|
1091
|
-
|
|
1092
|
-
Save/activation validation (`SendEmailMessageActionSaveValidator.validateFromAddress`) runs for all orgs and **throws `FROM_USER_EMPTY` when `senderId` is null** — so although describe marks it optional, it is effectively required. Additional cross-checks: E360 standalone orgs require the resolved address to be **DKIM-authenticated** (`EMAIL_ACTIVE_DKIM_REQUIRED`); with Business Units enabled, the from-domain must match the flow's business unit.
|
|
1093
|
-
|
|
1094
|
-
```json
|
|
1095
|
-
{ "name": "senderId", "value": { "stringValue": "0D2XXXXXXXXXXXXXXX" } }
|
|
1096
|
-
```
|
|
1097
|
-
|
|
1098
|
-
Optional dynamic-from override (only when that feature is enabled — does **not** replace `senderId`):
|
|
1099
|
-
|
|
1100
|
-
```json
|
|
1101
|
-
{ "name": "fromAddress", "value": { "elementReference": "Get_Contact.Email" } }
|
|
1102
|
-
```
|
|
1103
|
-
|
|
1104
|
-
### `communicationSubscriptionId` + `commSubscriptionChannelTypeId` — consent (deep dive)
|
|
1105
|
-
|
|
1106
|
-
- `communicationSubscriptionId` is a **`CommSubscription` record Id** (literal). `commSubscriptionChannelTypeId` is a **`CommSubscriptionChannelType` record Id** (literal). Both are Ids, **not** developer names.
|
|
1107
|
-
- **Companion rule:** setting `communicationSubscriptionId` without `commSubscriptionChannelTypeId` fails with `COMMUNICATION_SUBSCRIPTION_CHANNEL_TYPE_ID_MISSING`. Emit both or neither.
|
|
1108
|
-
- **Conditional requiredness:** enforced only on **E360 standalone orgs**, at save and activation. When `communicationSubscriptionId` is null the validator checks whether the content's message purpose requires consent under the org's UMA config — promotional/commercial content typically **requires** it (`COMMUNICATION_SUBSCRIPTION_REQUIRED`); transactional content typically does not. When unknown, omit it (draft saves); supply it before activation for promotional sends.
|
|
1109
|
-
- **Dependency:** comm-sub validation derives the email messaging channel from `senderId`, and the `commSubscriptionChannelType` must resolve to the **email** engagement channel type — so `senderId` must be valid for comm-sub validation to pass.
|
|
1110
|
-
|
|
1111
|
-
```json
|
|
1112
|
-
{ "name": "communicationSubscriptionId", "value": { "stringValue": "0LnXXXXXXXXXXXXXXX" } },
|
|
1113
|
-
{ "name": "commSubscriptionChannelTypeId", "value": { "stringValue": "0LpXXXXXXXXXXXXXXX" } }
|
|
1114
|
-
```
|
|
1115
|
-
|
|
1116
|
-
### Resolve names to Ids
|
|
1117
|
-
|
|
1118
|
-
A request usually names the email, the sender and the subscription ("send our Spring Sale email from Jordan Lee with consent from our Newsletter subscription") instead of giving Ids. Resolve each name with a read-only lookup before you write the action, then bind the Id you found as a literal. Match names exactly. If a name matches nothing, or matches more than one record, ask the user; never pick a near match or fall back to a default.
|
|
1119
|
-
|
|
1120
|
-
| The user names | Look it up | Bind |
|
|
1121
|
-
|---|---|---|
|
|
1122
|
-
| The email | [CMS discovery for Email](#cms-discovery-for-email-sendemailmessage): the published `sfdc_cms__email` row whose `title` is the name, then `GET /services/data/vXX.0/flowbuilder/messaging/content-fqn` with its `managedContentId` | `contentId` = the returned `contentFqn` |
|
|
1123
|
-
| The sender | Run all three SOQL lookups: `SELECT Id, DisplayName, Address FROM OrgWideEmailAddress WHERE DisplayName = '<name>' OR Address = '<name>'`, `SELECT Id, DisplayName FROM SenderEmailAddress WHERE DisplayName = '<name>'` and `SELECT Id, Name, Email FROM User WHERE Name = '<name>' AND IsActive = true`. Bind only when exactly one record matches across all three. If several match (for example an org-wide address and a User both named "Jordan Lee") or none do, ask the user and list each candidate's type, name and address. If the user names the sender type or gives an Id, look up only that. | `senderId` = that `Id` |
|
|
1124
|
-
| The subscription | `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/messaging/communication-subscriptions", queryParams: { channel: "email", contactPointType: "Email" })`. Omit `messagingChannelId` for email: the sender is not a messaging channel, and passing the sender's Id returns an empty list. | The row whose `name` is the name: `id` → `communicationSubscriptionId`, the same row's `channelTypeId` → `commSubscriptionChannelTypeId` |
|
|
1125
|
-
|
|
1126
|
-
`GET /services/data/vXX.0/flowbuilder/action/org-wide-email-addresses` lists the org-wide addresses the running user may send from as plain address strings, without Ids; use the SOQL above for the Id.
|
|
1127
|
-
|
|
1128
|
-
### Other cross-parameter rules
|
|
1129
|
-
|
|
1130
|
-
- **`contentId` is the single source of subject/body/template** — there is no template-vs-subject/body input choice on this action (contrast the platform `emailSimple` action). Validate the content record exists; never fabricate the key.
|
|
1131
|
-
- **Promotional content requires an org physical (postal) address** on the org, else `PROMO_EMAIL_WITH_EMPTY_ORG_ADDRESS` at runtime.
|
|
1132
|
-
- **STO:** when `useSto: true`, `stoTimeFrame` is validated.
|
|
1133
|
-
- **TTL (gated):** literal must be 1–1440 minutes; flow references skip the save-time range check.
|
|
1134
|
-
|
|
1135
|
-
### Worked example
|
|
1136
|
-
|
|
1137
|
-
`examples/send-email-message.json` — a full `actionCalls[]` entry with `senderId` (record Id), `contentId`, and the `communicationSubscriptionId` / `commSubscriptionChannelTypeId` pair, `messageId` via automatic output, and no `faultConnector` (the marketing-flow default).
|
|
1138
|
-
|
|
1139
|
-
> **Note:** This is an `actionCalls[]` fragment, not a complete flow. `contentId` is bound as a resolved `sfdc_cms__email` **FQN literal** (per the [`contentId` Rule](#contentid-rule-marketing-messaging-actions)) — replace `<CONTENT_KEY>` with the real resolved key; never bind a raw CMS managed-content key or an `elementReference`. In a record-triggered flow it must sit on a scheduled path and needs a `faultConnector` to a handler such as `Log_Send_Error`; in a marketing flow, add one only when the user asks for error handling.
|
|
1140
|
-
|
|
1141
|
-
### Anti-patterns (agent should reject / flag)
|
|
1142
|
-
|
|
1143
|
-
```jsonc
|
|
1144
|
-
// WRONG #1 — sender set via a made-up "fromAddress" as a literal email.
|
|
1145
|
-
{ "actionName": "sendEmailMessage",
|
|
1146
|
-
"inputParameters": [ { "name": "fromAddress", "value": { "stringValue": "noreply@acme.com" } } ] }
|
|
1147
|
-
// Correct: set senderId to a verified OWEA / active SenderEmailAddress / User Id.
|
|
1148
|
-
// { "name": "senderId", "value": { "stringValue": "0D2..." } }
|
|
1149
|
-
|
|
1150
|
-
// WRONG #2 — senderId bound to a flow reference (it is literal-only), e.g. a variable or a Get Records
|
|
1151
|
-
// lookup of the sender. Activation fails: The input parameter "Sender ID" cannot contain element references or merge fields.
|
|
1152
|
-
{ "name": "senderId", "value": { "elementReference": "varSenderId" } }
|
|
1153
|
-
// Correct: { "name": "senderId", "value": { "stringValue": "0D2..." } } — look the Id up before authoring (§ Resolve names to Ids).
|
|
1154
|
-
|
|
1155
|
-
// WRONG #3 — consent field named "communicationSubscription" (no such param here).
|
|
1156
|
-
{ "name": "communicationSubscription", "value": { "stringValue": "0Ln..." } }
|
|
1157
|
-
// Correct: use communicationSubscriptionId (+ commSubscriptionChannelTypeId).
|
|
1158
|
-
|
|
1159
|
-
// WRONG #4 — subscription Id without its mandatory channel-type companion.
|
|
1160
|
-
{ "name": "communicationSubscriptionId", "value": { "stringValue": "0Ln..." } }
|
|
1161
|
-
// (missing commSubscriptionChannelTypeId) → COMMUNICATION_SUBSCRIPTION_CHANNEL_TYPE_ID_MISSING
|
|
1162
|
-
|
|
1163
|
-
// WRONG #5 — a developer name instead of a record Id for either consent param.
|
|
1164
|
-
{ "name": "communicationSubscriptionId", "value": { "stringValue": "My_Newsletter_Sub" } }
|
|
1165
|
-
// Correct: a CommSubscription record Id.
|
|
1166
|
-
|
|
1167
|
-
// WRONG #6 (non-marketing flow, or the user asked for error handling) — no fault path. The action has hasCallout:true and can throw.
|
|
1168
|
-
{ "actionName": "sendEmailMessage", "connector": { "targetReference": "END_Flow" } }
|
|
1169
|
-
|
|
1170
|
-
// WRONG #7 — timeout path on a non-async action.
|
|
1171
|
-
{ "actionName": "sendEmailMessage",
|
|
1172
|
-
"timeoutConnector": { "targetReference": "On_Timeout" },
|
|
1173
|
-
"timeoutPathUsage": "EnableTimeoutPath" }
|
|
1174
|
-
// Not async — omit timeout entirely. Use useSto/stoTimeFrame for send-time optimization.
|
|
1175
|
-
```
|
|
1176
|
-
|
|
1177
|
-
> **Verification note.** Parameter names, types, binding rules, requiredness, cross-parameter
|
|
1178
|
-
> validation, and builder traits above were verified against **core-264**
|
|
1179
|
-
> (`gitcore.soma.salesforce.com/core-2206/core-264-public`, ref `p4/264-patch`) on **2026-08-26**
|
|
1180
|
-
> — `InvocableSendEmailMessageAction.java`, `EmailParameterUtils.java`, `ParameterConstants.java`,
|
|
1181
|
-
> `SendEmailMessageActionSaveValidator.java`, `CommSubValidator.java`, and the
|
|
1182
|
-
> `sendEmailMessage()` factory in `InvocableActionType.java`. This is **source-derived, not yet
|
|
1183
|
-
> live-verified** by a builder save/activate round-trip (unlike the mobile examples). Per org,
|
|
1184
|
-
> confirm live via `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details` before relying on: (a) the org's
|
|
1185
|
-
> flow runtime accepting `storeOutputAutomatically: true` for this action, (b) the exact
|
|
1186
|
-
> describe-surfaced casing of each param, and (c) that the CPE does not hide `senderId` /
|
|
1187
|
-
> comm-sub params from the direct-metadata describe path.
|
|
1188
|
-
|
|
1189
|
-
## Send SMS Message Action (E360)
|
|
1190
|
-
|
|
1191
|
-
One standard platform invocable action, owned by **E360 Journeys**, sends an SMS through a Marketing Messaging Action.
|
|
1192
|
-
|
|
1193
|
-
| Action | `actionName` (emit verbatim) | Enum (`InvocableActionType`) | Min API | Delivery |
|
|
1194
|
-
|---|---|---|---|---|
|
|
1195
|
-
| **Send SMS Message** | `sendSmsMessage` | `SEND_SMS_MESSAGE` | 246 | SMS |
|
|
1196
|
-
|
|
1197
|
-
> **Authority.** `examples/send-sms-message.json` records the exact
|
|
1198
|
-
> `Flow.Metadata` persisted after a hand-built Segment flow was saved as a
|
|
1199
|
-
> Draft through Flow Builder. It was not activated, so fields observed there
|
|
1200
|
-
> are not proof of activation requirements. The Flow Builder MCP describe path
|
|
1201
|
-
> does not currently resolve `sendSmsMessage` on the verified org; do not
|
|
1202
|
-
> replace the persisted action shape with generic Action defaults.
|
|
1203
|
-
|
|
1204
|
-
### Discovery workflow
|
|
1205
|
-
|
|
1206
|
-
1. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/action/invocable-action-details", queryParams: { actionName: "sendSmsMessage", actionType: "sendSmsMessage" })`. If the verified org returns no action, continue with the persisted contract below; do not invent parameters.
|
|
1207
|
-
2. Resolve `contentId` through the [CMS discovery workflow](#cms-discovery-for-sms-and-rcs) with `contentTypeFQN: "sfdc_cms__sms"`.
|
|
1208
|
-
3. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/messaging/sender-sms-codes")`. Omit `businessUnitId` unless you have a
|
|
1209
|
-
verified 15- or 18-character Salesforce record ID. A direct Salesforce Core
|
|
1210
|
-
Business Unit ID starts with `1QO`; accept another prefix only after
|
|
1211
|
-
verifying that the record is related to that Business Unit. Never pass the
|
|
1212
|
-
numeric MCE `mid` or the `<EID>-<MID>` selector. Select a returned row and bind its `id` to
|
|
1213
|
-
`senderId`; never bind `messagingPlatformKey` or a phone number. Stop when
|
|
1214
|
-
the list is empty.
|
|
1215
|
-
4. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/messaging/communication-subscriptions")` with `messagingChannelId` set to the
|
|
1216
|
-
selected sender row's `id`, `channel: "sms"`, and
|
|
1217
|
-
`contactPointType: "Phone"`. Omit `businessUnitRelatedId` unless step 3 used
|
|
1218
|
-
a verified 15- or 18-character Salesforce record ID: a direct Business Unit
|
|
1219
|
-
ID starting with `1QO`, or another record ID verified as related to that
|
|
1220
|
-
Business Unit. Then pass that same Salesforce ID. Never pass an MCE `mid` or
|
|
1221
|
-
`<EID>-<MID>` selector.
|
|
1222
|
-
Read rows from `communicationSubscriptions[]`. When rows exist, select one
|
|
1223
|
-
and bind its `id` to `communicationSubscriptionId` and its `channelTypeId`
|
|
1224
|
-
to `commSubscriptionChannelTypeId`. When the list is empty, omit both inputs
|
|
1225
|
-
only when the selected content does not require a communication subscription;
|
|
1226
|
-
otherwise stop. Never invent either ID.
|
|
1227
|
-
|
|
1228
|
-
### Shared metadata characteristics
|
|
1229
|
-
|
|
1230
|
-
- **Fault path: only when asked in a marketing flow.** The action declares
|
|
1231
|
-
`hasCallout: true` and can fail at runtime. In a marketing flow (the list in
|
|
1232
|
-
`../../shared/fault-paths/fault-paths.md`), add a `faultConnector` only if the
|
|
1233
|
-
user asks for error handling. In any other flow type, wire one when the live
|
|
1234
|
-
action shape supports it. One verified persisted Draft has
|
|
1235
|
-
`faultConnector: null`.
|
|
1236
|
-
- **Emit automatic output exactly.** Set `storeOutputAutomatically: true` and `outputParameters: []`.
|
|
1237
|
-
- **Output.** Current Core declares `messageId` (String). Automatic output makes
|
|
1238
|
-
it available as `{!<actionApiName>.messageId}` without explicit assignments.
|
|
1239
|
-
- **Emit the observed empty generic mapping.** Set `dataTypeMappings: []`; the
|
|
1240
|
-
persisted draft had no resolved generic placeholders.
|
|
1241
|
-
- **Set transaction control exactly.** Emit `flowTransactionModel: "CurrentTransaction"`.
|
|
1242
|
-
- **Omit async fields.** Do not emit `isWaitUntilCompleted`, `timeoutConnector`, or `timeoutPathUsage`.
|
|
1243
|
-
- **Custom Property Editor.** Declares `configurationEditor: "builder_e360_journeys-send-sms-editor"`. In the builder UI the CPE replaces the standard parameter list — see [Configuration Editors](#configuration-editors-custom-property-editors). When authoring metadata directly, bind the parameters below.
|
|
1244
|
-
- **Never place on `RecordBeforeSave` or `RecordAfterSave`.** Unlike callout actions in general (see [Validation Rules and Constraints](#validation-rules-and-constraints)), `sendSmsMessage` (`hasCallout: true`) is rejected outright on **every** such shape — no scheduled-path placement fixes it.
|
|
1245
|
-
- **Use a Marketing flow context that exposes the action.** Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/action/invocable-actions")` with the intended `processType`, `triggerType`, `builderType`, and `dataSpace`, and require `sendSmsMessage` in the result before authoring it. This skill fully documents `processType: "AutoLaunchedFlow"` with `start.triggerType: "Segment"` (see `../start/segment-triggered.md`) or `"OnDemandNoTrigger"` (see `../start/start.md` § On-Demand); Core also allows the action for Data Graph Data Change flows, but their Start contract is outside this recipe. Omitting `start.triggerType` makes Core validate the flow as a plain autolaunched flow and can fail with `ACTIONCALL_NOT_SUPPORTED_FOR_PROCESSTYPE`.
|
|
1246
|
-
- **Do not generalize the surrounding draft.** The hand-built source also
|
|
1247
|
-
persisted `environments: ["Default"]`, `areMetricsLoggedToDataCloud: true`,
|
|
1248
|
-
`dataGraph`, `schedule.frequency: "OnActivate"`, and an explicit `ends[]`
|
|
1249
|
-
target. Preserve those fields when reproducing that source, but do not require
|
|
1250
|
-
or invent them for every `sendSmsMessage` flow without live validation.
|
|
1251
|
-
When evolving that source in an `AUTO_LAYOUT_CANVAS` flow, give each newly-added
|
|
1252
|
-
terminating branch an explicit End (its own or a shared one — both valid); a
|
|
1253
|
-
fault pointed directly at an End is silently dropped on reload (not a round-trip
|
|
1254
|
-
breaker), so route faults to a handler when you want them kept — see
|
|
1255
|
-
`shared/anti-patterns.md` item 38.
|
|
1256
|
-
|
|
1257
|
-
### Input parameters (confirmed against real saved metadata — see status note above)
|
|
1258
|
-
|
|
1259
|
-
| Param | Type | Required | Notes |
|
|
1260
|
-
|---|---|---|---|
|
|
1261
|
-
| `contentId` | String | yes¹ | Managed Content **FQN**, not a bare key. Confirmed shape: `"marketing--Default_Content_Workspace.sfdc_cms__sms--<API_NAME>"`, as returned by `content-fqn`. ¹Required for activation, not draft save — omit when unknown. See the [`contentId` Rule](#contentid-rule-marketing-messaging-actions) above. Never fabricate. |
|
|
1262
|
-
| `senderId` | String | yes¹ | **Not `senderSmsCode`.** Bind the selected `GET /services/data/vXX.0/flowbuilder/messaging/sender-sms-codes` row's `id` as a literal `stringValue`; element references are rejected. Never bind `messagingPlatformKey`, a phone number, or a fabricated ID. ¹Gates activation, not draft save. |
|
|
1263
|
-
| `clickTracking` | Boolean | no | Literal design-time choice; confirmed value `true`. |
|
|
1264
|
-
| `communicationSubscriptionId` | String | no | Bind the selected `GET /services/data/vXX.0/flowbuilder/messaging/communication-subscriptions` row's `id`. |
|
|
1265
|
-
| `commSubscriptionChannelTypeId` | String | no | Bind the same subscription row's `channelTypeId`; never mix IDs from different rows. |
|
|
1266
|
-
| `blockoutWindowBehaviour` | String | no | Static enum. Confirmed value `"doNotSend"`; do not guess other members. |
|
|
1267
|
-
| `messageSendTiming` | String | no | Emit one live-described literal: `"Anytime"`, `"NotDuringActiveSession"`, or `"NotDuringOpenSession"`. Omit it to use Core's `"NotDuringActiveSession"` default. |
|
|
1268
|
-
| `timeToLive` | Integer | feature-gated | Emit only when the live describe exposes it. Use minutes from `1` through `1440`; values outside that range fail save validation. |
|
|
1269
|
-
| `sendTimeAttributeKeys` | String | feature-gated | Emit only when the live describe exposes it. Supply the marketer-selected attribute names as a comma-separated design-time literal, not a collection or element reference. |
|
|
1270
|
-
| `sendTimeAttributeSources` | String | feature-gated | Pair each selected attribute with its Flow source as `<attribute>=<value>`, then join entries with the literal `~|~`, for example `Loyalty_Tier={!Customer.Tier__c}~|~Order_Id={!Order.Id}`. This parameter permits Flow references. |
|
|
1271
|
-
| `contentSchemaParameter` | `ContentSchema` generic | no | Optional content-variable bindings; resolve and emit `dataTypeMappings[]` only when used. |
|
|
1272
|
-
|
|
1273
|
-
### Worked example
|
|
1274
|
-
|
|
1275
|
-
`examples/send-sms-message.json` — confirmed persisted draft action fragment
|
|
1276
|
-
with literal `contentId`, `senderId`, subscription IDs, `clickTracking`, and
|
|
1277
|
-
`blockoutWindowBehaviour`; `dataTypeMappings: []`;
|
|
1278
|
-
`storeOutputAutomatically: true`; and no `faultConnector` (the marketing-flow
|
|
1279
|
-
default). Add a fault path only when the user asks for error handling; see
|
|
1280
|
-
`../../shared/fault-paths/fault-paths.md` § Marketing Flows — Fault Paths Only When Asked. The fragment
|
|
1281
|
-
is Draft-save evidence only; it is not proof of activation.
|
|
1282
|
-
|
|
1283
|
-
> **Note:** This is an `actionCalls[]` entry fragment, not a complete flow. Add it only to an `AutoLaunchedFlow` with `start.triggerType: "Segment"` or `"OnDemandNoTrigger"`.
|
|
1284
|
-
|
|
1285
|
-
### Anti-patterns (agent should reject / flag)
|
|
1286
|
-
|
|
1287
|
-
```jsonc
|
|
1288
|
-
// WRONG #1 (non-marketing flow, or the user asked for error handling) — no fault path.
|
|
1289
|
-
{ "actionName": "sendSmsMessage", "storeOutputAutomatically": true }
|
|
1290
|
-
// Add faultConnector to a real handler. In a marketing flow (fault-paths.md list) where
|
|
1291
|
-
// the user did not ask for error handling, omitting it is correct.
|
|
1292
|
-
|
|
1293
|
-
// WRONG #2 — fabricating a contentId the user never supplied.
|
|
1294
|
-
{ "name": "contentId", "value": { "stringValue": "MC_GUESSED_VALUE" } }
|
|
1295
|
-
// Omit the field entirely instead — see the contentId Rule above.
|
|
1296
|
-
|
|
1297
|
-
// WRONG #3 — using sendSmsMessage without proving the Marketing flow context exposes it.
|
|
1298
|
-
{ "actionName": "sendSmsMessage" } // RecordBeforeSave, RecordAfterSave, or unprobed plain autolaunched
|
|
1299
|
-
// Refuse. Require it in GET /services/data/vXX.0/flowbuilder/action/invocable-actions for the exact context first.
|
|
1300
|
-
|
|
1301
|
-
// WRONG #4 — wrong parameter name and a fabricated sender code.
|
|
1302
|
-
{ "name": "senderSmsCode", "value": { "stringValue": "SC-ACME-US-2025" } }
|
|
1303
|
-
// Use `senderId` with the exact sender record ID supplied or resolved for the org.
|
|
1304
|
-
```
|
|
1305
|
-
|
|
1306
|
-
> **Verification note.** `Flow.Metadata` verifies the action envelope and six emitted inputs. Core 264 verifies `InvocableActionType.SEND_SMS_MESSAGE`, minimum API version 246, the three `messageSendTiming` literals, optional gated `timeToLive` and send-time attributes, and the `messageId` output.
|
|
1307
|
-
|
|
1308
|
-
## Send RCS Message Action (E360)
|
|
1309
|
-
|
|
1310
|
-
| Action | `actionName` (emit verbatim) | Enum (`InvocableActionType`) | Min API | Delivery |
|
|
1311
|
-
|---|---|---|---|---|
|
|
1312
|
-
| **Send RCS Message** | `sendRcsMessage` | `SEND_RCS_MESSAGE` | 262 | RCS |
|
|
1313
|
-
|
|
1314
|
-
### Discovery workflow
|
|
1315
|
-
|
|
1316
|
-
1. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/action/invocable-action-details", queryParams: { actionName: "sendRcsMessage", actionType: "sendRcsMessage" })`. Treat an absent action or a 403 as an
|
|
1317
|
-
availability failure; do not invent metadata.
|
|
1318
|
-
2. Resolve `contentId` through the [CMS discovery workflow](#cms-discovery-for-sms-and-rcs) with `contentTypeFQN: "sfdc_cms__multiChannelContent"`.
|
|
1319
|
-
3. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/messaging/sender-rcs-agents")`:
|
|
1320
|
-
- Omit optional `businessUnitId` unless you have a verified 15- or
|
|
1321
|
-
18-character Salesforce record ID. A direct Salesforce Core Business Unit
|
|
1322
|
-
ID starts with `1QO`; accept another prefix only after verifying that the
|
|
1323
|
-
record is related to that Business Unit. Never pass the numeric MCE `mid`
|
|
1324
|
-
or the `<EID>-<MID>` selector.
|
|
1325
|
-
- Items: `id`, `messagingPlatformKey`, `masterLabel`, `useCase`. Empty list → halt; do not guess an agent.
|
|
1326
|
-
- Do not copy sender-agent `useCase` into `inputParameters`.
|
|
1327
|
-
4. Bind the selected item's `id` to `senderAgentId`. Never bind `messagingPlatformKey`.
|
|
1328
|
-
5. Call `dispatch_readonly(method: "GET", url: "/services/data/vXX.0/flowbuilder/messaging/communication-subscriptions")`:
|
|
1329
|
-
- `messagingChannelId`: the sender's `id` (MessagingChannel.Id) from step 3. Never `messagingPlatformKey`.
|
|
1330
|
-
- `channel: "rcs"`, `contactPointType: "Phone"` — fixed RCS mapping. Omitting either → 400.
|
|
1331
|
-
- Omit `businessUnitRelatedId` unless step 3 used a verified 15- or
|
|
1332
|
-
18-character Salesforce record ID: a direct Business Unit ID starting with
|
|
1333
|
-
`1QO`, or another record ID verified as related to that Business Unit.
|
|
1334
|
-
Then pass that same Salesforce ID. Never pass an MCE `mid` or
|
|
1335
|
-
`<EID>-<MID>` selector.
|
|
1336
|
-
- Empty list → halt; do not guess.
|
|
1337
|
-
- Each row is one subscription with one `channelTypeId` (`MIN(CommSubscriptionChannelType.Id)` when several channel types share a subscription). Bind that row's `id` → `communicationSubscriptionId`, `channelTypeId` → `commSubscriptionChannelTypeId`.
|
|
1338
|
-
- Skip this pair only with `bypassConsent: true`, and only after explicit user confirmation of external consent.
|
|
1339
|
-
6. Require the CMS-selected `managedContentId` to resolve through `GET /services/data/vXX.0/flowbuilder/messaging/content-fqn`; bind only the returned `contentFqn`. A name, slug, content key, variant ID, raw managed-content ID, or unresolved FQN hard-fails save (`ManagedContentIdException` / `Invalid Managed Content Key!`).
|
|
1340
|
-
|
|
1341
|
-
### Metadata characteristics
|
|
1342
|
-
|
|
1343
|
-
- **Fault path: only when asked in a marketing flow.** `hasCallout: true` can throw at runtime. In a marketing flow, add a `faultConnector` only if the user asks for error handling; in any other flow type, always wire one (see [Fault Path](#fault-path)).
|
|
1344
|
-
- **Output.** Describe returns `messageId` (String). Emit `storeOutputAutomatically: true` and `outputParameters: []`.
|
|
1345
|
-
- **Transaction control.** `allowsTransactionControl: true`, `doRollbackOnError: false` — always emit `flowTransactionModel`.
|
|
1346
|
-
- **Synchronous.** Omit `timeoutConnector` / `timeoutPathUsage`.
|
|
1347
|
-
- **CPE.** `configurationEditor: "builder_e360_journeys-send-rcs-editor"`. Resolve params from the live describe anyway.
|
|
1348
|
-
- **`ContentSchema`.** Optional `contentSchemaParameter`. Emit `dataTypeMappings[]` only when binding content variables.
|
|
1349
|
-
- **Record-triggered.** Refuse `RecordBeforeSave`. In `RecordAfterSave`, put the action on `scheduledPaths[]`, never the immediate path.
|
|
1350
|
-
- **Consent is required.** Bind `communicationSubscriptionId` + `commSubscriptionChannelTypeId` on every send. `bypassConsent: true` is the only skip, and only after explicit external-consent confirmation. Sender `useCase` does not change this.
|
|
1351
|
-
- **Describe-driven tracking and content-derived use case.** Emit
|
|
1352
|
-
`isTrackingLinks` only when the live describe exposes it and the user selects
|
|
1353
|
-
a value. When the live describe exposes `messageUseCase`, derive its value
|
|
1354
|
-
from the selected RCS content metadata. Never ask the user to choose it
|
|
1355
|
-
independently and never copy sender-agent `useCase`. Continue to omit the
|
|
1356
|
-
SMS-only `clickTracking` and `blockoutWindowBehaviour` fields.
|
|
1357
|
-
|
|
1358
|
-
### Input parameters
|
|
1359
|
-
|
|
1360
|
-
Always re-fetch with `GET /services/data/vXX.0/flowbuilder/action/invocable-action-details`. Verified core-264 shape:
|
|
1361
|
-
|
|
1362
|
-
| Param | Type | Required by describe | Notes |
|
|
1363
|
-
|---|---|---|---|
|
|
1364
|
-
| `contentId` | String | yes | Runtime FQN. Omit when unknown. Never fabricate. |
|
|
1365
|
-
| `senderAgentId` | String | no¹ | `GET /services/data/vXX.0/flowbuilder/messaging/sender-rcs-agents` → `[].id` only. |
|
|
1366
|
-
| `communicationSubscriptionId` | String | no² | One list row's `id`. Pair with that same row's `channelTypeId`. Required unless `bypassConsent` is true. |
|
|
1367
|
-
| `commSubscriptionChannelTypeId` | String | no² | Same row's `channelTypeId`. Do not mix ids across rows. Required unless `bypassConsent` is true. |
|
|
1368
|
-
| `messageSendTiming` | String | no | Literal from the live describe. |
|
|
1369
|
-
| `bypassConsent` | Boolean | no | `true` only after explicit external-consent confirmation; then omit the subscription pair. |
|
|
1370
|
-
| `isTrackingLinks` | Boolean | no | Optional link-tracking choice from the live describe. |
|
|
1371
|
-
| `messageUseCase` | String | no | Derive from the selected RCS content metadata when exposed by the live describe. Never accept an independent user choice or copy sender-agent `useCase`. |
|
|
1372
|
-
| `contentSchemaParameter` | `ContentSchema` generic | no | Content-variable bindings. |
|
|
1373
|
-
|
|
1374
|
-
¹Describe marks this optional; save validation rejects an empty sender for a usable send. Discover and bind before activation.
|
|
1375
|
-
²Describe marks these optional; product requires the pair unless `bypassConsent` is true.
|
|
1376
|
-
|
|
1377
|
-
`clickTracking` and `blockoutWindowBehaviour` are SMS-only
|
|
1378
|
-
(`SMSParameterUtils`; RCS never registers `blockoutWindowBehaviour`).
|
|
1379
|
-
|
|
1380
|
-
`testPhoneNumber` is a required **pre-debug extension**, not a persisted input. Use it only for Send Test Messages debug.
|
|
1381
|
-
|
|
1382
|
-
### Worked example
|
|
1383
|
-
|
|
1384
|
-
`examples/send-rcs-message.json` — selected `senderAgentId` and consent IDs bound
|
|
1385
|
-
as literals from discovery, and `contentId` omitted only until CMS discovery plus
|
|
1386
|
-
`GET /services/data/vXX.0/flowbuilder/messaging/content-fqn` resolves a real FQN; `storeOutputAutomatically: true`,
|
|
1387
|
-
no `faultConnector` (the marketing-flow default).
|
|
1388
|
-
|
|
1389
|
-
Bind those RCS IDs as design-time literals under the general literal-binding
|
|
1390
|
-
rule. No RCS-specific live rejection of `elementReference` was verified; do not
|
|
1391
|
-
claim that the RCS action rejects runtime references solely from the SMS
|
|
1392
|
-
contract.
|
|
1393
|
-
|
|
1394
|
-
> Fragment only. Replace each ID placeholder with the selected discovery row's
|
|
1395
|
-
> literal ID. It references `END_Flow`; define that target in the complete flow. For `RecordAfterSave`, place the action under Start
|
|
1396
|
-
> `scheduledPaths[]`.
|
|
1397
|
-
|
|
1398
|
-
### Anti-patterns (agent should reject / flag)
|
|
1399
|
-
|
|
1400
|
-
```jsonc
|
|
1401
|
-
// WRONG #1 — provider key instead of discovered messaging-channel id.
|
|
1402
|
-
{ "name": "senderAgentId", "value": { "stringValue": "provider-agent-key" } }
|
|
1403
|
-
|
|
1404
|
-
// WRONG #2 — unresolved name/FQN as contentId (hard-fails save).
|
|
1405
|
-
{ "name": "contentId", "value": { "stringValue": "RCS_Welcome_Transactional" } }
|
|
1406
|
-
// Omit until GET /services/data/vXX.0/flowbuilder/messaging/content-fqn returns a real FQN.
|
|
1407
|
-
|
|
1408
|
-
// WRONG #3 — omitting consent, or bypassConsent without confirmed external consent.
|
|
1409
|
-
{ "name": "bypassConsent", "value": { "booleanValue": true } }
|
|
1410
|
-
// Also wrong: no communicationSubscriptionId / commSubscriptionChannelTypeId and no bypassConsent.
|
|
1411
|
-
// Also wrong: skipping consent because the sender useCase is TRANSACTIONAL.
|
|
1412
|
-
|
|
1413
|
-
// WRONG #4 (non-marketing flow, or the user asked for error handling) — no fault path.
|
|
1414
|
-
{ "actionName": "sendRcsMessage", "connector": { "targetReference": "END_Flow" } }
|
|
1415
|
-
|
|
1416
|
-
// WRONG #5 — RecordAfterSave immediate path, or any RecordBeforeSave emit.
|
|
1417
|
-
{ "actionName": "sendRcsMessage", "connector": { "targetReference": "Next_Element" } }
|
|
1418
|
-
|
|
1419
|
-
// WRONG #6 — SMS-only params.
|
|
1420
|
-
{ "name": "clickTracking", "value": { "booleanValue": true } }
|
|
1421
|
-
{ "name": "blockoutWindowBehaviour", "value": { "stringValue": "WaitUntilWindowEnds" } }
|
|
1422
|
-
```
|
|
1423
|
-
|
|
1424
|
-
> **Verification note.** Action metadata: core-264 `InvocableActionType.java` + `testSimpleDescribeAction` goldfile. Sender discovery: W-23731426 `listSenderRcsAgents`. Consent listing: `E360JourneyStaticMethods.getCommunicationSubscriptionsBuFiltering` (Connect maps `commSubId`/`commSubChannelTypeId` → `id`/`channelTypeId`; RCS `contactPointType` is `Phone` via `CHANNEL_TO_CONTACT_POINT`). Per-org, re-run describe and discovery before authoring.
|
|
1425
|
-
|
|
1426
|
-
## Conversation Messaging Action
|
|
1427
|
-
|
|
1428
|
-
**Send Conversation Messages** (`sendConversationMessages`) is the Enhanced Messaging / Digital Engagement analog of the E360 mobile actions above — it sends a `ConversationMessageDefinition` to `MessagingEndUser` recipients. Its builder traits differ (no callout, no transaction control, no generic types) and it carries save-time consent cross-validation.
|
|
1429
|
-
|
|
1430
|
-
**When authoring this action, load `conversation-messaging.md` and follow it** — it is the complete build guide (trait differences, describe-driven input parameters, consent rules, worked example, and anti-patterns).
|
|
1431
|
-
|
|
1432
|
-
## Send Email Actions
|
|
1433
|
-
|
|
1434
|
-
*(UMS `sendEmailMessage` + stock `emailSimple`)*
|
|
1435
|
-
|
|
1436
|
-
Two different email-sending actions with materially different shapes:
|
|
1437
|
-
|
|
1438
|
-
| Action | `actionType` / `actionName` | Container | `contentId` (CMS) | `flowTransactionModel` |
|
|
1439
|
-
|---|---|---|---|---|
|
|
1440
|
-
| **Send Email Message** (UMS marketing email, E360) | `sendEmailMessage` | A marketing flow whose action catalog lists it, for example a Journey / `AutomationEvent` start (`trgrOnEmailSubscription`), `IndivRelatedRecord`, or `OnDemandNoTrigger` (`../start/start.md` § On-Demand); confirm with `invocable-actions` for the exact context | **Required** for activation — resolve `sfdc_cms__email` FQN via [CMS discovery for Email](#cms-discovery-for-email-sendemailmessage) | `Automatic` |
|
|
1441
|
-
| **Send Email** (stock) | `emailSimple` | Bare `AutoLaunchedFlow` with no trigger (no `triggerType`) | None (no CMS dependency) | `CurrentTransaction` only |
|
|
1442
|
-
|
|
1443
|
-
### `sendEmailMessage` (UMS marketing email)
|
|
1444
|
-
|
|
1445
|
-
> **Same action as [Send Email Message (E360)](#send-email-message-e360) above.** That
|
|
1446
|
-
> section is the authoritative, describe-driven parameter contract (`senderId`, the consent
|
|
1447
|
-
> pair, `contentId`, builder traits, anti-patterns). This subsection keeps the **Journey /
|
|
1448
|
-
> `AutomationEvent` container** framing and a **live-verified** save; the two live-observed
|
|
1449
|
-
> warnings below independently corroborate the E360 section's `senderId` and
|
|
1450
|
-
> `commSubscriptionChannelTypeId` requirements. Author against the E360 section for the full
|
|
1451
|
-
> parameter set — the bullets here only add the container-specific rules.
|
|
1452
|
-
|
|
1453
|
-
- In a Journey / `AutomationEvent` flow: author in a **Journey** flow whose `start.triggerType` is `AutomationEvent` with
|
|
1454
|
-
`eventType`/`eventName` `trgrOnEmailSubscription`. The start's single required
|
|
1455
|
-
input is `communicationSubscription` (bind a real subscription `id`) — there is
|
|
1456
|
-
**no** `messagingChannel` analog like SMS has. This is the same subscription `id`
|
|
1457
|
-
bound below as the action's `communicationSubscriptionId` input parameter — one
|
|
1458
|
-
value, referenced under different field names on the Start element vs. the
|
|
1459
|
-
action call.
|
|
1460
|
-
- In an On-Demand Flow, use the On-Demand Start instead (`../start/start.md` § On-Demand): no
|
|
1461
|
-
start inputs and no recipient record, because the caller passes the person.
|
|
1462
|
-
- In a Journey / `AutomationEvent` flow, create the recipient first (e.g. Create Records →
|
|
1463
|
-
Contact), then the action.
|
|
1464
|
-
- Resolve `contentId` through [CMS discovery for Email](#cms-discovery-for-email-sendemailmessage)
|
|
1465
|
-
and bind the resolved `sfdc_cms__email` FQN. Omit only when unresolvable
|
|
1466
|
-
(activation stays blocked).
|
|
1467
|
-
- Bind **`senderId`** (a verified OrgWideEmailAddress / active SenderEmailAddress / active
|
|
1468
|
-
User Id — a record Id, literal `{stringValue}` only). Omitting it fails save with
|
|
1469
|
-
`FROM_USER_EMPTY`, and a missing/invalid sender is what surfaces the *Select a valid From
|
|
1470
|
-
address* activation warning below. See the [E360 `senderId` deep dive](#send-email-message-e360).
|
|
1471
|
-
- If you set `communicationSubscriptionId`, set its mandatory companion
|
|
1472
|
-
**`commSubscriptionChannelTypeId`** too (both are record Ids) — the Id alone fails with
|
|
1473
|
-
`COMMUNICATION_SUBSCRIPTION_CHANNEL_TYPE_ID_MISSING`.
|
|
1474
|
-
- `flowTransactionModel: "Automatic"`.
|
|
1475
|
-
- No `faultConnector` unless the user asks for error handling; this is a marketing flow (see [Fault Path](#fault-path)).
|
|
1476
|
-
|
|
1477
|
-
> **Activation-gating (not save-blocking) warnings observed on a live org:**
|
|
1478
|
-
> even with a valid `contentId`, `sendEmailMessage` retained two warnings —
|
|
1479
|
-
> `Select a valid From address` (the org had **zero** org-wide email addresses:
|
|
1480
|
-
> `GET /services/data/vXX.0/flowbuilder/action/org-wide-email-addresses` → `{"addresses":[]}`) and `We couldn't find a
|
|
1481
|
-
> Communication Subscription Channel Type ID` (no `commSubscriptionChannelTypeId` was bound). Both clear once
|
|
1482
|
-
> `senderId` and the consent pair are bound. A User can be the sender when the org has no org-wide address, and
|
|
1483
|
-
> `GET /services/data/vXX.0/flowbuilder/messaging/communication-subscriptions` with `channel: "email"`,
|
|
1484
|
-
> `contactPointType: "Email"` and no `messagingChannelId` returns the email subscriptions with their
|
|
1485
|
-
> `channelTypeId`; see [Resolve names to Ids](#resolve-names-to-ids).
|
|
1486
|
-
> `validate_flow` still returns `isSuccess: true` with these warnings. **Both are the
|
|
1487
|
-
> activation-time manifestation of the E360 section's required params** — *Select a
|
|
1488
|
-
> valid From address* ↔ `senderId` (`FROM_USER_EMPTY`), and the missing channel-type ↔
|
|
1489
|
-
> `commSubscriptionChannelTypeId`; see [Send Email Message (E360)](#send-email-message-e360).
|
|
1490
|
-
|
|
1491
|
-
```jsonc
|
|
1492
|
-
// actionCalls[] fragment — Journey/AutomationEvent flow. Save-verified (isSuccess:true) against a live org,
|
|
1493
|
-
// but this minimal shape kept two activation warnings (see note above): for activation, also bind senderId
|
|
1494
|
-
// and commSubscriptionChannelTypeId — see § Send Email Message (E360) for the full contract.
|
|
1495
|
-
{
|
|
1496
|
-
"name": "Send_Email_Message",
|
|
1497
|
-
"label": "Send Email Message",
|
|
1498
|
-
"actionType": "sendEmailMessage",
|
|
1499
|
-
"actionName": "sendEmailMessage",
|
|
1500
|
-
"nameSegment": "sendEmailMessage",
|
|
1501
|
-
"flowTransactionModel": "Automatic",
|
|
1502
|
-
"storeOutputAutomatically": false,
|
|
1503
|
-
"inputParameters": [
|
|
1504
|
-
{ "name": "communicationSubscriptionId", "value": { "stringValue": "<real subscription id>" } },
|
|
1505
|
-
{ "name": "contentId", "value": { "stringValue": "marketing--Default_Content_Workspace.sfdc_cms__email--<CONTENT_KEY>" } }
|
|
1506
|
-
],
|
|
1507
|
-
"outputParameters": []
|
|
1508
|
-
// no faultConnector: marketing flow, add one only if the user asks for error handling
|
|
1509
|
-
}
|
|
1510
|
-
```
|
|
1511
|
-
|
|
1512
|
-
### `emailSimple` (stock Send Email)
|
|
1513
|
-
|
|
1514
|
-
- Minimal container: a bare `AutoLaunchedFlow` with no trigger (Autolaunched
|
|
1515
|
-
Flow, No Trigger) — the persisted `start` has `triggers: []` and no
|
|
1516
|
-
`triggerType` key. No CMS/`contentId` dependency. This is not the
|
|
1517
|
-
`OnDemandNoTrigger` marketing flow type (On-Demand Flow), so the default
|
|
1518
|
-
fault-path rule applies.
|
|
1519
|
-
- `flowTransactionModel: "CurrentTransaction"` — **required**; `emailSimple`
|
|
1520
|
-
rejects `Automatic` with `ACTIONCALL_TRANSACTION_MODEL_NOT_ALLOWED: The action
|
|
1521
|
-
'EMAILSIMPLE' only supports 'CurrentTransaction'`.
|
|
1522
|
-
- All input parameters report `isRequired: false` in the describe; the "required"
|
|
1523
|
-
behavior is enforced as **cross-parameter runtime logic**, not static flags:
|
|
1524
|
-
- `emailAddresses` (or `emailAddressesArray`), `emailSubject`, `emailBody` for a
|
|
1525
|
-
body-only send.
|
|
1526
|
-
- `emailTemplateId` **requires** `recipientId` — validate emits
|
|
1527
|
-
`Because an email template was specified, Recipient ID is required.`
|
|
1528
|
-
- Wire a `faultConnector`.
|
|
1529
|
-
|
|
1530
|
-
> **Nuance on the generic cross-parameter note in
|
|
1531
|
-
> [Validation Rules and Constraints](#validation-rules-and-constraints):** the
|
|
1532
|
-
> `recipientId`-required-with-template rule reproduced and is real. A hard
|
|
1533
|
-
> "template conflicts with explicit subject/body" validation error did **not**
|
|
1534
|
-
> reproduce at `validate_flow` time — only an ID-format/existence check on
|
|
1535
|
-
> `emailTemplateId` appeared. **Caveat:** the probe used a synthetic, unresolvable
|
|
1536
|
-
> `emailTemplateId` (no real `EmailTemplate` record was obtainable in the test org), so
|
|
1537
|
-
> whether a *resolvable* template + explicit body triggers a distinct path remains
|
|
1538
|
-
> an open question, not a settled result.
|
|
1539
|
-
|
|
1540
|
-
```jsonc
|
|
1541
|
-
// actionCalls[] fragment — bare AutoLaunchedFlow (no triggerType). Verified isSuccess:true, warnings:[] against a live org.
|
|
1542
|
-
{
|
|
1543
|
-
"name": "Send_Email",
|
|
1544
|
-
"label": "Send Email",
|
|
1545
|
-
"actionType": "emailSimple",
|
|
1546
|
-
"actionName": "emailSimple",
|
|
1547
|
-
"nameSegment": "emailSimple",
|
|
1548
|
-
"flowTransactionModel": "CurrentTransaction",
|
|
1549
|
-
"storeOutputAutomatically": true,
|
|
1550
|
-
"inputParameters": [
|
|
1551
|
-
{ "name": "emailAddresses", "value": { "stringValue": "qa@example.com" } },
|
|
1552
|
-
{ "name": "emailSubject", "value": { "stringValue": "QA Test" } },
|
|
1553
|
-
{ "name": "emailBody", "value": { "stringValue": "QA body." } }
|
|
1554
|
-
],
|
|
1555
|
-
"outputParameters": [],
|
|
1556
|
-
"faultConnector": { "targetReference": "Log_Fault" }
|
|
1557
|
-
}
|
|
1558
|
-
```
|
|
1559
|
-
|
|
1560
|
-
> **Verification note.** Both actions were authored, `validate_flow`'d
|
|
1561
|
-
> (`isSuccess: true`, `errors: []`), saved, and retention-confirmed via
|
|
1562
|
-
> `GET /services/data/vXX.0/flowbuilder/flow/{id}` against a live org: `sendEmailMessage` and `emailSimple` both
|
|
1563
|
-
> saved as fully valid `Draft` versions. `processType: "Journey"` was
|
|
1564
|
-
> observed to persist **non-deterministically** — some saves coerced it to
|
|
1565
|
-
> `AutoLaunchedFlow`, others retained `Journey`. Because `sendEmailMessage` requires
|
|
1566
|
-
> a Journey container, this is not a cosmetic drift: after every `POST /services/data/vXX.0/flowbuilder/flow/actions/save` on a
|
|
1567
|
-
> `sendEmailMessage` flow, re-read the persisted `processType` via `GET /services/data/vXX.0/flowbuilder/flow/{id}`
|
|
1568
|
-
> and treat a coercion to `AutoLaunchedFlow` as a save failure — do not proceed to
|
|
1569
|
-
> activation on the assumption the container held.
|