service-email-to-case-configure について
ヘッドレスな組織設定向けに、Metadata API で Salesforce Email-to-Case を構成するスキルです。On-Demand を有効にしてからルーティングアドレスを追加する二段階で適用し、結果を再取得して検証します。
主な機能
- 01Email-to-Case 設定
- 02対応するルーティングアドレスの作成
- 03二段階で設定を適用
- 04既存の Support Settings を保持
- 05再取得による変更検証
活用シーン
- 01Setup UI を使わない Email-to-Case の設定
- 02EmailToCase、Outlook、GmailOAuth のルーティング追加
- 03認証済み Salesforce 組織の構成
MCP 対応
MCP サーバーやクライアントについての記述はありません。Metadata API と Salesforce CLI を使って Salesforce を構成します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill service-email-to-case-configureインストール後、Claude Code で/service-email-to-case-configureを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/CaseSettings.settings-meta.xmlexamples/CaseSettings-two-addresses.settings-meta.xmlreferences/apply-mechanics.mdrouting_address_reference.mdtroubleshooting.mdscripts/apply-casesettings.pycheck-agent-email-capability.shvalidate-casesettings.pyscripts/tests/__init__.py_bootstrap.py_fakeorg.py_run.pytest_apply_org_scenarios.pytest_get_session.pytest_new_capabilities.pytest_validate_casesettings.py詳細
メール-to-ケースの設定(Metadata API)
Metadata API のみを使用して Salesforce のメール-to-ケースを設定します(Setup UI は使用しません)。ヘッドレス環境の組織設定向けです。このスキルでは、希望する emailToCase の状態を反映した CaseSettings ソースファイルを作成し、scripts/apply-casesettings.py で適用します。このスクリプトは updateMetadata を 2 つのフェーズで実行します。フェーズ A では emailToCase ブロック全体と Support Settings を適用し、フェーズ B ではルーティングアドレスを適用してから、再読み込みして検証します。新規組織ではデプロイを 1 回で行うと失敗するため、2 つのフェーズに分けています。アドレスを関連付ける前に On-Demand が有効になっている必要があります(「ルール/制約」を参照)。
対象範囲
- 対象範囲内:組織全体でメール-to-ケースを有効にし、その切り替え項目を設定すること(必須入力と手順 4 に全フィールドの一覧があります)。
EmailToCase、Outlook、GmailOAuthのルーティングアドレスを作成すること。apply-casesettings.pyを使用して、sf-CLI で認証済みの組織に変更を適用すること。再読み込みして検証すること。 - 対象範囲外:
E2cEasyルーティングアドレス — Service Easy Setup ウィザードからのみ作成でき、Metadata API では作成できません。ユーザーをウィザードに案内してください。- 組織の認証 — ユーザーが別途(例:
sf org login web)認証します。スクリプトはそのセッションを再利用し、パスワードやトークンを扱うことはありません。 - Case オブジェクトのスキーマ、レイアウト、割り当てルール、Web-to-Case。
Agentforce サービスエージェントの添付(委任)
ユーザーが Agentforce Service Agent にこれらのメールへの回答を求めている場合は、まずメール-to-ケースのベース(以下のワークフロー)を設定してから、作業を委任してください。このスキルがエージェントを作成または変更することはありません。
まず組織の機能を確認してください。 エージェントを添付するには、組織で Agentforce Email-to-Case の利用資格が必要です。この利用資格は BotEmailDefinition メタデータ型に反映されるため、委任する前に読み取り専用で確認してください。
scripts/check-agent-email-capability.sh <target-org-alias> # pins describe to the org's API version
終了コードが 3 → 利用資格なし:停止してユーザーに伝え、通常のメール-to-ケースのベースのみを設定してください。Agentforce エージェントやチャネル連携の変更は行わないでください。 それ以外のゼロ以外の終了コードは、利用資格がないという意味ではなく、組織に到達できないことを示します。認証を修正して再実行してください。終了コードが 0 の場合は、次の作業を委任してください。
- エージェントの作成 →
agentforce-generate。 メールチャネルではサポートされていない Service Customer Verification topic は除外し、人間の担当者に引き継げるよう Escalation subagent を含めてください。メールでは、エスカレーションによりケースがサービス担当者に移管されます。このサブエージェントがないと、エージェントはエスカレーションできません。 - 連携 →
service-agentforce-channel-configureの Branch C。
必要な入力
適用する前に収集または推測します。誤った前提によって結果が壊れたり不正確になったりする場合に限り、確認してください。
- 対象組織のエイリアス — すでに認証済みの組織の sf CLI エイリアス/ユーザー名です。スクリプトは
sf org displayとsf org auth show-access-tokenを使ってセッションを取得します。ログインは行いません。 - ルーティングアドレス — 各アドレスについて、
routingName(一意のラベル)、addressType(既定値はEmailToCase、またはOutlook/GmailOAuth)、caseOrigin、casePriorityを指定します。caseOriginまたはcasePriorityがない場合、プラットフォームはアドレスを拒否するため、ソースファイルでは4項目すべてを必須として扱ってください。 - 各ルーティングアドレスの顧客向けメールアドレス — アドレスの順番どおりに、それぞれ明示的に尋ねてください。推測したり、既定値を設定したり、以前のコンテキストの値を再利用したりしてはいけません。ソースファイルには保存しません。適用時に
--routing-emailで渡します(アドレスごとに1つ指定します。個数が一致しない場合、スクリプトは安全のため処理を中止します)。 - Support Settings — Default Case Owner と Automated Case User — 現状維持を優先し、決して推測しません。
- フィールドごとに独立して保持します。 設定済みのフィールドには手を加えません。変更するのは、ユーザーが明示的に希望した場合のみです(
--overwrite-support-settings)。未設定のフィールドだけを尋ねてください。 - 未設定のフィールドごとに尋ねてください(認証済みユーザーを既定値にしてはいけません)。Default Case Owner はタイプ(
User/Queue)と値(有効な Username または Queue DeveloperName)を尋ね、--owner-type/--owner-valueに渡します。Automated Case User はタイプ(User/System)を尋ねます。Userの場合はユーザー名が必要です。Systemの場合は値は不要です。--automated-type/--automated-valueに渡します(組織に自動ユーザーがまだ存在しない場合は、--system-user-emailを任意で指定できます)。 - 値が無効な場合、スクリプトは失敗します。 有効な値を取得して再実行してください。代わりの値を指定したり、推測したりしてはいけません。
- ユーザーが明示的に希望した場合に限り、
--use-authenticated-userを渡してください。
- フィールドごとに独立して保持します。 設定済みのフィールドには手を加えません。変更するのは、ユーザーが明示的に希望した場合のみです(
- アドレスごとのケースの既定値(任意)—
createTask、saveEmailHeaders、および任意のアドレスごとの Default Case Owner(caseOwnerとcaseOwnerType)です。アドレスごとに明示的に選択してください(手順6を参照)。既定では省略されるため、ケースは組織の Default Case Owner/割り当てルールに従います。設定する場合、caseOwner(有効な Username または Queue DeveloperName)にはcaseOwnerType(User/Queue)を組み合わせる必要があります。これが指定されていない場合、スクリプトは組織に照らして検証し、安全のため処理を中止します。 - 組織レベルの切り替え設定(任意)— ユーザーが希望した場合にのみ設定します。コンテナーは2つあります。
emailToCaseセクション(enableHtmlEmail、notifyOwnerOnNewCaseEmail、enableE2CDeduplicateAttachments、showWordCountInComposer、およびenableE2CSourceTracking、overEmailLimitAction、unauthorizedSenderAction)と、トップレベルの Support Settings(enableDraftEmails— 要素名は複数形で、emailToCaseの兄弟要素)です。コンテナーと UI ラベルの対応については、手順4の表を参照してください。トップレベルのスカラー型切り替え設定はフェーズ A で適用します。
既定値:enableEmailToCase と enableOnDemandEmailToCase は true が既定値です(どちらも必須です。ルーティングアドレスより先に On-Demand を設定します)。addressType の既定値は EmailToCase です。Support Settings に既定値はありません。設定済みの場合はそのまま保持し、未設定の場合は確認します(認証済みユーザーは決して使用しません)。
ワークフロー
すべての手順を順番に実行します。
-
組織(およびその種類)を確認する — 対象組織のエイリアスが認証済みであることを確認します(
sf org display --target-org <alias>)。適用スクリプトはOrganizationの行を確認し、--confirm-productionが渡されない限り、本番組織(非サンドボックス、非トライアル)への変更を拒否します。Email-to-Case の有効化は永続的で、組織全体に適用されます。本番環境の場合はユーザーに伝え、--confirm-productionを付けて再実行する前に確認してください。サンドボックス、スクラッチ組織、トライアルでは、このフラグなしでデプロイされます。 -
ルーティングメールアドレスを確認する — 各ルーティングアドレスについて、顧客向けの正確なメールアドレスをユーザーに尋ねてください(推測したり、既定値を設定したり、以前の情報を引き継いだりしてはいけません)。ソースファイルに記載されたアドレスの順番どおりに、
--routing-emailでスクリプトに渡してください。 -
テンプレートを読み込む — 構造とフィールドの配置を確認するため、
assets/CaseSettings.settings-meta.xmlを読みます。コメントは作成時のガイダンスとしてあなた向けに記載されています。出力にコピーしないでください。設定する要素だけを出力し、examples/CaseSettings-two-addresses.settings-meta.xmlと同様に、出力にコメントを含めないでください。 -
E2C のスイッチを有効にしてから、オプションの切り替え項目を確認する —
enableEmailToCaseとenableOnDemandEmailToCaseの両方をtrueに設定します(どちらも必須です。ルーティングアドレスを作成するには、On-Demand を有効にしておく必要があります。スクリプトではフェーズ A で有効にしてから、フェーズ B に進みます)。次に、テンプレートでデフォルトで有効になっている必須ではない便利な設定を確認します。UI ラベル フィールド コンテナ HTML メールを有効にする enableHtmlEmailemailToCaseメールの添付ファイルの重複を排除する enableE2CDeduplicateAttachmentsemailToCase作成画面に文字数を表示する showWordCountInComposeremailToCase新しいメールについてケース所有者に通知する notifyOwnerOnNewCaseEmailemailToCaseメールの下書きを有効にする enableDraftEmails(トップレベルのCaseSettings)サポート設定 これらを有効にする前に、どの設定が有効になるのかをユーザーに正確に伝え、不要なものを除外できるようにしてください(例:「次のオプション設定も有効にします。… — スキップしたいものがあればお知らせください。」)。ユーザーが除外を希望した項目は削除し、それ以外は正しいコンテナに配置します(4 つは
<emailToCase>内、enableDraftEmailsはルート直下)。ユーザーが同意していないオプションやその他のフラグを、黙って有効にしてはいけません。確認済みの切り替え項目はフェーズ A で適用します。 -
ルーティングアドレスごとに適切な方法を選ぶ —
references/routing_address_reference.mdを使用し、各アドレスのaddressTypeに基づいて判断します。指定されたアドレスにE2cEasyが含まれている場合は、そこで作業を止め、Metadata を出力する代わりに Service Easy Setup ウィザードを利用するようユーザーに案内します。 -
ルーティングアドレスのフィールドを設定する — 各
EmailToCase/Outlook/GmailOAuthアドレスに対し、addressType、routingName、caseOrigin、casePriorityを設定します(すべて必須です。いずれかが欠けていると、プラットフォームは「Missing caseOrigin」または「Missing casePriority」というエラーで処理を拒否します)。必要に応じて、その他のケースのデフォルト値も設定します。ソースファイルにemailAddressを記述してはいけません。適用時に--routing-emailで指定します。読み取り専用フィールドのemailServicesAddressやisVerifiedも設定してはいけません。これらはプラットフォームが管理します。複数のアドレスを設定する完全な例は、examples/CaseSettings-two-addresses.settings-meta.xmlを参照してください。アドレスごとのデフォルトケース所有者(オプトイン)。 ケースをこのアドレスから受け取った場合に、特定の所有者へ割り当てるのか、組織のデフォルトケース所有者/割り当てルールに任せるのか(デフォルト)を、アドレスごとに一つずつ確認します。アドレスによって、異なる所有者に割り当てることもできます。ユーザーが希望しない場合は、ソースファイルから
caseOwnerとcaseOwnerTypeを完全に省略します(テンプレートではコメントアウトされています)。ユーザーが希望する場合は、タイプ(User/Queue)と値(有効な Username または Queue DeveloperName)を尋ね、<caseOwnerType>と<caseOwner>の両方を設定します。タイプを指定せずにcaseOwnerを設定すると、プラットフォームは処理を拒否します。apply-casesettings.pyは組織に照らして値を検証し、値がない場合はフェイルクローズします。推測したり、トップレベルのデフォルトケース所有者を使い回したりしないでください。 -
サポート設定を確認する(デフォルトのケース所有者+自動ケースユーザー) —
python3 scripts/apply-casesettings.py --target-org <alias> --input <source-file> --verify-onlyを実行し、defaultCaseOwner/defaultCaseUser/useSystemUserAsDefaultCaseUserを確認します。ユーザーが値を指定した場合は、ソースファイルに書き込みます(defaultCaseOwner+defaultCaseOwnerType、defaultCaseUser、またはuseSystemUserAsDefaultCaseUser+任意のsystemUserEmail)。ソースファイルは採点対象となり、バージョン管理可能な成果物です。スクリプトでは、これらをフラグとして指定することもできます。組織にすでに設定されているフィールドは、そのままにします — 省略すれば保持されます(上書きするのはユーザーが求めた場合のみ。その場合は--overwrite-support-settingsを指定します)。フィールドが未設定で、かつユーザーから値が指定されていない場合は、確認してください。認証済みユーザーを想定してはいけません(明示的に求められた場合のみ--use-authenticated-userを指定します)。 -
ソースファイルを検証する —
python3 scripts/validate-casesettings.py <path-to-source-file>を実行し、報告されたエラーを適用前に解決します。 -
組織に適用する — 次を実行します。
python3 scripts/apply-casesettings.py --target-org <alias> --input <source-file> \ --routing-email <email-for-address-1> [--routing-email <email-for-address-2> ...] \ [--owner-type User|Queue --owner-value <username-or-queue-devname>] \ [--automated-type User --automated-value <username> | --automated-type System [--system-user-email <email>]] \ [--confirm-production]各ルーティングアドレスにつき、ドキュメント内の順序どおりに
--routing-emailを1つだけ指定します。所有者/自動ユーザー関連のフラグは、組織のサポート設定がすでに構成されていない場合にのみ指定します(手順7)。構成済みの場合は省略し、既存の設定を保持します。スクリプトが値を無効として拒否した場合は、その内容を伝え、有効な値を確認してから再実行します。認証済みユーザーにフォールバックしてはいけません。スクリプトが本番環境と報告して終了した場合、自分で--confirm-productionを追加してはいけません — まずユーザーに確認します(手順1)。スクリプトはフェーズA(サポート設定+切り替え)を適用し、次にフェーズB(ルーティングアドレス)を適用して、再読み込みによる検証を行います。エラーがあれば、ゼロ以外の終了コードで終了します。 -
結果を確認する — JSON の概要を確認します。
verified.enableEmailToCase/verified.enableOnDemandEmailToCaseがtrueであり、verified.routingAddressCountがアドレス数と一致し、各phaseBエントリのステータスがcreated(またはalready_exists)であること、さらにsupportSettings.actionがpreserved-existing/set-from-input/set-from-authenticated-userのいずれかであることを確認します。書き込みを行わずに再読み込みするには、--verify-onlyを使用します。
手順10の完了後、設定は完了です。
設定後 — 完了後の案内
以下の項目はワークフローの手順ではありません — 設定が完了したことを確認してから、ユーザーに案内してください。
転送(実際の受信メールには必須)
受信メールを顧客向けアドレスから実際に Salesforce へ届ける方法として、必ず次の案内をユーザーに伝えてください。
お客様のルーティングアドレスに、Salesforce が生成したメールサービスアドレスが割り当てられました。受信メールを受け取るには、お使いのメールシステムで、顧客向けアドレス(例:
[email protected])宛てのメールを、生成されたサービスアドレスに転送するよう設定してください。
エンドツーエンドの証明(第3幕)
受信メールによってケースが作成されることを実証するため、実際の往復テストを提案します。ユーザーが希望しない場合は省略します。このスキルがメールを送信することはありません。2つの操作を人間に依頼し、その後 SOQL で検証します。(1)アドレスの所有権確認 — Salesforce が確認リンクをメールで送信します。人間がリンクをクリックした場合にのみ、isVerified が切り替わります。ユーザーにクリックしてもらい、完了するまで待ちます。(2)テストメールの送信 — ユーザーに、外部メールボックスからルーティングアドレスの Salesforce 生成のメールサービスアドレス宛てに、実際のメールを1通送信するよう依頼し(顧客向けアドレスではありません。顧客向けアドレスで受信できるのは転送設定後です)、送信元を報告してもらい、完了するまで待ちます。(3)証拠を使って検証 — その後、次を実行します。
python3 scripts/apply-casesettings.py --target-org <alias> --verify-cases \
[--supplied-email <external-sender-address>]
読み取り専用です。Origin='Email' の Case(過去3日間。必要に応じて送信元で絞り込み)と、それにリンクされた受信 EmailMessage レコード(Incoming=true、ParentId = 新しいケース)をクエリします。リンクされた受信メールを持つ一致ケースがない場合は、ゼロ以外の終了コードで終了します(メールがまだ処理されていません。しばらく待って再実行するか、アドレスが未検証です)。成功すると、Case と EmailMessage の証拠を proven: true とともに出力します。
ルール/制約
| 制約 | 理由 |
|---|---|
apply-casesettings.py(2 フェーズの updateMetadata)を使って適用し、通常のデプロイや最小限の emailToCase パッチは決して使わないでください | 新規 org では、1 回のデプロイでは失敗します。アドレスを紐付ける前に On-Demand をプロビジョニングするのは、フィールド単位の切り替えではなく、完全な emailToCase ブロックです。references/apply-mechanics.md を参照してください。 |
スキルが所有するトップレベルフィールドのみを書き込み、CaseSettings レコード全体を決してそのまま返さないでください | プラットフォームはペイロード内のすべてのトップレベルフィールドを再検証します(例:Case Feed → Chatter)。emailToCase + enableDraftEmails + Support Settings のみを送信すれば、無関係な失敗を避けられ、Chatter の前提条件も不要です。省略したフィールドの値は、フィールド単位のマージによって維持されます。 |
顧客向けメールアドレスは明示的なユーザー入力(--routing-email)で指定し、ソースファイルに記載したり、決めつけたりしないでください | 推測したアドレスや古いアドレスがプロビジョニングされるのを防ぎます。--routing-email の数とアドレスの数が一致しない場合、スクリプトはフェイルクローズします。 |
CaseSettings の fullName は常に Case です | これは org のシングルトン設定タイプです。スクリプトは自動的に Case を対象にします。 |
| Support Settings が設定済みの場合はフィールドごとに保持し、設定済みだと決めつけないでください | Default Case Owner と Automated Case User は独立しています。設定済みの各フィールドは(--overwrite-support-settings を指定しない限り)変更されず、未設定のフィールドに限り、明示的かつ org で検証済みの値が必要です(そうでなければフェイルクローズします)。認証済みユーザーが使われるのは --use-authenticated-user を指定した場合のみです。 |
Automated Case User の「System」と、名前を指定した defaultCaseUser は併用できません | --automated-type System は useSystemUserAsDefaultCaseUser を設定するため、ユーザー値を含めてはいけません。プラットフォームは両方が指定されると拒否します。 |
| スクリプトは読み取り → パッチ → 更新の順に処理します(アドレスは追加のみ) | 現在の設定にマージするため、既存のルーティングアドレスは保持されます。重複する routingName/emailAddress は already_exists として報告されます。新しいアドレスは既存のアドレスより前に出力されます(updateMetadata はコレクション全体を置き換えるため、新しいアドレスの後に既存のアドレスが続くと、既存のアドレスが削除されます。実行時ガードにより、既存のアドレスが1つでも削除される場合は処理が失敗します)。references/apply-mechanics.md を参照してください。 |
EmailToCaseSettings を直接適用してはいけません。また、一度有効にした enableEmailToCase をオフにすることはできません | CaseSettings の子要素である emailToCase としてのみ書き込みます。最初に true を適用すると、プラットフォームはこの機能を恒久的に有効にします。再び false に設定できるとは決して考えないでください。 |
本番 org では明示的な --confirm-production が必要です。確認なしにこのフラグを追加してはいけません | Email-to-Case の有効化は恒久的で、org 全体に適用されます。ユーザーが確認するまで、スクリプトはサンドボックスでもトライアルでもない org(および種類を読み取れない org)ではフェイルクローズします。サンドボックスとトライアルは対象外です。 |
| 受信 Case の確認は、ユーザーが実行する読み取り専用の手順です。スキルはメールを送信しません | --verify-cases は、人がアドレスを確認してテストメールを送信した後にのみ、Case/EmailMessage をクエリします。受信メールが紐付いた Case が存在するまでフェイルクローズします。 |
E2cEasy アドレスには Service Easy Setup ウィザードを使用する必要があります | 事前構築済みの service_case キューの紐付けと isVerified の切り替えは、Metadata API では再現できません。 |
emailServicesAddress または isVerified を決して書き込まないでください | どちらも読み取り専用で、プラットフォームが生成します。スクリプトは、これらが含まれていれば削除します。 |
| 生成されるソースファイルには、設定対象の要素のみを含めます。XML コメントは含めません | テンプレートや例のコメントは作成時のガイダンスであり、出力に含めるものではありません。コピーするとファイルが冗長になります(完成版にはコメントがありません)。また、<placeholder> トークンを含む CLI の例のコメントは、XML 検証に失敗することがあります。説明はチャットの返信に記載し、.settings-meta.xml には決して記載しないでください。 |
注意点
(Phase B のプロビジョニングエラー、Case Feed/Chatter、アドレスごとの所有者が一部しか設定されない問題、GmailOAuth の競合、--verify-cases の失敗、各種トグルの配置に関するすべての注意点を含む)症状 → 解決策の完全な表については、references/troubleshooting.md をお読みください。
出力要件
成果物:
- 希望する
emailToCaseの状態を指定したCaseSettingsのソースファイル(例:Case.settings-meta.xml)。トグルとルーティングアドレスのフィールドを含め、emailAddress(適用時に指定)、読み取り専用フィールド、XML コメントは含めません。構造はassets/CaseSettings.settings-meta.xmlに準拠します。 apply-casesettings.pyによって適用された組織の状態と、その JSON サマリー(解決された所有者、アドレスごとのステータス、検証結果の読み取り)。
参照ファイル一覧
| ファイル | 読む/実行するタイミング |
|---|---|
assets/CaseSettings.settings-meta.xml | ステップ 3 — ソースファイルの開始テンプレート |
references/apply-mechanics.md | スクリプトが updateMetadata ペイロードを構築または実行する順序を変更する前に読む |
references/troubleshooting.md | 適用または検証のステップでエラーが報告された場合、または設定済みの設定が想定どおりに動作しない場合 — 症状 → 解決策の完全な表 |
references/routing_address_reference.md | ステップ 5〜6 — ルーティングアドレスのフィールドの意味と addressType のサーフェス選択ルール |
examples/CaseSettings-two-addresses.settings-meta.xml | ステップ 6 — 複数のルーティングアドレスを使用する場合のソースファイル構造の確認 |
scripts/check-agent-email-capability.sh | Agentforce サービスエージェントを関連付ける場合 — 委任前の機能ゲート(BotEmailDefinition の有無を調査) |
scripts/validate-casesettings.py | ステップ 8 — 適用前の決定論的な構造検証 |
scripts/apply-casesettings.py | ステップ 9 — 2 フェーズの updateMetadata で設定を適用して検証 |
scripts/tests/test_get_session.py | セッショントークンの取得(get_session/_usable_access_token)を変更する場合に実行 — トークン抽出と API バージョンの解決を保護するユニットテストスイート |