概要
Salesforce の Campaign Member(Contact / Lead)が追加された際に、自動で SendWOW のオーダーを作成するための連携手順です。
本ドキュメントについて
シンプルな最小構成での連携を想定しています。
- 送付物(Touch)・作成者・承認者・配送日数は固定値で運用
-
オーダーは必ず承認者付き(
assigned_toあり)で作成し、SendWOW 画面での人間チェックを挟む - 別途こういうことがしたいなどの相談はCPにご相談ください
全体構成
[Salesforce]
CampaignMember 作成
│
▼
Record-Triggered Flow
│ ・WhoType で Contact / Lead 判定
│ ・Contact / Lead から氏名等を取得
│ ・固定値(Custom Label)と組み合わせて payload を構築
│
▼
HTTP Callout (Named Credential 経由)
POST https://api.sendwow.jp/public/v1/{team_id}/orders/
Header: X-Sendwow-Secret-Key
│
▼
[SendWOW]
SendWOW 画面で承認者がチェック・承認
│
▼
オーダー確定 → 発送 / デジタルギフトリンク発行
事前準備(SendWOW 側)
Salesforce 側の設定
1. 外部ログイン情報 (External Credential) の作成
設定 → セキュリティ → 指定ログイン情報 画面の 「外部ログイン情報」タブ で新規作成します。シークレットキー本体はここに格納します。
| 項目 | 値 |
|---|---|
| 表示ラベル | SendWOW Public API |
| 名前 | SendWOW_Public_API |
| 認証プロトコル | カスタム (Custom) |
保存後、同画面の詳細ページで以下を追加します。
プリンシパル (Principals)
| 項目 | 値 |
|---|---|
| パラメーター名 | 任意(例: SendWOW Secret) |
| シーケンス番号 | 1 |
| ID 種別 | 名前付きプリンシパル (Named Principal) |
| 認証パラメーター | 名前: SecretKey / 値: <SendWOW から提供されたシークレットキー>
|
カスタムヘッダー
| 名前 | 値 |
|---|---|
X-Sendwow-Secret-Key |
{!$Credential.SendWOW_Public_API.SecretKey} |
$Credential.<外部ログイン情報の名前>.<パラメーター名> です。外部ログイン情報の「名前」やパラメーター名を変更するとここの参照も壊れるので注意。
2. 指定ログイン情報 (Named Credential) の作成
同じ 設定 → セキュリティ → 指定ログイン情報 画面の 「指定ログイン情報」タブ で新規作成し、1. で作った外部ログイン情報を紐付けます。
| 項目 | 値 |
|---|---|
| 表示ラベル | SendWOW Public API |
| 名前 | SendWOW_Public_API |
| URL | https://api.sendwow.jp |
| 有効 | ✓ |
| 外部ログイン情報 | 1. で作成した SendWOW_Public_API
|
| HTTP ヘッダーで数式を許可 | ✓ |
| コールアウトに HTTP ヘッダーを生成 | ✓ |
3. 権限セット (Permission Set) の作成と付与
外部ログイン情報は 権限セット経由でアクセス許可しないと Flow から呼び出せません(新方式の最大のハマりポイント)。
-
設定 → ユーザー → 権限セットで新規作成(例:SendWOW API Access) - 権限セット詳細 → 外部ログイン情報プリンシパルアクセス (External Credential Principal Access) → 1. で作った外部ログイン情報のプリンシパルを追加
-
Flow を実行するユーザーに権限セットを割り当てる
- Record-Triggered Flow がトリガーユーザーのコンテキストで動く場合: 対象ユーザー全員に付与
- Flow を「システムコンテキスト」で実行する設定にしている場合: 自動プロセスユーザー (Automated Process User) への割り当てが必要なケースあり
4. 外部サービス登録 (OpenAPI スキーマ アップロード)
Flow から SendWOW API を呼び出すための HTTP コールアウト を、OpenAPI 3.0 スキーマファイルから登録します。スキーマを使うと Salesforce が自動で Apex 型を生成し、Flow Builder で型補完が効くようになります。
4-1. OpenAPI スキーマファイルの準備
-
設定 → 統合 → 外部サービス→ 「新規外部サービス」 - 「API 仕様から」 を選択
- ウィザードで以下を入力:
- 外部サービス名:
SendWOWCreateOrder - 指定ログイン情報: 2. で作成した
SendWOW_Public_API - サービススキーマソース: 完全なスキーマ
yaml openapi: 3.0.3 info: title: SendWOW Public API description: | SendWOW のオーダー作成用 Public API。 Salesforce External Services 向けに最小化したスキーマ。 version: "1.0.0" servers: - url: https://api.sendwow.jp description: Production paths: /public/v1/{team_id}/orders/: post: operationId: createOrder summary: SendWOW オーダーを作成する parameters: - name: team_id in: path required: true description: SendWOW チーム ID (UUID) schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateOrderRequest' responses: '201': description: オーダー作成成功 content: application/json: schema: $ref: '#/components/schemas/CreateOrderResponse' '400': description: バリデーションエラー '403': description: シークレットキー不正 '404': description: チームまたはユーザーが見つからない components: schemas: CreateOrderRequest: type: object required: [contact, touch_id, created_by] properties: contact: $ref: '#/components/schemas/Contact' touch_id: { type: string } created_by: { type: string } assigned_to: { type: string } shipping_date: { type: string } Contact: type: object required: [last_name] properties: last_name: { type: string } first_name: { type: string } email: { type: string } department: { type: string } job_title: { type: string } crm: { type: string } crm_id: { type: string } shipping_address: $ref: '#/components/schemas/Address' account: $ref: '#/components/schemas/Account' Account: type: object properties: name: { type: string } site_url: { type: string } shipping_address: $ref: '#/components/schemas/Address' Address: type: object properties: postcode: { type: string } pref: { type: string } city: { type: string } street1: { type: string } street2: { type: string } CreateOrderResponse: type: object properties: id: { type: string }
- 外部サービス名:
- 「保存 & 次へ」→ 操作一覧で
createOrderを選択 → 「保存」で登録完了
5. Flow 作成 + Apex 型リソース変数の事前作成
Flow 本体の組み立て前に、Apex 型のリソース変数を5つまとめて作成しておきます。こうしておくと Assignment を組む際に「リソース新規作成 → 戻る」の往復が不要になります。
5-1. Flow 新規作成(トリガー設定のみ)
設定 → プロセス自動化 → フロー で新規作成します。
| 項目 | 値 |
|---|---|
| Flow 種類 | レコードトリガーフロー |
| オブジェクト | CampaignMember |
| トリガー | レコードが作成されたとき |
| 実行条件 | (シンプル運用なら条件なし) |
| 最適化 | 「アクションと関連レコード」 |
5-2. Apex 型リソース変数の作成
Flow Builder のツールボックス → 「新規リソース」 で以下5つを作成します。いずれも リソースタイプ: 変数 / データ型: Apex 定義 で、Apex クラスは 4. で生成された型を選びます。
| API 参照名 | Apex クラス | 用途 |
|---|---|---|
varOrderBody |
ExternalService__SendWOWCreateOrder_CreateOrderRequest |
API リクエスト本体 |
varContact |
ExternalService__SendWOWCreateOrder_Contact |
contact オブジェクト |
varContactShippingAddress |
ExternalService__SendWOWCreateOrder_Address |
contact.shipping_address |
varAccount |
ExternalService__SendWOWCreateOrder_Account |
contact.account |
varAccountShippingAddress |
ExternalService__SendWOWCreateOrder_Address |
contact.account.shipping_address |
6. Flow の組み立て
- で作った Flow に、以下の要素を順番に追加していきます。
6-1. レコードを取得(Get Records): Contact
| 項目 | 値 |
|---|---|
| API 参照名 | Contact |
| オブジェクト | Contact |
| 条件 |
Id Equals {!$Record.ContactId}
|
| 取得するレコード | 最初のレコードのみ |
6-2. レコードを取得(Get Records): Account
| 項目 | 値 |
|---|---|
| API 参照名 | Account |
| オブジェクト | Account |
| 条件 |
Id Equals {!Contact.AccountId}
|
| 取得するレコード | 最初のレコードのみ |
6-3. 割り当て(Assignment) ×5(内側のネストから順に組み立て)
ContactShippingAddress(Assignment 1): contact.shipping_address を組み立てる
-
{!varContactShippingAddress.postcode}={!Contact.MailingPostalCode} -
{!varContactShippingAddress.pref}={!Contact.MailingState} -
{!varContactShippingAddress.city}={!Contact.MailingCity} -
{!varContactShippingAddress.street1}={!Contact.MailingStreet}
AccountShippingAddress(Assignment 2): contact.account.shipping_address を組み立てる
-
{!varAccountShippingAddress.postcode}={!Account.ShippingPostalCode} -
{!varAccountShippingAddress.pref}={!Account.ShippingState} -
{!varAccountShippingAddress.city}={!Account.ShippingCity} -
{!varAccountShippingAddress.street1}={!Account.ShippingStreet}
ContactAccount(Assignment 3): contact.account を組み立てる
-
{!varAccount.name}={!Account.Name} -
{!varAccount.sitex5furl}={!Account.Website} -
{!varAccount.shippingx5faddress}={!varAccountShippingAddress}
ContactObj(Assignment 4): contact を組み立てる
-
{!varContact.lastx5fname}={!Contact.LastName} -
{!varContact.firstx5fname}={!Contact.FirstName} -
{!varContact.email}={!Contact.Email} -
{!varContact.department}={!Contact.Department} -
{!varContact.jobx5ftitle}={!Contact.Title} -
{!varContact.crm}=salesforce_contact -
{!varContact.crmx5fid}={!$Record.ContactId} -
{!varContact.shippingx5faddress}={!varContactShippingAddress} -
{!varContact.account}={!varAccount}
Order(Assignment 5): リクエスト本体を組み立てる
-
{!varOrderBody.contact}={!varContact} -
{!varOrderBody.touchx5fid}= 提供された Touch ID (例:a2be5b2b-33bf-48a7-aa2e-500fe340965e) -
{!varOrderBody.createdx5fby}= 提供された作成者 email -
{!varOrderBody.assignedx5fto}= 提供された承認者 email -
{!varOrderBody.shippingx5fdate}= 配送希望日 (YYYY-MM-DD)
6-4. アクション: SendWOW オーダー作成
| 項目 | 値 |
|---|---|
| アクション | カテゴリ「外部サービス」→ SendWOWCreateOrder → createOrder
|
| team_id | 提供された Team ID |
| body | {!varOrderBody} |
オプション・Decision: Callout 成功 / 失敗
- 成功時 (201): 終了
- 失敗時(デフォルト): Fault Path で管理者へメール通知
6-5. Flowの有効化
画面右上の有効可をクリックして有効可してください
リクエストペイロード(参考)
以下は SendWOW Public API のリクエスト / レスポンス仕様の参考情報です。Flow からは 4. でアップロードした OpenAPI スキーマに基づく Apex 型変数 (5-2 で作成) を組み立てて送信します。
エンドポイント
POST https://api.sendwow.jp/public/v1/{team_id}/orders/
| ヘッダー | 値 |
|---|---|
X-Sendwow-Secret-Key |
SendWOW で発行したシークレットキー |
Content-Type |
application/json |
リクエストボディ(送る商品によってフォーマットが変わるのでCPに相談ください)
{
"contact": {
"last_name": "{!varContact.LastName}",
"first_name": "{!varContact.FirstName}",
"email": "{!varContact.Email}",
"department": "{!varContact.Department}",
"job_title": "{!varContact.Title}",
"crm": "salesforce_contact",
"crm_id": "{!$Record.ContactId}",
"shipping_address": {
"postcode": "{!varContact.MailingPostalCode}",
"pref": "{!varContact.MailingState}",
"city": "{!varContact.MailingCity}",
"street1": "{!varContact.MailingStreet}",
"street2": ""
},
"account": {
"name": "{!varAccount.Name}",
"site_url": "{!varAccount.Website}",
"shipping_address": {
"postcode": "{!varAccount.ShippingPostalCode}",
"pref": "{!varAccount.ShippingState}",
"city": "{!varAccount.ShippingCity}",
"street1": "{!varAccount.ShippingStreet}",
"street2": ""
}
}
},
"touch_id": "a2be5b2b-33bf-48a7-aa2e-500fe340965e",
"created_by": "shirokura.takumi@smapo.co",
"assigned_to": "shirokura.takumi@smapo.co",
"shipping_date": "1970-01-01"
}
レスポン例
{
"id": "0190c2d3-4567-7abc-89de-f0123456789a"
}