Salesforce側にいる営業から「あの顧客、サポートと何をやり取りしてるの?」と聞かれて、すぐに答えられますか?
本記事はZendesk ↔ Salesforceの公式連携(無料)を無料アカウントだけで検証した記録です。追加ライセンスなしでどこまでできるのか、足りない1ピースの補い方までわかります。
1. はじめに:この記事が解決する課題
解決したい課題は次の1文です。
Salesforce側にいる人が、Zendeskで進行している顧客とのサポート対応を追いたい
検証環境について
Salesforce Developer Edition(無料・無期限)+ Zendesk無料トライアル(14日・クレジットカード不要)の組み合わせで、本記事の内容はすべて再現できます。検証手順は4章にまとめています。
2. まずお見せします:連携するとSalesforceがこうなる
設定を終えると、Salesforce側はこう変わります。
- ✅ 取引先責任者ページに「この顧客の今の問い合わせ」がCase関連リストとして並ぶ(取引先ページならその会社の全担当者分がまとめて見える)
- ✅ ケースを開けば、Zendeskチケットのやり取りがパネルでその場で読める(リアルタイム)
- ✅ 「どの顧客がどれだけ問い合わせているか」「解決までどれくらいかかっているか」が標準のレポート/ダッシュボードで見える
- ✅ チケットのステータス更新を起点に「解決したら担当営業に通知」のようなフローが組める
- ✅ ZendeskチケットURL項目からワンクリックでZendeskへジャンプできる
ただし「やり取りの中身そのものをSalesforceのレコードとして残したい」場合は追加の工夫が必要です(理由と対策は6章・8章で解説します)。
必要なのはこの2点だけです。
- 追加ライセンス 不要(連携自体はZendesk Marketplaceで「Free integration」)
- Zendeskは Suite/Support Team以上、Salesforceは Enterprise / Unlimited / Performance / Developer エディション(ProfessionalはAPIアドオンが必要)
3. 前提整理:概念の対応と連携の全体像
3-1 Salesforce読者のためのZendeskの概念
Zendesk側の用語はSalesforceとほぼ1:1で対応すると考えると読みやすくなります。
| Zendesk | Salesforce | 備考 |
|---|---|---|
| 組織(Organization) | 取引先(Account) | 顧客企業1社を表す |
| ユーザー(User) | 取引先責任者(Contact) | 問い合わせてくる個人。メール受信で自動作成される |
| チケット(Ticket) | Case | 問い合わせ1件。ライフサイクルを持つ |
3-2 公式連携の4機能マップと依存関係
公式連携は「接続」した後に、以下の4機能を個別に有効化する構成です。
| # | 機能 | 方向 | 何をするか |
|---|---|---|---|
| ⓪ | データ同期 | SF → ZD | Account→組織、Contact→ユーザーとして取り込む |
| ① | チケット同期 | ZD → SF | チケットをCaseとして作成・更新する |
| ② | Salesforceトリガー | SF → ZD | Case作成を起点にZendeskチケットを自動作成する |
| ③ | チケットビュー | SF上に表示 | Salesforce画面にZendeskチケットの閲覧パネルを置く |
②を有効にすると、SalesforceでCaseを作成したタイミングでZendeskチケットが自動生成されます。生成されたチケットでの対応・ステータス変化は①でCaseに戻るので、①+②で「Salesforceで起票→Zendeskで対応→Salesforceで状況把握」という往復が回ります。逆に、顧客からのメールで生えたZendeskチケットを①でCase化する使い方だけでもよく、②は必須ではありません(条件ベースのルールなので、起票したいCaseだけに絞ることもできます)。
重要な依存関係が2つあります。
- ⓪が①の基盤: チケット同期がCaseの「問い合わせ件名/取引先」を解決するには、Zendesk側のユーザー/組織とSalesforce側のContact/Accountの対応が取れている必要があり、それを作るのが⓪です
- 照合キーは「組織=名前」「責任者=メールアドレス」: データ同期はAccount名と組織名の一致でペアリングし(Zendesk内で名前の一意性が前提。同名組織があると同期エラー)、Contactはメールアドレスで照合します。同期後はSalesforceのレコードIDがZendesk側のexternal IDに入り、リンク管理されます
「同期(①⓪:データをコピーする)」と「可視化(③:コピーせず参照する)」は別物、という軸で頭に入れておくと、この連携の設計が読みやすくなります。
4. 【環境構築】無料アカウントではじめる
| 環境 | 条件 | |
|---|---|---|
| Salesforce | Developer Edition | 無料・無期限。公式連携の対応エディションにDeveloperが明記されている |
| Zendesk | 無料トライアル | 14日間・クレジットカード不要 |
Dev Editionにした理由は期限がないことと、接続ユーザー=自分(初期管理者)で権限回りがシンプルなためです。Zendesk側は14日で消えますが、本命の設定・データはすべてSalesforce側に残る構成なので、検証には十分です。
セットアップ手順:
-
developer.salesforce.com/signupからDeveloper Editionを作成 - テスト用のAccountとContactを1件ずつ作成
- 設定 → セキュリティ → セッション設定で「Lock sessions to the IP address」を外す(接続要件)
- Zendeskトライアルを開始
- Zendesk管理センター → Apps and integrations → Integrations → Salesforce → Add connection → Productionを選択し、OAuthでSF管理者ログイン
- ⓪データ同期を有効化し、テスト用Account/Contactを更新してZendesk側に流しておく(6章の紐づけ検証の布石)
- ①チケット同期をConfigureで有効化(Salesforce側のCaseにカスタム項目が自動作成される)
- ②Salesforceトリガーで「Case作成→チケット生成」のルールを設定
- ③チケットビューを有効化(次の2点も参照)
- (管理者以外でのパネル表示を確認する場合)Salesforceライセンス+標準プロファイルのテストユーザーを作成。※Force.com系ライセンスで作るとCRMオブジェクト自体が見えず、原因の切り分けに時間を取られます
My Domain: LightningページにZendeskコンポーネントを置くにはMy Domainのデプロイが必要です。近年作成した組織なら最初からデプロイ済み(設定で「My Domain」を検索してステータスがDeployedか確認)です。無ければその場で数分でデプロイできます。
管理者以外にもパネルを見せる場合: 追加の設定が必要です(Connected Appのプロファイル割当+Zendeskカスタム項目への参照権限。手順と実測の詳細は7章参照)。
5. 【検証①】データ同期(SF→ZD)の実態
5-1 組織紐づけの実態(実測)
まず基本事実: Zendesk側では、メールでの問い合わせだけでは組織は作られません(自動作成されるのはユーザーだけです)。SalesforceのAccountからZendesk組織を自動作成する主たる経路がこのデータ同期で、3-2で述べた「①チケット同期のCase紐づけの基盤」もここで作られます。
「リクエスターがどの組織に属しているか」が、同期されたCaseの「取引先」の成否を左右します。検証結果は次の2点に集約されます。
| # | シナリオ | 結果 |
|---|---|---|
| A | SalesforceのContactを同期して作られたユーザー | ✅ 同期時に組織所属も自動で付く(Contactの所属Accountに対応する組織) |
| B | SFに未登録のアドレスからの新規チケット | ❌ 組織なし。同期されたCaseの「取引先」も空になる(リクエスター名/メール項目では追える) |
運用の指針はシンプルです: 問い合わせ元はSFのContactとして登録し、同期で組織所属を付けるのが一次経路。未登録アドレスの初回メールで取引先が空になるのは想定の挙動で、SF側にContactを足して同期すれば以降は紐づきます。なお、未登録ユーザーをドメインで自動所属させる補完も、Zendesk側で組織にドメインを手動設定すれば使えますが、このドメイン値はデータ同期のマッピングでは流せませんでした(実測: マッピング先の一覧にDomainsが出ないため、Zendesk側での直接管理になります)。
5-2 いつ動くか
データ同期はイベント駆動です。Salesforceのレコードが(API経由で)作成・更新されると、同期条件を満たしたものがZendeskに反映されます。裏ではSalesforceのStreaming API(Push Topic購読)が使われています。
つまり:
- 有効化後に作成・更新されたレコード → 同期される
- 有効化前から存在し、その後一度も更新されないレコード → いつまでも同期されない
5-3 既存データの一括取り込み
有効化前から存在するAccount/Contactも、一度更新イベントを起こせば同期されます。公式ガイド(How do I sync many Accounts, Contacts or Leads at once)で案内されている手順の要約です。
- Salesforce側にチェックボックス項目(例: 「Sync with Salesforce」)を作成
- Data Loader等で対象レコードのチェックボックスを一括オンに更新
- 更新イベントが同期を発火し、Zendeskに組織/ユーザーとして流れ込む
チェックボックスの中身自体に意味はなく、「全件に更新イベントを起こす」ための仕掛けです。無害な項目に同じ値を書き込む一括更新でも同じ効果があります。実行時の注意点:
-
名前の衝突: Zendesk側に同名の組織が既にあると
Name or Email has already been takenエラーで同期が落ちます。過去に手動で組織を作り込んでいた場合は、先にZendesk側を整理(削除またはリネーム)してから実行 - API上限: 一括更新はSalesforce APIを消費します。大量件数は分割実行を(Dev Editionのような上限の小さい組織では特に)
- 一度同期されれば、以後の作成・更新は自動で伝播します
「最初の一括取り込みだけ手作業、以後は自動」という運用で落ち着くのが一般的です。
5-4 「作らない・消さない」設計
検証して印象的だったのは、Salesforceのマスタを連携が一切書き換えない点です。
| 機能 | Salesforce側 | Zendesk側 |
|---|---|---|
| ⓪データ同期 | 読み取りのみ | 組織/ユーザーを作成・更新 |
| ①チケット同期 | Caseを作成・更新のみ(Account/Contactは参照解決のみ) | 読み取り |
| ②SFトリガー | 読み取り | チケットを作成 |
| ③チケットビュー | 読み取り専用 | API参照のみ |
- SalesforceのAccount/Contactを連携が作成・削除することはない(マスタはSFが正という設計)
- チケット同期では、リクエスターの名前とメールアドレスを常に専用カスタム項目(
Zendesk_Support_Ticket_Requester_Name__c/_Email__c)に記録します。一方でCaseの「問い合わせ件名(ContactId)」は既存Contactと照合して解決できた場合のみ埋まり、解決できなければ空になります(Contactを新規作成することはない。名前/メール項目が残っているので、リンクがなくても誰からの問い合わせかは追える)
5-5 削除は伝播しない
どちら方向にも削除は伝播しません。
- SF側でAccount/Contactを削除 → Zendesk側の組織/ユーザーは残る(孤立レコード)
- Zendeskチケットを削除 → SalesforceのCaseは残る
運用としては、external ID(同期時にSFのAccount IDがZendesk組織に入る)で突合して定期的にクリーンアップする、SF側での整理は削除ではなくマージや有効/無効フラグで行う(更新イベントは伝播するため)、がおすすめです。
6. 【検証②】チケット同期(ZD→SF):Caseに入るもの・入らないもの
まず前提として、SalesforceのCaseにはやり取りの中身を入れる「箱」が複数用意されています。
Case(問い合わせ案件1件)
│ Subject(件名)/ Status / Priority / Type / Origin
│ Description(最初の問い合わせ本文を置く想定のロングテキスト)
│ ContactId(問い合わせ件名)/ AccountId(取引先)
├──< CaseComment ← 対応の往復コメント
├──< EmailMessage ← 実際に送受信したメール本体
├──< Task / Event ← 活動
└──< Attachment / Files
Salesforce自身のサポート機能(Email-to-Case等)はこれらの箱を自動で埋めます。ではZendesk公式連携はこの箱のどこまでを埋めるのか——検証結果を見ていきます。
6-1 入るもの(標準マッピング)
| Zendeskチケット | Salesforce Case |
|---|---|
| Subject | 件名 |
| Status / Priority / Type | ステータス / 優先度 / タイプ |
| Description(最初のコメント) | 説明 |
| Ticket ID | Zendesk_Support_Ticket_ID__c |
| Requester 名/メール | Zendesk_Support_Ticket_Requester_Name__c / _Email__c |
| 組織 | 取引先(AccountId)※紐づけが解決できる場合 |
| リクエスター | 問い合わせ件名(ContactId)※同上 |
| Tags / URL / ブランド / チケットフォーム名 | 各種カスタム項目 |
| 解決時間(カレンダー/営業時間)、解決日時 | 各種カスタム項目 |
6-2 入らないもの
公式ドキュメントに明記されています:
"Ticket comments are not synced to a case field"(チケットコメントはケース項目に同期されない)
つまりCaseの説明に入るのは最初のコメント(問い合わせ本文)だけで、2回目以降の往復(公開・非公開問わず)はSalesforce側のどこにも記録されません。加えて:
- 添付ファイルは同期されない
- クローズ済みチケットは同期されない
また同期はイベント駆動なので、連携より前のチケットは遡りません。切り替え時期を決めて「◯日以降の対応はSalesforceで見える」と周知する運用が必要です。
6-3 Contact/Accountが解決される条件
Caseの「問い合わせ件名」「取引先」が埋まるには、Zendesk側のリクエスター/組織とSalesforce側のレコードの対応が取れている必要があります。どの条件で埋まるかは5-1の実測表(A〜E)のとおりです(対応が取れない場合は空になり、その場合もリクエスター名/メールのカスタム項目には記録されます)。
6-4 はまりどころ:同期トリガー
チケット同期を有効化すると、Zendesk側に「(Salesforce Integration) Sync tickets to Salesforce」トリガーとWebhookが自動作成されます。
- どのチケットを同期するかはこのトリガーの条件で制御できる(条件は編集可)
- トリガー/Webhookの削除・リネームは禁止
- チケットが同期されないときは、まずこのトリガーが有効か・条件に合致しているかを確認
7. 【検証③】チケットビュー:見えるけど view only
チケットビューは、SalesforceのページにZendeskチケットの閲覧パネルを埋め込む機能です。Account / Contact / Lead / Case / Opportunityページに置けます。表示の既定の照合条件は次の通りです。
| ページ | チケットの表示条件 |
|---|---|
| 取引先 / 商談 | Zendesk組織名 = Salesforce取引先名 |
| 取引先責任者 / リード | リクエスターのメール = レコードのメールアドレス |
パネルはZendeskをリアルタイム参照するので常に最新で、スレッド全体が読めます。
ただし公式ドキュメントに明記の通り:
"The ticket view in the Case page is view only"
返信・コメント追加・ステータス変更は一切できません。この連携の思想は「対応はZendesk、閲覧はSalesforce」です。Salesforceから返信したい場合は8章の補完か、そもそもZendeskエージェントとして直接対応することになります。
全ユーザーに開放するためのSalesforce側設定(設定 → アプリ → 接続アプリケーション → 接続アプリケーションを管理 → 「Salesforce Integration for Zendesk」→ ポリシーの編集):
- OAuthポリシーで「管理者が承認したユーザーは事前承認済み」に設定
- 保存後、「プロファイルの管理」で対象プロファイルを割り当て(System Administratorの選択が必須)
一般ユーザーが「No ticket ID was found」になる場合(実測): チケット同期が作成する Zendes_* カスタム項目(Zendes_Support_Ticket_ID__c 等)の項目レベルセキュリティが、初期状態ではシステム管理者のみになっていました。一般プロファイルのユーザーはパネル自体は表示されても「Failed to fetch ticket for this case. No ticket ID was found」となりチケットが出ません。標準プロファイルは編集不可のため、権限セットを作成してZendesk系項目に参照アクセスを付与し、該当ユーザーに割り当てるのが確実な直し方です。
なおZendesk公式記事には「Connected AppのOAuthポリシーでPKCE(Require Proof Key for Code Exchange)を有効化せよ」という手順がありますが、検証時点のSalesforce UIにはこの設定が存在せず(アプリ定義はZendesk側所有のため客組織では編集不可)、上記のプロファイル割当+FLS付与のみで管理者以外の閲覧が成立することを実測で確認しました。
8. やり取りの中身をSalesforceに「残す」補完手段
8-1 Email Archiving × Email to Salesforce(活動履歴に残す)
ZendeskのEmail Archiving(全送信メールを指定アドレスに自動BCC)と、SalesforceのEmail to Salesforce(E2S)(届いたメールのTo/CCを取引先責任者・リードと照合し、活動履歴に自動記録)を組み合わせる、ノーコードの方法です。
なぜ成立するか:Email ArchivingのBCCは「実際の送信メールそのもののコピー」なのでToヘッダーに顧客アドレスが残り、E2SのTo/CC照合がそのまま動きます(E2Sの本来の使い方=送信メールのBCCと完全に一致)。
セットアップチェックリスト:
- Salesforce: 設定 → メール管理 → メール to Salesforce を有効化、メール配信性を「すべてのメール」に
-
Salesforce: 連携用ユーザー(例:
zendesk@yourcompany.com)を作成し、「私のメール to Salesforce」からユーザーごとの転送用アドレスを控える - Salesforce: そのユーザーの「許可するメールアドレス」にZendeskのサポートアドレス(送信元From)を追加 ← 忘れるとメールが無視されます
- Zendesk: 管理センター → Objects and rules → チケット → 設定 → Email Archiving にE2Sアドレスを設定
- テスト: Salesforceに既存の取引先責任者宛にZendeskから返信し、活動履歴に記録されるか確認
プラン要件: Email Archivingは Support/Suite Enterprise以上 でないと表示されません(トライアルで欄の有無を確認できます)。また記録されるのは連携開始後に送信されたメールのみ(遡りなし)、E2S側の処理上限もあるため大量送信時は事前確認を。
8-2 webhook + Apex/ミドルウェア(同期されない部分を自作で埋める)
Zendeskのトリガー→webhook→Salesforce APIで、公開コメントをCaseComment(または活動Task)として書き込む方法です。6章の「入らないもの」をピンポイントで補完できます。
まず押さえるべき制約:Zendeskのwebhookは1トリガーにつき固定のHTTPリクエスト1回で、レスポンスを次のリクエストに使う連鎖ができません。一方Salesforce APIは「①OAuthトークン取得(数時間で失効)→②Contact查照→③レコード作成」の連鎖が必要です。よって:
- Apex RESTエンドポイント方式(開発リソースがある場合): Salesforce内に認証不要エンドポイントを作り、共有シークレットをヘッダーで検証。查照・作成はApex内で完結
@RestResource(urlMapping='/zendesk-ticket/*')
global class ZendeskWebhookHandler {
@HttpPost
global static void createCaseComment() {
String key = RestContext.request.headers.get('X-Api-Key');
// 鍵はカスタムメタデータ型で管理(ゲストユーザーコンテキストでも
// Apexはシステムモードで動くため読み取れる)
String expected = WebhookSetting__mdt.getInstance('zendesk').ApiKey__c;
if (key == null || key != expected) {
RestContext.response.statusCode = 401;
return;
}
// 以降:リクエストボディのto/ccでContactを查照し、
// 該当CaseにCaseCommentを作成(E2S相当の照合を自前実装)
}
}
webhookボディにはプレースホルダーで宛先を載せられます(顧客宛先の取りこぼしなし)。
{
"ticket_id": {{ticket.id}},
"to": "{{ticket.requester.email}}",
"cc": "{{ticket.cc_emails}}",
"subject": "{{ticket.title}}"
}
- ミドルウェア方式(開発せずに組む場合): Zapier / Make / Power Automate等を挟み、トークン管理と查照を任せる。Power AutomateのSalesforceコネクタはプレミアム(追加ライセンス)なので注意
Apexエンドポイントを公開する場合、HTTPS必須・鍵のローテーション・ペイロードの厳格なバリデーション・(可能なら)ゲストユーザーのIP範囲制限をセットで。Zendeskの送信元IPの扱いについては9章を参照してください。
8-3 サードパーティコネクタ
Exalate / Unito等の有償コネクタはコメントの双方向同期を明示的にサポートしています。「Caseコメントを書けばZendeskに反映」のような双方向運用まで求まる場合の選択肢です。月額費用が発生しますが、認証・リトライ・マッピングを面倒見てくれます。
8-4 手段比較
| 手段 | コスト | プラン要件 | 同期範囲 | メンテナンス |
|---|---|---|---|---|
| 8-1 E2S×Archiving | 無料 | Zendesk Enterprise要 | 送信メール→活動履歴 | ほぼ不要 |
| 8-2 webhook自作 | 開発コスト | なし | 好きなように | 自分で面倒を見る |
| 8-3 サードパーティ | 月額 | なし | コメント双方向 | ベンダー依存 |
| (参考)公式連携のみ | 無料 | Team以上 | Caseメタデータ+最初のコメントのみ | ほぼ不要 |
9. セキュリティと運用上の注意
- 認証はOAuth 2.0: パスワードを預けずトークンで通信し、SalesforceのConnected Appからいつでも失効可能。接続にはAPI専用ユーザーではなく、フルライセンス+管理者相当の権限を持つユーザーが必要
- Zendeskの送信元IPは固定ではない: レンジをPublic IPs APIで公開していますが、固定保証はなく変更もあり得ます。IPで縛る運用は「レンジ変更時に同期が黙って止まる」リスクとセットなので、トークン管理で担保するのが定石
- その他: トライアル14日でZendesk側の環境は消える(設定と結果はドキュメント化を)/同期はSalesforce APIを消費する(Dev Editionは上限が小さいので注意)/削除非伝播(5-5)によりZendesk側に孤立レコードが溜まる(external IDでの定期クリーンアップを)
10. まとめ:ユースケース別の選び方
- 対応状況を「見られれば」十分 → 公式連携のみ。Case関連リスト+パネル+レポートで十分成立します。「チケットが解決したら担当営業に通知」「優先度Highが戦略アカウントで発生したらAMにタスク」のようなフローも、同期されるステータス項目を起点に標準機能で組めます
- 中身もSalesforceレコードに残したい → 8章の補完手段。営業が顧客レコードのタイムラインでメールを追いたいなら8-1(活動履歴)、Caseのスレッドとして残すなら8-2(CaseComment)
- 双方向でガッツリ → 8-3の有償コネクタ、またはサポート対応自体をSalesforce Service Cloudへ集約する再検討も
公式連携は「同期」というより「Salesforceからの可視化」に徹した、無料でよくできた土台です。足りない1ピース(やり取りの中身)だけ、要件に合わせて足す、という付き合い方が現実的だと思います。
11. 参考リンク
- Connecting your Salesforce organization to Zendesk(Zendesk公式)
- Setting up ticket sync from Zendesk to Salesforce(Zendesk公式)
- Setting up ticket view in Salesforce(Zendesk公式)
- Configuring data sync from Salesforce to Zendesk(Zendesk公式)
- Zendesk tickets fail to sync into cases in Salesforce(Zendesk公式)
- Salesforce data sync error: Name or Email has already been taken(Zendesk公式)
- What profile permissions are required for the Zendesk for Salesforce integration(Zendesk公式)
- Salesforce App Integration with Zendesk Support(Zendesk Marketplace・Free integration)
- Archiving ticket email notifications(Zendesk公式)
- Enable Email to Salesforce for Your Users(Salesforce Help)
- Zendesk Public IPs(Zendesk Developer Docs)
検証は無料アカウントで誰でも再現できます。「うちの環境だとこうだった」などの追試報告や、A案/B案を実際に組んだ方の知見コメントをお待ちしています。
なお、本記事は人間とのやり取りを通じてAIが作成しました。