@salesforce/afv-skills 1.44.0 → 1.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/consumer-goods-rtr-datacloud-export-configure/SKILL.md +72 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/references/inputs-and-namespace.md +38 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/references/procedure.md +158 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/scripts/detect-namespace.js +86 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/scripts/render-apex.js +64 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/scripts/resolve-id-by-name.js +47 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/scripts/sf-rest.js +171 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/scripts/soql-escape.js +26 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/scripts/upsert-report-config.apex +51 -0
- package/skills/consumer-goods-rtr-datacloud-export-configure/scripts/upsert-system-setting.apex +21 -0
- package/skills/consumer-goods-tpe-dashboard-configure/SKILL.md +74 -0
- package/skills/consumer-goods-tpe-dashboard-configure/references/phases-1-6.md +112 -0
- package/skills/consumer-goods-tpe-dashboard-configure/references/phases-7-12.md +157 -0
- package/skills/consumer-goods-tpe-dashboard-configure/scripts/find-failure-reason.js +132 -0
- package/skills/consumer-goods-tpe-dashboard-configure/scripts/poll-status.js +116 -0
- package/skills/consumer-goods-tpe-dashboard-configure/scripts/render-apex.js +64 -0
- package/skills/consumer-goods-tpe-dashboard-configure/scripts/run-data-transform.js +121 -0
- package/skills/consumer-goods-tpe-dashboard-configure/scripts/schedule-business-period-export.apex +27 -0
- package/skills/consumer-goods-tpe-dashboard-configure/scripts/sf-rest.js +171 -0
- package/skills/consumer-goods-tpe-dashboard-configure/scripts/soql-escape.js +25 -0
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/SKILL.md +141 -0
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/references/payload-shapes.md +447 -0
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/references/procedure.md +263 -0
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/scripts/clone-tpe-dashboards.js +537 -0
- package/skills/consumer-goods-tpe-dashboard-custom-kpi-configure/scripts/sf-rest.js +195 -0
- package/skills/consumer-goods-tpe-datakit-deploy/SKILL.md +157 -0
- package/skills/consumer-goods-tpe-datakit-deploy/scripts/detect-namespace.js +86 -0
- package/skills/consumer-goods-tpe-datakit-deploy/scripts/download-static-resource.js +151 -0
- package/skills/consumer-goods-tpe-datakit-deploy/scripts/extract-crm-field-permissions.js +115 -0
- package/skills/consumer-goods-tpe-datakit-deploy/scripts/sf-rest.js +109 -0
- package/skills/consumer-goods-tpe-datakit-deploy/scripts/update-field-permissions.js +433 -0
- package/skills/service-catalog-template-coordinate/SKILL.md +263 -0
- package/skills/service-catalog-template-coordinate/examples/output-templates.md +44 -0
- package/skills/service-catalog-template-coordinate/references/mcp-invocation.md +183 -0
- package/skills/service-catalog-template-coordinate/references/operations.md +230 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/SKILL.md +243 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/references/cli-invocation.md +205 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/references/helper-contracts.md +236 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/references/permset-topology.md +132 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/scripts/classify-activated-agents.mjs +106 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/scripts/classify-agent-access-state.mjs +113 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/scripts/classify-assignment-state.mjs +99 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/scripts/classify-platform-permset-availability.mjs +155 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/scripts/gate-unified-catalog-tiers.mjs +100 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/scripts/rank-candidate-users.mjs +95 -0
- package/skills/service-itsm-agentic-setup-agent-runtime-access-assign/scripts/resolve-target-user.mjs +86 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +44 -23
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +33 -9
- package/skills/service-itsm-agentic-setup-agentforce-studio-configure/SKILL.md +17 -18
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +3 -1
- package/skills/service-itsm-agentic-setup-configure/SKILL.md +20 -12
- package/skills/service-itsm-agentic-setup-configure/examples/output-templates.md +73 -5
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -7
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/cli-invocation.md +45 -33
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/reactivation.md +8 -6
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +10 -10
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-agent-existence.mjs +114 -56
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/classify-preflight.mjs +33 -17
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +9 -3
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -7
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/cli-invocation.md +43 -32
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/reactivation.md +6 -4
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +10 -10
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-agent-existence.mjs +106 -55
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/classify-preflight.mjs +27 -13
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +9 -3
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +159 -161
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone-action.json +51 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +1 -1
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +120 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +28 -5
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +19 -1
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +350 -30
- package/skills/service-itsm-channels-coordinate/SKILL.md +80 -213
- package/skills/service-itsm-slack-itservice-configure/SKILL.md +363 -0
- package/skills/service-itsm-slack-itservice-configure/references/connect-agentforce-to-slack.md +159 -0
- package/skills/service-itsm-slack-itservice-configure/references/manage-slack-connection.md +88 -0
- package/skills/service-itsm-slack-itservice-configure/references/manage-user-access.md +117 -0
- package/skills/service-itsm-slack-itservice-configure/references/record-visibility.md +78 -0
- package/skills/service-itsm-slack-itservice-configure/references/site-membership-verification.md +126 -0
- package/skills/service-itsm-slack-itservice-configure/scripts/classify-user-access.mjs +167 -0
- package/skills/service-itsm-teams-configure/SKILL.md +50 -47
- package/skills/service-itsm-teams-configure/references/azure-credential-population.md +42 -28
- package/skills/service-itsm-teams-configure/references/gotchas.md +1 -2
- package/skills/service-itsm-teams-coordinate/SKILL.md +22 -18
- package/skills/service-itsm-teams-coordinate/examples/output-templates.md +12 -9
- package/skills/service-itsm-teams-itdesk-configure/SKILL.md +60 -44
- package/skills/service-itsm-teams-itservice-configure/SKILL.md +56 -70
- package/skills/service-catalog-template-deploy/SKILL.md +0 -310
- package/skills/service-catalog-template-deploy/references/cli-invocation.md +0 -258
- package/skills/service-catalog-template-deploy/scripts/activate-verify.mjs +0 -164
- package/skills/service-catalog-template-deploy/scripts/build-deploy-payload.mjs +0 -94
- package/skills/service-catalog-template-deploy/scripts/resolve-template.mjs +0 -331
- package/skills/service-catalog-template-search/SKILL.md +0 -212
- package/skills/service-catalog-template-search/references/cli-invocation.md +0 -128
- package/skills/service-catalog-template-search/scripts/classify-catalog.mjs +0 -205
|
@@ -48,8 +48,8 @@ Microsoft Teams. Every operation dispatches through **headless-360**.
|
|
|
48
48
|
afterward; explaining why the direct org-preference PATCH route fails and why this route
|
|
49
49
|
works instead; disabling the feature if requested; giving the user step-by-step instructions
|
|
50
50
|
for the Azure/Entra app registration (Step 4a) since no Salesforce API can perform that part;
|
|
51
|
-
once the user provides the resulting Client ID/Tenant ID (in chat) and the Client Secret (
|
|
52
|
-
|
|
51
|
+
once the user provides the resulting Client ID/Tenant ID (in chat) and the Client Secret (written
|
|
52
|
+
to a gitignored secret file via the copy-paste command in Step 4a, never in chat), writing them
|
|
53
53
|
directly into the `MSTeamsSetupClientCredentialsEC` Named Credential via API — this
|
|
54
54
|
Salesforce-side write is always automated by this skill, never deferred back to the user;
|
|
55
55
|
registering the Experience Cloud site as the Teams "preferred site" extension via
|
|
@@ -160,13 +160,12 @@ inaccessible via direct PATCH — is now enabled as a side effect of the feature
|
|
|
160
160
|
### Step 4 — Report *interim* status (setup is NOT complete yet)
|
|
161
161
|
|
|
162
162
|
Report feature status and whether `ITSMTeamsEnabled` reads `true` — but **frame this as progress,
|
|
163
|
-
not completion.** Enabling the Go feature is only the first half
|
|
164
|
-
functional** until the Microsoft Entra app is registered, its credentials are written into the
|
|
165
|
-
|
|
166
|
-
"
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
proceed directly into Step 4a. See the **Completion contract** below for what "complete" requires.
|
|
163
|
+
not completion.** Enabling the Go feature is only the first half; the integration is **not
|
|
164
|
+
functional** until the Microsoft Entra app is registered, its credentials are written into the Named
|
|
165
|
+
Credential + Auth Provider, and admin consent is granted (Step 4a). Do **not** mark Teams
|
|
166
|
+
"Done"/"complete" or hand back to a coordinator as done. State plainly: *"The Salesforce feature is
|
|
167
|
+
enabled; Teams integration is not yet complete — the Microsoft Entra app registration comes next."*
|
|
168
|
+
Then proceed into Step 4a. See the **Completion contract** below for what "complete" requires.
|
|
170
169
|
|
|
171
170
|
### Step 4a — Follow the Go page's own order: Create Entra app → Configure Named Credentials → Grant consent
|
|
172
171
|
|
|
@@ -182,26 +181,39 @@ order; do not skip ahead to Named Credentials before the Entra app exists, and d
|
|
|
182
181
|
clicks and wait for them to provide the resulting values:
|
|
183
182
|
- **portal.azure.com** → **Microsoft Entra ID** → **App registrations** → **New registration**.
|
|
184
183
|
Name it something identifiable (e.g. `Salesforce ITSM Teams Integration`); single-tenant is
|
|
185
|
-
fine unless the user's org spans multiple tenants
|
|
186
|
-
|
|
184
|
+
fine unless the user's org spans multiple tenants. Leave the redirect URI blank at creation —
|
|
185
|
+
the Delegated Graph permissions below require one, but it's added later as the Auth Provider
|
|
186
|
+
callback (Step 5; see `references/azure-credential-population.md`).
|
|
187
187
|
- From the app's **Overview** page, note the **Application (client) ID** and **Directory
|
|
188
188
|
(tenant) ID**.
|
|
189
189
|
- **Certificates & secrets** → **New client secret** → copy the secret **value** immediately
|
|
190
190
|
(unrecoverable after leaving the page).
|
|
191
|
-
- **API permissions** → **Add a permission** → **Microsoft Graph** → **
|
|
192
|
-
permissions** → add
|
|
193
|
-
|
|
194
|
-
`
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
(
|
|
201
|
-
|
|
191
|
+
- **API permissions** → **Add a permission** → **Microsoft Graph** → **Delegated
|
|
192
|
+
permissions** → add all 17 below, then click **Grant admin consent** so every row reads
|
|
193
|
+
*Granted*. These are **Delegated** (not Application) — verified working set:
|
|
194
|
+
`Channel.Create`, `Channel.ReadBasic.All`, `ChannelMember.Read.All`,
|
|
195
|
+
`ChannelMember.ReadWrite.All`, `ChannelMessage.Edit`, `ChannelMessage.Read.All`,
|
|
196
|
+
`ChannelMessage.ReadWrite`, `ChannelMessage.Send`, `Team.Create`, `Team.ReadBasic.All`,
|
|
197
|
+
`Group.Read.All`, `Group.ReadWrite.All`, `openid`, `profile`, `email`, `offline_access`,
|
|
198
|
+
`User.Read`. Several require admin consent (*Admin consent required = Yes*), so the **Grant
|
|
199
|
+
admin consent** click is mandatory — ungranted consent-required rows make Teams calls fail
|
|
200
|
+
(see the AccessDenied gotcha). Do **not** add `TeamworkAppSettings.ReadWrite.All` (not in the
|
|
201
|
+
working set). Scopes can change between releases — if MS docs list more, add and re-grant.
|
|
202
|
+
- Provide the credentials **without exposing the secret in chat**: **Client ID** and **Tenant
|
|
203
|
+
ID** are non-secret and may be given in the conversation; the **Client Secret is confidential —
|
|
204
|
+
NEVER ask for it in chat.** Have the user write it to a **gitignored file**: substitute the
|
|
205
|
+
job/temp path for `<secret-file>` (e.g. `$CLAUDE_JOB_DIR/tmp/teams-secret`), then hand them exactly
|
|
206
|
+
this to copy-paste into the Claude Code prompt (secret Value, not the Secret ID, between the quotes):
|
|
207
|
+
```bash
|
|
208
|
+
! umask 077; printf '%s' 'PASTE-CLIENT-SECRET-HERE' > <secret-file> && echo written
|
|
209
|
+
```
|
|
210
|
+
Keep the leading `!` — it runs the line in this session's Bash so the file persists. It prints
|
|
211
|
+
`written`; then read it from `<secret-file>` at write time (Step 5) and never echo or log it.
|
|
212
|
+
> **Note:** the `!`-prefix line is echoed into the chat transcript — if the secret shows up there,
|
|
213
|
+
> treat it as compromised and have the user rotate it in Azure after setup works.
|
|
202
214
|
2. **Configure Setup Named Credentials** ("Go to Setup" button on the Go page — the manual
|
|
203
215
|
equivalent of what this skill automates). **Once you have the Client ID / Tenant ID and the
|
|
204
|
-
secret is available in the
|
|
216
|
+
secret is available in the secret file, do not tell the user to enter anything into Setup —
|
|
205
217
|
call the Named Credential APIs directly**, per "Populating `MSTeamsSetupClientCredentialsEC`
|
|
206
218
|
given a user-supplied client ID/secret" under Step 5 below. **This same set of values must ALSO be written into the
|
|
207
219
|
`microsoft_auth_provider` Auth Provider** (the inbound-SSO side, distinct from the outbound-Graph
|
|
@@ -225,7 +237,7 @@ order; do not skip ahead to Named Credentials before the Entra app exists, and d
|
|
|
225
237
|
|
|
226
238
|
Everything the user does above (steps 1's Azure clicks and step 3's consent click) is their
|
|
227
239
|
manual responsibility because no Salesforce API reaches Azure/Entra. Everything Salesforce-side —
|
|
228
|
-
writing the supplied credential (secret read from the
|
|
240
|
+
writing the supplied credential (secret read from the gitignored secret file, never from chat) into
|
|
229
241
|
the Named Credential in step 2 — is this skill's job to automate; that division of labor is the
|
|
230
242
|
entire point of this skill.
|
|
231
243
|
|
|
@@ -281,27 +293,18 @@ If this returns `400 UNKNOWN_EXCEPTION "...external credential \"MSTeamsSetupCli
|
|
|
281
293
|
might not exist"`, the Azure/Entra step (Gotchas) has not been completed yet — this is not a bug
|
|
282
294
|
in the call itself.
|
|
283
295
|
|
|
284
|
-
If instead it returns `AccessDenied` (or `400 UNKNOWN_EXCEPTION "
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
1. In the Azure app registration → **API permissions**, ensure the Microsoft Graph permissions are
|
|
294
|
-
the **Application** type (not Delegated), then click **"Grant admin consent"** for the tenant.
|
|
295
|
-
2. **Repopulate the credential** (see "Populating..." below) — re-provisioning or any feature
|
|
296
|
-
re-enable can leave the EC/Auth Provider empty; a freshly-populated `MSTeamsSetupClientCredentialsEC`
|
|
297
|
-
showing `authenticationStatus: "Configured"` is required at the moment of the retry.
|
|
298
|
-
|
|
299
|
-
Retry Step 5 after both. Only treat this as a genuine org-license blocker (the `MsTeamsAppApiFamily`
|
|
300
|
-
gotcha below) if the call **still** fails once Application-type Graph permissions + admin consent
|
|
301
|
-
are confirmed and the credential is freshly `Configured`.
|
|
296
|
+
If instead it returns `AccessDenied` (or `400 UNKNOWN_EXCEPTION "...Unable to fetch tenant ID"`)
|
|
297
|
+
**even after** the EC shows `authenticationStatus: "Configured"`, the cause is almost always an
|
|
298
|
+
**incomplete Azure/Entra grant** — fixable, not a license wall (verified: same call went
|
|
299
|
+
`AccessDenied` → `201 Success` after these). Check, in order: (1) **admin consent not granted** —
|
|
300
|
+
several Step 4a scopes read *Admin consent required = Yes* and surface as `AccessDenied` until an
|
|
301
|
+
admin clicks **Grant admin consent**; confirm every row reads *Granted*. (2) **credential empty** —
|
|
302
|
+
a re-provision can empty the EC; it must read `Configured` at retry, so **repopulate** it. Retry
|
|
303
|
+
Step 5 after both. **Do not "fix" this by switching Delegated → Application** — the verified working
|
|
304
|
+
integration is Delegated + admin consent; flipping to Application diverges from the known-good setup.
|
|
302
305
|
|
|
303
306
|
Once you have the Azure Client ID and Tenant ID (given in chat) and the Client Secret (read from the
|
|
304
|
-
|
|
307
|
+
gitignored secret file written in Step 4a — never requested in chat), do the
|
|
305
308
|
Salesforce-side writes yourself — do not tell the user to enter values in Setup. The full verified
|
|
306
309
|
recipe (populating `MSTeamsSetupClientCredentialsEC`, populating the `microsoft_auth_provider` Auth
|
|
307
310
|
Provider for inbound SSO via the Metadata API, matching the portal user's `Username` to the Microsoft
|
|
@@ -324,8 +327,8 @@ optional tail. Report **complete only when every item below is verified** (not m
|
|
|
324
327
|
1. **Feature enabled** — `service-cloud-itsm-teams-integration` reads `ENABLED` and
|
|
325
328
|
`ITSMTeamsEnabled` reads `true` (Steps 1–3).
|
|
326
329
|
2. **Microsoft Entra app registered** — the user has completed Step 4a's Azure clicks and provided
|
|
327
|
-
the Client ID and Tenant ID (in chat) with the Client Secret
|
|
328
|
-
|
|
330
|
+
the Client ID and Tenant ID (in chat) with the Client Secret written to the gitignored secret
|
|
331
|
+
file via the Step 4a copy-paste command (never pasted in chat). Until they do, **stop
|
|
329
332
|
and wait** — this is a hard gate; you cannot proceed past it, and you must not report completion
|
|
330
333
|
around it.
|
|
331
334
|
3. **Credentials populated (Salesforce-side, automated by this skill)** — `MSTeamsSetupClientCredentialsEC`
|
|
@@ -375,8 +378,8 @@ not instead of, the Step 2 feature-enable call if the user wants both Hubs.
|
|
|
375
378
|
## Gotchas
|
|
376
379
|
|
|
377
380
|
The verified, load-bearing pitfalls (direct-PATCH 401, empty Auth Provider, Azure Web-vs-SPA
|
|
378
|
-
redirect, Username=UPN handler, portal API-Enabled, static consent link,
|
|
379
|
-
|
|
381
|
+
redirect, Username=UPN handler, portal API-Enabled, static consent link, version-prefix
|
|
382
|
+
requirement, and more) are catalogued in
|
|
380
383
|
[`references/gotchas.md`](references/gotchas.md). Read it before reporting a step as failed or
|
|
381
384
|
retrying an enablement guess.
|
|
382
385
|
|
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Reference for `service-itsm-teams-configure` Step 5. Once the org has an external credential named
|
|
4
4
|
`MSTeamsSetupClientCredentialsEC` and the user has supplied their Azure **Client ID** and **Tenant
|
|
5
|
-
ID** (non-secret identifiers, given in chat) and
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
ID** (non-secret identifiers, given in chat) and written the **Client Secret** to a **gitignored
|
|
6
|
+
secret file** via the Step 4a copy-paste command (**never ask for the secret in chat**; do NOT use an
|
|
7
|
+
`export`-to-env-var route — an interactive `!`-prefix export runs in a different shell than the
|
|
8
|
+
agent's tool calls, so the value never reaches the agent), these are the Salesforce-side writes that
|
|
9
|
+
populate the outbound Graph credential, the inbound-SSO Auth Provider, and the portal-user access
|
|
10
|
+
that make the Teams IT Service / IT Desk apps actually work. Read the secret from that file at write
|
|
11
|
+
time (`cat <secret-file>` into an in-memory variable); never print, echo, or log its value, and never
|
|
12
|
+
send a literal `$TEAMS_ENTRA_CLIENT_SECRET` token to an API — always resolve it to its actual value
|
|
13
|
+
first (see the Secret-substitution note in Step 2). Do all of these yourself — the user's manual
|
|
14
|
+
responsibility ends at the Azure admin center.
|
|
13
15
|
|
|
14
16
|
## Populating `MSTeamsSetupClientCredentialsEC` given a user-supplied client ID/secret
|
|
15
17
|
|
|
16
18
|
**Once the user supplies the Client ID and Tenant ID (in chat) and the Client Secret is available in
|
|
17
|
-
the
|
|
19
|
+
the gitignored secret file (Step 4a — never in chat), write them into
|
|
18
20
|
Salesforce yourself via the calls below. Do not respond by telling the user to open Setup and enter
|
|
19
21
|
the values manually — that defeats the purpose of this skill.** The user's manual responsibility
|
|
20
22
|
ends at the Azure admin center (Step 4a); every Salesforce-side write, including this one, is this
|
|
@@ -32,16 +34,17 @@ skill's job.
|
|
|
32
34
|
This endpoint is full-replace — GET the EC first and mutate, don't send a partial body.
|
|
33
35
|
2. Set the principal's client ID + secret (both required together in one call; there is no
|
|
34
36
|
partial-update path for just the client ID):
|
|
35
|
-
**Secret substitution — read this first.**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
with a **non-logging** read
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
literal to
|
|
37
|
+
**Secret substitution — read this first.** The credential API body is JSON, **not a shell**: it
|
|
38
|
+
does **not** expand any `$TEAMS_ENTRA_CLIENT_SECRET`-style token. Passing such a literal string in
|
|
39
|
+
the body stores that literal text as the OAuth client secret and Graph authentication then fails
|
|
40
|
+
after an apparently-successful configuration. You must read the secret's **actual value from the
|
|
41
|
+
gitignored secret file** (Step 4a) and place that value into `clientSecret.value` at call time. Do
|
|
42
|
+
it with a **non-logging** read — `cat <secret-file>` captured into an in-memory variable, or build
|
|
43
|
+
the JSON body with a small script that reads the file (as done for the `MSTeamsSetupClientCredentialsEC`
|
|
44
|
+
POST) — never `echo`/print it, never place the resolved secret in any text you emit to the user or
|
|
45
|
+
into a log, and delete any temp body file that held it immediately after the call. The `<secret
|
|
46
|
+
value read from the secret file>` placeholder below denotes that resolved value, not a literal to
|
|
47
|
+
send:
|
|
45
48
|
```text
|
|
46
49
|
mcp__headless-360__dispatch(
|
|
47
50
|
method: "POST", // or PUT (update-credential) if credentials already exist for this principal
|
|
@@ -52,10 +55,10 @@ skill's job.
|
|
|
52
55
|
"principalType": "NamedPrincipal",
|
|
53
56
|
"authenticationProtocol": "OAuth",
|
|
54
57
|
"authenticationProtocolVariant": "ClientCredentialsClientSecretBasic",
|
|
55
|
-
// clientSecret.value MUST be the
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
"credentials": { "clientId": {"value": "<client id>"}, "clientSecret": {"value": "<secret value read from
|
|
58
|
+
// clientSecret.value MUST be the actual secret read from the gitignored secret file (Step 4a)
|
|
59
|
+
// — NOT a literal "$TEAMS_ENTRA_CLIENT_SECRET" token (the JSON body does not expand variables).
|
|
60
|
+
// Read it in memory via a non-logging read (cat the file); never echo it.
|
|
61
|
+
"credentials": { "clientId": {"value": "<client id>"}, "clientSecret": {"value": "<secret value read from the secret file>"} }
|
|
59
62
|
}
|
|
60
63
|
)
|
|
61
64
|
```
|
|
@@ -73,7 +76,7 @@ Enabling the Teams feature also provisions a Microsoft-type **Auth Provider** na
|
|
|
73
76
|
Consumer Secret, or endpoint URLs). This is the **inbound SSO** side — it authenticates employees
|
|
74
77
|
logging into the Experience Cloud portal that the Teams IT Service app embeds. It is a *separate
|
|
75
78
|
artifact* from the outbound-Graph `MSTeamsSetupClientCredentialsEC` Named Credential, but takes the
|
|
76
|
-
**same three values** the user supplied (secret from the
|
|
79
|
+
**same three values** the user supplied (secret read from the gitignored secret file, never chat). Populate it automatically in the same pass — a previous run
|
|
77
80
|
of this skill forgot this step, leaving portal SSO login broken even though the Named Credential
|
|
78
81
|
was configured.
|
|
79
82
|
|
|
@@ -90,7 +93,7 @@ deploy it (this sets every field, including the secret, with no UI):
|
|
|
90
93
|
<AuthProvider xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
91
94
|
<authorizeUrl>https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/authorize</authorizeUrl>
|
|
92
95
|
<consumerKey><CLIENT_ID></consumerKey>
|
|
93
|
-
<consumerSecret
|
|
96
|
+
<consumerSecret>__SECRET_PLACEHOLDER__</consumerSecret>
|
|
94
97
|
<defaultScopes>openid profile email offline_access https://graph.microsoft.com/.default</defaultScopes>
|
|
95
98
|
<friendlyName>microsoft_auth_provider</friendlyName>
|
|
96
99
|
<includeOrgIdInIdentifier>false</includeOrgIdInIdentifier>
|
|
@@ -106,9 +109,20 @@ sf project deploy start --source-dir force-app --target-org <org-alias>
|
|
|
106
109
|
```
|
|
107
110
|
|
|
108
111
|
**Secret handling:** substitute `<TENANT_ID>` / `<CLIENT_ID>` (non-secret) directly, but inject the
|
|
109
|
-
`<consumerSecret>` value from
|
|
110
|
-
gitignored temp copy under a scratch dir, deploy that, then delete
|
|
111
|
-
|
|
112
|
+
`<consumerSecret>` value **read from the gitignored secret file** (Step 4a) at build time into a
|
|
113
|
+
gitignored temp copy under a scratch dir, deploy that, then delete the whole scratch dir. A verified
|
|
114
|
+
non-logging way to do the substitution (the secret only ever lives in a transient shell var and the
|
|
115
|
+
scratch file, never in emitted text):
|
|
116
|
+
```bash
|
|
117
|
+
# template has __SECRET_PLACEHOLDER__ where <consumerSecret> should be; <TENANT_ID>/<CLIENT_ID> already filled in
|
|
118
|
+
SECRET="$(cat <secret-file>)" perl -pe 's/__SECRET_PLACEHOLDER__/$ENV{SECRET}/' template.xml \
|
|
119
|
+
> force-app/main/default/authproviders/microsoft_auth_provider.authprovider-meta.xml
|
|
120
|
+
sf project deploy start --source-dir force-app --target-org <org-alias>
|
|
121
|
+
rm -f force-app/main/default/authproviders/microsoft_auth_provider.authprovider-meta.xml # shred secret-bearing file
|
|
122
|
+
```
|
|
123
|
+
**Never commit the populated file** and never echo the secret. The secret comes from the gitignored
|
|
124
|
+
secret file — not from chat, and not from an env var (the interactive `!`-prefix export does not
|
|
125
|
+
reach the agent's shell).
|
|
112
126
|
|
|
113
127
|
Notes:
|
|
114
128
|
- Use the **tenant-specific** `/…/<TENANT_ID>/oauth2/v2.0/…` endpoints, not `/common/` or
|
|
@@ -13,11 +13,10 @@ step as failed or retrying an enablement guess.
|
|
|
13
13
|
| Azure redirect URI must be under the **Web** platform, not SPA | The `microsoft_auth_provider` Auth Provider is a **confidential client** (server-side token exchange using the ConsumerSecret). Azure rejects secret-based token requests against a redirect URI registered as **Single-page application (SPA)**. Symptom: login *appears* to start (Salesforce logs `LoginHistory` "Success" and mints `OauthToken` rows) but the callback fails at `.../services/authcallback/microsoft_auth_provider` with **`OAUTH_APPROVAL_ERROR_GENERIC`**. Fix (verified): register the callback URI under the Azure app's **Web** platform, not SPA. When emitting the callback URL to the user, always say **Web**. See the callback-URL note under "Populating the `microsoft_auth_provider` Auth Provider." |
|
|
14
14
|
| Portal login "you don't have access to the Microsoft account in Salesforce" → Username must equal the MS email/UPN | A custom Apex registration handler **`MsTeamsItsmSSOHandler`** (Core `service-itsm-teams-impl`, bound to `microsoft_auth_provider`) resolves the signed-in Microsoft user by `SELECT Id FROM User WHERE Username = :data.email` — the **Microsoft `email`/UPN claim must exactly equal a Salesforce `User.Username`** (not `User.Email`, not `FederationIdentifier`); `canCreateUser` returns false (no JIT), and 0 or >1 matches both return null → login denied. **One handler serves BOTH the IT Service (Employee) and IT Desk (Fulfiller) apps.** Fix (verified): set the intended portal user's `Username` to the MS UPN (after confirming no duplicate) via `PATCH .../sobjects/User/<id>` `{"Username":"<ms-upn>"}`. See "Making a portal user resolvable..." under Step 5. |
|
|
15
15
|
| Portal Connect API `API_DISABLED_FOR_ORG` / 403 → user needs API Enabled | The Teams IT Service (Employee) app calls Connect APIs on the embedded portal (e.g. `/connect/it-service/permissions/EmployeeApp`); without the **API Enabled** user permission these return `API_DISABLED_FOR_ORG` (403 in the Network tab) and the app fails to load data despite a successful login. The managed permission sets (`TeamsForEmployeeUser`, `EmployeeHubEmployeeUser`) don't grant `ApiEnabled` and **can't be edited** (managed-package: MDAPI retrieve "cannot be found", SObject PATCH "invalid record id"). Fix (verified): create + deploy a new **unmanaged** permission set with `ApiEnabled` only and assign it. **Do not add `ChatterInternalUser`** — the Unified Employee license forbids it (assignment fails "user license doesn't allow the permission: ChatterInternalUser"). See "Granting the portal user API Enabled..." under Step 5. |
|
|
16
|
-
| Azure/Entra app registration + admin consent have no Salesforce API | Salesforce only exposes a consent URL via an internal Aura controller (no public REST contract) — the user must click through the Azure admin center themselves. Give them the exact steps in Step 4a rather than a vague pointer, and once they provide the Client ID/Tenant ID (in chat) with the Client Secret
|
|
16
|
+
| Azure/Entra app registration + admin consent have no Salesforce API | Salesforce only exposes a consent URL via an internal Aura controller (no public REST contract) — the user must click through the Azure admin center themselves. Give them the exact steps in Step 4a rather than a vague pointer, and once they provide the Client ID/Tenant ID (in chat) with the Client Secret written to a gitignored secret file via the Step 4a copy-paste command (**never request the secret in chat**; the `!`-prefix `export` route does not reach the agent's shell), take over immediately and write the credential into Salesforce yourself (see "Populating `MSTeamsSetupClientCredentialsEC`..." under Step 5) — do not tell them to enter it manually in Setup. |
|
|
17
17
|
| Go page's real checklist order (verified from a live screenshot) | The "Integrate Salesforce with Teams" group on the feature's Go page has exactly 3 items, in this order: **Create Microsoft Entra ID App** → **Configure Setup Named Credentials** → **Grant Azure Administrator Consent**. This is a *separate* checklist group from "Set Up Salesforce IT Desk" / "Set Up Salesforce IT Service" (delegated to `service-itsm-teams-itdesk-configure` / `service-itsm-teams-itservice-configure`) — do not conflate the groups when reporting progress to the user. |
|
|
18
18
|
| "Grant Azure Administrator Consent" consent link is static, not per-org | Clicking "Grant Consent" on the Go page opens a modal with this exact link: `https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize?client_id=cd6bd63f-41ef-47cc-9465-86e986179a29&response_type=code&redirect_uri=https://salesforce.com&response_mode=query&scope=Organization.ReadWrite.All`. The `client_id` here is Salesforce's own multi-tenant Entra app (**not** the app the user registers in step 1, and **not** related to the Client ID/Secret that go into the Named Credential) — it requests `Organization.ReadWrite.All` from whichever Microsoft tenant the signed-in admin belongs to (`organizations` tenant segment, not a specific tenant ID). headless-360 has no operation that generates this link or reads the Go page's live checklist state (searched `discover` for "grant Azure administrator consent generate consent URL" and "guided setup checklist progress Salesforce Go" — no matching SOR) — paste the link above verbatim and tell the user to click it themselves, signed in as a Microsoft tenant admin. |
|
|
19
19
|
| `preferredSite` / Teams extension registration **is** a public Connect API (verified) — corrects an earlier assumption | `POST /services/data/v67.0/connect/service-itsm-teams/graph-api/extensions` body `{"siteUrlPathPrefixes": ["<site urlPathPrefix>"]}` registers the Experience Cloud site as the Teams extension target; `PATCH .../extensions/{extensionId}` updates it. Verified live: it dispatches and reaches real logic (not a stub) — it fails with `400 UNKNOWN_EXCEPTION "We couldn't access the credential(s)... external credential \"MSTeamsSetupClientCredentialsEC\" might not exist"` until the Azure/Entra app registration is done and that named/external credential is wired up in Setup. Once the credential exists, call this to complete preferred-site selection — do not treat it as Aura-only. |
|
|
20
20
|
| `service-itsm-teams-connect-api` SOR (headless-360 `discover`) | Also exposes `get-teams-get-teams-list`, `get-teams-get-channel-list`, `post-teams-channel-message-send`, `get-teams-get-permissions`, `get-service-itsm-teams-collaboration-app-settings` (valid `targetApplication` values are `TeamsFulfillerApp` / `TeamsEmployeeApp`, not `teams`) — useful for verifying end-to-end Teams connectivity after the manual tail is complete. |
|
|
21
|
-
| `ms-teams-app-connect-api` (`/connect/ms-teams-app/tenant-config`) gates Step 5 and has **no known unlock path** | `GET`/`PUT`/`DELETE` all return `403 FUNCTIONALITY_NOT_ENABLED [MsTeamsAppApiFamily]`, even after `service-cloud-itsm-teams-integration` is enabled and `MSTeamsSetupClientCredentialsEC` is fully configured. **Verified this is the same blocker as Step 5's "Unable to fetch tenant ID" error** — `post-teams-extension`/`patch-teams-extension-update` internally depend on this tenant-config lookup. Checked and ruled out: (a) no Go feature-enablement API name unlocks it — tried `ms-teams-app`, `ms-teams-app-integration`, `microsoft-teams-app-integration`, `teams-app-connect-api`, `msteams-app-api`, `service-cloud-ms-teams-app-api`, `MsTeamsAppApiFamily` itself, all `400 NOT_FOUND "Could not find the requested feature"`; (b) no `PermissionSetLicense` among all 112 in the org grants it — only `TeamsForEmployeePsl`/`TeamsForITSrvcsPsl` relate to Teams, and neither gates this family. This appears to be a hard org/edition-level license gate with no self-service unlock via headless-360 — if a user hits this, Step 5 cannot be completed in this org; do not keep retrying enablement guesses. |
|
|
22
21
|
| A `MSTeamsSetupAutomationAccess` ("Automate Microsoft Teams Setup") permission set also auto-provisions | Was unassigned in this session — assign it to the Setup admin driving this flow if further automation steps need it. (The IT Desk/IT Service checklist permission sets — `TeamsForITSrvcsUser`, `TeamsForEmployeeUser`, `MicrosoftGraphAccess` — are documented in the child skills.) |
|
|
23
22
|
| Version prefix required | headless-360 `dispatch`/`dispatch_readonly` do not resolve API versions — always pass the full `/services/data/vXX.0/...` prefix. |
|
|
@@ -11,10 +11,6 @@ metadata:
|
|
|
11
11
|
- "service-itsm-teams-employee-agent-configure"
|
|
12
12
|
- "service-itsm-teams-itdesk-configure"
|
|
13
13
|
- "service-itsm-teams-itservice-configure"
|
|
14
|
-
# No accessCheck gate: this orchestrator's Stage 1 is what enables ITSMTeamsEnabled,
|
|
15
|
-
# so it must be invokable on a brand-new org before that preference exists. Downstream
|
|
16
|
-
# child skills retain their own accessCheck. Empty array = applies to any org.
|
|
17
|
-
accessCheck: []
|
|
18
14
|
allowed-tools: Read AskUserQuestion
|
|
19
15
|
---
|
|
20
16
|
|
|
@@ -43,9 +39,11 @@ There are exactly **three mandatory halts** and **one branch** in the whole flow
|
|
|
43
39
|
- **HALT 1 — Azure/Entra app** (Stage 2): you give the user the app-registration instructions and
|
|
44
40
|
**wait** for them to register the app and provide the credentials. No Salesforce API can do this.
|
|
45
41
|
The **Client ID** and **Tenant ID** are non-secret identifiers and may be given in chat; the
|
|
46
|
-
**Client Secret is a confidential credential — NEVER ask for it in the conversation.** The
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
**Client Secret is a confidential credential — NEVER ask for it in the conversation.** The agent
|
|
43
|
+
gives the user one exact copy-paste command that writes the secret to a gitignored secret file
|
|
44
|
+
(`! umask 077; printf '%s' 'PASTE-SECRET' > <secret-file> && echo written`) and reads it from that
|
|
45
|
+
file. Keep the leading `!` — it runs the line in this session's Bash so the file persists. The agent
|
|
46
|
+
never prints, echoes, or logs the value.
|
|
49
47
|
- **HALT 2 — IT Desk app install** (Stage 3): you give the Microsoft Marketplace link and **wait**
|
|
50
48
|
for the user to reply **"installed"**. No API installs a Teams app into a tenant catalog.
|
|
51
49
|
- **HALT 3 — IT Service app install** (Stage 4): same as HALT 2, for the IT Service app.
|
|
@@ -70,16 +68,17 @@ then continue straight into Stage 2 — do **not** stop here.
|
|
|
70
68
|
|
|
71
69
|
### Stage 2 — Microsoft Entra app + Named Credentials ⟶ HALT 1
|
|
72
70
|
Still within **`service-itsm-teams-configure`** (its Step 4a): give the user the exact Azure/Entra
|
|
73
|
-
app-registration clicks **including the Microsoft Graph
|
|
71
|
+
app-registration clicks **including the Microsoft Graph permissions** it lists, and
|
|
74
72
|
**HALT** until they provide the credentials. The **Client ID** and **Tenant ID** are non-secret
|
|
75
73
|
identifiers — accept them in chat. The **Client Secret is confidential: never request it in the
|
|
76
|
-
conversation.**
|
|
77
|
-
(
|
|
78
|
-
|
|
74
|
+
conversation.** Give the user one exact copy-paste command that writes it to a gitignored secret file
|
|
75
|
+
(`! umask 077; printf '%s' 'PASTE-SECRET' > <secret-file> && echo written`) and read it from that
|
|
76
|
+
file. Keep the leading `!` — it runs the line in this session's Bash so the file persists. Never
|
|
77
|
+
print or echo it. The moment the identifiers are given and the secret is in the file:
|
|
79
78
|
- Write those values into the `MSTeamsSetupClientCredentialsEC` Named Credential **and** the
|
|
80
79
|
`microsoft_auth_provider` Auth Provider **yourself, via API — nothing manual** (the child skill's
|
|
81
|
-
Step 5 and its azure-credential-population reference carry the exact API bodies).
|
|
82
|
-
secret
|
|
80
|
+
Step 5 and its azure-credential-population reference carry the exact API bodies). Read the
|
|
81
|
+
secret from the file at call time — do not inline the raw value into any logged text.
|
|
83
82
|
- Give the user the static **Grant Admin Consent** link and register the preferred site (child Step 5).
|
|
84
83
|
Then continue to Stage 3 automatically.
|
|
85
84
|
|
|
@@ -87,8 +86,8 @@ Then continue to Stage 3 automatically.
|
|
|
87
86
|
Invoke **`service-itsm-teams-itdesk-configure`**. Drive its whole checklist:
|
|
88
87
|
- Turn on the `OrgHasITSMFulfillerTeams` org preference (via API).
|
|
89
88
|
- **Manage User Access** — assign the fulfiller permission sets to the confirmed user(s):
|
|
90
|
-
`TeamsForITSrvcsUser` + `MicrosoftGraphAccess`, **plus
|
|
91
|
-
|
|
89
|
+
`TeamsForITSrvcsUser` + `MicrosoftGraphAccess`, **plus the API Enabled login permission set**
|
|
90
|
+
(commonly `Teams_Employee_ApiAccess`) — required for login, not optional.
|
|
92
91
|
- **Turn on Swarming** — this stage includes `service-itsm-swarming-configure`
|
|
93
92
|
(enables `service-cloud-swarming` and sets `SWARM_COLLABORATION_TOOL = "Teams"`).
|
|
94
93
|
- Give the **IT Desk Microsoft Marketplace link** + help doc, tell the user **the Azure account
|
|
@@ -98,9 +97,9 @@ Invoke **`service-itsm-teams-itdesk-configure`**. Drive its whole checklist:
|
|
|
98
97
|
### Stage 4 — Set up IT Service (employee side) ⟶ HALT 3
|
|
99
98
|
Invoke **`service-itsm-teams-itservice-configure`**. Drive its whole checklist:
|
|
100
99
|
- Turn on the `OrgHasEmployeeServiceTeams` org preference (via API).
|
|
101
|
-
- **Manage User Access** — assign the employee permission
|
|
102
|
-
`TeamsForEmployeeUser`
|
|
103
|
-
the child's login prerequisites require.
|
|
100
|
+
- **Manage User Access** — assign the employee permission set to the confirmed UEL user(s):
|
|
101
|
+
`TeamsForEmployeeUser` (the dialog assigns only this one — **not** `MicrosoftGraphAccess`), **plus
|
|
102
|
+
the API Enabled login permission set** the child's login prerequisites require.
|
|
104
103
|
- **Select the Digital Experience Site** (`SLACK_PREFERRED_SITE`) via API.
|
|
105
104
|
- Give the **IT Service Microsoft Marketplace link** + help doc, repeat the **email-must-match** note,
|
|
106
105
|
and **HALT** until the user replies **"installed."** Then continue to Stage 5.
|
|
@@ -133,6 +132,11 @@ portal user. Then tell the user to **retest from a brand-new Teams chat** to con
|
|
|
133
132
|
the Entra app is unregistered, or a halt awaiting "installed"), keep that stage **`Blocked`/waiting**
|
|
134
133
|
and hold at the halt — do not mark it done and do not skip ahead.
|
|
135
134
|
- Do not re-present a menu. State what just finished and what you're doing next, then do it.
|
|
135
|
+
- **Keep the report tight — summarize, don't transcribe.** Report each stage as a one-line status in
|
|
136
|
+
the stage-progress table plus at most a short sentence of context; do **not** paste the child skill's
|
|
137
|
+
API request/response bodies, tool-call logs, or step-by-step internals into the report — that detail
|
|
138
|
+
lives in the child skill, and re-narrating it here is the single biggest source of a bloated,
|
|
139
|
+
low-signal report. The reader needs *what happened and what's next*, not a replay of every call.
|
|
136
140
|
|
|
137
141
|
## Completion summary
|
|
138
142
|
|
|
@@ -26,10 +26,12 @@ Microsoft Teams for ITSM Setup (via service-itsm-teams-coordinate)
|
|
|
26
26
|
│ 8 │ Build IT Service embedded agent (optional) │ Not started │
|
|
27
27
|
└───┴────────────────────────────────────────────┴──────────────────────┘
|
|
28
28
|
|
|
29
|
-
Next: send me the Azure app's Client ID and Tenant ID
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
Next: send me the Azure app's Client ID and Tenant ID here. For the Client Secret, DON'T paste it in
|
|
30
|
+
chat — instead copy-paste this one command into the prompt (put your secret's Value between the
|
|
31
|
+
single quotes), then tell me it's done:
|
|
32
|
+
! umask 077; printf '%s' 'PASTE-CLIENT-SECRET-HERE' > <secret-file> && echo written
|
|
33
|
+
I'll read it from that file and write everything into the Named Credential and Auth Provider
|
|
34
|
+
automatically.
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
Status values: `Not started`, `In progress`, `Waiting (<what for>)`, `Blocked`, `Done`.
|
|
@@ -37,11 +39,12 @@ Status values: `Not started`, `In progress`, `Waiting (<what for>)`, `Blocked`,
|
|
|
37
39
|
## Halt messages
|
|
38
40
|
|
|
39
41
|
- **HALT 1 (Stage 2 — Azure/Entra app):** deliver the child's app-registration instructions
|
|
40
|
-
(including the Microsoft Graph
|
|
41
|
-
and **Tenant ID** here
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
(including the Microsoft Graph permissions) and end with: *"Send me the **Client ID**
|
|
43
|
+
and **Tenant ID** here. For the **Client Secret**, please don't paste it in chat — copy-paste this
|
|
44
|
+
one command into the prompt with your secret's Value between the single quotes, then tell me it's
|
|
45
|
+
done: `! umask 077; printf '%s' 'PASTE-CLIENT-SECRET-HERE' > <secret-file> && echo written`. I'll
|
|
46
|
+
read it from that file and populate the Named Credential and Auth Provider automatically — no
|
|
47
|
+
manual Setup entry needed."* (Substitute the real job/temp path for `<secret-file>`.) Then wait.
|
|
45
48
|
- **HALT 2 / HALT 3 (Stages 3 & 4 — app install):** deliver the Microsoft Marketplace link + help
|
|
46
49
|
doc, then: *"Install the app in your Microsoft Teams admin center, then reply **installed** and
|
|
47
50
|
I'll continue. Note: the Azure/Microsoft email the user signs in with must match that Salesforce
|
|
@@ -36,8 +36,9 @@ dispatches through **headless-360**.
|
|
|
36
36
|
|
|
37
37
|
- **In scope**: Turning on the `OrgHasITSMFulfillerTeams` preference; giving the user the exact
|
|
38
38
|
Teams marketplace link + help doc for the IT Desk app install; assigning
|
|
39
|
-
`TeamsForITSrvcsUser`/`MicrosoftGraphAccess` permission sets to confirmed users
|
|
40
|
-
|
|
39
|
+
`TeamsForITSrvcsUser`/`MicrosoftGraphAccess` permission sets to confirmed users **plus
|
|
40
|
+
provisioning the org-wide API-Enabled login permission set** (created once, required to sign in);
|
|
41
|
+
delegating "Set Teams as Collaboration Tool for Swarming" to `service-itsm-swarming-configure`.
|
|
41
42
|
- **Out of scope**: The base Teams Salesforce Go page toggle (`ITSMTeamsEnabled`), Azure/Entra app
|
|
42
43
|
registration, Named Credential population, and Teams extension/preferred-site registration —
|
|
43
44
|
use `service-itsm-teams-configure` (a prerequisite for this skill). The IT Service/employee
|
|
@@ -103,6 +104,17 @@ live from the "Manage Microsoft Teams for Employee Service User Access" dialog:
|
|
|
103
104
|
- `MicrosoftGraphAccess` (label **"MicrosoftGraphAccess"**) — assigned alongside it in the same
|
|
104
105
|
dialog.
|
|
105
106
|
|
|
107
|
+
**A third, "login" permission set is also required — one you provision once per org.** The two
|
|
108
|
+
dialog permsets provision the IT Desk *surface* but **do not let the fulfiller sign in**: both read
|
|
109
|
+
`PermissionsApiEnabled = false`, so the embedded app's Connect calls 403 and login fails with
|
|
110
|
+
"server not reachable." The fulfiller needs a permission set carrying the **API Enabled** system
|
|
111
|
+
permission. Some orgs already have one named `Teams_Employee_ApiAccess` (a **custom** permset — do
|
|
112
|
+
**not** assume a fresh customer org has it); otherwise create it. It is a **shared, org-wide
|
|
113
|
+
artifact** — the same permset also covers IT Service login, so **create it only once** and just
|
|
114
|
+
*assign* it wherever needed. The resolve-or-create-then-assign recipe is in
|
|
115
|
+
[Login prerequisite](#login-prerequisite--provision-the-login-permission-set-verified) below. Do
|
|
116
|
+
this as part of this step; don't wait for login to break.
|
|
117
|
+
|
|
106
118
|
**Do not just assign every active user.** Ask the user which specific user(s) should get access.
|
|
107
119
|
If they want to see the list of users first (rather than naming them), page it — **show at most
|
|
108
120
|
10 users per page**, then ask "want to see more?" before showing the next page, since orgs can
|
|
@@ -125,8 +137,9 @@ still want one assigned — but call out which rows look like system accounts so
|
|
|
125
137
|
have to guess). If the user says a listed batch is "not employee users, skip," move on to the
|
|
126
138
|
next page rather than assigning any of them.
|
|
127
139
|
|
|
128
|
-
Once the user confirms specific user(s), look up
|
|
129
|
-
org but don't hardcode them — query fresh
|
|
140
|
+
Once the user confirms specific user(s), look up the two dialog permission sets' `Id`s (they are
|
|
141
|
+
stable per org but don't hardcode them — query fresh; the third "login" permset is resolved in the
|
|
142
|
+
Login prerequisite below):
|
|
130
143
|
|
|
131
144
|
```text
|
|
132
145
|
mcp__headless-360__dispatch_readonly(
|
|
@@ -152,46 +165,49 @@ Verify by re-querying `PermissionSetAssignment` for that `AssigneeId`, or simply
|
|
|
152
165
|
from the assignment call plus a `SELECT ... FROM PermissionSetAssignment WHERE AssigneeId =
|
|
153
166
|
'<user id>' AND PermissionSetId = '<permset id>'` readback.
|
|
154
167
|
|
|
155
|
-
#### Login prerequisite — the
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
fulfiller who opens the IT Desk app in Teams
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
`
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
168
|
+
#### Login prerequisite — provision the login permission set (verified)
|
|
169
|
+
|
|
170
|
+
With only `TeamsForITSrvcsUser` + `MicrosoftGraphAccess` the IT Desk *surface* is provisioned, but a
|
|
171
|
+
fulfiller who opens the IT Desk app in Teams hits **"server not reachable"** on the login page. The
|
|
172
|
+
verified blocker is **API Enabled**: both dialog permsets read `PermissionsApiEnabled = false`
|
|
173
|
+
(verified live), so the embedded app's Connect calls 403. Assigning the fulfiller a permission set
|
|
174
|
+
with `PermissionsApiEnabled = true` resolves the login. That permset is **org-wide, created once**
|
|
175
|
+
and shared with IT Service — resolve-or-create, then assign:
|
|
176
|
+
|
|
177
|
+
1. **Reuse if it already exists** (an API-Enabled permset — commonly `Teams_Employee_ApiAccess`):
|
|
178
|
+
`SELECT Id, Name, PermissionsApiEnabled FROM PermissionSet WHERE Name = 'Teams_Employee_ApiAccess'`.
|
|
179
|
+
If found with `PermissionsApiEnabled = true`, take its `Id` and skip to step 3.
|
|
180
|
+
2. **Otherwise create it once** (`PermissionsApiEnabled` is createable — verified):
|
|
181
|
+
```text
|
|
182
|
+
mcp__headless-360__dispatch(
|
|
183
|
+
method: "POST",
|
|
184
|
+
url: "/services/data/v67.0/sobjects/PermissionSet",
|
|
185
|
+
body: { "Name": "Teams_Employee_ApiAccess", "Label": "Teams Employee API Access", "PermissionsApiEnabled": true }
|
|
186
|
+
)
|
|
187
|
+
```
|
|
188
|
+
Capture the returned `Id`. Because it's shared org-wide, don't recreate it if a later run (or the
|
|
189
|
+
IT Service skill) already made it — step 1's query is the guard.
|
|
190
|
+
3. **Assign it** to each confirmed fulfiller, alongside the two dialog permsets:
|
|
191
|
+
```text
|
|
192
|
+
mcp__headless-360__dispatch(
|
|
193
|
+
method: "POST",
|
|
194
|
+
url: "/services/data/v67.0/sobjects/PermissionSetAssignment",
|
|
195
|
+
body: { "AssigneeId": "<user id>", "PermissionSetId": "<login permset Id>" }
|
|
196
|
+
)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
After assigning, have the user **fully close and reopen the Teams app** (the OAuth authorize is
|
|
200
|
+
cached client-side). Also confirm **CORS Allowed Origins** contains both `https://teams.cloud.microsoft`
|
|
201
|
+
and `https://cdn.scs.static.lightning.force.com` (`SELECT UrlPattern FROM CorsWhitelistEntry`).
|
|
202
|
+
|
|
203
|
+
The `ServiceCloudMSTeamsEca` External Client App that backs Teams login is **auto-installed by the
|
|
204
|
+
Go-page toggle and needs no configuration** — `Teams_Employee_ApiAccess` grants API Enabled and is
|
|
205
|
+
unrelated to the ECA. Do not add `SetupEntityAccess` rows or change the ECA's OAuth policy.
|
|
206
|
+
|
|
207
|
+
If login still fails in a fresh session after the API-Enabled permset is assigned, the remaining
|
|
191
208
|
suspect is the **"Allow OAuth for employees"** profile checkbox (Setup-UI-only — no API write path).
|
|
192
|
-
See `service-itsm-teams-itservice-configure`'s *Login prerequisites*
|
|
193
|
-
|
|
194
|
-
the fulfiller (IT Desk) and employee (IT Service) apps.
|
|
209
|
+
See `service-itsm-teams-itservice-configure`'s *Login prerequisites* for the full pass/fail
|
|
210
|
+
diagnostic chain.
|
|
195
211
|
|
|
196
212
|
### Step 4 — Set Teams as Collaboration Tool for Swarming (delegate)
|
|
197
213
|
|
|
@@ -217,7 +233,7 @@ is now fully automated end-to-end, no manual "Go to Feature Page" click required
|
|
|
217
233
|
| `OrgHasITSMFulfillerTeams` does not unblock `ITSMTeamsEnabled` | These are separate bits — enabling this preference does not itself unblock the Teams Salesforce Go page toggle preference, and vice versa. |
|
|
218
234
|
| "Set Teams as Collaboration Tool for Swarming" needs `service-cloud-swarming` enabled first | Delegate to `service-itsm-swarming-configure` rather than enabling that feature inline. That skill both enables the feature and writes `SWARM_COLLABORATION_TOOL` to `"Teams"` — the whole checklist item is API-reachable, not just the base feature enable. |
|
|
219
235
|
| Permission sets / PSLs | `TeamsForITSrvcsUser`, `MicrosoftGraphAccess` (permission sets) and PSL `TeamsForITSrvcsPsl` auto-provisioned and were confirmed `Active` (10 licenses) immediately after the feature-enable in this session — no manual PSL/permset creation needed once `TeamsITSrvcsAddOn`+`IncidentManagementAddOn` are licensed. |
|
|
220
|
-
| Manage-User-Access permsets don't cover login — assign
|
|
236
|
+
| Manage-User-Access permsets don't cover login — assign an API-Enabled permset | Verified: after assigning `TeamsForITSrvcsUser` + `MicrosoftGraphAccess`, the IT Desk agent still failed Teams login with **"server not reachable"** — both dialog permsets have `PermissionsApiEnabled = false`, so the embedded app's Connect calls 403. The fix is an **API-Enabled** permission set (`PermissionsApiEnabled = true`), commonly `Teams_Employee_ApiAccess` — a **custom, org-wide** permset shared with IT Service, so **create it once** then assign. A test org may already have it; **a fresh customer org won't**, so resolve-or-create. (The `ServiceCloudMSTeamsEca` ECA is auto-installed by the Go-page toggle and needs no configuration — it does not gate login and `Teams_Employee_ApiAccess` is unrelated to it.) See [Step 3 → Login prerequisite](#login-prerequisite--provision-the-login-permission-set-verified). |
|
|
221
237
|
| Version prefix required | headless-360 `dispatch`/`dispatch_readonly` do not resolve API versions — always pass the full `/services/data/vXX.0/...` prefix. |
|
|
222
238
|
|
|
223
239
|
---
|