Skip to content
AI & Agents
Skill

/service-de-channel-activate

Activate an Enhanced `MessagingChannel` (WhatsApp / Apple / Facebook / SMS / RCS) by PATCHing `MessagingChannelUsage.DeploymentStatus` from `Disabled` to `Provisioning` via the standard REST sobject endpoint. The UDD save-hook fires on the REST write, dispatches by `MessageType`

From plugin
forcedotcom-sf-skills
997200 skills2 agents14 commands3 MCP
Install
$ npx -y skills add forcedotcom/afv-library --skill service-de-channel-activate --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/service-de-channel-activate

Context preview

The summary Claude sees to decide when to auto-load this skill.

Activate an Enhanced `MessagingChannel` (WhatsApp / Apple / Facebook / SMS / RCS) by PATCHing `MessagingChannelUsage.DeploymentStatus` from `Disabled` to `Provisioning` via the standard REST sobject endpoint. The UDD save-hook fires on the REST write, dispatches by `MessageType`

SKILL.md

service-de-channel-activate.SKILL.md
name: service-de-channel-activate
description: "Activate an Enhanced `MessagingChannel` (WhatsApp / Apple / Facebook / SMS / RCS) by PATCHing `MessagingChannelUsage.DeploymentStatus` from `Disabled` to `Provisioning` via the standard REST sobject endpoint. The UDD save-hook fires on the REST write, dispatches by `MessageType` for the external callout (`WHATS_APP` → Meta `/register`, `FACEBOOK` → `subscribeFacebookPage`, `TEXT` → `registerCsotSms`; Apple, LINE, and others need no external call), writes the terminal `Active` or `Error`, and flips `MessagingChannel.IsActive`. The chain is synchronous on the HTTP response — WhatsApp returns 204 only after Meta confirms registration (~15-21s); channels with no external callout are near-instant (~1s on Apple). No Aura RPC; no CSRF cookies. Use this skill when the user needs to activate an already-inserted Enhanced messaging channel headlessly via REST."
metadata:
  version: "1.0"
  minApiVersion: "67.0"
  domains: ["Service"]
  cliTools:
    - tool: ["jq"]
      semver: ">=1.6.0"
    - tool: ["node"]
      semver: ">=20.0.0"
    - tool: ["sf"]
      semver: ">=2.0.0"
  relatedSkills:
    - "service-de-channel-consent-configure"
    - "service-de-channel-create"
    - "service-de-channel-routing-configure"

Activating a Messaging Channel

What this skill does

Given a `{CHANNEL_ID}`, reads the channel's `MessagingChannelUsage.Id`, then fires `PATCH /services/data/v{V}/sobjects/MessagingChannelUsage/{MCU_ID}` with body `{"DeploymentStatus":"Provisioning"}`. The server-side chain:

1. `MessagingChannelUsageFunctions.validateBeforeSave` runs `validateDeploymentStatus` → `validateChannelReadinessOnProvisioning`. For WhatsApp this confirms consent is configured. Rejected writes return HTTP 400 `FIELD_INTEGRITY_EXCEPTION`. 2. `MessagingChannelUsageFunctions.saveHook_PostStmtExecuteOnce` fires unconditionally after the UPDATE statement. It calls `MessagingChannelUsageFunctionsHelper.handlePostSave` which registers a post-commit `TransactionObserver`. 3. At commit, the observer calls `ConversationChannelUsageDeploymentStatusService.handleProvisioning` (inherited from `AbstractChannelUsageDeploymentStatusService`), which:

  • Calls `runProvisioning` — `switch`-dispatches by `MessageType` for the external callout:
  • `WHATS_APP` → `registerCsotWhatsAppNumber` → `LiveMessageSetupApi.registerWhatsAppNumber` → Meta `/register` + status verification. 15-21s wall-clock.
  • `FACEBOOK` → `metaGraphApiService.subscribeFacebookPage`.
  • `TEXT` → `registerCsotSms`.
  • `AppleBusinessChat`, `Line`, everything else → `default` branch, no external callout, no network wait.
  • On success: writes `DeploymentStatus = 'Active'` via PLSQL.
  • On failure: writes `DeploymentStatus = 'Error'` plus `ErrorReason` / `ErrorDetails`.

4. Inside the same observer, a second pass syncs `MessagingChannel.IsActive = true` once MCU reaches `Active` (the `isTransitioningStatus` flag skips the flip while status is still `Provisioning`).

All synchronous within the PATCH request — the 204 response only comes back after the full chain completes. WhatsApp: ~15-21s (Meta `/register` round-trip). Apple / Line: ~1s (no external call; just the local save-hook + observer + PLSQL write). Verified on wadtesting 2026-04-30.

Reference File Index

| Reference file | Load when | | --- | --- | | `references/phone-verification.md` | Stage 3 comes back with `ErrorReason === "VERIFICATION_REQUIRED"` (WhatsApp only) — the phone-number OTP verification sub-flow. | | `references/worked-examples.md` | You want a reference run of the WhatsApp happy-path, Apple activation, a readiness failure, or the already-active no-op. | | `references/gotchas.md` | Troubleshooting an unexpected result, or before modifying this skill — the eleven known gotchas. |

Why REST PATCH instead of Apex?

A direct REST PATCH produces the identical save-hook chain as the old `activateChannelUsage` Apex method, with substantially less machinery — no CSRF cookie acquisition, no bootstrap fetch, no Aura response parsing, no double-wrapped `returnValue`. REST semantics are honest: 204 means the transition succeeded; 4xx means it didn't.

Code proof: `MessagingChannelUsageFunctions.saveHook_PostStmtExecuteOnce` fires on any DML path (REST, SOAP, Apex, Metadata API) — there is no Apex-specific gate. The entity XML (`MessagingChannelUsage.entity.xml`) marks `DeploymentStatus` as `editAccess="always"` with no `<readonly>` attribute. The transition validator (`getValidAPIStatusTransitions`) allows `Disabled → Provisioning` (and `New → Provisioning`, and `Error → Provisioning | Deprovisioning`, and `Active → Deprovisioning`). The DB-only transitions `Provisioning → Active | Error` are reserved for the observer's PLSQL call — that's why we write `Provisioning` and let the server pick the terminal state.

When NOT to use this skill

  • **The channel is already `IsActive=true`.** Re-firing is blocked by the API transition validator (`Active → Provisioning` is not in `getValidAPIStatusTransitions()`) — the PATCH would return 400. The Stage 1 precondition check catches this and emits `noop:true`.
  • **Routing isn't configured.** `activateChannelUsage` used to fail with `LiveMessageSetupException` / `nullQueueId` at the Apex entry point. With the REST path the same guard lives in `validateChannelReadinessOnProvisioning` — write with `SessionHandlerId=null && FallbackQueueId=null` → 400 `FIELD_INTEGRITY_EXCEPTION`. Run `service-de-channel-routing-configure` first. The Stage 1 check still runs defensively.
  • **The MCU doesn't exist.** Can't PATCH a row that's missing. Run the insertion skill first — it always creates the MCU as a side-effect of `addChannel`.

Inputs (from caller)

  • `{CHANNEL_ID}` — a 15- or 18-char `MessagingChannel.Id` (prefix `0Mj`). The channel must already exist with a non-null `SessionHandlerId` or `FallbackQueueId`.
  • `{ORG_ALIAS}` — optional; the `sf` CLI target-org alias. Default: what
Read more
Ships withforcedotcom-sf-skills

This repository provides a curated collection of Salesforce agent skills for building applications.

Get the whole plugin

Other skills on forcedotcom-sf-skills.