@salesforce/afv-skills 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/activating-datacloud/CREDITS.md +5 -0
- package/skills/activating-datacloud/README.md +39 -0
- package/skills/activating-datacloud/SKILL.md +118 -0
- package/skills/analyzing-omnistudio-dependencies/CREDITS.md +5 -0
- package/skills/analyzing-omnistudio-dependencies/SKILL.md +477 -0
- package/skills/analyzing-omnistudio-dependencies/references/dependency-patterns.md +508 -0
- package/skills/analyzing-omnistudio-dependencies/references/namespace-guide.md +300 -0
- package/skills/building-omnistudio-callable-apex/CREDITS.md +9 -0
- package/skills/building-omnistudio-callable-apex/README.md +80 -0
- package/skills/building-omnistudio-callable-apex/SKILL.md +276 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_callable_openinterface.cls +40 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_callable_vanilla.cls +32 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_migration.cls +54 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_openinterface.cls +45 -0
- package/skills/building-omnistudio-callable-apex/assets/pattern_test_class.cls +65 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/Industries_QuoteByProductCallable.cls +115 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/Industries_QuoteByProductCallableTest.cls +189 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_QuoteByProductCallable/TRANSCRIPT.md +115 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomCallable.cls +74 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomCallableTest.cls +146 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/MyCustomRemoteClass.cls +16 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterface2Conversion/TRANSCRIPT.md +120 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/IndustriesCallableException.cls +7 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomCallable.cls +73 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomCallableTest.cls +128 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/MyCustomVlocityOpenInterface2.cls +23 -0
- package/skills/building-omnistudio-callable-apex/examples/Test_VlocityOpenInterfaceConversion/TRANSCRIPT.md +75 -0
- package/skills/building-omnistudio-datamapper/CREDITS.md +5 -0
- package/skills/building-omnistudio-datamapper/SKILL.md +270 -0
- package/skills/building-omnistudio-datamapper/assets/completion-summary-template.md +28 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-extract.json +6 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-item.json +12 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-load.json +6 -0
- package/skills/building-omnistudio-datamapper/assets/omni-data-transform-transform.json +6 -0
- package/skills/building-omnistudio-datamapper/references/best-practices.md +277 -0
- package/skills/building-omnistudio-datamapper/references/naming-conventions.md +145 -0
- package/skills/building-omnistudio-flexcard/CREDITS.md +5 -0
- package/skills/building-omnistudio-flexcard/SKILL.md +325 -0
- package/skills/building-omnistudio-flexcard/assets/omni-ui-card.json +10 -0
- package/skills/building-omnistudio-flexcard/references/best-practices.md +291 -0
- package/skills/building-omnistudio-flexcard/references/data-binding-guide.md +311 -0
- package/skills/building-omnistudio-flexcard/references/scoring-rubric.md +66 -0
- package/skills/building-omnistudio-flexcard/scripts/flexcard-commands.sh +24 -0
- package/skills/building-omnistudio-integration-procedure/CREDITS.md +5 -0
- package/skills/building-omnistudio-integration-procedure/SKILL.md +275 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-element-dr-extract.json +10 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-element-set-values.json +10 -0
- package/skills/building-omnistudio-integration-procedure/assets/omni-process-ip.json +12 -0
- package/skills/building-omnistudio-integration-procedure/assets/scoring-report-format.txt +14 -0
- package/skills/building-omnistudio-integration-procedure/references/best-practices.md +388 -0
- package/skills/building-omnistudio-integration-procedure/references/element-types.md +588 -0
- package/skills/building-omnistudio-integration-procedure/scripts/cli-commands.sh +18 -0
- package/skills/building-omnistudio-omniscript/CREDITS.md +5 -0
- package/skills/building-omnistudio-omniscript/SKILL.md +367 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-element-step.json +10 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-element-text-block.json +11 -0
- package/skills/building-omnistudio-omniscript/assets/omni-process-omniscript.json +12 -0
- package/skills/building-omnistudio-omniscript/references/best-practices.md +480 -0
- package/skills/building-omnistudio-omniscript/references/element-types.md +1172 -0
- package/skills/building-omnistudio-omniscript/scripts/check-duplicate-omniscript.sh +13 -0
- package/skills/building-omnistudio-omniscript/scripts/cli-reference.sh +21 -0
- package/skills/building-omnistudio-omniscript/scripts/deploy-omniscript.sh +29 -0
- package/skills/building-sf-integrations/CREDITS.md +5 -0
- package/skills/building-sf-integrations/README.md +95 -0
- package/skills/building-sf-integrations/SKILL.md +192 -0
- package/skills/building-sf-integrations/assets/callouts/callout-retry-handler.cls +167 -0
- package/skills/building-sf-integrations/assets/callouts/http-response-handler.cls +257 -0
- package/skills/building-sf-integrations/assets/callouts/rest-queueable-callout.cls +262 -0
- package/skills/building-sf-integrations/assets/callouts/rest-sync-callout.cls +211 -0
- package/skills/building-sf-integrations/assets/cdc/cdc-handler.cls +246 -0
- package/skills/building-sf-integrations/assets/cdc/cdc-subscriber-trigger.trigger +139 -0
- package/skills/building-sf-integrations/assets/endpoint-security/example.cspTrustedSite-meta.xml +58 -0
- package/skills/building-sf-integrations/assets/endpoint-security/example.remoteSite-meta.xml +39 -0
- package/skills/building-sf-integrations/assets/external-credentials/jwt-external-credential.externalCredential-meta.xml +90 -0
- package/skills/building-sf-integrations/assets/external-credentials/oauth-external-credential.externalCredential-meta.xml +87 -0
- package/skills/building-sf-integrations/assets/external-services/external-service-operations.md +221 -0
- package/skills/building-sf-integrations/assets/external-services/openapi-registration.externalServiceRegistration-meta.xml +193 -0
- package/skills/building-sf-integrations/assets/named-credentials/certificate-auth.namedCredential-meta.xml +62 -0
- package/skills/building-sf-integrations/assets/named-credentials/custom-auth.namedCredential-meta.xml +71 -0
- package/skills/building-sf-integrations/assets/named-credentials/oauth-client-credentials.namedCredential-meta.xml +51 -0
- package/skills/building-sf-integrations/assets/named-credentials/oauth-jwt-bearer.namedCredential-meta.xml +67 -0
- package/skills/building-sf-integrations/assets/platform-events/event-publisher.cls +191 -0
- package/skills/building-sf-integrations/assets/platform-events/event-subscriber-action.cls +295 -0
- package/skills/building-sf-integrations/assets/platform-events/event-subscriber-trigger.trigger +108 -0
- package/skills/building-sf-integrations/assets/platform-events/platform-event-definition.object-meta.xml +124 -0
- package/skills/building-sf-integrations/assets/soap/soap-callout-service.cls +186 -0
- package/skills/building-sf-integrations/assets/soap/wsdl2apex-guide.md +213 -0
- package/skills/building-sf-integrations/hooks/scripts/suggest_credential_setup.py +271 -0
- package/skills/building-sf-integrations/hooks/scripts/validate_integration.py +363 -0
- package/skills/building-sf-integrations/references/callout-patterns.md +719 -0
- package/skills/building-sf-integrations/references/cdc-guide.md +288 -0
- package/skills/building-sf-integrations/references/cli-reference.md +94 -0
- package/skills/building-sf-integrations/references/event-driven-architecture-guide.md +266 -0
- package/skills/building-sf-integrations/references/event-patterns.md +838 -0
- package/skills/building-sf-integrations/references/external-services-guide.md +303 -0
- package/skills/building-sf-integrations/references/messaging-api-v2.md +609 -0
- package/skills/building-sf-integrations/references/named-credentials-automation.md +201 -0
- package/skills/building-sf-integrations/references/named-credentials-guide.md +173 -0
- package/skills/building-sf-integrations/references/platform-events-guide.md +288 -0
- package/skills/building-sf-integrations/references/rest-callout-patterns.md +288 -0
- package/skills/building-sf-integrations/references/scoring-rubric.md +59 -0
- package/skills/building-sf-integrations/references/security-best-practices.md +248 -0
- package/skills/building-sf-integrations/scripts/README.md +100 -0
- package/skills/building-sf-integrations/scripts/configure-named-credential.sh +236 -0
- package/skills/building-sf-integrations/scripts/set-api-credential.sh +146 -0
- package/skills/building-sf-integrations/scripts/templates/setup-credentials-with-csp.sh +158 -0
- package/skills/configuring-connected-apps/CREDITS.md +3 -0
- package/skills/configuring-connected-apps/README.md +99 -0
- package/skills/configuring-connected-apps/SKILL.md +224 -0
- package/skills/configuring-connected-apps/assets/connected-app-basic.xml +29 -0
- package/skills/configuring-connected-apps/assets/connected-app-canvas.xml +62 -0
- package/skills/configuring-connected-apps/assets/connected-app-jwt.xml +49 -0
- package/skills/configuring-connected-apps/assets/connected-app-oauth.xml +65 -0
- package/skills/configuring-connected-apps/assets/eca-global-oauth.xml +36 -0
- package/skills/configuring-connected-apps/assets/eca-oauth-settings.xml +36 -0
- package/skills/configuring-connected-apps/assets/eca-policies.xml +36 -0
- package/skills/configuring-connected-apps/assets/external-client-app.xml +35 -0
- package/skills/configuring-connected-apps/references/example-usage.md +256 -0
- package/skills/configuring-connected-apps/references/migration-guide.md +328 -0
- package/skills/configuring-connected-apps/references/oauth-flows-reference.md +660 -0
- package/skills/configuring-connected-apps/references/security-checklist.md +209 -0
- package/skills/configuring-connected-apps/references/testing-validation-guide.md +275 -0
- package/skills/connecting-datacloud/CREDITS.md +5 -0
- package/skills/connecting-datacloud/README.md +59 -0
- package/skills/connecting-datacloud/SKILL.md +155 -0
- package/skills/connecting-datacloud/examples/connections/heroku-postgres.json +15 -0
- package/skills/connecting-datacloud/examples/connections/ingest-api-connection.json +5 -0
- package/skills/connecting-datacloud/examples/connections/ingest-api-schema.json +31 -0
- package/skills/connecting-datacloud/examples/connections/redshift.json +16 -0
- package/skills/connecting-datacloud/examples/connections/sharepoint-unstructured.json +20 -0
- package/skills/connecting-datacloud/examples/connections/snowflake-connection.json +42 -0
- package/skills/debugging-apex-logs/CREDITS.md +22 -0
- package/skills/debugging-apex-logs/README.md +74 -0
- package/skills/debugging-apex-logs/SKILL.md +172 -0
- package/skills/debugging-apex-logs/assets/benchmarking-template.cls +327 -0
- package/skills/debugging-apex-logs/assets/cpu-heap-optimization.cls +307 -0
- package/skills/debugging-apex-logs/assets/dml-in-loop-fix.cls +219 -0
- package/skills/debugging-apex-logs/assets/null-pointer-fix.cls +252 -0
- package/skills/debugging-apex-logs/assets/soql-in-loop-fix.cls +157 -0
- package/skills/debugging-apex-logs/references/analysis-playbook.md +53 -0
- package/skills/debugging-apex-logs/references/benchmarking-guide.md +287 -0
- package/skills/debugging-apex-logs/references/cli-commands.md +368 -0
- package/skills/debugging-apex-logs/references/common-issues.md +68 -0
- package/skills/debugging-apex-logs/references/debug-log-reference.md +328 -0
- package/skills/debugging-apex-logs/references/log-analysis-tools.md +248 -0
- package/skills/debugging-apex-logs/references/scoring-rubric.md +21 -0
- package/skills/deploying-metadata/CREDITS.md +25 -0
- package/skills/deploying-metadata/README.md +104 -0
- package/skills/deploying-metadata/SKILL.md +214 -0
- package/skills/deploying-metadata/assets/destructiveChanges.xml +143 -0
- package/skills/deploying-metadata/assets/package.xml +121 -0
- package/skills/deploying-metadata/references/agent-deployment-guide.md +628 -0
- package/skills/deploying-metadata/references/deploy.sh +73 -0
- package/skills/deploying-metadata/references/deployment-report-template.md +89 -0
- package/skills/deploying-metadata/references/deployment-workflows.md +395 -0
- package/skills/deploying-metadata/references/orchestration.md +183 -0
- package/skills/deploying-metadata/references/trigger-deployment-safety.md +376 -0
- package/skills/deploying-omnistudio-datapacks/CREDITS.md +5 -0
- package/skills/deploying-omnistudio-datapacks/README.md +88 -0
- package/skills/deploying-omnistudio-datapacks/SKILL.md +174 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle/TRANSCRIPT.md +124 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle/deploy-business-internet-plus-bundle.yaml +11 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle-deploy/TRANSCRIPT.md +142 -0
- package/skills/deploying-omnistudio-datapacks/examples/business-internet-plus-bundle-deploy/deploy-business-internet-plus-bundle.yaml +10 -0
- package/skills/deploying-omnistudio-datapacks/references/job-file-template.md +42 -0
- package/skills/deploying-omnistudio-datapacks/references/troubleshooting-matrix.md +24 -0
- package/skills/developing-agentforce/assets/metadata/http-callout-flow.flow-meta.xml +1 -1
- package/skills/developing-agentforce/references/actions-reference.md +8 -8
- package/skills/fetching-salesforce-docs/README.md +66 -0
- package/skills/fetching-salesforce-docs/SKILL.md +209 -0
- package/skills/fetching-salesforce-docs/requirements.txt +2 -0
- package/skills/fetching-salesforce-docs/scripts/extract_help_salesforce.py +497 -0
- package/skills/fetching-salesforce-docs/scripts/extract_salesforce_doc.py +357 -0
- package/skills/fetching-salesforce-docs/scripts/runtime_bootstrap.py +58 -0
- package/skills/generating-apex/CREDITS.md +1 -26
- package/skills/generating-apex-test/CREDITS.md +2 -27
- package/skills/generating-lwc-components/CREDITS.md +5 -0
- package/skills/generating-lwc-components/README.md +126 -0
- package/skills/generating-lwc-components/SKILL.md +191 -0
- package/skills/generating-lwc-components/assets/apex-controller/LwcController.cls +327 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.css +72 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.html +111 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.js +163 -0
- package/skills/generating-lwc-components/assets/basic-component/basicComponent.js-meta.xml +137 -0
- package/skills/generating-lwc-components/assets/datatable-component/datatableComponent.html +111 -0
- package/skills/generating-lwc-components/assets/datatable-component/datatableComponent.js +367 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.css +63 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.html +154 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.js +348 -0
- package/skills/generating-lwc-components/assets/flow-screen-component/flowScreenComponent.js-meta.xml +87 -0
- package/skills/generating-lwc-components/assets/form-component/formComponent.html +165 -0
- package/skills/generating-lwc-components/assets/form-component/formComponent.js +275 -0
- package/skills/generating-lwc-components/assets/graphql-component/graphqlComponent.html +100 -0
- package/skills/generating-lwc-components/assets/graphql-component/graphqlComponent.js +336 -0
- package/skills/generating-lwc-components/assets/jest-test/componentName.test.js.example +371 -0
- package/skills/generating-lwc-components/assets/message-channel/RecordSelected.messageChannel-meta.xml +71 -0
- package/skills/generating-lwc-components/assets/message-channel/lmsPublisher.js +103 -0
- package/skills/generating-lwc-components/assets/message-channel/lmsSubscriber.js +181 -0
- package/skills/generating-lwc-components/assets/modal-component/modalComponent.html +85 -0
- package/skills/generating-lwc-components/assets/modal-component/modalComponent.js +199 -0
- package/skills/generating-lwc-components/assets/record-picker/recordPicker.html +55 -0
- package/skills/generating-lwc-components/assets/record-picker/recordPicker.js +199 -0
- package/skills/generating-lwc-components/assets/state-store/store.js +282 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.css +65 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.html +95 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.js-meta.xml +75 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.test.ts.example +301 -0
- package/skills/generating-lwc-components/assets/typescript-component/typescriptComponent.ts +295 -0
- package/skills/generating-lwc-components/assets/workspace-api/workspaceComponent.html +71 -0
- package/skills/generating-lwc-components/assets/workspace-api/workspaceComponent.js +316 -0
- package/skills/generating-lwc-components/hooks/scripts/lwc-lsp-validate.py +295 -0
- package/skills/generating-lwc-components/hooks/scripts/post-tool-validate.py +347 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/deprecated_patterns.json +74 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/styling_hooks.json +111 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_data/valid_slds_classes.json +127 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_linter_wrapper.py +294 -0
- package/skills/generating-lwc-components/hooks/scripts/slds_rules/__init__.py +22 -0
- package/skills/generating-lwc-components/hooks/scripts/template_validator.py +332 -0
- package/skills/generating-lwc-components/hooks/scripts/validate_slds.py +595 -0
- package/skills/generating-lwc-components/references/accessibility-guide.md +843 -0
- package/skills/generating-lwc-components/references/advanced-features.md +108 -0
- package/skills/generating-lwc-components/references/async-notification-patterns.md +661 -0
- package/skills/generating-lwc-components/references/cli-commands.md +545 -0
- package/skills/generating-lwc-components/references/component-patterns.md +1476 -0
- package/skills/generating-lwc-components/references/flow-integration-guide.md +675 -0
- package/skills/generating-lwc-components/references/jest-testing.md +1011 -0
- package/skills/generating-lwc-components/references/lms-guide.md +860 -0
- package/skills/generating-lwc-components/references/lwc-best-practices.md +1310 -0
- package/skills/generating-lwc-components/references/performance-guide.md +861 -0
- package/skills/generating-lwc-components/references/scoring-and-testing.md +116 -0
- package/skills/generating-lwc-components/references/slds-blueprints.json +14389 -0
- package/skills/generating-lwc-components/references/slds-design-guide.md +166 -0
- package/skills/generating-lwc-components/references/state-management.md +642 -0
- package/skills/generating-lwc-components/references/template-anti-patterns.md +948 -0
- package/skills/generating-lwc-components/references/triangle-pattern.md +365 -0
- package/skills/generating-lwc-components/scripts/local-dev-preview.sh +34 -0
- package/skills/generating-mermaid-diagrams/CREDITS.md +46 -0
- package/skills/generating-mermaid-diagrams/README.md +114 -0
- package/skills/generating-mermaid-diagrams/SKILL.md +218 -0
- package/skills/generating-mermaid-diagrams/assets/agentforce/agent-flow.md +313 -0
- package/skills/generating-mermaid-diagrams/assets/architecture/system-landscape.md +351 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/b2b-commerce-erd.md +317 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/campaigns-erd.md +195 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/consent-erd.md +262 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/files-erd.md +266 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/forecasting-erd.md +261 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/fsl-erd.md +332 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/party-model-erd.md +237 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/quote-order-erd.md +277 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/revenue-cloud-erd.md +343 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/sales-cloud-erd.md +192 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/salesforce-erd.md +209 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/scheduler-erd.md +276 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/service-cloud-erd.md +217 -0
- package/skills/generating-mermaid-diagrams/assets/datamodel/territory-management-erd.md +241 -0
- package/skills/generating-mermaid-diagrams/assets/integration/api-sequence.md +387 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/authorization-code-pkce.md +197 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/authorization-code.md +152 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/client-credentials.md +233 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/device-authorization.md +295 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/jwt-bearer.md +256 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/refresh-token.md +281 -0
- package/skills/generating-mermaid-diagrams/assets/oauth/user-agent-social-sign-on.md +281 -0
- package/skills/generating-mermaid-diagrams/assets/role-hierarchy/user-hierarchy.md +322 -0
- package/skills/generating-mermaid-diagrams/references/color-palette.md +464 -0
- package/skills/generating-mermaid-diagrams/references/diagram-conventions.md +313 -0
- package/skills/generating-mermaid-diagrams/references/erd-conventions.md +320 -0
- package/skills/generating-mermaid-diagrams/references/mermaid-reference.md +434 -0
- package/skills/generating-mermaid-diagrams/references/mermaid-styling.md +81 -0
- package/skills/generating-mermaid-diagrams/references/preview-guide.md +49 -0
- package/skills/generating-mermaid-diagrams/references/usage-examples.md +340 -0
- package/skills/generating-mermaid-diagrams/scripts/README.md +160 -0
- package/skills/generating-mermaid-diagrams/scripts/mermaid_preview.py +654 -0
- package/skills/generating-mermaid-diagrams/scripts/query-org-metadata.py +293 -0
- package/skills/generating-visual-diagrams/CREDITS.md +80 -0
- package/skills/generating-visual-diagrams/README.md +83 -0
- package/skills/generating-visual-diagrams/SKILL.md +208 -0
- package/skills/generating-visual-diagrams/assets/architecture/integration-flow.md +55 -0
- package/skills/generating-visual-diagrams/assets/erd/core-objects.md +131 -0
- package/skills/generating-visual-diagrams/assets/erd/custom-objects.md +60 -0
- package/skills/generating-visual-diagrams/assets/lwc/dashboard-card.md +45 -0
- package/skills/generating-visual-diagrams/assets/lwc/data-table.md +57 -0
- package/skills/generating-visual-diagrams/assets/lwc/record-form.md +60 -0
- package/skills/generating-visual-diagrams/assets/review/apex-review.md +57 -0
- package/skills/generating-visual-diagrams/assets/review/lwc-review.md +48 -0
- package/skills/generating-visual-diagrams/references/architect-aesthetic-guide.md +257 -0
- package/skills/generating-visual-diagrams/references/examples-index.md +35 -0
- package/skills/generating-visual-diagrams/references/gemini-cli-setup.md +65 -0
- package/skills/generating-visual-diagrams/references/interview-questions.md +529 -0
- package/skills/generating-visual-diagrams/references/iteration-workflow.md +173 -0
- package/skills/generating-visual-diagrams/scripts/check-prerequisites.sh +101 -0
- package/skills/generating-visual-diagrams/scripts/generate_image.py +243 -0
- package/skills/handling-sf-data/CREDITS.md +5 -0
- package/skills/handling-sf-data/README.md +112 -0
- package/skills/handling-sf-data/SKILL.md +235 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-10000.apex +293 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-200.apex +208 -0
- package/skills/handling-sf-data/assets/bulk/bulk-insert-500.apex +219 -0
- package/skills/handling-sf-data/assets/bulk/bulk-upsert-external-id.apex +324 -0
- package/skills/handling-sf-data/assets/cleanup/delete-by-created-date.apex +319 -0
- package/skills/handling-sf-data/assets/cleanup/delete-by-name.apex +240 -0
- package/skills/handling-sf-data/assets/cleanup/delete-test-data.apex +311 -0
- package/skills/handling-sf-data/assets/cleanup/rollback-transaction.apex +266 -0
- package/skills/handling-sf-data/assets/csv/account-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/contact-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/custom-object-import.csv +11 -0
- package/skills/handling-sf-data/assets/csv/opportunity-import.csv +11 -0
- package/skills/handling-sf-data/assets/factories/account-factory.apex +165 -0
- package/skills/handling-sf-data/assets/factories/case-factory.apex +237 -0
- package/skills/handling-sf-data/assets/factories/contact-factory.apex +168 -0
- package/skills/handling-sf-data/assets/factories/custom-object-factory.apex +260 -0
- package/skills/handling-sf-data/assets/factories/event-factory.apex +275 -0
- package/skills/handling-sf-data/assets/factories/hierarchy-factory.apex +372 -0
- package/skills/handling-sf-data/assets/factories/lead-factory.apex +190 -0
- package/skills/handling-sf-data/assets/factories/opportunity-factory.apex +206 -0
- package/skills/handling-sf-data/assets/factories/task-factory.apex +246 -0
- package/skills/handling-sf-data/assets/factories/user-factory.apex +278 -0
- package/skills/handling-sf-data/assets/json/account-contact-tree.json +130 -0
- package/skills/handling-sf-data/assets/json/account-opportunity-tree.json +110 -0
- package/skills/handling-sf-data/assets/json/full-hierarchy-tree.json +188 -0
- package/skills/handling-sf-data/assets/soql/aggregate.soql +226 -0
- package/skills/handling-sf-data/assets/soql/child-to-parent.soql +162 -0
- package/skills/handling-sf-data/assets/soql/parent-to-child.soql +153 -0
- package/skills/handling-sf-data/assets/soql/polymorphic.soql +198 -0
- package/skills/handling-sf-data/assets/soql/subquery.soql +287 -0
- package/skills/handling-sf-data/references/anonymous-apex-guide.md +98 -0
- package/skills/handling-sf-data/references/bulk-operations-guide.md +94 -0
- package/skills/handling-sf-data/references/bulk-testing-example.md +194 -0
- package/skills/handling-sf-data/references/cleanup-rollback-example.md +322 -0
- package/skills/handling-sf-data/references/cleanup-rollback-guide.md +84 -0
- package/skills/handling-sf-data/references/crud-workflow-example.md +183 -0
- package/skills/handling-sf-data/references/governor-limits-reference.md +74 -0
- package/skills/handling-sf-data/references/orchestration.md +174 -0
- package/skills/handling-sf-data/references/relationship-query-examples.md +249 -0
- package/skills/handling-sf-data/references/sf-cli-data-commands.md +158 -0
- package/skills/handling-sf-data/references/soql-relationship-guide.md +84 -0
- package/skills/handling-sf-data/references/test-data-best-practices.md +104 -0
- package/skills/handling-sf-data/references/test-data-factory-usage.md +290 -0
- package/skills/handling-sf-data/references/test-data-patterns.md +98 -0
- package/skills/handling-sf-data/scripts/soql_validator.py +292 -0
- package/skills/handling-sf-data/scripts/validate_data_operation.py +379 -0
- package/skills/harmonizing-datacloud/CREDITS.md +3 -0
- package/skills/harmonizing-datacloud/README.md +31 -0
- package/skills/harmonizing-datacloud/SKILL.md +117 -0
- package/skills/modeling-omnistudio-epc-catalog/CREDITS.md +14 -0
- package/skills/modeling-omnistudio-epc-catalog/README.md +89 -0
- package/skills/modeling-omnistudio-epc-catalog/SKILL.md +395 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/attribute-assignment-template.json +402 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/compiled-attribute-overrides-template.json +43 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/completion-block-template.txt +8 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/decomposition-relationships-template.json +233 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_AttributeAssignments.json +514 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_CompiledAttributeOverrides.json +21 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_DataPack.json +649 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_DecompositionRelationships.json +200 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ObjectFieldAttributes.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_OrchestrationScenarios.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_OverrideDefinitions.json +266 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ParentKeys.json +23 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_PriceListEntries.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_ProductChildItems.json +34 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-premium-fttc-simple-offer/Business-Internet-Premium-FTTC_RuleAssignments.json +21 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_AttributeAssignments.json +410 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_DataPack.json +535 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ObjectFieldAttributes.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_OrchestrationScenarios.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ParentKeys.json +23 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_PriceListEntries.json +220 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/business-internet-pro-vpl-simple-offer/Business-Internet-Pro-VPL_ProductChildItems.json +414 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_AttributeAssignments.json +382 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_DataPack.json +565 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ObjectFieldAttributes.json +104 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_OrchestrationScenarios.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ParentKeys.json +13 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_PriceListEntries.json +106 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/samsung-galaxy-s22-bundle/Samsung-Galaxy-S22-Bundle_ProductChildItems.json +72 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_AttributeAssignments.json +142 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_DataPack.json +377 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_DecompositionRelationships.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ObjectFieldAttributes.json +36 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ParentKeys.json +8 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_PriceListEntries.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_PricebookEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/examples/static-ip-simple-offer/Static-IP_ProductChildItems.json +34 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/object-field-attributes-template.json +138 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/orchestration-scenarios-template.json +54 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/override-definitions-template.json +134 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/parent-keys-template.json +29 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/price-list-entries-template.json +158 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/pricebook-entries-template.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/product-child-item-template.json +338 -0
- package/skills/modeling-omnistudio-epc-catalog/assets/product2-offer-template.json +527 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/.gitkeep +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_AttributeAssignments.json +95 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_CompiledAttributeOverrides.json +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_DataPack.json +214 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_DecompositionRelationships.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ObjectFieldAttributes.json +98 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_OrchestrationScenarios.json +22 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_OverrideDefinitions.json +1 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ParentKeys.json +13 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_PriceListEntries.json +35 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_PricebookEntries.json +28 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/Business-Internet-Plus_ProductChildItems.json +110 -0
- package/skills/modeling-omnistudio-epc-catalog/examples/business-internet-plus-bundle/TRANSCRIPT.md +58 -0
- package/skills/modeling-omnistudio-epc-catalog/references/epc-field-guide.md +90 -0
- package/skills/modeling-omnistudio-epc-catalog/references/naming-conventions.md +80 -0
- package/skills/modeling-omnistudio-epc-catalog/references/scoring-model.md +57 -0
- package/skills/modeling-omnistudio-epc-catalog/scripts/cli-validation-commands.sh +19 -0
- package/skills/modeling-omnistudio-epc-catalog/scripts/sample-invocations.sh +18 -0
- package/skills/orchestrating-datacloud/CREDITS.md +15 -0
- package/skills/orchestrating-datacloud/README.md +129 -0
- package/skills/orchestrating-datacloud/SKILL.md +236 -0
- package/skills/orchestrating-datacloud/UPSTREAM.md +45 -0
- package/skills/orchestrating-datacloud/assets/definitions/activation-target.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/activation.template.json +7 -0
- package/skills/orchestrating-datacloud/assets/definitions/calculated-insight.template.json +7 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-action-target.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-action.template.json +5 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-graph.template.json +21 -0
- package/skills/orchestrating-datacloud/assets/definitions/data-stream.template.json +55 -0
- package/skills/orchestrating-datacloud/assets/definitions/dmo.template.json +17 -0
- package/skills/orchestrating-datacloud/assets/definitions/identity-resolution.template.json +30 -0
- package/skills/orchestrating-datacloud/assets/definitions/mapping.template.json +14 -0
- package/skills/orchestrating-datacloud/assets/definitions/relationship.template.json +12 -0
- package/skills/orchestrating-datacloud/assets/definitions/search-index.template.json +9 -0
- package/skills/orchestrating-datacloud/assets/definitions/segment.template.json +16 -0
- package/skills/orchestrating-datacloud/references/feature-readiness.md +157 -0
- package/skills/orchestrating-datacloud/references/plugin-setup.md +140 -0
- package/skills/orchestrating-datacloud/scripts/bootstrap-plugin.sh +53 -0
- package/skills/orchestrating-datacloud/scripts/diagnose-org.mjs +511 -0
- package/skills/orchestrating-datacloud/scripts/generate-manifest.mjs +68 -0
- package/skills/orchestrating-datacloud/scripts/verify-plugin.sh +58 -0
- package/skills/preparing-datacloud/CREDITS.md +7 -0
- package/skills/preparing-datacloud/README.md +51 -0
- package/skills/preparing-datacloud/SKILL.md +191 -0
- package/skills/preparing-datacloud/examples/ingestion-api/.env.example +8 -0
- package/skills/preparing-datacloud/examples/ingestion-api/README.md +48 -0
- package/skills/preparing-datacloud/examples/ingestion-api/send-data.py +144 -0
- package/skills/querying-soql/CREDITS.md +21 -0
- package/skills/querying-soql/README.md +41 -0
- package/skills/querying-soql/SKILL.md +143 -0
- package/skills/querying-soql/assets/aggregate-queries.soql +242 -0
- package/skills/querying-soql/assets/basic-queries.soql +188 -0
- package/skills/querying-soql/assets/bulkified-query-pattern.cls +280 -0
- package/skills/querying-soql/assets/optimization-patterns.soql +259 -0
- package/skills/querying-soql/assets/relationship-queries.soql +203 -0
- package/skills/querying-soql/assets/selector-class.cls +219 -0
- package/skills/querying-soql/references/anti-patterns.md +348 -0
- package/skills/querying-soql/references/cli-commands.md +358 -0
- package/skills/querying-soql/references/field-coverage-rules.md +514 -0
- package/skills/querying-soql/references/query-optimization.md +142 -0
- package/skills/querying-soql/references/selector-patterns.md +479 -0
- package/skills/querying-soql/references/soql-reference.md +227 -0
- package/skills/querying-soql/references/soql-syntax-reference.md +208 -0
- package/skills/querying-soql/scripts/post-tool-validate.py +322 -0
- package/skills/retrieving-datacloud/CREDITS.md +7 -0
- package/skills/retrieving-datacloud/README.md +44 -0
- package/skills/retrieving-datacloud/SKILL.md +120 -0
- package/skills/retrieving-datacloud/examples/search-indexes/hybrid-structured.json +44 -0
- package/skills/retrieving-datacloud/examples/search-indexes/vector-knowledge.json +43 -0
- package/skills/running-apex-tests/CREDITS.md +22 -0
- package/skills/running-apex-tests/README.md +94 -0
- package/skills/running-apex-tests/SKILL.md +158 -0
- package/skills/running-apex-tests/assets/basic-test.cls +169 -0
- package/skills/running-apex-tests/assets/bulk-test.cls +255 -0
- package/skills/running-apex-tests/assets/dml-mock.cls +339 -0
- package/skills/running-apex-tests/assets/mock-callout-test.cls +353 -0
- package/skills/running-apex-tests/assets/stub-provider-example.cls +364 -0
- package/skills/running-apex-tests/assets/test-data-factory.cls +328 -0
- package/skills/running-apex-tests/hooks/scripts/parse-test-results.py +364 -0
- package/skills/running-apex-tests/references/cli-commands.md +289 -0
- package/skills/running-apex-tests/references/mocking-patterns.md +500 -0
- package/skills/running-apex-tests/references/performance-optimization.md +283 -0
- package/skills/running-apex-tests/references/test-fix-loop.md +49 -0
- package/skills/running-apex-tests/references/test-patterns.md +154 -0
- package/skills/running-apex-tests/references/testing-best-practices.md +509 -0
- package/skills/segmenting-datacloud/CREDITS.md +3 -0
- package/skills/segmenting-datacloud/README.md +36 -0
- package/skills/segmenting-datacloud/SKILL.md +115 -0
|
@@ -0,0 +1,719 @@
|
|
|
1
|
+
<!-- Parent: building-sf-integrations/SKILL.md -->
|
|
2
|
+
# Callout Patterns Reference
|
|
3
|
+
|
|
4
|
+
This document provides detailed implementation patterns for REST and SOAP callouts in Salesforce integrations.
|
|
5
|
+
|
|
6
|
+
> **Parent Document**: [building-sf-integrations/SKILL.md](../SKILL.md)
|
|
7
|
+
> **Related**: [event-patterns.md](./event-patterns.md)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Table of Contents
|
|
12
|
+
|
|
13
|
+
- [REST Callout Patterns](#rest-callout-patterns)
|
|
14
|
+
- [Synchronous REST Callout](#synchronous-rest-callout)
|
|
15
|
+
- [Asynchronous REST Callout (Queueable)](#asynchronous-rest-callout-queueable)
|
|
16
|
+
- [Retry Handler with Exponential Backoff](#retry-handler-with-exponential-backoff)
|
|
17
|
+
- [SOAP Callout Patterns](#soap-callout-patterns)
|
|
18
|
+
- [WSDL2Apex Process](#wsdl2apex-process)
|
|
19
|
+
- [SOAP Service Implementation](#soap-service-implementation)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## REST Callout Patterns
|
|
24
|
+
|
|
25
|
+
### Synchronous REST Callout
|
|
26
|
+
|
|
27
|
+
**Use Case**: Need immediate response, NOT triggered from DML
|
|
28
|
+
|
|
29
|
+
**Template**: `assets/callouts/rest-sync-callout.cls`
|
|
30
|
+
|
|
31
|
+
**When to Use**:
|
|
32
|
+
- User-initiated actions requiring immediate feedback
|
|
33
|
+
- API calls from Lightning Web Components
|
|
34
|
+
- Scheduled batch jobs needing sequential processing
|
|
35
|
+
- Any non-trigger context where response is needed
|
|
36
|
+
|
|
37
|
+
**When NOT to Use**:
|
|
38
|
+
- Triggered from DML operations (triggers, Process Builder, flows)
|
|
39
|
+
- Long-running operations (>10 seconds expected)
|
|
40
|
+
- High-volume batch operations
|
|
41
|
+
|
|
42
|
+
#### Implementation
|
|
43
|
+
|
|
44
|
+
```apex
|
|
45
|
+
public with sharing class {{ServiceName}}Callout {
|
|
46
|
+
|
|
47
|
+
private static final String NAMED_CREDENTIAL = 'callout:{{NamedCredentialName}}';
|
|
48
|
+
|
|
49
|
+
public static HttpResponse makeRequest(String method, String endpoint, String body) {
|
|
50
|
+
HttpRequest req = new HttpRequest();
|
|
51
|
+
req.setEndpoint(NAMED_CREDENTIAL + endpoint);
|
|
52
|
+
req.setMethod(method);
|
|
53
|
+
req.setHeader('Content-Type', 'application/json');
|
|
54
|
+
req.setTimeout(120000); // 120 seconds max
|
|
55
|
+
|
|
56
|
+
if (String.isNotBlank(body)) {
|
|
57
|
+
req.setBody(body);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Http http = new Http();
|
|
61
|
+
return http.send(req);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public static Map<String, Object> get(String endpoint) {
|
|
65
|
+
HttpResponse res = makeRequest('GET', endpoint, null);
|
|
66
|
+
return handleResponse(res);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public static Map<String, Object> post(String endpoint, Map<String, Object> payload) {
|
|
70
|
+
HttpResponse res = makeRequest('POST', endpoint, JSON.serialize(payload));
|
|
71
|
+
return handleResponse(res);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public static Map<String, Object> put(String endpoint, Map<String, Object> payload) {
|
|
75
|
+
HttpResponse res = makeRequest('PUT', endpoint, JSON.serialize(payload));
|
|
76
|
+
return handleResponse(res);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public static Map<String, Object> patch(String endpoint, Map<String, Object> payload) {
|
|
80
|
+
HttpResponse res = makeRequest('PATCH', endpoint, JSON.serialize(payload));
|
|
81
|
+
return handleResponse(res);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public static void deleteRequest(String endpoint) {
|
|
85
|
+
makeRequest('DELETE', endpoint, null);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private static Map<String, Object> handleResponse(HttpResponse res) {
|
|
89
|
+
Integer statusCode = res.getStatusCode();
|
|
90
|
+
|
|
91
|
+
if (statusCode >= 200 && statusCode < 300) {
|
|
92
|
+
return (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
|
|
93
|
+
} else if (statusCode >= 400 && statusCode < 500) {
|
|
94
|
+
throw new CalloutException('Client Error: ' + statusCode + ' - ' + res.getBody());
|
|
95
|
+
} else if (statusCode >= 500) {
|
|
96
|
+
throw new CalloutException('Server Error: ' + statusCode + ' - ' + res.getBody());
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### Key Features
|
|
105
|
+
|
|
106
|
+
- **Named Credential Integration**: Uses `callout:` syntax for secure authentication
|
|
107
|
+
- **Timeout Management**: 120-second max timeout (governor limit)
|
|
108
|
+
- **HTTP Method Support**: GET, POST, PUT, PATCH, DELETE
|
|
109
|
+
- **Status Code Handling**: Differentiates between client (4xx) and server (5xx) errors
|
|
110
|
+
- **JSON Serialization**: Automatic JSON handling for request/response bodies
|
|
111
|
+
|
|
112
|
+
#### Usage Example
|
|
113
|
+
|
|
114
|
+
```apex
|
|
115
|
+
// GET request
|
|
116
|
+
try {
|
|
117
|
+
Map<String, Object> data = StripeCallout.get('/v1/customers/cus_123');
|
|
118
|
+
String email = (String) data.get('email');
|
|
119
|
+
} catch (CalloutException e) {
|
|
120
|
+
// Handle error
|
|
121
|
+
System.debug(LoggingLevel.ERROR, 'Callout failed: ' + e.getMessage());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// POST request
|
|
125
|
+
Map<String, Object> payload = new Map<String, Object>{
|
|
126
|
+
'email' => 'customer@example.com',
|
|
127
|
+
'name' => 'John Doe'
|
|
128
|
+
};
|
|
129
|
+
Map<String, Object> response = StripeCallout.post('/v1/customers', payload);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### Asynchronous REST Callout (Queueable)
|
|
135
|
+
|
|
136
|
+
**Use Case**: Callouts triggered from DML (triggers, Process Builder)
|
|
137
|
+
|
|
138
|
+
**Template**: `assets/callouts/rest-queueable-callout.cls`
|
|
139
|
+
|
|
140
|
+
**When to Use**:
|
|
141
|
+
- Callouts from triggers (REQUIRED - sync callouts fail in triggers)
|
|
142
|
+
- Fire-and-forget operations (no immediate response needed)
|
|
143
|
+
- Bulk operations processing multiple records
|
|
144
|
+
- Long-running API calls (>10 seconds)
|
|
145
|
+
|
|
146
|
+
**Governor Limit Considerations**:
|
|
147
|
+
- Max 50 queueable jobs per transaction
|
|
148
|
+
- Queueable can chain to another queueable (max depth varies by org)
|
|
149
|
+
- Callout timeout: 120 seconds
|
|
150
|
+
|
|
151
|
+
#### Implementation
|
|
152
|
+
|
|
153
|
+
```apex
|
|
154
|
+
public with sharing class {{ServiceName}}QueueableCallout implements Queueable, Database.AllowsCallouts {
|
|
155
|
+
|
|
156
|
+
private List<Id> recordIds;
|
|
157
|
+
private String operation;
|
|
158
|
+
|
|
159
|
+
public {{ServiceName}}QueueableCallout(List<Id> recordIds, String operation) {
|
|
160
|
+
this.recordIds = recordIds;
|
|
161
|
+
this.operation = operation;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public void execute(QueueableContext context) {
|
|
165
|
+
if (recordIds == null || recordIds.isEmpty()) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
// Query records
|
|
171
|
+
List<{{ObjectName}}> records = [
|
|
172
|
+
SELECT Id, Name, {{FieldsToSend}}
|
|
173
|
+
FROM {{ObjectName}}
|
|
174
|
+
WHERE Id IN :recordIds
|
|
175
|
+
WITH USER_MODE
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
// Make callout for each record (consider batching)
|
|
179
|
+
for ({{ObjectName}} record : records) {
|
|
180
|
+
makeCallout(record);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
} catch (CalloutException e) {
|
|
184
|
+
// Log callout errors
|
|
185
|
+
System.debug(LoggingLevel.ERROR, 'Callout failed: ' + e.getMessage());
|
|
186
|
+
// Consider: Create error log record, retry logic, notification
|
|
187
|
+
} catch (Exception e) {
|
|
188
|
+
System.debug(LoggingLevel.ERROR, 'Error: ' + e.getMessage());
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private void makeCallout({{ObjectName}} record) {
|
|
193
|
+
HttpRequest req = new HttpRequest();
|
|
194
|
+
req.setEndpoint('callout:{{NamedCredentialName}}/{{Endpoint}}');
|
|
195
|
+
req.setMethod('POST');
|
|
196
|
+
req.setHeader('Content-Type', 'application/json');
|
|
197
|
+
req.setTimeout(120000);
|
|
198
|
+
|
|
199
|
+
Map<String, Object> payload = new Map<String, Object>{
|
|
200
|
+
'id' => record.Id,
|
|
201
|
+
'name' => record.Name
|
|
202
|
+
// Add more fields
|
|
203
|
+
};
|
|
204
|
+
req.setBody(JSON.serialize(payload));
|
|
205
|
+
|
|
206
|
+
Http http = new Http();
|
|
207
|
+
HttpResponse res = http.send(req);
|
|
208
|
+
|
|
209
|
+
if (res.getStatusCode() >= 200 && res.getStatusCode() < 300) {
|
|
210
|
+
// Success - update record status if needed
|
|
211
|
+
} else {
|
|
212
|
+
// Handle error
|
|
213
|
+
throw new CalloutException('API Error: ' + res.getStatusCode());
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### Trigger Integration
|
|
220
|
+
|
|
221
|
+
```apex
|
|
222
|
+
trigger OpportunityTrigger on Opportunity (after insert, after update) {
|
|
223
|
+
List<Id> opportunityIds = new List<Id>();
|
|
224
|
+
|
|
225
|
+
for (Opportunity opp : Trigger.new) {
|
|
226
|
+
// Only sync closed-won opportunities
|
|
227
|
+
if (opp.StageName == 'Closed Won') {
|
|
228
|
+
opportunityIds.add(opp.Id);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (!opportunityIds.isEmpty()) {
|
|
233
|
+
// Enqueue async callout
|
|
234
|
+
System.enqueueJob(new SalesforceQueueableCallout(opportunityIds, 'SYNC'));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### Bulkification Pattern
|
|
240
|
+
|
|
241
|
+
For high-volume scenarios, batch multiple callouts:
|
|
242
|
+
|
|
243
|
+
```apex
|
|
244
|
+
private void makeCallouts(List<{{ObjectName}}> records) {
|
|
245
|
+
// Batch up to 10 records per callout
|
|
246
|
+
Integer BATCH_SIZE = 10;
|
|
247
|
+
List<Map<String, Object>> batch = new List<Map<String, Object>>();
|
|
248
|
+
|
|
249
|
+
for (Integer i = 0; i < records.size(); i++) {
|
|
250
|
+
batch.add(buildPayload(records[i]));
|
|
251
|
+
|
|
252
|
+
if (batch.size() == BATCH_SIZE || i == records.size() - 1) {
|
|
253
|
+
// Make single callout with batch
|
|
254
|
+
sendBatch(batch);
|
|
255
|
+
batch.clear();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private void sendBatch(List<Map<String, Object>> batch) {
|
|
261
|
+
HttpRequest req = new HttpRequest();
|
|
262
|
+
req.setEndpoint('callout:{{NamedCredentialName}}/batch');
|
|
263
|
+
req.setMethod('POST');
|
|
264
|
+
req.setHeader('Content-Type', 'application/json');
|
|
265
|
+
req.setTimeout(120000);
|
|
266
|
+
req.setBody(JSON.serialize(new Map<String, Object>{'records' => batch}));
|
|
267
|
+
|
|
268
|
+
Http http = new Http();
|
|
269
|
+
HttpResponse res = http.send(req);
|
|
270
|
+
// Handle response
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
### Retry Handler with Exponential Backoff
|
|
277
|
+
|
|
278
|
+
**Use Case**: Handle transient failures with intelligent retry logic
|
|
279
|
+
|
|
280
|
+
**Template**: `assets/callouts/callout-retry-handler.cls`
|
|
281
|
+
|
|
282
|
+
**Retry Strategy**:
|
|
283
|
+
- **Max Retries**: 3 attempts
|
|
284
|
+
- **Backoff**: Exponential (1s, 2s, 4s)
|
|
285
|
+
- **Retry on**: 5xx server errors, network timeouts
|
|
286
|
+
- **Don't Retry**: 4xx client errors (bad request, auth failure)
|
|
287
|
+
|
|
288
|
+
#### Implementation
|
|
289
|
+
|
|
290
|
+
```apex
|
|
291
|
+
public with sharing class CalloutRetryHandler {
|
|
292
|
+
|
|
293
|
+
private static final Integer MAX_RETRIES = 3;
|
|
294
|
+
private static final Integer BASE_DELAY_MS = 1000; // 1 second
|
|
295
|
+
|
|
296
|
+
public static HttpResponse executeWithRetry(HttpRequest request) {
|
|
297
|
+
Integer retryCount = 0;
|
|
298
|
+
HttpResponse response;
|
|
299
|
+
|
|
300
|
+
while (retryCount < MAX_RETRIES) {
|
|
301
|
+
try {
|
|
302
|
+
Http http = new Http();
|
|
303
|
+
response = http.send(request);
|
|
304
|
+
|
|
305
|
+
// Success or client error (4xx) - don't retry
|
|
306
|
+
if (response.getStatusCode() < 500) {
|
|
307
|
+
return response;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Server error (5xx) - retry with backoff
|
|
311
|
+
retryCount++;
|
|
312
|
+
if (retryCount < MAX_RETRIES) {
|
|
313
|
+
// Exponential backoff: 1s, 2s, 4s
|
|
314
|
+
Integer delayMs = BASE_DELAY_MS * (Integer) Math.pow(2, retryCount - 1);
|
|
315
|
+
// Note: Apex doesn't have sleep(), so we schedule retry via Queueable
|
|
316
|
+
throw new RetryableException('Server error, retry ' + retryCount);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
} catch (CalloutException e) {
|
|
320
|
+
retryCount++;
|
|
321
|
+
if (retryCount >= MAX_RETRIES) {
|
|
322
|
+
throw e;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return response;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
public class RetryableException extends Exception {}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
#### Queueable Retry Pattern
|
|
335
|
+
|
|
336
|
+
Since Apex doesn't support `Thread.sleep()`, implement retry delays using Queueable chaining:
|
|
337
|
+
|
|
338
|
+
```apex
|
|
339
|
+
public with sharing class CalloutWithRetryQueueable implements Queueable, Database.AllowsCallouts {
|
|
340
|
+
|
|
341
|
+
private HttpRequest request;
|
|
342
|
+
private Integer retryCount;
|
|
343
|
+
private static final Integer MAX_RETRIES = 3;
|
|
344
|
+
|
|
345
|
+
public CalloutWithRetryQueueable(HttpRequest req) {
|
|
346
|
+
this(req, 0);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private CalloutWithRetryQueueable(HttpRequest req, Integer retries) {
|
|
350
|
+
this.request = req;
|
|
351
|
+
this.retryCount = retries;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
public void execute(QueueableContext context) {
|
|
355
|
+
try {
|
|
356
|
+
Http http = new Http();
|
|
357
|
+
HttpResponse res = http.send(request);
|
|
358
|
+
|
|
359
|
+
if (res.getStatusCode() >= 500 && retryCount < MAX_RETRIES) {
|
|
360
|
+
// Server error - retry
|
|
361
|
+
System.debug(LoggingLevel.WARN, 'Retry ' + (retryCount + 1) + ' for ' + request.getEndpoint());
|
|
362
|
+
System.enqueueJob(new CalloutWithRetryQueueable(request, retryCount + 1));
|
|
363
|
+
} else if (res.getStatusCode() >= 200 && res.getStatusCode() < 300) {
|
|
364
|
+
// Success
|
|
365
|
+
handleSuccess(res);
|
|
366
|
+
} else {
|
|
367
|
+
// Client error - don't retry
|
|
368
|
+
handleError(res);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
} catch (CalloutException e) {
|
|
372
|
+
if (retryCount < MAX_RETRIES) {
|
|
373
|
+
System.enqueueJob(new CalloutWithRetryQueueable(request, retryCount + 1));
|
|
374
|
+
} else {
|
|
375
|
+
throw e;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private void handleSuccess(HttpResponse res) {
|
|
381
|
+
// Process successful response
|
|
382
|
+
System.debug('Callout succeeded: ' + res.getBody());
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private void handleError(HttpResponse res) {
|
|
386
|
+
// Log error
|
|
387
|
+
System.debug(LoggingLevel.ERROR, 'Callout error: ' + res.getStatusCode() + ' - ' + res.getBody());
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
#### Idempotency Considerations
|
|
393
|
+
|
|
394
|
+
When implementing retries, ensure API operations are idempotent:
|
|
395
|
+
|
|
396
|
+
```apex
|
|
397
|
+
// BAD: Non-idempotent (creates new record on each retry)
|
|
398
|
+
POST /api/orders { "item": "Widget", "quantity": 1 }
|
|
399
|
+
|
|
400
|
+
// GOOD: Idempotent (uses idempotency key)
|
|
401
|
+
POST /api/orders
|
|
402
|
+
Headers: Idempotency-Key: {{recordId}}-{{timestamp}}
|
|
403
|
+
{ "item": "Widget", "quantity": 1 }
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## SOAP Callout Patterns
|
|
409
|
+
|
|
410
|
+
### WSDL2Apex Process
|
|
411
|
+
|
|
412
|
+
SOAP integrations in Salesforce use WSDL2Apex to auto-generate Apex classes from WSDL files.
|
|
413
|
+
|
|
414
|
+
#### Step-by-Step Process
|
|
415
|
+
|
|
416
|
+
**Step 1: Generate Apex from WSDL**
|
|
417
|
+
|
|
418
|
+
1. Navigate to **Setup** → **Apex Classes** → **Generate from WSDL**
|
|
419
|
+
2. Upload WSDL file or provide URL
|
|
420
|
+
3. Salesforce parses WSDL and generates:
|
|
421
|
+
- Stub class (contains service endpoint and operations)
|
|
422
|
+
- Request/Response classes (for each operation)
|
|
423
|
+
- Type classes (for complex data types)
|
|
424
|
+
|
|
425
|
+
**Step 2: Configure Named Credential**
|
|
426
|
+
|
|
427
|
+
Create a Named Credential for the SOAP endpoint:
|
|
428
|
+
|
|
429
|
+
```xml
|
|
430
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
431
|
+
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
432
|
+
<label>{{ServiceName}} SOAP</label>
|
|
433
|
+
<endpoint>https://api.example.com/soap/v1</endpoint>
|
|
434
|
+
<principalType>NamedUser</principalType>
|
|
435
|
+
<protocol>Password</protocol>
|
|
436
|
+
<username>{{Username}}</username>
|
|
437
|
+
<password>{{Password}}</password>
|
|
438
|
+
</NamedCredential>
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**Step 3: Use Generated Classes**
|
|
442
|
+
|
|
443
|
+
Generated classes follow this naming pattern:
|
|
444
|
+
- **Stub Class**: `{{WsdlNamespace}}.{{ServiceName}}`
|
|
445
|
+
- **Port Type**: `{{WsdlNamespace}}.{{PortTypeName}}`
|
|
446
|
+
- **Operations**: Methods on the port type class
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
### SOAP Service Implementation
|
|
451
|
+
|
|
452
|
+
**Template**: `assets/soap/soap-callout-service.cls`
|
|
453
|
+
|
|
454
|
+
#### Basic SOAP Callout
|
|
455
|
+
|
|
456
|
+
```apex
|
|
457
|
+
public with sharing class {{ServiceName}}SoapService {
|
|
458
|
+
|
|
459
|
+
public static {{ResponseType}} callService({{RequestType}} request) {
|
|
460
|
+
try {
|
|
461
|
+
// Generated stub class
|
|
462
|
+
{{WsdlGeneratedClass}}.{{PortType}} stub = new {{WsdlGeneratedClass}}.{{PortType}}();
|
|
463
|
+
|
|
464
|
+
// Set endpoint (use Named Credential if possible)
|
|
465
|
+
stub.endpoint_x = 'callout:{{NamedCredentialName}}';
|
|
466
|
+
|
|
467
|
+
// Set timeout
|
|
468
|
+
stub.timeout_x = 120000;
|
|
469
|
+
|
|
470
|
+
// Make the call
|
|
471
|
+
return stub.{{OperationName}}(request);
|
|
472
|
+
|
|
473
|
+
} catch (Exception e) {
|
|
474
|
+
System.debug(LoggingLevel.ERROR, 'SOAP Callout Error: ' + e.getMessage());
|
|
475
|
+
throw new CalloutException('SOAP service error: ' + e.getMessage());
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
#### Example: Weather Service SOAP Callout
|
|
482
|
+
|
|
483
|
+
**WSDL**: `https://your-external-system.com/service?wsdl` *(replace with your actual WSDL endpoint)*
|
|
484
|
+
|
|
485
|
+
**Generated Classes** (example based on a weather service WSDL):
|
|
486
|
+
- `GlobalWeatherSoap`
|
|
487
|
+
- `GetWeatherRequest`
|
|
488
|
+
- `GetWeatherResponse`
|
|
489
|
+
|
|
490
|
+
**Service Implementation**:
|
|
491
|
+
|
|
492
|
+
```apex
|
|
493
|
+
public with sharing class WeatherService {
|
|
494
|
+
|
|
495
|
+
public static String getWeather(String city, String country) {
|
|
496
|
+
try {
|
|
497
|
+
// Initialize SOAP stub
|
|
498
|
+
GlobalWeatherSoap.GlobalWeatherSoap stub =
|
|
499
|
+
new GlobalWeatherSoap.GlobalWeatherSoap();
|
|
500
|
+
|
|
501
|
+
// Configure endpoint and timeout
|
|
502
|
+
stub.endpoint_x = 'callout:GlobalWeather_NC';
|
|
503
|
+
stub.timeout_x = 120000;
|
|
504
|
+
|
|
505
|
+
// Build request
|
|
506
|
+
GlobalWeatherSoap.GetWeatherRequest req =
|
|
507
|
+
new GlobalWeatherSoap.GetWeatherRequest();
|
|
508
|
+
req.CityName = city;
|
|
509
|
+
req.CountryName = country;
|
|
510
|
+
|
|
511
|
+
// Make callout
|
|
512
|
+
GlobalWeatherSoap.GetWeatherResponse res = stub.GetWeather(req);
|
|
513
|
+
|
|
514
|
+
return res.GetWeatherResult;
|
|
515
|
+
|
|
516
|
+
} catch (System.CalloutException e) {
|
|
517
|
+
System.debug(LoggingLevel.ERROR, 'Weather API callout failed: ' + e.getMessage());
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
#### SOAP Headers and Authentication
|
|
525
|
+
|
|
526
|
+
For SOAP services requiring custom headers (e.g., WS-Security):
|
|
527
|
+
|
|
528
|
+
```apex
|
|
529
|
+
public with sharing class SecureSoapService {
|
|
530
|
+
|
|
531
|
+
public static void callServiceWithAuth(String username, String password) {
|
|
532
|
+
// Generated stub
|
|
533
|
+
MyService.MyServiceSoap stub = new MyService.MyServiceSoap();
|
|
534
|
+
|
|
535
|
+
// Set endpoint
|
|
536
|
+
stub.endpoint_x = 'callout:MyService_NC';
|
|
537
|
+
stub.timeout_x = 120000;
|
|
538
|
+
|
|
539
|
+
// Set SOAP headers for authentication
|
|
540
|
+
stub.inputHttpHeaders_x = new Map<String, String>{
|
|
541
|
+
'SOAPAction' => 'http://tempuri.org/IMyService/MyOperation',
|
|
542
|
+
'Authorization' => 'Basic ' + EncodingUtil.base64Encode(
|
|
543
|
+
Blob.valueOf(username + ':' + password)
|
|
544
|
+
)
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
// Make request
|
|
548
|
+
MyService.MyRequest req = new MyService.MyRequest();
|
|
549
|
+
MyService.MyResponse res = stub.MyOperation(req);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
#### SOAP Fault Handling
|
|
555
|
+
|
|
556
|
+
```apex
|
|
557
|
+
public with sharing class RobustSoapService {
|
|
558
|
+
|
|
559
|
+
public static Object callWithFaultHandling() {
|
|
560
|
+
try {
|
|
561
|
+
MyService.MyServiceSoap stub = new MyService.MyServiceSoap();
|
|
562
|
+
stub.endpoint_x = 'callout:MyService_NC';
|
|
563
|
+
stub.timeout_x = 120000;
|
|
564
|
+
|
|
565
|
+
MyService.MyRequest req = new MyService.MyRequest();
|
|
566
|
+
return stub.MyOperation(req);
|
|
567
|
+
|
|
568
|
+
} catch (System.CalloutException e) {
|
|
569
|
+
// Parse SOAP fault
|
|
570
|
+
String errorMessage = e.getMessage();
|
|
571
|
+
|
|
572
|
+
if (errorMessage.contains('faultcode')) {
|
|
573
|
+
// SOAP Fault occurred
|
|
574
|
+
System.debug(LoggingLevel.ERROR, 'SOAP Fault: ' + errorMessage);
|
|
575
|
+
// Extract fault details using XML parsing if needed
|
|
576
|
+
} else {
|
|
577
|
+
// Network/HTTP error
|
|
578
|
+
System.debug(LoggingLevel.ERROR, 'Callout error: ' + errorMessage);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
throw e;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
#### Async SOAP Callout (Queueable)
|
|
588
|
+
|
|
589
|
+
For SOAP callouts triggered from DML:
|
|
590
|
+
|
|
591
|
+
```apex
|
|
592
|
+
public with sharing class SoapQueueableCallout implements Queueable, Database.AllowsCallouts {
|
|
593
|
+
|
|
594
|
+
private List<Id> recordIds;
|
|
595
|
+
|
|
596
|
+
public SoapQueueableCallout(List<Id> recordIds) {
|
|
597
|
+
this.recordIds = recordIds;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
public void execute(QueueableContext context) {
|
|
601
|
+
try {
|
|
602
|
+
// Query records
|
|
603
|
+
List<Account> accounts = [
|
|
604
|
+
SELECT Id, Name, BillingCity, BillingCountry
|
|
605
|
+
FROM Account
|
|
606
|
+
WHERE Id IN :recordIds
|
|
607
|
+
WITH USER_MODE
|
|
608
|
+
];
|
|
609
|
+
|
|
610
|
+
// Initialize SOAP stub
|
|
611
|
+
GlobalWeatherSoap.GlobalWeatherSoap stub =
|
|
612
|
+
new GlobalWeatherSoap.GlobalWeatherSoap();
|
|
613
|
+
stub.endpoint_x = 'callout:GlobalWeather_NC';
|
|
614
|
+
stub.timeout_x = 120000;
|
|
615
|
+
|
|
616
|
+
// Process each record
|
|
617
|
+
for (Account acc : accounts) {
|
|
618
|
+
GlobalWeatherSoap.GetWeatherRequest req =
|
|
619
|
+
new GlobalWeatherSoap.GetWeatherRequest();
|
|
620
|
+
req.CityName = acc.BillingCity;
|
|
621
|
+
req.CountryName = acc.BillingCountry;
|
|
622
|
+
|
|
623
|
+
GlobalWeatherSoap.GetWeatherResponse res = stub.GetWeather(req);
|
|
624
|
+
|
|
625
|
+
// Update account with weather data
|
|
626
|
+
acc.Weather_Data__c = res.GetWeatherResult;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Update records
|
|
630
|
+
update as user accounts;
|
|
631
|
+
|
|
632
|
+
} catch (Exception e) {
|
|
633
|
+
System.debug(LoggingLevel.ERROR, 'SOAP Queueable error: ' + e.getMessage());
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
## Best Practices
|
|
642
|
+
|
|
643
|
+
### Callout Governor Limits
|
|
644
|
+
|
|
645
|
+
| Limit | Value | Notes |
|
|
646
|
+
|-------|-------|-------|
|
|
647
|
+
| Max callouts per transaction | 100 | Batch multiple requests if possible |
|
|
648
|
+
| Max timeout per callout | 120 seconds | Set explicitly with `setTimeout()` |
|
|
649
|
+
| Max total timeout per transaction | 120 seconds | All callouts combined |
|
|
650
|
+
| Max heap size | 6 MB (sync) / 12 MB (async) | Large responses consume heap |
|
|
651
|
+
|
|
652
|
+
### Security Checklist
|
|
653
|
+
|
|
654
|
+
- Use Named Credentials for authentication (NEVER hardcode credentials)
|
|
655
|
+
- Minimize OAuth scopes to least privilege
|
|
656
|
+
- Use Certificate-based auth for high-security integrations
|
|
657
|
+
- Validate SSL certificates (don't disable SSL verification)
|
|
658
|
+
- Sanitize user input before including in callout payloads
|
|
659
|
+
- Log callout errors without exposing sensitive data
|
|
660
|
+
|
|
661
|
+
### Error Handling Patterns
|
|
662
|
+
|
|
663
|
+
```apex
|
|
664
|
+
try {
|
|
665
|
+
HttpResponse res = makeCallout();
|
|
666
|
+
handleResponse(res);
|
|
667
|
+
} catch (System.CalloutException e) {
|
|
668
|
+
// Network error, timeout, SSL error
|
|
669
|
+
logError('Callout failed', e);
|
|
670
|
+
} catch (JSONException e) {
|
|
671
|
+
// Malformed JSON response
|
|
672
|
+
logError('JSON parsing failed', e);
|
|
673
|
+
} catch (Exception e) {
|
|
674
|
+
// Unexpected error
|
|
675
|
+
logError('Unexpected error', e);
|
|
676
|
+
}
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
### Testing Callouts
|
|
680
|
+
|
|
681
|
+
Use `Test.setMock()` to mock HTTP responses:
|
|
682
|
+
|
|
683
|
+
```apex
|
|
684
|
+
@isTest
|
|
685
|
+
private class MyCalloutTest {
|
|
686
|
+
|
|
687
|
+
@isTest
|
|
688
|
+
static void testSuccessfulCallout() {
|
|
689
|
+
// Set mock response
|
|
690
|
+
Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
|
|
691
|
+
|
|
692
|
+
Test.startTest();
|
|
693
|
+
Map<String, Object> result = MyService.get('/customers/123');
|
|
694
|
+
Test.stopTest();
|
|
695
|
+
|
|
696
|
+
System.assertEquals('customer@example.com', result.get('email'));
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// Mock class
|
|
700
|
+
private class MockHttpResponseGenerator implements HttpCalloutMock {
|
|
701
|
+
public HttpResponse respond(HttpRequest req) {
|
|
702
|
+
HttpResponse res = new HttpResponse();
|
|
703
|
+
res.setHeader('Content-Type', 'application/json');
|
|
704
|
+
res.setBody('{"email":"customer@example.com"}');
|
|
705
|
+
res.setStatusCode(200);
|
|
706
|
+
return res;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
---
|
|
713
|
+
|
|
714
|
+
## Related Resources
|
|
715
|
+
|
|
716
|
+
- [Event Patterns](./event-patterns.md) - Platform Events and Change Data Capture
|
|
717
|
+
- [Main Skill Documentation](../SKILL.md) - building-sf-integrations overview
|
|
718
|
+
- [Named Credentials Templates](../assets/named-credentials/) - Authentication templates
|
|
719
|
+
- [Callout Templates](../assets/callouts/) - Ready-to-use callout patterns
|