关于 service-email-to-case-configure
通过 Metadata API 配置 Salesforce Email-to-Case 的技能,适用于无界面组织设置。它分两个阶段应用设置,先启用 On-Demand,再添加路由地址,最后重新读取并验证结果。
主要功能
- 01配置 Email-to-Case 设置
- 02创建受支持的路由地址
- 03分两个阶段应用设置
- 04保留现有 Support Settings
- 05重新读取并验证更改
适用场景
- 01不使用 Setup UI 配置 Email-to-Case
- 02添加 EmailToCase、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详细介绍
配置 Email-to-Case(Metadata API)
完全通过 Metadata API 配置 Salesforce Email-to-Case(不使用 Setup UI),以便在无头组织中进行配置。此技能会为所需的 emailToCase 状态构建 CaseSettings 源文件,然后通过 scripts/apply-casesettings.py 应用该文件。该脚本分两个阶段运行 updateMetadata:先应用完整的 emailToCase 块和 Support Settings(阶段 A),再应用路由地址(阶段 B),最后通过重新读取进行验证。之所以分成两个阶段,是因为在新组织中一次部署会失败:必须先启用 On-Demand,地址才能绑定(请参阅规则 / 限制)。
范围
- 范围内:在整个组织中启用 Email-to-Case 并设置其开关(完整字段列表见必需输入和第 4 步);创建
EmailToCase、Outlook和GmailOAuth路由地址;通过apply-casesettings.py将更改应用到经过 sf-CLI 身份验证的组织;通过重新读取进行验证。 - 范围外:
E2cEasy路由地址 — 只能通过 Service Easy Setup 向导创建,不能通过 Metadata API 创建;请引导用户使用该向导。- 对组织进行身份验证 — 用户在带外完成身份验证(例如
sf org login web);脚本会复用该会话,不会处理密码或令牌。 - Case 对象架构、布局、分配规则或 Web-to-Case。
关联 Agentforce 服务 Agent(委派)
当用户希望 Agentforce 服务 Agent 回复这些电子邮件时,请先配置 Email-to-Case 基础设置(下文的工作流),然后进行委派 — 此技能不会创建或修改 Agent。
首先检查组织是否具备相应能力。 关联 Agent 需要组织具备 Agentforce Email-to-Case 授权;该授权由 BotEmailDefinition 元数据类型体现,因此请在委派之前进行只读探测:
scripts/check-agent-email-capability.sh <target-org-alias> # pins describe to the org's API version
退出代码为 3 → 未获授权:停止操作,告知用户,并且只配置普通的 Email-to-Case 基础设置 — 不要更改任何 Agentforce Agent 或渠道配置。 其他任何非零退出代码都表示组织不可达,而不是“未获授权” — 请修复身份验证后重新运行。退出代码为 0 时,进行委派:
- 创建 Agent →
agentforce-generate,省略Service Customer Verification 主题(电子邮件渠道不支持),并包含 Escalation 子 Agent,以便 Agent 能转交给人工处理 — 在电子邮件渠道中,升级会将 Case 转交给服务代表;没有该子 Agent,Agent 就无法升级。 - 配置连接 →
service-agentforce-channel-configure的分支 C。
必需输入
应用前收集或推断。只有错误假设会导致结果损坏或不正确时才提问:
- 目标组织别名 — 已通过身份验证的组织的 sf CLI 别名/用户名。脚本通过
sf org display和sf org auth show-access-token获取会话;不会替你登录。 - 路由地址 — 每个地址都需要提供:
routingName(唯一标签)、addressType(默认为EmailToCase,或Outlook/GmailOAuth)、caseOrigin和casePriority。如果缺少caseOrigin或casePriority,平台会拒绝该地址,因此请在源文件中将这四项全部视为必需项。 - 每个路由地址对应的面向客户的电子邮件地址 — 按地址顺序逐一明确询问;绝不可猜测、设置默认值或沿用先前上下文中的值。此项不存储在源文件中,而是在应用时通过
--routing-email传入(每个地址一个;数量不匹配时,脚本会安全失败)。 - 支持设置 — 默认案例所有者和自动化案例用户 — 优先保留现有设置,绝不自行假设:
- 每个字段独立保留。 已配置的字段保持不变;只有用户提出要求时才更改(
--overwrite-support-settings)。只询问未设置的字段。 - 对于每个未设置的字段,询问(绝不默认使用已通过身份验证的用户):默认案例所有者的类型(
User/Queue)+ 值(有效的 Username 或 Queue DeveloperName)→--owner-type/--owner-value;自动化案例用户的类型(User/System)——User需要提供用户名,System无需提供值 →--automated-type/--automated-value(对于尚不存在组织自动化用户的System,可选传入--system-user-email)。 - 如果任何值无效,脚本会失败——获取有效值后重新运行;绝不替换或猜测。
- 仅当用户明确提出要求时才传入
--use-authenticated-user。
- 每个字段独立保留。 已配置的字段保持不变;只有用户提出要求时才更改(
- 每个地址的案例默认值(可选)—
createTask、saveEmailHeaders,以及可选的每个地址的默认案例所有者(caseOwner+caseOwnerType),每个地址需选择启用(见步骤 6):默认省略,使案例分配给组织的默认案例所有者或遵循分配规则。设置时,caseOwner(有效的 Username 或 Queue DeveloperName)必须与caseOwnerType(User/Queue)配对;脚本会对照组织进行验证,缺少时安全失败。 - 组织级开关(可选)— 仅在用户提出要求时设置。包含两个容器:
emailToCase部分(enableHtmlEmail、notifyOwnerOnNewCaseEmail、enableE2CDeduplicateAttachments、showWordCountInComposer,以及enableE2CSourceTracking、overEmailLimitAction、unauthorizedSenderAction),以及顶层支持设置(enableDraftEmails— 元素名称为复数,与emailToCase同级)。容器与界面标签的对应关系见步骤 4 的表格;顶层标量开关在阶段 A 应用。
默认值:enableEmailToCase 和 enableOnDemandEmailToCase 默认均为 true(两者均为必需项——先启用按需功能,再配置路由地址);addressType 默认为 EmailToCase。支持设置没有默认值——若已设置则保留,否则需询问用户(绝不使用已通过身份验证的用户)。
工作流程
所有步骤按顺序执行。
-
确认组织(及其类型) — 确认目标组织别名已通过身份验证(
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)支持设置 启用这些设置之前,请明确告知用户将开启哪些设置,并允许用户选择退出(例如:“我还会启用以下可选设置:……如果你想跳过其中任何一项,请告诉我。”)。移除用户选择退出的设置;其余设置保留在正确的容器中(四项位于
<emailToCase>内,enableDraftEmails位于根级)。切勿在未告知用户的情况下启用这些设置或任何其他用户未同意的可选标记。已确认的切换项在阶段 A 中应用。 -
为每个路由地址选择正确的操作界面 — 根据
references/routing_address_reference.md,按addressType为每个地址作出判断。如果用户要求的地址中有任何一个为E2cEasy,请停止操作,并引导用户改用 Service Easy Setup 向导,而不是为其输出 Metadata。 -
填写路由地址字段 — 对每个
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,顺序与文档中的地址一致。仅当组织尚未配置支持设置时(步骤 7),才提供所有者/自动用户标志;如果已配置,则省略这些标志,现有设置会保留。如果脚本判定某个值无效,请告知用户该值,让用户提供有效值,然后重新运行——切勿回退到已通过身份验证的用户。如果脚本报告目标为生产环境并退出,请勿自行添加--confirm-production——必须先与用户确认(步骤 1)。脚本会先应用阶段 A(支持设置 + 开关),再应用阶段 B(路由地址),随后重新读取以验证,并在出现任何故障时以非零状态退出。 -
确认结果——检查 JSON 摘要:
verified.enableEmailToCase/verified.enableOnDemandEmailToCase为true,verified.routingAddressCount与地址数量一致,每个phaseB条目的状态为status: created(或already_exists),且supportSettings.action为preserved-existing/set-from-input/set-from-authenticated-user。使用--verify-only重新读取而不写入。
步骤 10 完成后,配置即告完成。
设置后——完成后的指导
以下内容不是工作流步骤——确认设置完成后再向用户介绍。
转发(实际接收邮件的必要条件)
始终向用户提供以下指导——这是客户可见地址收到的入站邮件实际送达 Salesforce 的方式:
现在,您的路由地址已有一个由 Salesforce 生成的电子邮件服务地址。如需接收入站邮件,请将您的电子邮件系统配置为把发送到客户可见地址(例如
[email protected])的邮件转发到该生成的服务地址。
端到端验证(第 3 幕)
提出验证入站邮件是否会创建案例——进行一次实时往返验证;如果用户拒绝,则跳过。该技能不会发送邮件——它会协调两个由人工执行的操作,然后通过 SOQL 验证:(1)地址所有权——Salesforce 会发送一条包含确认链接的邮件;只有人工点击后,isVerified 才会变为已验证。请告知用户点击链接并等待。(2)发送测试邮件——请用户从外部邮箱向路由地址由 Salesforce 生成的电子邮件服务地址发送一封真实邮件(而不是客户可见地址;只有配置转发后,该地址才能收到邮件),并报告发件人,然后等待。(3)通过证据验证——然后运行:
python3 scripts/apply-casesettings.py --target-org <alias> --verify-cases \
[--supplied-email <external-sender-address>]
只读:查询 Case 中 Origin='Email' 的记录(最近 3 天,可按发件人进一步筛选),以及关联的入站 EmailMessage 记录(Incoming=true,ParentId = 新建的 Case)。如果没有匹配的 Case 关联入站邮件,则以非零状态退出(邮件尚未处理——等待后重新运行——或者地址尚未验证)。成功时会输出 Case + EmailMessage 证据,并显示 proven: true。
规则 / 约束
| 约束 | 原因 |
|---|---|
通过 apply-casesettings.py(两阶段 updateMetadata)应用,绝不能直接部署或仅修补 emailToCase | 在新组织中,单次部署会失败;必须使用完整的 emailToCase 块(而非仅切换字段),才能在绑定地址前配置按需功能。请参阅 references/apply-mechanics.md。 |
只写入此技能负责的顶层字段,绝不回显整个 CaseSettings 记录 | 平台会重新验证载荷中的每个顶层字段(例如 Case Feed → Chatter);只发送 emailToCase + enableDraftEmails + Support Settings 可避免无关错误,也不需要 Chatter 前置条件。省略的字段会通过字段级合并保留原值。 |
面向客户的电子邮件地址必须由用户明确输入(--routing-email),绝不能写在源文件中,也绝不能自行假定 | 这样可以防止配置错误或过时的地址。如果 --routing-email 数量 ≠ 地址数量,脚本会安全失败。 |
CaseSettings 的 fullName 始终为 Case | 这是组织级单例设置类型;脚本会自动以 Case 为目标。 |
| 如果 Support Settings 已配置,则按字段保留;绝不自行假定 | Default Case Owner 和 Automated Case User 相互独立——每个已配置字段都会保持不变(除非使用 --overwrite-support-settings),只有未设置的字段才需要明确且经组织验证的值(否则安全失败)。只有使用 --use-authenticated-user 时才会使用已验证用户。 |
Automated Case User“System”和指定名称的 defaultCaseUser 互斥 | --automated-type System 会设置 useSystemUserAsDefaultCaseUser,且不得携带用户值;平台会拒绝同时设置两者。 |
| 脚本按读取 → 修补 → 更新的顺序执行(地址仅追加) | 它会合并到当前设置,因此会保留现有路由地址;重复的 routingName/emailAddress 会报告为 already_exists。新地址会排在现有地址之前(updateMetadata 会整体替换集合;若新地址排在现有地址之后,就会删除现有地址;运行时保护会在任何现有地址被删除时中止执行)。请参阅 references/apply-mechanics.md。 |
绝不直接应用 EmailToCaseSettings;启用后无法关闭 enableEmailToCase | 它只会作为 CaseSettings 的子项 emailToCase 写入。首次应用 true 后,平台会永久启用此功能;绝不能指望将其重新设为 false。 |
生产组织必须明确使用 --confirm-production;绝不能未经提示就添加该标志 | 启用 Email-to-Case 是永久且适用于整个组织的。对于非沙盒、非试用组织(以及无法读取组织类型的组织),在用户确认前脚本会安全失败。沙盒和试用组织不受此限制。 |
| 证明入站 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 服务 Agent 时使用——委派前的功能门控(探测 BotEmailDefinition) |
scripts/validate-casesettings.py | 第 8 步——应用前进行确定性结构验证 |
scripts/apply-casesettings.py | 第 9 步——通过两阶段 updateMetadata 应用设置并进行验证 |
scripts/tests/test_get_session.py | 更改会话令牌获取方式(get_session / _usable_access_token)时运行——用于保护令牌提取和 API 版本解析的单元测试套件 |