service-agentforce-channel-configure について
既存の Agentforce エージェントを既存の Salesforce チャネルに接続し、あふれた作業を受けるキューを設定するスキルです。チャット、Voice、Email-to-Case のルーティングを扱い、チャネルやエージェント自体の作成は対象外です。
主な機能
- 01チャネルの受信業務をエージェントへルーティング
- 02フォールバックキューの設定
- 03チャットとメッセージングへの対応
- 04Voice ルーティングフローの設定
- 05Email-to-Case ルーティングの設定
- 06任意のアウトバウンドエスカレーション設定
活用シーン
- 01既存のチャットチャネルへのエージェント接続
- 02Voice 通話の Agentforce エージェントへの転送
- 03Email-to-Case のエージェントルーティング設定
- 04エージェント不在時の代替キュー設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill service-agentforce-channel-configureインストール後、Claude Code で/service-agentforce-channel-configureを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/BotEmailDefinition.botEmailDefinition-meta.xmlmdapi-package.xmlsettings-mdapi-package.xmlassets/email/unfiled$public/AgentforceForServiceEmailTemplate.emailAgentforceForServiceEmailTemplate.email-meta.xmlreferences/agent-wiring.mdbotemaildefinition.mdchannel-branch-email.mdchannel-branch-voice.mdchannel-types.mdlive-traffic-gate.mdqueue-resolution.mdrouting-flow.mdscripts/validate-botemaildefinition.pyvalidate-emailtemplate.py詳細
service-agentforce-channel-configure:Agentforce エージェントをチャネルに接続する
既存のチャネルと既存の Agentforce エージェント間に、インバウンドのルーティングを追加します。エージェントはチャネルから作業項目を受け取ります。エージェントが利用できない場合、フォールバックキューが超過分を処理します。
このスキルは汎用的で、Help Agent テンプレートだけでなく、あらゆる Agentforce エージェントで機能します。
対象範囲
対象範囲:
- 正しい
QueueSobjectの SobjectType を持つフォールバックキューの解決または作成 - ブランチ A(Enhanced Chat/Enhanced Messaging):既存の MessagingChannel に
sessionHandlerType=AgentforceServiceAgentとsessionHandlerQueueをデプロイし、Data API PATCH を使用してSessionHandlerIdを関連付ける - ブランチ B(Voice):電話番号と
PstnVoiceMessagingChannel がすでに存在することを前提とします(例:service-helpagent-coordinateなど、呼び出し元によってプロビジョニング済み)。その後、エージェントにルーティングし、フォールバックとしてキューを使用するインバウンド RoutingFlow(routingType: Copilot)を作成します - ブランチ C(Email-to-Case):ケース所有者への直接割り当てまたは Omni-Channel RoutingFlow によるインバウンドルーティングに加え、エージェントを Service Email に関連付ける
BotEmailDefinition(メール設定)をデプロイし、ルーティングアドレスに関連付ける - 任意のアウトバウンドエスカレーション:検証済みのエージェントから人間への引き継ぎ契約を
service-agentforce-human-escalation-configureに委任する
対象外:
- エージェントの作成 —
agentforce-generateまたはservice-helpagent-coordinateを使用 - MessagingChannel の作成 —
service-digital-engagement-channel-configureを使用 - Embedded Service Deployment の作成 —
service-digital-engagement-deployment-configureを使用 - Voice または Email-to-Case のチャネルインフラストラクチャの作成
必須の入力
- エージェントの
DeveloperNameと エージェントラベル(MasterLabel)— 既存の有効なエージェントである必要があります - チャネルタイプ — Enhanced Chat、Enhanced Messaging(サードパーティ)、Voice、Email-to-Case のいずれか
- チャネル識別子 — MessagingChannel の
DeveloperName(ブランチ A)、またはチャネル名/コンテキスト(ブランチ B/C) - 対象組織のエイリアス
ワークフロー
手順は順番に実行します。先に references/channel-types.md を読み、続行する前にルーティングブランチを確認してください。
フェーズ 0 — 本番環境への書き込みガード(必須、書き込み前)
このスキルはメタデータ/データへの書き込み(MessagingChannel の編集、RoutingFlow のデプロイ、エージェントの再公開)を実行します。書き込みを行う前に、対象組織を分類して、実際の本番環境の場合は拒否してください。
sf data query --target-org $ORG --json \
--query "SELECT Id, IsSandbox, TrialExpirationDate, OrganizationType FROM Organization LIMIT 1"
safe_to_writeが true になるのは、IsSandbox=true、またはTrialExpirationDateが null 以外(トライアル/CDO)、またはOrganizationTypeがDeveloper Edition/Base Editionの場合のみです。safe_to_writeが false の場合は、停止してください。これは実際の顧客の本番環境であり、エスカレーション/チャネル接続は適用しないことを明確に伝えてください。書き込みフェーズには進まないでください。safe_to_writeが true の場合は、書き込み計画(変更する MessagingChannel/RoutingFlow/エージェント)を提示し、続行する前に対象組織についてユーザーの明示的な確認を得てください。
このゲートを決して回避しないでください。ここで誤って本番環境に書き込むと、稼働中の顧客トラフィックのルーティングが変更されます。
フェーズ 1 — エージェントを確認してキューを解決する
-
エージェントが存在し、有効なバージョンがあることを確認します:
# Get the definition sf data query --target-org $ORG --json \ --query "SELECT Id, DeveloperName, MasterLabel FROM BotDefinition WHERE DeveloperName='{AGENT_DEVELOPER_NAME}'" # Check for an Active version sf data query --target-org $ORG --json \ --query "SELECT Id, Status FROM BotVersion WHERE BotDefinitionId='{BOT_DEFINITION_ID}' AND Status='Active' LIMIT 1"定義が見つからない場合、または
Status = Activeのバージョンがない場合は、明確なメッセージを表示して停止します。分岐 A の注意点 — 有効な BotVersion は必要条件ですが、
sessionHandlerAsaとしてバインドするには十分ではありません。 プラットフォームが受け付けるのは、デプロイ可能な Agentforce Service Agent(通常はExternalCopilot)としてプロビジョニング/接続されているエージェントのみです。単に Active であるだけのエージェントをバインドすると、フェーズ 2 のデプロイでOnly active Agentforce Service Agents are supported for a Messaging Channelのエラーが発生します。書き込み前に読み取り専用でバインド可能か確認します。組織内の MessagingChannel でsessionHandlerType=AgentforceServiceAgentがすでに使われている場合は、それを取得し(sf project retrieve start --metadata "MessagingChannel:{EXISTING}" --target-org $ORG)、その<sessionHandlerAsa>を読み取ります。この一覧が、バインド可能であることが実証された組織内の ASA です。選択したエージェントがプロビジョニング済みの ASA ではなく、バインド可能な ASA も存在しない場合は、BLOCKEDと報告して停止します:Agentforce Service Agent としてプロビジョニングされたエージェントを指定してください。 -
フォールバックキューとルーティング設定を解決します —
references/queue-resolution.mdに従います:- チャネルタイプから SobjectType を特定します(
references/channel-types.mdを参照) - 互換性のある既存キューを照会し、
AskUserQuestionで提示するか、新規作成します - 既存の
QueueRoutingConfigを照会します。存在しない場合は、適切な容量の割合で作成します QUEUE_DEVELOPER_NAME、QUEUE_NAME、QUEUE_IDを記録します
- チャネルタイプから SobjectType を特定します(
フェーズ 2 — インバウンドルーティングを接続する
ライブトラフィックに関する警告ゲート(分岐の前に実行)
ルーティングを変更する前に、チャネルにすでに有効なインバウンドルーティングがあるか検出します(分岐 A:SessionHandlerType が空でない。分岐 B/C:サービスチャネルに割り当てられた有効な RoutingFlow がある)。有効なルーティングがある場合は、まずユーザーのプロンプトで切り替えのタイミングがすでに指定されているか確認します(「切り替えない」/「手動で接続」/「先に確認」→ 確認を求めず保留、「今すぐ切り替え」/「すぐに有効化」→ 確認を求めず続行)。プロンプトに指定がない場合に限り、AskUserQuestion で警告し、ユーザーに 「今すぐルーティングを変更」 または 「セットアップ後、手動で接続」 を選択してもらいます。曖昧な回答や選択がない場合は、保留する方法を既定とします(ライブ環境でのルーティング変更は行いません)。保留する場合は DEFER_INBOUND_ROUTING=true に設定し、選択した分岐のチャネル有効化手順をスキップして、フェーズ 2 の最後に手動接続の手順を表示します。
チャネルに既存のルーティングがない場合、このゲートを完全にスキップして直接続行します。
検出に使用するクエリ、正確な AskUserQuestion ブロック、各分岐の保留時のフロー規則、および手動接続の文面については、references/live-traffic-gate.md を参照してください。
分岐 A — Enhanced Chat / Enhanced Messaging(サードパーティー)
RoutingFlow は不要です。sessionHandlerType と sessionHandlerQueue のみを設定して MessagingChannel をデプロイし、その後 Data API の PATCH でボットを紐付けます。v67 では Metadata API は sessionHandlerAsa を受け付けません。デプロイするとこの項目は警告なしで削除され、PATCH を実行しない限り SessionHandlerId は null のままです。PATCH を実行する前に、ボットが Active になっている必要があります(そうでない場合は「Only active Agentforce Service Agents are supported」と表示されます)。
以下の 5 つの手順を順番どおりにすべて実行します。取得と編集は現在の SFDX プロジェクトで行い、デプロイ時に force-app 内の編集済み .messagingChannel-meta.xml が読み込まれるようにします。一時ディレクトリは使用しないでください。
-
現在の MessagingChannel メタデータを作業ディレクトリのプロジェクトに取得します:
sf project retrieve start \ --metadata "MessagingChannel:{CHANNEL_DEVELOPER_NAME}" \ --target-org $ORG -
取得した
.messagingChannel-meta.xmlをその場で編集し、次の 2 つのフィールドだけを設定します(<sessionHandlerAsa>は追加しないでください):<sessionHandlerType>AgentforceServiceAgent</sessionHandlerType> <sessionHandlerQueue>{QUEUE_DEVELOPER_NAME}</sessionHandlerQueue>ファイル編集ツール(Edit/Write)を使用して編集し、作業ディレクトリ内の
force-app/main/default/messagingChannels/{CHANNEL_DEVELOPER_NAME}.messagingChannel-meta.xmlにある取得済みファイルに変更を保存します。一時パスへのインラインsed/catヒアドキュメントでの手編集はしないでください。手順 3 のデプロイでは、同じディスク上のファイルを読み込む必要があります。 -
デプロイします:
sf project deploy start \ --metadata "MessagingChannel:{CHANNEL_DEVELOPER_NAME}" \ --target-org $ORGデプロイが
Only active Agentforce Service Agents are supported for a Messaging Channelというエラーで失敗した場合、このエージェントはこの組織で紐付け可能な ASA ではありません(Phase 1 の注意事項を参照)。同じエージェントで再試行しないでください。失敗したデプロイはアトミックであるため、チャネルは変更されていません。修正方法として、すでに Agentforce Service Agent としてプロビジョニング済みのエージェントを紐付けるか、このエージェントをプロビジョニングしてから再実行するよう案内し、BLOCKEDと報告します。 -
Data API PATCH でボットを紐付けます:
CHAN_ID=$(sf data query --target-org $ORG --json \ --query "SELECT Id FROM MessagingChannel WHERE DeveloperName='{CHANNEL_DEVELOPER_NAME}'" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])") BOT_ID=$(sf data query --target-org $ORG --json \ --query "SELECT Id FROM BotDefinition WHERE DeveloperName='{AGENT_DEVELOPER_NAME}'" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])") QUEUE_ID=$(sf data query --target-org $ORG --json \ --query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='{QUEUE_DEVELOPER_NAME}'" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['records'][0]['Id'])") sf api request rest --method PATCH -o $ORG \ "/services/data/v67.0/sobjects/MessagingChannel/${CHAN_ID}" \ --body "{\"SessionHandlerId\":\"${BOT_ID}\",\"FallbackQueueId\":\"${QUEUE_ID}\"}" # Expected: HTTP 204 -
確認します:
sf data query --target-org $ORG --json \ --query "SELECT SessionHandlerId, FallbackQueueId FROM MessagingChannel WHERE Id='${CHAN_ID}'"SessionHandlerIdとFallbackQueueIdの両方が null でないことを確認します。
エージェントファイルの変更は不要です。再公開も必要ありません。Phase 3(任意)に進みます。
分岐 B — Voice
PstnVoice MessagingChannel をインバウンドの Copilot RoutingFlow に接続し、キューをフォールバックとして設定します。また、エージェントを再公開する前に、必須の modality voice: ブロックを追加します。
references/channel-branch-voice.md の手順を最初から最後まで実行してください。要点は次のとおりです。
- 手順 0 — 既存の
PstnVoiceMessagingChannel を再利用するか、そのスキルの Voice チャネルのリファレンスを使用して、まずservice-helpagent-coordinateにプロビジョニングしてもらいます。組織がパートナーのテレフォニープロバイダーを使用している場合は中止してください(references/channel-types.mdを参照)。 - 手順 1~3 —
references/routing-flow.mdのテンプレートを使ってインバウンド RoutingFlow を作成してデプロイし、ActiveVersionIdが null でないことを確認します。 - 手順 4 —
sessionHandlerType=Flow、sessionHandlerFlow={FLOW_DEVELOPER_NAME}、sessionHandlerQueue={QUEUE_DEVELOPER_NAME}を設定した{CHANNEL_DEVELOPER_NAME}のMessagingChannelメタデータファイルをデプロイします。これを設定しないとフローは実行されず、通話が切断されます。SessionHandlerIdが300で始まることを確認します。 - 手順 5 —
.agentファイルに、プラットフォームのデフォルトのmodality voice:ブロック(voice_idUgBBYS2sOqTuMpoF3BR0、「Mark」、en_US)がない場合は追加します。ユーザーに尋ねる必要はありません。references/agent-wiring.mdに従って再公開します。
Phase 3(任意)に進みます。
ブランチ C — メールからケースへの変換
ユーザーがケース所有者への直接割り当てか、Omni-Channel の Copilot RoutingFlow のどちらかを選択できるようにします。このブランチには、API v68.0 以降、connection service_email: サーフェス、BotEmailDefinition が必要です。
references/channel-branch-email.md の手順に沿って最後まで進めてください。重要な注意点は次のとおりです(詳細な手順はこのファイルを参照してください)。
- ステップ 1 — Tooling-API PATCH または
--metadata-dirによるSettings:Caseのデプロイでルーティングアドレスのフィールドをバインドします。ソースの--metadata Settings:Caseデプロイは絶対に使用しないでください(sourceApiVersionを読み取り、ユーザーのプロジェクトを変更してしまいます)。 - ステップ 2 — インバウンドルーティングを選択します(
AskUserQuestion):ケース所有者(caseOwner= エージェントのボットユーザー)または Omni-Channel フロー(CopilotRoutingFlow +routingFlow/fallbackQueue)。どちらを選んでもボットユーザーを解決します。ルーティングフィールドはステップ 4d のデプロイに含めます。 - ステップ 3 — エージェントはすでに有効化されているため、必須の
connection service_email:サーフェスを追加する際は、無効化 → 公開 → 有効化の順に実行します(単純な公開ではcouldn't find the default agent userエラーが発生します)。エスカレーションが必要な場合は、ここでアウトバウンドルートもまとめて設定します。 - ステップ 4 — BotEmailDefinition:保存時の条件を事前確認し、返信テンプレートを検証してから、
--metadata-dirでデプロイします。その後、botEmailDefinition+ ステップ 2 のルーティングフィールド + 必須のcasePriorityを含む単一のSettings:Caseデプロイでルーティングアドレスをバインドします。失敗した場合は中止します。
ルーティングアドレスのバインドが検証できたら、ブランチ C は完了です。フェーズ 3 に進みます。
フェーズ 3 — アウトバウンドエスカレーション(任意)
正式な担当: エージェントから人間への完全なエスカレーションは
service-agentforce-human-escalation-configureが担当します。これには、エスカレーションのトピック、プランナーとの連携、担当者がいる人間対応キュー、アウトバウンドフロー、失敗しきい値の指示、再公開、決定論的な検証が含まれます。
インバウンドルーティングが確認できたら、ユーザーに次のように尋ねます。
「インバウンドルーティングが設定され、チャネルは [エージェント名] にルーティングされるようになりました。リクエストに応じてエージェントが人間に引き継げるよう、アウトバウンドエスカレーションも設定しますか?」
はいの場合は、service-agentforce-human-escalation-configure に委任します。既知の入力として、解決済みのエージェント、チャネルタイプ、コンテキストオブジェクト、フォールバックキューを渡します。このスキルの書き込み手順や検証手順をここで重複して実行しないでください。
ルール/制約
| ルール | 理由 |
|---|---|
| 変更を加える前に、エージェントが存在し、Active であることを確認してください | 存在しない、または非アクティブなエージェントにチャネルを接続しても、実行時にエラーが通知されずに失敗します |
チャネルにすでにアクティブなインバウンドルーティングがある場合は、プロンプト内の明示的な延期/切り替えの意図に従ってください。意図が明示されていない場合は AskUserQuestion で警告し、判断が曖昧な場合は延期をデフォルトにしてください | 再ルーティングは直ちに有効になり、ライブトラフィックに影響します。キューと RoutingFlow の作成は常に進め、ゲートで制御するのはアクティベーションの手順だけです。安全なデフォルトは、既存の設定を破壊しないことです |
| 延期する場合は、Phase 3 の前に手動で接続するための正確な手順を表示してください | 運用担当者が切り替えの準備ができたときに実行するコマンドを、正確に把握できる必要があります |
| 現在のメタデータを取得せずに MessagingChannel を変更しないでください | 取得せずに上書きすると、既存の設定が失われます |
分岐 A:RoutingFlow を作成せず、エージェントも再公開しません。メタデータ経由で sessionHandlerType と sessionHandlerQueue をデプロイし、Data API の PATCH で SessionHandlerId をバインドしてください | v67 では sessionHandlerAsa が Metadata API で受け付けられないため、デプロイ時に通知なくドロップされます。そのため、Bot のバインドはデプロイ後に Data API の PATCH で行う必要があります。PATCH の前に Bot が Active である必要があります |
| 分岐 B/C:必ず新しい RoutingFlow を作成し、既存の組織フローを再利用しないでください | OOB プラットフォームフローでは ActiveVersionId: null であることが一般的で、参照できません |
分岐 B/C:QueueBased ではなく、routingType: Copilot と copilotLabel を使用してください | QueueBased はキューに直接ルーティングします。Copilot はまずエージェントにルーティングし、フォールバックとしてキューを使用します |
キューの Id をクエリし、RoutingFlow XML に埋め込む必要があります | queueId パラメーターには 18 文字のレコード Id をハードコードする必要があります。空欄のままにしないでください |
キューの命名規則:{ChannelTypeLabel} Queue | エージェントではなく、チャネルタイプに基づいて命名します |
| アウトバウンドのエスカレーションは任意です。インバウンドルーティングの完了を決して妨げないでください | インバウンドとアウトバウンドは独立しています。アウトバウンドの手順がなくても、インバウンドの接続は完了します |
分岐 C:BotEmailDefinition は --metadata BotEmailDefinition:<name> ではなく、必ず --metadata-dir でデプロイしてください | CLI の SDR レジストリに登録されていないため、名前付きタイプでのデプロイは失敗します。メタデータ形式なら機能します |
分岐 C:ServiceCustomerVerification トピックを持つエージェントをメールに接続しないでください | 検出したら停止し、自動削除しないでください(複数サーフェスで使うエージェントにとって正当な設定である可能性があります)。channel-branch-email.md の Step 4a を参照してください |
検証チェックリスト
キュー
- キューに、チャネルタイプに対応する正しい
SobjectTypeのQueueSobjectレコードがある - 新規作成の場合、実行ユーザーがキューのメンバーである
- キューに、正しい
CapacityPercentage(Chat/Voice/Email の順に 50/100/25)が設定されたQueueRoutingConfigがある
分岐 A — MessagingChannel
- デプロイ後に
SessionHandlerType = AgentforceServiceAgentになっている - Data API の PATCH 前に Bot が Active である
- Data API の PATCH 後に
SessionHandlerIdが null ではない(Bot のBotDefinition.Idと一致し、0Xxで始まる) - Data API の PATCH 後に
FallbackQueueIdが null ではない(解決されたキュー Id と一致する)
分岐 B/C — RoutingFlow
- RoutingFlow の
ActiveVersionIdが null ではない - フローの
routeWorkアクションでroutingType = Copilotになっている -
copilotLabelがエージェントのMasterLabelと完全に一致する -
queueIdが設定されている(空ではない)
分岐 C — メールルーティングアドレス
- 新規作成の場合、正しい
PersonalNameとAddressを持つEmailRoutingAddressレコードが作成されている - 新規作成の場合、
caseOrigin、saveEmailHeaders: true、addressType: EmailToCaseを指定して CaseSettings にパッチが適用されている - 新規作成の場合、サポートアドレスに確認メールが送信されたことをユーザーに通知している(ブロックしない)
ブランチ C — BotEmailDefinition
- 事前チェック合格: エージェントが
EinsteinServiceAgentであり、agentforceServiceAgentUserを持つボットユーザーが存在する。アクティブバージョンがServiceEmailサーフェスを備えている。メールエージェントにServiceCustomerVerificationトピックが存在しない - 返信
EmailTemplateが SFX、HTML、公開であり、[[[GENERATED_CONTENT]]]+[[[LEGAL_DISCLOSURE]]]を含む - ヘッドレスパス (API ≥68):
BotEmailDefinitionが--metadata-dir経由でデプロイされ、success: trueである。legalDisclaimer/signatureが10文字以上 - ルーティングアドレスの
botEmailDefinition子が、デプロイされたコンポーネントのfullNameに設定されている - 同じルーティングアドレスにインバウンドルーティングが設定されている:
caseOwner+caseOwnerTypeまたはroutingFlow+fallbackQueue、かつcasePriorityが存在する
オプションのフェーズ 3 — アウトバウンドエスカレーション
-
service-agentforce-human-escalation-configureがCONFIGUREDまたはALREADY-CONFIGUREDを返した
参照ファイルインデックス
| ファイル | 読むタイミング |
|---|---|
references/channel-types.md | フェーズ 1 — SobjectType とルーティングブランチを決定する |
references/queue-resolution.md | フェーズ 1 — キューの検索、作成、Id のキャプチャ |
references/live-traffic-gate.md | フェーズ 2 — 検出クエリ、遅延フローのルール、およびライブトラフィック警告ゲート用の手動配線コピー |
references/channel-branch-voice.md | ブランチ B — Voice インバウンド配線の全体: PstnVoice チャネル選択、RoutingFlow、MessagingChannel の割り当て、modality voice: の再公開 |
references/channel-branch-email.md | ブランチ C — Email-to-Case 配線の全体: API v68.0+ の前提条件ゲート、CaseSettings フラグ、EmailRoutingAddress + 読み取り-変更-書き込みパッチ、インバウンド RoutingFlow、必須の connection service_email: サーフェスブロック、ヘッドレス BotEmailDefinition デプロイ、ルーティングアドレスのバインディング |
references/botemaildefinition.md | ブランチ C ステップ 4 — BotEmailDefinition のフィールド、保存時の検証順序、ASA テンプレートのルール、--metadata-dir デプロイのレシピ、ServiceEmail サーフェスの前提条件、複合組織ゲート |
references/routing-flow.md | ブランチ B/C — インバウンド RoutingFlow の XML テンプレート、デプロイ、検証 |
references/agent-wiring.md | フェーズ 3 (オプション) — アウトバウンドエスカレーションの connection ブロック |
assets/BotEmailDefinition.botEmailDefinition-meta.xml | ブランチ C ステップ 4c — BotEmailDefinition ソースファイルの開始テンプレート |
assets/mdapi-package.xml | ブランチ C ステップ 4c — --metadata-dir デプロイ用のメタデータ形式 package.xml |
assets/email/unfiled$public/AgentforceForServiceEmailTemplate.email + .email-meta.xml | ブランチ C ステップ 4b (フォールバック) — ユーザーがテンプレートを持っていない場合の、ASA 準拠の最小限の SFX 返信テンプレート |
scripts/validate-botemaildefinition.py | ブランチ C ステップ 4c — デプロイ前に BotEmailDefinition ファイルを検証する |
scripts/validate-emailtemplate.py | ブランチ C ステップ 4b (フォールバック) — デプロイ前に SFX テンプレートを検証する |