sf-integration について
sf-integrationは、Salesforceの連携設定とアーキテクチャ設計を扱うスキルです。認証情報、認証フロー、外部サービス、イベント機構を解説し、Apexのコールアウトコードとは範囲を分けています。
主な機能
- 01Named Credentialsと認証の設定
- 02Connected AppsとOAuthフローの設定
- 03OpenAPIベースのExternal Services登録
- 04Platform EventsとCDCの設計
- 05連携構成と移行方法の検討
活用シーン
- 01Salesforce APIの認証設定
- 02外部API操作をFlowで利用
- 03レコード変更やPlatform Eventsの購読
- 04Remote Site SettingsからNamed Credentialsへの移行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ clientell-ai/ salesforce-skills --skill sf-integrationインストール後、Claude Code で/sf-integrationを入力して読み込まれたか確認します。
同梱ファイルreferences/integration-reference.md
詳細
Salesforce 統合の設定とアーキテクチャ
Salesforce 統合アーキテクトとして、統合インフラストラクチャ(Named Credentials、Connected Apps、External Services、Platform Events、CDC、認証フロー)を設定します。メタデータのセットアップ、セキュリティ設定、アーキテクチャ上の判断に重点を置きます。
対象範囲:このスキルでは、統合の 設定とメタデータ を扱います。Apex のコールアウトコードパターン(HttpRequest、@RestResource、SOAP、モック)については、sf-apex integration patterns を参照してください。
1. Named Credentials
Named Credentials を使用すると、エンドポイント URL と認証をコードから分離できます。アーキテクチャは 2 種類あります。
Legacy Named Credentials
エンドポイントと認証を 1 つのメタデータファイルにまとめます。現在もサポートされていますが、制限があります。
<?xml version="1.0" encoding="UTF-8"?>
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyService</fullName>
<label>My Service</label>
<endpoint>https://api.example.com</endpoint>
<principalType>NamedUser</principalType>
<protocol>Password</protocol>
<username>api_user</username>
</NamedCredential>
Legacy の protocol 値:Password、Oauth、Jwt、JwtExchange、AwsSv4、NoAuthentication。
Enhanced Named Credentials(推奨)
役割を 2 種類のメタデータに分けます。
| コンポーネント | 用途 | ファイルのサフィックス |
|---|---|---|
| External Credential | 認証設定(プロトコル、プリンシパル、ID) | .externalCredential-meta.xml |
| Named Credential | エンドポイント URL。External Credential を参照します | .namedCredential-meta.xml |
External Credential を参照する Enhanced Named Credential:
<?xml version="1.0" encoding="UTF-8"?>
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyService</fullName>
<label>My Service</label>
<endpoint>https://api.example.com</endpoint>
<externalCredential>MyService_Auth</externalCredential>
<generateAuthorizationHeader>true</generateAuthorizationHeader>
<allowMergeFieldsInBody>false</allowMergeFieldsInBody>
<allowMergeFieldsInHeader>true</allowMergeFieldsInHeader>
</NamedCredential>
OAuth Client Credentials を使用する External Credential:
<?xml version="1.0" encoding="UTF-8"?>
<ExternalCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyService_Auth</fullName>
<label>My Service Auth</label>
<authenticationProtocol>Oauth</authenticationProtocol>
<externalCredentialParameters>
<parameterName>ClientId</parameterName>
<parameterType>AuthProviderUrl</parameterType>
<parameterValue>YOUR_CLIENT_ID</parameterValue>
</externalCredentialParameters>
<externalCredentialParameters>
<parameterName>Scope</parameterName>
<parameterType>AuthParameter</parameterType>
<parameterValue>api read</parameterValue>
</externalCredentialParameters>
<principals>
<principalName>MyServicePrincipal</principalName>
<principalType>NamedPrincipal</principalType>
<sequenceNumber>1</sequenceNumber>
</principals>
</ExternalCredential>
External Credential の権限セットマッピング
ユーザーは、権限セットマッピングを通じて External Credential にアクセスします。これを設定しないと、コールアウトが NAMED_CREDENTIAL_NOT_FOUND で失敗します。
<externalCredentialPrincipalAccesses>
<enabled>true</enabled>
<externalCredentialPrincipal>MyService_Auth - MyServicePrincipal</externalCredentialPrincipal>
</externalCredentialPrincipalAccesses>
使い分け
| シナリオ | 推奨事項 |
|---|---|
| 新しい統合 | Enhanced Named Credential + External Credential |
| シンプルな単一ユーザー認証 | Legacy Named Credential(使用可) |
| 同じ認証を使う複数のエンドポイント | 1 つの External Credential と複数の Named Credential |
| ユーザーごとの OAuth トークン | Per-User プリンシパルを使用する External Credential |
| Remote Site Settings からの移行 | 認証管理のため Named Credentials に移行 |
2. Connected Apps
Connected Apps は、Salesforce にアクセスする外部アプリケーション、または Salesforce 間の認証に使用する OAuth クライアント設定を定義します。
Connected App のメタデータ
<?xml version="1.0" encoding="UTF-8"?>
<ConnectedApp xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyConnectedApp</fullName>
<label>My Connected App</label>
<contactEmail>[email protected]</contactEmail>
<oauthConfig>
<callbackUrl>https://myapp.example.com/callback</callbackUrl>
<certificate>MyCertificateName</certificate>
<consumerKey>WILL_BE_GENERATED</consumerKey>
<isAdminApproved>true</isAdminApproved>
<isConsumerSecretOptional>false</isConsumerSecretOptional>
<scopes>Api</scopes>
<scopes>RefreshToken</scopes>
<scopes>OfflineAccess</scopes>
</oauthConfig>
<oauthPolicy>
<ipRelaxation>ENFORCE</ipRelaxation>
<refreshTokenPolicy>SPECIFIC_LIFETIME</refreshTokenPolicy>
<refreshTokenValidityPeriod>720</refreshTokenValidityPeriod>
<refreshTokenValidityUnits>HOURS</refreshTokenValidityUnits>
</oauthPolicy>
</ConnectedApp>
OAuth スコープのリファレンス
| スコープ値 | 意味 |
|---|---|
Api | REST/SOAP API へのアクセス |
Web | ブラウザー経由でのアクセス(Web スコープ) |
Full | フルアクセス(本番環境では避けてください) |
RefreshToken | リフレッシュトークンを有効化(offline_access) |
OfflineAccess | RefreshToken と同じ |
Chatter | Chatter REST API |
CustomPermissions | カスタム権限へのアクセス |
OpenID | OpenID Connect の ID |
Profile | ユーザープロファイル情報 |
Email | ユーザーのメールアドレス |
JWT Bearer Flow の設定
対話型ログインを必要としないサーバー間連携の場合:
- X.509 証明書を生成し、Connected App にアップロードします
- 統合ユーザーのプロファイルに対して Connected App を事前承認します
isAdminApprovedをtrueに設定します- クライアントは、秘密鍵で署名した JWT をトークンエンドポイントに送信します
- トークンエンドポイント:
https://login.salesforce.com/services/oauth2/token
Grant type:urn:ietf:params:oauth:grant-type:jwt-bearer
Web Server Flow の設定
ユーザー向けアプリケーションの場合:
- コールバック URL を設定します(HTTPS が必須で、完全一致する必要があります)
- 適切なスコープを設定します(
Fullは避けてください) - セキュリティ要件に基づいて IP 制限ポリシーを設定します
- リフレッシュトークンの有効期間を設定します
IP 制限のオプション
| 値 | 動作 |
|---|---|
ENFORCE | Connected App の IP 制限を適用します |
BYPASS | 組織の IP 制限をバイパスします |
BYPASS_WITH_VALID_BROWSER_SESSION | 有効なブラウザーセッションがある場合にのみバイパスします |
3. External Services
External Services を使用すると、OpenAPI 仕様を登録し、Flow、Einstein Bots、Apex で使用できる呼び出し可能なアクションを自動生成できます。
登録手順
- 外部 API エンドポイント用の名前付きクレデンシャルを作成します
- Setup > External Services に移動します
- OpenAPI(Swagger)仕様を指定します。URLを指定するか、JSON/YAMLを貼り付けます
- Salesforce がオペレーションを解析し、呼び出し可能なアクションを生成します
要件と制約
- OpenAPI 3.0 のみ(新規登録では 2.0/Swagger はサポートされません)
- 仕様のサイズ上限:100 KB
- 登録ごとのオペレーション数の上限:50
- すべてのオペレーションで、認証に名前付きクレデンシャルを使用します
- 生成されたアクションは、Flow の External Service アクションとして表示されます
- サポートされる HTTP メソッド:GET、POST、PUT、PATCH、DELETE
Flow での External Service の使用
登録後、各オペレーションが呼び出し可能なアクションになります。
- Flow Builder で、Action 要素を追加します
- カテゴリ「External Services」で絞り込みます
- オペレーション(例:
createOrder、getCustomer)を選択します - Flow の変数を入出力パラメーターに割り当てます
- 名前付きクレデンシャルが認証を自動的に処理します
External Service のメタデータ
<?xml version="1.0" encoding="UTF-8"?>
<ExternalServiceRegistration xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyExternalService</fullName>
<label>My External Service</label>
<namedCredential>MyService</namedCredential>
<schema>--- OpenAPI JSON spec inlined or referenced ---</schema>
<schemaType>OpenApi3</schemaType>
<serviceBinding>
<fieldName>operationName</fieldName>
<value>createOrder</value>
</serviceBinding>
<status>Complete</status>
</ExternalServiceRegistration>
4. プラットフォームイベント
Salesforce 内および外部システムとの間で、疎結合のイベント駆動型連携を実現するカスタムイベントバスです。
イベント定義
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Order_Event__e</fullName>
<label>Order Event</label>
<pluralLabel>Order Events</pluralLabel>
<publishBehavior>PublishAfterCommit</publishBehavior>
<fields>
<fullName>Order_Id__c</fullName>
<label>Order Id</label>
<type>Text</type>
<length>18</length>
</fields>
<fields>
<fullName>Action__c</fullName>
<label>Action</label>
<type>Text</type>
<length>50</length>
</fields>
<fields>
<fullName>Payload__c</fullName>
<label>Payload</label>
<type>LongTextArea</type>
<length>131072</length>
<visibleLines>5</visibleLines>
</fields>
</CustomObject>
発行動作
| 動作 | イベントが発行されるタイミング | 使用する場面 |
|---|---|---|
PublishAfterCommit | トランザクションが正常にコミットされた後 | デフォルトです。コミット済みデータを反映するイベントに使用します |
PublishImmediately | トランザクションがロールバックされる場合でも、直ちに | ロギング、監査、ファイア・アンド・フォーゲット通知 |
重要なルール:トランザクションがロールバックされると、PublishAfterCommit イベントは発行されません。PublishImmediately イベントはロールバックの有無にかかわらず発行されます。慎重に使用してください。
サブスクライバーのパターン
- Apex トリガー:
trigger OrderEventTrigger on Order_Event__e (after insert)-- 独自の実行コンテキストで実行されます - Flow:Platform Event-Triggered Flow を使用します(Record-Triggered Flow はサブスクライブできません)
- 外部:外部システムのサブスクライバーには、CometD または Pub/Sub API(gRPC)を使用します
リプレイと保持期間
- 標準プラットフォームイベント:24 時間保持され、Replay ID を使ってリプレイできます
- 大容量プラットフォームイベント:72 時間保持され、スループットが高くなります(150K/時間)
- サブスクライバーの障害後に特定の位置から再開するには、CometD または Pub/Sub API で
ReplayIdを使用します - サブスクライバーはリプレイ位置を設定できます:
-1(最新)、-2(保持されているすべてのイベント)、または特定の Replay ID
5. Change Data Capture(CDC)
作成、更新、削除、削除解除といったレコードの変更を、イベントバス上のイベントとしてストリーミングします。
CDC の有効化
- Setup > Change Data Capture
- 追跡するオブジェクト(標準またはカスタム)を選択します
- 変更は次のチャネルに発行されます:
/data/<ObjectName>ChangeEvent(例:/data/AccountChangeEvent)
カスタムオブジェクトの場合:/data/<CustomObject__c>ChangeEvent は /data/Custom_Object__ChangeEvent になります
ChangeEventHeader のフィールド
すべての CDC イベントには、変更メタデータを含むヘッダーがあります。
| フィールド | 説明 |
|---|---|
entityName | SObject の API 名 |
changeType | CREATE、UPDATE、DELETE、UNDELETE |
changedFields | 変更されたフィールドのリスト(UPDATE のみ) |
commitTimestamp | 変更がコミットされた日時 |
transactionKey | 同じトランザクションからの変更をまとめます |
sequenceNumber | トランザクション内の順序 |
recordIds | 変更されたレコードの ID |
commitUser | 変更を行ったユーザー |
commitNumber | 単調増加するコミットシーケンス |
CDC サブスクライバートリガー
trigger AccountChangeEventTrigger on AccountChangeEvent (after insert) {
for (AccountChangeEvent event : Trigger.new) {
EventBus.ChangeEventHeader header = event.ChangeEventHeader;
String changeType = header.getChangeType();
List<String> changedFields = header.getChangedFields();
if (changeType == 'UPDATE' && changedFields.contains('Rating')) {
// React to Rating field changes
for (String recordId : header.getRecordIds()) {
// Queue processing for each changed record
}
}
}
}
CDC とプラットフォームイベントの比較
| 項目 | CDC | プラットフォームイベント |
|---|---|---|
| トリガー | レコードの DML によって自動的に発生 | コード/Flow から明示的に発行 |
| スキーマ | SObject のフィールドを反映 | カスタム定義のフィールド |
| ユースケース | データ変更への対応 | ビジネスプロセスの疎結合化 |
| 保持期間 | 72 時間 | 24 時間(標準)/72 時間(大容量) |
| 外部サブスクライブ | Pub/Sub API、CometD | Pub/Sub API、CometD |
6. 送信メッセージング(レガシー)
ワークフロールールによってトリガーされる、SOAP ベースの送信通知です。レガシーパターンのため、新規開発では Platform Events を推奨します。
- ワークフロールールからのみ実行されます(Process Builder または Flow からは実行されません)
- SOAP 形式で、24 時間にわたり指数バックオフによる自動再試行が行われます
- エンドポイントは Ack ID を返す必要があります。確認応答があるか、24 時間のタイムアウトに達するまで再試行されます
- メッセージあたりのフィールド数は最大 100 個です
- 移行先:Platform Events(疎結合のパブリッシュ/サブスクライブ)、Flow + HTTP Callout(宣言型)、または Apex Callout(複雑なリクエスト/レスポンス)
7. Remote Site Settings と Named Credentials
移行パス
Remote Site Settings はエンドポイント URL のみを許可リストに追加します。Named Credentials はその上に認証管理機能を追加します。
| 機能 | Remote Site Setting | Named Credential |
|---|---|---|
| URL の許可リストへの追加 | はい | はい(暗黙的) |
| 認証管理 | いいえ(コード内で手動設定) | はい(自動) |
| 認証情報の保管 | 開発者の責任 | プラットフォーム管理 |
| 環境ごとの設定 | 手動 | 組み込み |
| マージフィールド | いいえ | はい(ヘッダー、本文、URL) |
| デプロイ可能 | はい | はい |
移行手順:
- Remote Site URL をエンドポイントとして Named Credential を作成します
- 認証プロトコル(OAuth、Password、JWT など)を設定します
- Apex コードを更新し、ハードコードされたエンドポイントを
callout:NamedCredentialNameに置き換えます - 認証ヘッダーの構築処理をコードから削除します
- Remote Site Setting を削除します
- 本番環境に移行する前にサンドボックスでテストします
8. 認証フローの選択ガイド
| フロー | ユースケース | クライアントタイプ | ユーザー操作 |
|---|---|---|---|
| JWT Bearer | サーバー間、CI/CD、バックエンド自動化 | 機密 | なし(事前承認済み) |
| Web Server(Auth Code) | ユーザーログインを伴う Web アプリ | 機密 | ブラウザーリダイレクト |
| Auth Code + PKCE | SPA、モバイルアプリ、パブリッククライアント | パブリック | ブラウザーリダイレクト |
| Client Credentials | M2M、サービスアカウント(ユーザーコンテキストなし) | 機密 | なし |
| Device Flow | CLI ツール、ヘッドレスデバイス、IoT | パブリックまたは機密 | 帯域外ユーザー認証 |
| Refresh Token | 再認証せずにセッションを維持 | どちらでも可 | なし(サイレント) |
判断ルール
- ユーザーコンテキストが不要ですか? Client Credentials(利用可能な場合)または JWT Bearer を使用します
- バックエンドサービスですか? X.509 証明書を使用する JWT Bearer を使用します
- ユーザー向け Web アプリですか? Web Server フローを使用します
- パブリッククライアント(SPA/モバイル)ですか? Auth Code + PKCE を使用します(必須)
- ブラウザーを使用できませんか? Device Flow を使用します
- 長期間のアクセスが必要ですか?
RefreshToken/OfflineAccessスコープを追加します
9. 注意点
Named Credentials
- 同期トランザクションあたりのコールアウト数は最大 100 件 です(すべての HTTP リクエストと共有されます)
- Enhanced Named Credentials では Permission Set のマッピングが必要です。設定しないとコールアウトは警告なく失敗します
- External Credential のパラメーター名では大文字と小文字が区別されます
- OAuth ヘッダーを自動挿入するには、
generateAuthorizationHeaderをtrueにする必要があります
Platform Events
- パブリッシュ上限は 1 時間あたり 150,000 イベント(大量処理用)です。標準の場合は 50,000 です
- トランザクションがロールバックされると、
PublishAfterCommitイベントは失われます。再試行はありません - 少なくとも 1 回の配信が行われます。サブスクライバーは冪等である必要があります
- サブスクライバーのトリガーが失敗すると、自動的に再試行されます(バックオフを伴い最大 8 回)
EventBus.publish()は例外をスローしません。エラーがないかSaveResultを確認してください
Change Data Capture
- リプレイ可能期間は 72 時間 です。72 時間より古いイベントは失われます
- CDC イベントは、デフォルトでは Bulk API 操作に対して発生しません(有効化が必要です)
- 大規模なトランザクションによる変更は、複数のイベントに分割されることがあります(
sequenceNumberを確認してください) - すべての標準オブジェクトで利用できるわけではありません。Salesforce のドキュメントを確認してください
External Services
- OpenAPI 3.0 のみ対応 です。Swagger 2.0 の仕様は変換する必要があります
- 仕様のサイズ上限は 100 KB です
- 登録あたりの操作数は最大 50 件です
- 複雑なネストされたスキーマは正しく解析されない場合があります。可能であればフラット化してください
接続済みアプリ
- 作成時にコンシューマーキー/シークレットが生成されます -- メタデータから設定できません
- JWT Bearer フローと Client Credentials フローには管理者の承認が必要です
- 証明書の有効期限が切れると、認証が気付かれないまま失敗します -- 監視してローテーションしてください
- IP 制限緩和ポリシーはユーザーの IP 制限ではなく、接続済みアプリに適用されます
- 接続済みアプリへの変更が反映されるまで最大 10 分かかります
全般
- 順序に注意しないと、同じトランザクション内で同期コールアウトと DML を混在させることはできません(コールアウトを DML より先に実行するか、
@future/Queueable を使用してください) - コールアウトのタイムアウト上限:1 リクエストあたり 120 秒、トランザクションあたり合計 120 秒
ワークフロー
- 上記の判断ガイドを使用して、統合パターンを特定します
- Glob と Grep を使用して、プロジェクト内の既存の統合メタデータを検索します
- Named Credential/External Credential/Connected App のメタデータを生成または更新します
- イベント駆動型の場合は、Platform Events または CDC を設定します
- 仕様駆動型の場合は、External Services を設定します
- External Credentials の Permission Set マッピングを確認します
- デプロイ方法を提案します:
sf project deploy start -d force-app/main/default/namedCredentials/
参考資料
- 統合リファレンス -- メタデータ XML テンプレート、認証フローの詳細、アーキテクチャの判断ガイド
- Apex 統合パターン -- コールアウトコード、@RestResource、SOAP、モック(別のスキル)
- ガバナー制限 -- トランザクションごとの制限