--- name: sf-integration description: > Creates comprehensive Salesforce integrations with 120-point scoring. Use when setting up Named Credentials, External Services, REST/SOAP callouts, Platform Events, Change Data Capture, or connecting Salesforce to external systems. license: MIT metadata: version: "1.2.0" author: "Jag Valaiyapathy" scoring: "120 points across 6 categories" hooks: PreToolUse: - matcher: Bash hooks: - type: command command: "python3 ${SHARED_HOOKS}/scripts/guardrails.py" timeout: 5000 PostToolUse: - matcher: Write hooks: - type: command command: "python3 ${SKILL_HOOKS}/suggest_credential_setup.py" timeout: 5000 - type: command command: "python3 ${SKILL_HOOKS}/validate_integration.py" timeout: 10000 - type: command command: "python3 ${SHARED_HOOKS}/suggest-related-skills.py sf-integration" timeout: 5000 - matcher: Edit hooks: - type: command command: "python3 ${SKILL_HOOKS}/suggest_credential_setup.py" timeout: 5000 - type: command command: "python3 ${SHARED_HOOKS}/suggest-related-skills.py sf-integration" timeout: 5000 SubagentStop: - type: command command: "python3 ${SHARED_HOOKS}/scripts/chain-validator.py sf-integration" timeout: 5000 --- # sf-integration: Salesforce Integration Patterns Expert Expert integration architect specializing in secure callout patterns, event-driven architecture, and external service registration for Salesforce. ## Core Responsibilities 1. **Named Credential Generation**: Create Named Credentials with OAuth 2.0, JWT Bearer, Certificate, or Custom authentication 2. **External Credential Generation**: Create modern External Credentials (API 61+) with Named Principals 3. **External Service Registration**: Generate ExternalServiceRegistration metadata from OpenAPI/Swagger specs 4. **REST Callout Patterns**: Synchronous and asynchronous HTTP callout implementations ([details](resources/callout-patterns.md#rest-callout-patterns)) 5. **SOAP Callout Patterns**: WSDL2Apex guidance and WebServiceCallout patterns ([details](resources/callout-patterns.md#soap-callout-patterns)) 6. **Platform Events**: Event definitions, publishers, and subscriber triggers ([details](resources/event-patterns.md#platform-events)) 7. **Change Data Capture**: CDC enablement and subscriber patterns ([details](resources/event-patterns.md#change-data-capture-cdc)) 8. **Validation & Scoring**: Score integrations against 6 categories (0-120 points) ## Key Insights | Insight | Details | Action | |---------|---------|--------| | **Named Credential Architecture** | Legacy (pre-API 61) vs External Credentials (API 61+) | Check org API version first | | **Callouts in Triggers** | Synchronous callouts NOT allowed in triggers | Always use async (Queueable, @future) | | **Governor Limits** | 100 callouts per transaction, 120s timeout max | Batch callouts, use async patterns | | **External Services** | Auto-generates Apex from OpenAPI specs | Requires Named Credential for auth | --- ## ⚠️ CRITICAL: Named Credential Architecture (API 61+) ### Legacy Named Credentials vs External Credentials | Feature | Legacy Named Credential | External Credential (API 61+) | |---------|------------------------|------------------------------| | **API Version** | Pre-API 61 | API 61+ (Winter '24+) | | **Principal Concept** | Single principal per credential | Named Principal + Per-User Principal | | **OAuth Support** | Basic OAuth 2.0 | Full OAuth 2.0 + PKCE, JWT | | **Permissions** | Profile-based | Permission Set + Named Principal | | **Recommendation** | Legacy orgs only | **Use for all new development** | ### Decision Matrix ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ WHEN TO USE WHICH CREDENTIAL TYPE │ ├─────────────────────────────────────────────────────────────────────────────┤ │ Use LEGACY Named Credential if: │ │ • Org API version < 61 │ │ • Migrating existing integrations (maintain compatibility) │ │ • Simple API key / Basic Auth (quick setup) │ │ │ │ Use EXTERNAL Credential (API 61+) if: │ │ • New development (recommended) │ │ • OAuth 2.0 with PKCE required │ │ • Per-user authentication needed │ │ • Fine-grained permission control required │ │ • JWT Bearer flow for server-to-server │ └─────────────────────────────────────────────────────────────────────────────┘ ``` --- ## Workflow (5-Phase Pattern) ### Phase 1: Requirements Gathering Use `AskUserQuestion` to gather: 1. **Integration Type**: Outbound REST/SOAP, Inbound REST, Event-driven (Platform Events, CDC) 2. **Authentication Method**: OAuth 2.0 (Client Credentials, JWT Bearer, Authorization Code), Certificate-based, API Key/Basic Auth 3. **External System Details**: Base endpoint URL, API version, rate limits, required headers 4. **Sync vs Async Requirements**: Real-time response needed → Sync | Fire-and-forget or DML-triggered → Async (Queueable) ### Phase 2: Template Selection | Integration Need | Template | Location | |-----------------|----------|----------| | **Named Credentials** | `oauth-client-credentials.namedCredential-meta.xml` | `templates/named-credentials/` | | **External Credentials** | `oauth-external-credential.externalCredential-meta.xml` | `templates/external-credentials/` | | **External Services** | `openapi-registration.externalServiceRegistration-meta.xml` | `templates/external-services/` | | **REST Callouts** | `rest-sync-callout.cls`, `rest-queueable-callout.cls` | `templates/callouts/` | | **SOAP Callouts** | `soap-callout-service.cls` | `templates/soap/` | | **Platform Events** | `platform-event-definition.object-meta.xml` | `templates/platform-events/` | | **CDC Subscribers** | `cdc-subscriber-trigger.trigger` | `templates/cdc/` | ### Phase 3: Generation & Validation **File Locations**: ``` force-app/main/default/ ├── namedCredentials/ # Legacy Named Credentials ├── externalCredentials/ # External Credentials (API 61+) ├── externalServiceRegistrations/ ├── classes/ # Callout services, handlers ├── objects/{{EventName}}__e/ # Platform Events └── triggers/ # Event/CDC subscribers ``` **Validate using scoring system** (see [Scoring System](#scoring-system-120-points) below) ### Phase 4: Deployment **Deployment Order** (CRITICAL): ``` 1. Named Credentials / External Credentials FIRST 2. External Service Registrations (depends on Named Credentials) 3. Apex classes (callout services, handlers) 4. Platform Events / CDC configuration 5. Triggers (depends on events being deployed) ``` **Use sf-deploy skill**: `Skill(skill="sf-deploy")` **CLI Commands**: See [CLI Commands Reference](#cli-commands-reference) ### Phase 5: Testing & Verification 1. **Test Named Credential**: Setup → Named Credentials → Test Connection 2. **Test External Service**: Invoke generated Apex methods 3. **Test Callout**: Anonymous Apex or test class with `Test.setMock()` 4. **Test Events**: Publish and verify subscriber execution --- ## Named Credentials | Auth Type | Use Case | Template | Key Config | |-----------|----------|----------|------------| | **OAuth 2.0 Client Credentials** | Server-to-server, no user context | `oauth-client-credentials.namedCredential-meta.xml` | scope, tokenEndpoint | | **OAuth 2.0 JWT Bearer** | CI/CD, backend services | `oauth-jwt-bearer.namedCredential-meta.xml` | Certificate + Connected App | | **Certificate (Mutual TLS)** | High-security integrations | `certificate-auth.namedCredential-meta.xml` | Client cert required | | **Custom (API Key/Basic)** | Simple APIs | `custom-auth.namedCredential-meta.xml` | username/password | Templates in `templates/named-credentials/`. ⚠️ **NEVER hardcode credentials** - always use Named Credentials! --- ## External Credentials (API 61+) **Use Case**: Modern OAuth 2.0 with per-user or named principal authentication **Template**: `templates/external-credentials/oauth-external-credential.externalCredential-meta.xml` **Key Features**: - Named Principal vs Per-User Principal support - OAuth 2.0 with PKCE - JWT Bearer flow - Permission Set-based access control **Quick Start**: ```xml Oauth {{PrincipalName}} NamedPrincipal ``` --- ## External Services (OpenAPI/Swagger) **Process**: 1. Obtain OpenAPI 2.0 (Swagger) or 3.0 spec from external API 2. Create Named Credential for authentication 3. Register External Service in Salesforce (Setup → External Services OR via metadata) 4. Salesforce auto-generates Apex classes: `ExternalService.{{ServiceName}}` **Template**: `templates/external-services/openapi-registration.externalServiceRegistration-meta.xml` **CLI Alternative**: ```bash sf api request rest /services/data/v62.0/externalServiceRegistrations \ --method POST \ --body '{"label":"{{Label}}","namedCredential":"{{NC}}","schemaUrl":"{{URL}}"}' ``` **Usage Example**: ```apex ExternalService.Stripe stripe = new ExternalService.Stripe(); ExternalService.Stripe_createCustomer_Request req = new ExternalService.Stripe_createCustomer_Request(); req.email = 'customer@example.com'; ExternalService.Stripe_createCustomer_Response resp = stripe.createCustomer(req); ``` --- ## Callout Patterns ### REST Callouts **For detailed REST callout patterns, see [resources/callout-patterns.md](resources/callout-patterns.md)** #### Quick Reference | Pattern | Use Case | Template | |---------|----------|----------| | **Synchronous** | User-initiated, need immediate response | `rest-sync-callout.cls` | | **Asynchronous (Queueable)** | Triggered from DML (triggers), fire-and-forget | `rest-queueable-callout.cls` | | **Retry Handler** | Handle transient failures with exponential backoff | `callout-retry-handler.cls` | **Key Points**: - Use Named Credentials: `req.setEndpoint('callout:{{NamedCredentialName}}/{{path}}')` - Set timeout: `req.setTimeout(120000)` (120s max) - Handle status codes: 2xx success, 4xx client error (don't retry), 5xx server error (retry) **Detailed Examples**: - [Synchronous REST Callout](resources/callout-patterns.md#synchronous-rest-callout) - [Asynchronous Queueable Callout](resources/callout-patterns.md#asynchronous-rest-callout-queueable) - [Retry Handler with Exponential Backoff](resources/callout-patterns.md#retry-handler-with-exponential-backoff) ### SOAP Callouts **For detailed SOAP callout patterns, see [resources/callout-patterns.md#soap-callout-patterns](resources/callout-patterns.md#soap-callout-patterns)** #### Quick Reference **WSDL2Apex Process**: 1. Setup → Apex Classes → Generate from WSDL 2. Upload WSDL file 3. Salesforce generates stub classes **Usage**: ```apex {{WsdlGeneratedClass}}.{{PortType}} stub = new {{WsdlGeneratedClass}}.{{PortType}}(); stub.endpoint_x = 'callout:{{NamedCredentialName}}'; stub.timeout_x = 120000; return stub.{{OperationName}}(request); ``` **Detailed Examples**: - [WSDL2Apex Process](resources/callout-patterns.md#wsdl2apex-process) - [SOAP Service Implementation](resources/callout-patterns.md#soap-service-implementation) --- ## Event-Driven Patterns ### Platform Events **For detailed Platform Event patterns, see [resources/event-patterns.md#platform-events](resources/event-patterns.md#platform-events)** #### Quick Reference **Event Types**: - **Standard Volume**: ~2,000 events/hour, 3-day retention - **High Volume**: Millions/day, 24-hour retention, at-least-once delivery **Templates**: - Event Definition: `templates/platform-events/platform-event-definition.object-meta.xml` - Publisher: `templates/platform-events/event-publisher.cls` - Subscriber: `templates/platform-events/event-subscriber-trigger.trigger` **Publishing**: ```apex List results = EventBus.publish(events); ``` **Subscribing**: ```apex trigger {{EventName}}Subscriber on {{EventName}}__e (after insert) { for ({{EventName}}__e event : Trigger.new) { {{EventName}}Handler.processEvent(event); } } ``` **Detailed Examples**: - [Platform Event Definition](resources/event-patterns.md#platform-event-definition) - [Event Publisher](resources/event-patterns.md#event-publisher) - [Event Subscriber Trigger](resources/event-patterns.md#event-subscriber-trigger) ### Change Data Capture (CDC) **For detailed CDC patterns, see [resources/event-patterns.md#change-data-capture-cdc](resources/event-patterns.md#change-data-capture-cdc)** #### Quick Reference **Enablement**: Setup → Integrations → Change Data Capture **Channel Naming**: `{{ObjectAPIName}}ChangeEvent` (e.g., `AccountChangeEvent`) **Subscriber Template**: ```apex trigger {{ObjectName}}CDCSubscriber on {{ObjectName}}ChangeEvent (after insert) { for ({{ObjectName}}ChangeEvent event : Trigger.new) { EventBus.ChangeEventHeader header = event.ChangeEventHeader; String changeType = header.getChangeType(); // CREATE, UPDATE, DELETE, UNDELETE List changedFields = header.getChangedFields(); String recordId = header.getRecordIds()[0]; switch on changeType { when 'CREATE' { {{ObjectName}}CDCHandler.handleCreate(event); } when 'UPDATE' { {{ObjectName}}CDCHandler.handleUpdate(event, changedFields); } when 'DELETE' { {{ObjectName}}CDCHandler.handleDelete(recordId); } when 'UNDELETE' { {{ObjectName}}CDCHandler.handleUndelete(event); } } } } ``` **Detailed Examples**: - [CDC Enablement](resources/event-patterns.md#cdc-enablement) - [CDC Subscriber Trigger](resources/event-patterns.md#cdc-subscriber-trigger) - [CDC Handler Service](resources/event-patterns.md#cdc-handler-service) --- ## Scoring System (120 Points) ### Category Breakdown | Category | Points | Evaluation Criteria | |----------|--------|---------------------| | **Security** | 30 | Named Credentials used (no hardcoded secrets), OAuth scopes minimized, certificate auth where applicable | | **Error Handling** | 25 | Retry logic present, timeout handling (120s max), specific exception types, logging implemented | | **Bulkification** | 20 | Batch callouts considered, CDC bulk handling, event batching for Platform Events | | **Architecture** | 20 | Async patterns for DML-triggered callouts, proper service layer separation, single responsibility | | **Best Practices** | 15 | Governor limit awareness, proper HTTP methods, idempotency for retries | | **Documentation** | 10 | Clear intent documented, endpoint versioning noted, API contract documented | ### Scoring Thresholds ``` Score: XX/120 Rating ├─ ⭐⭐⭐⭐⭐ Excellent (108-120): Production-ready, follows all best practices ├─ ⭐⭐⭐⭐ Very Good (90-107): Minor improvements suggested ├─ ⭐⭐⭐ Good (72-89): Acceptable with noted improvements ├─ ⭐⭐ Needs Work (54-71): Address issues before deployment └─ ⭐ Block (<54): CRITICAL issues, do not deploy ``` ### Scoring Output Format ``` 📊 INTEGRATION SCORE: XX/120 ⭐⭐⭐⭐ Rating ════════════════════════════════════════════════════ 🔐 Security XX/30 ████████░░ XX% ├─ Named Credentials used: ✅ ├─ No hardcoded secrets: ✅ └─ OAuth scopes minimal: ✅ ⚠️ Error Handling XX/25 ████████░░ XX% ├─ Retry logic: ✅ ├─ Timeout handling: ✅ └─ Logging: ✅ 📦 Bulkification XX/20 ████████░░ XX% ├─ Batch callouts: ✅ └─ Event batching: ✅ 🏗️ Architecture XX/20 ████████░░ XX% ├─ Async patterns: ✅ └─ Service separation: ✅ ✅ Best Practices XX/15 ████████░░ XX% ├─ Governor limits: ✅ └─ Idempotency: ✅ 📝 Documentation XX/10 ████████░░ XX% ├─ Clear intent: ✅ └─ API versioning: ✅ ════════════════════════════════════════════════════ ``` --- ## Cross-Skill Integration | To Skill | When to Use | |----------|-------------| | sf-connected-apps | OAuth Connected App for Named Credential | | sf-apex | Custom callout service beyond templates | | sf-metadata | Query existing Named Credentials | | sf-deploy | Deploy to org | | sf-ai-agentscript | Agent action using External Service | | sf-flow | HTTP Callout Flow for agent | ### Agentforce Integration Flow `sf-integration` → Named Credential + External Service → `sf-flow` → HTTP Callout wrapper → `sf-ai-agentscript` → Agent with `flow://` target → `sf-deploy` → Deploy all --- ## CLI Commands Reference ### Named Credentials ```bash # List Named Credentials sf org list metadata --metadata-type NamedCredential --target-org {{alias}} # Deploy Named Credential sf project deploy start --metadata NamedCredential:{{Name}} --target-org {{alias}} # Retrieve Named Credential sf project retrieve start --metadata NamedCredential:{{Name}} --target-org {{alias}} ``` ### External Services ```bash # List External Service Registrations sf org list metadata --metadata-type ExternalServiceRegistration --target-org {{alias}} # Deploy External Service sf project deploy start --metadata ExternalServiceRegistration:{{Name}} --target-org {{alias}} ``` ### Platform Events ```bash # List Platform Events sf org list metadata --metadata-type CustomObject --target-org {{alias}} | grep "__e" # Deploy Platform Event sf project deploy start --metadata CustomObject:{{EventName}}__e --target-org {{alias}} ``` --- ## 🔧 Helper Scripts sf-integration includes automation scripts to configure credentials without manual UI steps. ### Available Scripts | Script | Purpose | Usage | |--------|---------|-------| | `configure-named-credential.sh` | Set API keys via ConnectApi (Enhanced NC) | `./scripts/configure-named-credential.sh ` | | `set-api-credential.sh` | Store keys in Custom Settings (legacy) | `./scripts/set-api-credential.sh - ` | ### Auto-Run Behavior When you create credential metadata files, Claude automatically suggests running the appropriate script: | File Pattern | Suggested Action | |--------------|------------------| | `*.namedCredential-meta.xml` | Run `configure-named-credential.sh` | | `*.externalCredential-meta.xml` | Run `configure-named-credential.sh` | | `*.cspTrustedSite-meta.xml` | Deploy endpoint security | ### Example Workflow ```bash # 1. Claude generates credential metadata files # 2. Hook detects and suggests next steps # 3. Deploy metadata first sf project deploy start --metadata ExternalCredential:WeatherAPI \ --metadata NamedCredential:WeatherAPI \ --target-org MyOrg # 4. Run automation script ./scripts/configure-named-credential.sh MyOrg # Enter API key when prompted (secure, hidden input) ``` ### Prerequisites - **Salesforce CLI v2+**: `sf` command available - **Authenticated org**: `sf org login web -a ` - **Deployed metadata**: External Credential and Named Credential deployed 📚 **Documentation**: See [docs/named-credentials-automation.md](docs/named-credentials-automation.md) for complete guide. --- ## Anti-Patterns | Anti-Pattern | Problem | Correct Pattern | |--------------|---------|-----------------| | Hardcoded credentials | Security vulnerability, credential rotation nightmare | Use Named Credentials | | Sync callout in trigger | `CalloutException: Uncommitted work pending` | Use Queueable with `Database.AllowsCallouts` | | No timeout specified | Default 10s may be too short | Set `req.setTimeout(120000)` (max 120s) | | No retry logic | Transient failures cause data loss | Implement exponential backoff | | Ignoring status codes | Silent failures | Check `statusCode` and handle 4xx/5xx | | 100+ callouts per transaction | Governor limit exceeded | Batch callouts, use async | | No logging | Can't debug production issues | Log all callout requests/responses | | Exposing API errors to users | Security risk, poor UX | Catch and wrap in user-friendly messages | --- ## Additional Resources 📚 **Detailed Documentation**: - [Callout Patterns](resources/callout-patterns.md) - REST and SOAP callout implementations - [Event Patterns](resources/event-patterns.md) - Platform Events and Change Data Capture - [Messaging API v2](docs/messaging-api-v2.md) - **NEW**: MIAW custom client architecture (Agentforce external chat) 📁 **Templates**: - `templates/named-credentials/` - Authentication templates - `templates/external-credentials/` - External Credential templates (API 61+) - `templates/external-services/` - OpenAPI registration templates - `templates/callouts/` - REST/SOAP callout patterns - `templates/platform-events/` - Event definitions and publishers - `templates/cdc/` - Change Data Capture triggers --- ## Notes & Dependencies - **API Version**: 62.0+ (Winter '25) recommended for External Credentials - **Required Permissions**: API Enabled, External Services access - **Optional Skills**: sf-connected-apps (OAuth setup), sf-apex (custom callout code), sf-deploy (deployment) - **Scoring Mode**: Strict (block deployment if score < 54) --- ## License MIT License - See LICENSE file for details.