forcedotcom/sf-skills8 files

Service De Channel Create

**INTERNAL USE ONLY — invoked by `service-de-headless-channel-configure`.** Insert an Enhanced messaging `MessagingChannel` (plus child `MessagingChannelUsage` as a free side-effect) of any type — WhatsApp, LINE, Apple Business Chat, Facebook, or SMS. Given a `{MESSAGE_TYPE}` and its inputs, runs the shared preflight → Connect-insert → verify flow, branching only where a type differs. Uses `POST /services/data/v{V}/connect/livemessage/channels` — no Aura session, no shell-stored token. **Invoke `service-de-headless-channel-configure` instead** — it handles insert → route → activate in one flow; replaces the four former per-type creation skills.

Specification
Skill ID
forcedotcom/sf-skills/service-de-channel-create
Publisher
forcedotcom
Repository
sf-skills
Installs
0
Files
8
Synced
Sep 23, 2026
How to use it

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-de-channel-createInstalls these files
  • SKILL.md
  • references/apple.md
  • references/connect-insert.md
  • references/facebook.md
  • references/line.md
  • references/sms.md
  • references/whatsapp.md
  • references/worked-examples.md

What this skill tells the agent

Inserting Messaging Channels

Reference File Index

Reference fileLoad when
references/whatsapp.mdMESSAGE_TYPE=WhatsApp — WABA partnership (Stage 2) + SF-side manage-WABA (Stage 3) prereqs, request body, WhatsApp gotchas.
references/line.mdMESSAGE_TYPE=Line — optional token verify, authDetails body shape, LINE gotchas.
references/apple.mdMESSAGE_TYPE=AppleBusinessChat — empty-config body, Apple-precondition errors, Apple gotchas.
references/facebook.mdMESSAGE_TYPE=Facebook — browser OAuth → page-selection flow, Facebook gotchas.
references/sms.mdMESSAGE_TYPE=Text — phone-number platform key, present-but-unvalidated smsProvider, number-provisioning prerequisite (caller's), SMS gotchas.
references/connect-insert.mdShared authProviderId lookup + Connect POST + response-classification detail (Stage 4).
references/worked-examples.mdEnd-to-end traces per type (fresh insert, preflight short-circuit, OAuth).

What this skill does

Given a {MESSAGE_TYPE} and its inputs, creates a MessagingChannel record with PlatformType=Enhanced, IsActive=false. The same server-side path (LiveMessageSetupServiceImpl.addChannel → LiveMessageChannelsUtil.findOrCreateCsotMessagingChannel) also inserts a MessagingChannelUsage row (DeploymentType=Conversation, DeploymentStatus=New on fresh insert — Disabled on a channel that was previously activated then deactivated) — we get it for free.

One primary path for every type: Connect REST API. POST /services/data/v{V}/connect/livemessage/channels with an org OAuth session managed by sf api request rest. Public, sanctioned, live since API v66+. No Aura session, no token extracted into shell state.

Idempotent on (MessagingPlatformKey, MessageType) — re-firing with the same platform key returns the existing channel's id. This matters because MessagingChannel records are not deletable via standard means, so the preflight (Stage 1) is the practical idempotency guard.

All types return the same envelope shape, so callers don't branch on type after insert: {ok, channelId, mcuId, developerName, isActive:false, messageType, messagingPlatformKey, path, created, durationMs}.

Supported types (the only branch point)

{MESSAGE_TYPE}Platform key (messagingPlatformKey)Prerequisite (caller supplies)Body extrasRef
WhatsAppPhone Number IDservice-de-waba-integrate (run in Stage 2-3)externalAccountId, isoCountryCodewhatsapp.md
LineLINE channel idLINE id + secret + token (LINE Developers Console)authDetails.{client_secret,access_token}line.md
AppleBusinessChatApple BC Account ID (GUID)Apple BC Account ID (register.apple.com/business-chat)(none — empty config)apple.md
FacebookFacebook Page IDOAuth handled internallyauthDetails: {} (OAuth-derived)facebook.md
TextPhone number / short codenumber already provisioned (caller supplies)smsProvider (key required, value may be ""), isoCountryCodesms.md

Unsupported (would need their own leaf logic, not yet built): WeChat, MsCopilot, Alexa. For these, emit the unsupported-type envelope (Stage 0).

When NOT to use this skill

  • End-to-end setup. If the user wants insert → route → activate, invoke service-de-headless-channel-configure — it orchestrates this skill plus routing, consent, and activation. This skill only handles the insertion step (see Stage 0).
  • The channel already exists and you only want to re-route / activate it. Skip insertion; call service-de-channel-routing-configure / service-de-channel-activate with the existing channelId.

Inputs (from caller)

  • {MESSAGE_TYPE} — one of WhatsApp, Line, AppleBusinessChat, Facebook, Text. Case-sensitive (matches the SF picklist). Text is the enum value for SMS — there is no SMS type.
  • {ORG_ALIAS} — optional; sf CLI target-org alias. Default: sf config get target-org.
  • {API_VERSION} — optional; Connect API version. Default: the org's current API version (sf org display --json | jq -r '.result.apiVersion'). Always use the org's native version to avoid 404s.
  • {CHANNEL_NAME} — display name shown in Setup → Messaging Settings. Required for AppleBusinessChat (no phone/screen-name fallback); prompted if omitted for others.

Type-specific inputs:

  • WhatsApp: {WABA_ID} (sent as externalAccountId), {PHONE_NUMBER_ID} (the platform key — must differ from WABA_ID), {ISO_COUNTRY_CODE} (optional, default US).
  • Line: {LINE_CHANNEL_ID} (platform key), {LINE_CHANNEL_SECRET}, {LINE_ACCESS_TOKEN}, {VERIFY_TOKEN_FIRST} (optional, default true).
  • AppleBusinessChat: {APPLE_BC_ID} (platform key, GUID).
  • Facebook: {PAGE_ID} (optional — OAuth fetches/prompts if absent).
  • Text (SMS): {SMS_NUMBER} (the platform key — the phone number / short code string, already provisioned to the org), {SMS_PROVIDER} (sent as smsProvider — the smsProvider key must be present in the body or the insert 400s with "SMS provider is missing", but its value is not validated or stored, so an empty string "" works; default to "" when the caller doesn't supply a provider), {ISO_COUNTRY_CODE} (optional, default US). This skill does not provision the number — the caller must already know their number.

Output (to caller)

Success:

{"ok": true, "channelId": "0Mj...", "mcuId": "0gL...", "developerName": "...",
 "isActive": false, "messageType": "{MESSAGE_TYPE}", "messagingPlatformKey": "...",
 "path": "connect" | "preflight", "created": true | false, "durationMs": 1234}

created: false + path: "preflight" means the row already existed and was returned idempotently.

Failure (shared):

{"ok": false, "kind": "wrong-skill", "correctSkill": "service-de-headless-channel-configure", "hint": "..."}
{"ok": false, "kind": "unsupported-type", "supportedTypes": ["WhatsApp","Line","AppleBusinessChat","Facebook","Text"], "hint": "..."}
{"ok": false, "kind": "missing-input", "missing": ["..."], "hint": "caller must provide all required inputs for this type"}
{"ok": false, "kind": "auth",     "hint": "OAuth token invalid / expired — run 'sf org login web'"}
{"ok": false, "kind": "business", "message": "...", "errorCode": "..."}
{"ok": false, "kind": "transport","status": 500, "message": "..."}
{"ok": false, "kind": "verify-failed", "hint": "Connect returned 201 but follow-up SOQL shows no matching channel"}

Type-specific failure kinds (partnership-blocked, user-declined, waba-manage-failed, meta-precondition for WhatsApp; line-token-invalid for LINE; apple-precondition for Apple; oauth-not-complete, oauth-failed for Facebook) are documented in the per-type reference files.


Stage 0: Enforce orchestrator-only invocation

This skill is INTERNAL USE ONLY. It should only be invoked by the service-de-headless-channel-configure orchestrator.

If the user's original request was to "install", "set up", "create", or "activate" a messaging channel (or any phrasing that implies end-to-end setup), immediately return:

{
  "ok": false,
  "kind": "wrong-skill",
  "hint": "This is an internal insertion skill. For end-to-end channel setup (insert → route → activate), invoke 'service-de-headless-channel-configure' instead with the desired MESSAGE_TYPE.",
  "correctSkill": "service-de-headless-channel-configure"
}

And render to the user:

Error: Wrong skill invoked.

This skill (service-de-channel-create) only handles the insertion step.
For complete channel setup, use: /service-de-headless-channel-configure

That orchestrator runs: insert → configure routing → activate in one flow.

Only proceed to Stage 0.1 if:

More from forcedotcom

Use this skill in a project

Open any RiverX project, search the Skills panel for forcedotcom/sf-skills/service-de-channel-create, and install it in one click.

Use this skill