Service Email To Case Configure
Use to configure Salesforce Email-to-Case headlessly via the Metadata API. Reads CaseSettings, applies the emailToCase config with updateMetadata, and verifies by re-reading. Also the entry point for attaching an Agentforce agent to Email-to-Case: configures the E2C base, then delegates agent creation and channel wiring. TRIGGER on set up/configure Email-to-Case, enable E2C routing addresses, add a routing address, or E2C with an Agentforce agent. DO NOT TRIGGER for the interactive Easy Setup wizard, On-Demand E2C only, general Case/web-to-case setup, or an agent with no E2C involved.
- Skill ID
- forcedotcom/sf-skills/service-email-to-case-configure
- Publisher
- forcedotcom
- Repository
- sf-skills
- Installs
- 0
- Files
- 17
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
forcedotcom/sf-skills/service-email-to-case-configureInstalls these files- SKILL.md
- assets/CaseSettings.settings-meta.xml
- examples/CaseSettings-two-addresses.settings-meta.xml
- references/apply-mechanics.md
- references/routing_address_reference.md
- references/troubleshooting.md
- scripts/apply-casesettings.py
- scripts/check-agent-email-capability.sh
- scripts/tests/__init__.py
- scripts/tests/_bootstrap.py
- scripts/tests/_fakeorg.py
- scripts/tests/_run.py
- scripts/tests/test_apply_org_scenarios.py
- scripts/tests/test_get_session.py
- scripts/tests/test_new_capabilities.py
- scripts/tests/test_validate_casesettings.py
- scripts/validate-casesettings.py
What this skill tells the agent
Configure Email-to-Case (Metadata API)
Configure Salesforce Email-to-Case entirely through the Metadata API (no Setup UI), for headless org configuration. The skill builds a CaseSettings source file for the desired emailToCase state, then applies it with scripts/apply-casesettings.py, which runs updateMetadata in two phases — the full emailToCase block + Support Settings (Phase A), then routing addresses (Phase B) — and verifies by re-reading. Two phases because a single deploy fails on a fresh org: On-Demand must be live before an address binds (see Rules / Constraints).
Scope
- In scope: Enabling Email-to-Case org-wide and setting its toggles (full field lists in Required Inputs and step 4); creating
EmailToCase,Outlook, andGmailOAuthrouting addresses; applying the change to an sf-CLI-authenticated org viaapply-casesettings.py; verifying by re-reading. - Out of scope:
- `E2cEasy` routing addresses — created only through the Service Easy Setup wizard, not the Metadata API; route the user there.
- Authenticating the org — the user authenticates out-of-band (e.g.
sf org login web); the script reuses that session and never handles passwords or tokens. - Case object schema, layouts, assignment rules, or Web-to-Case.
Attaching an Agentforce service agent (delegation)
When the user wants an Agentforce Service Agent to answer these emails, configure the Email-to-Case base (the Workflow below), then delegate — this skill never creates or modifies agents.
Gate on org capability first. Attaching an agent needs the org entitled for Agentforce Email-to-Case; that entitlement surfaces as the BotEmailDefinition metadata type, so probe read-only before delegating:
scripts/check-agent-email-capability.sh <target-org-alias> # pins describe to the org's API versionExit 3 → not entitled: stop, tell the user, and configure the plain Email-to-Case base only — make no Agentforce agent or channel-wiring changes. Any other non-zero is an unreachable org, not "not entitled" — fix auth and re-run. On exit 0, delegate:
- Agent creation → `agentforce-generate`, omitting the Service Customer Verification topic (unsupported on the email channel) and including an Escalation subagent so the agent can hand off to a human — on email, escalation transfers the case to a service rep, and without the subagent the agent can't escalate.
- Wiring → `service-agentforce-channel-configure` Branch C.
Required Inputs
Gather or infer before applying. Ask only when a wrong assumption would produce a broken or incorrect result:
- Target org alias — the sf CLI alias/username of an already-authenticated org. The script obtains the session with
sf org displayandsf org auth show-access-token; it does not log in for you. - Routing address(es) — for each:
routingName(unique label),addressType(EmailToCasedefault, orOutlook/GmailOAuth),caseOrigin, andcasePriority. The platform rejects the address ifcaseOriginorcasePriorityis missing, so treat all four as required in the source file. - Customer-facing email address per routing address — ask explicitly for each, in address order; never guess, default, or reuse from earlier context. Not stored in the source file — passed at apply time via
--routing-email(one per address; the script fails closed on a count mismatch). - Support Settings — Default Case Owner & Automated Case User — preserve-first, never assumed:
- Independent, preserved per field. Each configured field is left untouched; change one only if the user asks (
--overwrite-support-settings). Ask only for the field(s) unset. - For each unset field, ask (never default to the authenticated user): Default Case Owner type (
User/Queue) + value (active Username or Queue DeveloperName) →--owner-type/--owner-value; Automated Case User type (User/System) —Userneeds a username,Systemneeds no value →--automated-type/--automated-value(+ optional--system-user-emailfor System when the org's automated user doesn't exist yet). - If any value is invalid, the script fails — get a valid value and re-run; never substitute or guess.
- Pass
--use-authenticated-useronly if the user explicitly asks. - Case defaults per address (optional) —
createTask,saveEmailHeaders, and an optional per-address Default Case Owner (caseOwner+caseOwnerType), opt-in per address (see step 6): omitted by default so cases fall to the org Default Case Owner / assignment rules. When set,caseOwner(active Username or Queue DeveloperName) must be paired withcaseOwnerType(User/Queue); the script validates it against the org, failing closed if absent. - Org-level toggles (optional) — set only if the user asks. Two containers: the `emailToCase` section (
enableHtmlEmail,notifyOwnerOnNewCaseEmail,enableE2CDeduplicateAttachments,showWordCountInComposer, plusenableE2CSourceTracking,overEmailLimitAction,unauthorizedSenderAction), and top-level Support Settings (enableDraftEmails— plural element name, a sibling ofemailToCase). See step 4's table for container/UI-label mapping; top-level scalar toggles apply in Phase A.
Defaults: enableEmailToCase and enableOnDemandEmailToCase default to true (both required — On-Demand before routing addresses); addressType defaults to EmailToCase. Support Settings have no default — preserved if set, otherwise elicited (never the authenticated user).
Workflow
All steps are sequential.
- Confirm the org (and its type) — confirm the target org alias is authenticated (
sf org display --target-org <alias>). The apply script checks theOrganizationrow and refuses to mutate a production org (non-sandbox, non-trial) unless--confirm-productionis passed — enabling Email-to-Case is permanent and org-wide. If production, tell the user and confirm before re-running with--confirm-production. Sandboxes, scratch orgs, and trials deploy without the flag.
- Elicit the routing email(s) — ask the user for the exact customer-facing email address for each routing address (never assume, default, or carry a value over from earlier). Pass them to the script via
--routing-emailin the order the addresses appear in the source file.
- Load the template — read
assets/CaseSettings.settings-meta.xmlfor structure and field placement. Its comments are authoring guidance for you — never copy them into the output. Emit only the elements you set; the output must be comment-free, matchingexamples/CaseSettings-two-addresses.settings-meta.xml.
- Enable the E2C switches, then confirm the optional toggles — set both
enableEmailToCaseandenableOnDemandEmailToCasetotrue(both required; On-Demand must be on before routing addresses can be created — the script enables it in Phase A before Phase B). Then handle the non-required convenience settings, which the template turns on by default:
| UI label | Field | Container |
|---|---|---|
| Enable HTML email | enableHtmlEmail | emailToCase |
| Eliminate duplicate email attachments | enableE2CDeduplicateAttachments | emailToCase |
| Show word count in composer | showWordCountInComposer | emailToCase |
| Notify case owners on new emails | notifyOwnerOnNewCaseEmail | emailToCase |
| Enable Email Drafts | enableDraftEmails (top-level CaseSettings) | Support Settings |
More from forcedotcom
Use this skill in a project
Open any RiverX project, search the Skills panel for forcedotcom/sf-skills/service-email-to-case-configure, and install it in one click.
