service-digital-engagement-messaging-site-integrate
Integrates a Messaging for In-App and Web (MIAW) Embedded Messaging chat widget into an Experience Cloud site by patching the site's LWR or Aura page bundle, deploying, publishing, and verifying guest access. Use when the user wants to embed messaging on an Experience site, add a chat widget to a co
By forcedotcom · 2,342 installs
npx skills add forcedotcom/sf-skills --skill service-digital-engagement-messaging-site-integrate
Source repository · Upstream listing
Embed Messaging Widget on an Experience Cloud Site
Wires an existing Embedded Messaging (MIAW) deployment onto an Experience Cloud site by retrieving the site's bundle (LWR DigitalExperienceBundle or Aura ExperienceBundle ), patching the home page JSON to place the experience messaging:embeddedMessaging component, staging the bundle into the local project, deploying it, publishing the site, and verifying guest access.
The operation is idempotent: if the component is already present it is updated in place (its id is preserved), so re running with different ESD coordinates cleanly updates.
Scope
In scope : Detecting LWR vs Aura bundle type; scaffolding missing LWR template routes required by the site template (e.g. too many requests ); patching all sfdc cms themeLayout/ /content.json files to insert or update the Embedded Messaging component in the footer region (site wide placement); staging the bundle into force app ; async deploy with polling; resolving the Network.Name and publishing the site; guest URL smoke test; manual Experience Builder fallback with a deep link.
Out of scope : Creating the EmbeddedServiceConfig (Embedded Service Deployment) itself — use service digital engagement deployment configure ; creating the MessagingChannel — use service digital engagement channel configure ; creating the Experience Cloud site itself — use experience lwr site generate ; generating a standalone JS snippet for a non Experience website.
Clarifying Questions
Before executing, ask the user if not already clear:
Site name? The DeveloperName of the Experience Cloud site (the metadata folder name under digitalExperiences/site/<siteName / or experiences/<siteName / ).
Deployment coordinates? The deploymentName (Embedded Service Deployment DeveloperName ), the scrtUrl , and the siteEndpoint (Experience site base URL). All three come from the published EmbeddedServiceConfig — obtain from service digital engagement deployment configure output if not provided.
Target org alias? For the sf commands.
URL path prefix? The site's UrlPathPrefix (needed to resolve Network.Name for publish and to hit the guest URL for verification).
Required Inputs
Gather or infer before proceeding:
Site name — DeveloperName of the site
Deployment name — DeveloperName of the EmbeddedServiceConfig
scrtUrl — SCRT2 endpoint URL from the deployment
siteEndpoint — Base URL of the Experience site
Target org alias
URL path prefix — Site's public URL path segment (e.g. esw site )
Defaults applied to the component's attributes when writing:
isExpSiteAuthMode : false
hideChatButtonOnLoad : "Default"
clientVersion : "WebV1"
Workflow
Steps are sequential. If any automated step fails, proceed to the manual fallback (Phase 6) and do not claim the widget is "live" until either the guest URL smoke test returns 200 or the user confirms manual publish.
Phase 1 — Detect Bundle Type
1. Retrieve both candidate bundles into <retrieve dir . The script only performs a deterministic path check, so the retrieve calls must run first:
Either call may return "no metadata found" — that is expected; the missing bundle simply means the site is the other type.
2. Run scripts/detect bundle type.sh <retrieve dir <siteName . It emits exactly one token to stdout:
LWR → the LWR marker file exists ( digitalExperiences/site/<siteName /sfdc cms view/home/content.json ). Go to Phase 2.
AURA → the Aura marker file exists ( experiences/<siteName /views/homeGuestLayout.json ). Go to Phase 3.
UNKNOWN (exit code 1) → neither marker exists. Skip to the manual fallback in Phase 6.
Read references/bundle detection.md for retrieval command shapes and troubleshooting.
Phase 2 — Patch the LWR Bundle
3. Scaffold any missing LWR template routes (commonly too many requests ) before patching — missing routes fail the deploy. Route+view scaffolding is owned by experience lwr site generate (see its configure content route.md , configure content view.md , and handle component and region ids.md ). Delegate to that skill for the actual scaffold; this skill only supplies the messaging specific context (which route the deploy is complaining about, and confirmation that the scaffolded pair resolves that specific deploy error). See references/lwr route scaffolding.md for the delegation pointer.
4. Patch all themeLayout files by running:
The script iterates every sfdc cms themeLayout/ /content.json file. For each, it locates the footer region at .contentBody.component.children[] , walks into the existing community layout:section wrapper's inner slot region, and either updates the existing experience messaging:embeddedMessaging component in place (preserving its id ) or appends a fresh component node. Targeting the themeLayout footer makes the widget site wide (floating overlay on every page), equivalent to the Aura themeFooter placement. See references/lwr patch.md for the JSON shapes and how to verify.
5. Proceed to Phase 4.
Phase 3 — Patch the Aura Bundle
6. Patch the home guest layout by running:
The script iterates .regions[] , picks the first region whose .components[] is non empty, recurses through any forceCommunity:section wrappers, and either updates the existing .componentName == "experience messaging:embeddedMessaging" component in place (preserving id ) or appends a fresh forceCommunity:section wrapper. Aura uses componentName / componentAttributes (not definition / attributes ) and has no dxpStyle . See references/aura patch.md for JSON shapes and verification steps.
7. Proceed to Phase 4.
Phase 4 — Stage and Deploy
8. Copy the modified bundle into the project's default package. Use cp R so unchanged files travel with the modified one:
LWR: cp R <retrieve dir /digitalExperiences force app/main/default/
Aura: cp R <retrieve dir /experiences force app/main/default/ and also copy the sibling <siteName .site meta.xml file — Aura deploys are rejected without it.
9. Async deploy and poll :
Poll every 15 seconds up to 10 minutes:
Stop when status is Succeeded , Failed , SucceededPartial , or Canceled . On failure, surface the deploy report and do not proceed to publish. See references/deploy and publish.md for the full polling loop and common failure modes.
Phase 5 — Publish and Verify
10. Resolve the Network.Name . Network.Name frequently differs from the site DeveloperName , so query it by the URL path prefix rather than guessing:
11. Publish the community with the resolved name:
12. Smoke test guest access by hitting the public URL:
Report success only when the response is 200 .
Phase 6 — Manual Fallback
13. If any automated step fails (bundle undetectable, patch write blocked, deploy fails, publish fails, or guest URL not 200 ), print the Experience Builder deep link and verbatim instructions from references/manual fallback.md . Do not claim the widget is live until the user confirms.
The deep link is:
Resolve <MyDomain via sf org display target org <org alias and <Network.Id via:
Do not hardcode either value. Instruct the user to open Experience Builder, drag the Embedded Messaging component onto the target page, pick the deployment from the property panel, and click Publish.
Rules / Constraints
Constraint Rationale
Detect bundle type from retrieval output, do not assume LWR and Aura sites need different files patched with different key names
Preserve the existing component id when updating in place Ensures idempotency; the Experience runtime keys off id
Every new id must be a fresh UUID Duplicate IDs corrupt the layout and can fail render
LWR uses definition / attributes ; Aura uses componentName / componentAttributes Wrong key names silently drop the component from render
LWR community layout:section sectionConfig lives inside .attributes as a JSON string (not a top level property, not a nested object) Top level placement violates the schema's additionalProperties: false constraint; the serializer also expects a string not an object
Aura sibling <siteName .site meta.xml must be copied alongside the bundle Deploy is rejected without it
Poll the async deploy; do not fire and forget Publish must run only after deploy succeeds
Resolve Network.Name from UrlPathPrefix , do not reuse site DeveloperName The two are frequently different
Do not claim "live on the site" until the guest URL returns 200 or the user confirms Publish is asynchronous; premature success reports mislead
Never hardcode MyDomain or Network.Id in the manual fallback link Values are org specific and must be queried
Idempotency: re running with new ESD coordinates must update in place Users iterate on deploymentName , scrtUrl , siteEndpoint during setup
Gotchas
Issue Resolution
too many requests route missing during LWR deploy Scaffold the missing route+view pair per references/lwr route scaffolding.md
Aura deploy rejected with missing site metadata Copy the sibling <siteName .site meta.xml from the retrieve dir
Component appended but not rendering Confirm the region wrapper uses the correct type: "region" key and that Aura components use componentName (not definition )
sf community publish fails with "community not found" The Network.Name differs from site DeveloperName ; resolve via UrlPathPrefix query
Guest URL returns 403 or 503 after publish Publish is async — retry the smoke test after 60s before falling back to manual
Re run adds a second messaging component The recursive search matched on the wrong key name; component detection must use definition (LWR) or componentName (Aura)
Deploy succeeds but widget does not appear on all pages For LWR, confirm the component was injected into sfdc cms themeLayout/ /content.json footer (not sfdc cms view/home/content.json — that is page specific). For Aura, confirm homeGuestLayout.json was patched (themeFooter region).
sectionConfig written as an object Serialize it as a JSON string; the CMS parser will not accept an object
Verification Checklist
Bundle Detection
[ ] Was exactly one of sfdc cms view/home/content.json (LWR) or views/homeGuestLayout.json (Aura) found?
[ ] If neither was found, did the workflow route to the manual fallback?
Patch Correctness
[ ] For LWR, are the messaging component's keys definition and attributes ?
[ ] For Aura, are the keys componentName and componentAttributes ?
[ ] When updating in place, was the existing id preserved?
[ ] When appending, are all new id values fresh UUIDs?
[ ] For LWR, did the script patch every sfdc cms themeLayout/ /content.json (not just home/content.json )?
[ ] For LWR, does the messaging node appear inside the footer region's subtree in each themeLayout?
[ ] For LWR, is clientVersion set to "WebV2" in the messaging node attributes?
Deploy
[ ] For Aura, was <siteName .site meta.xml copied alongside the bundle?
[ ] Was the async deploy polled until a terminal status?
[ ] Is the terminal status Succeeded or SucceededPartial before proceeding to publish?
Publish
[ ] Was Network.Name resolved via UrlPathPrefix , not reused from site DeveloperName ?
[ ] Did sf community publish complete without error?
Verify
[ ] Did the guest URL curl return 200 ?
[ ] Did the workflow refrain from claiming success until 200 was observed or the user confirmed manual publish?
Output Expectations
Deliverables:
Modified sfdc cms themeLayout/ /content.json files (one per themeLayout) in the retrieval di