service-omni-agent-users-create
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseservice-omni-agent-users-create
service-omni-agent-users-create
Create N agent users on a Salesforce org via Anonymous Apex so Omni-Channel has agents to route work to. Usernames follow a deterministic per-org pattern, detection is SOQL-based, and the skill inserts only the users that are missing — so it is safe to re-run. It is invoked by after enables Omni-Channel; assigning permission sets () and adding users to queues () are separate leaves. Supervisor users come from .
service-omni-channel-setup-coordinateservice-omni-base-settings-configureservice-omni-permission-set-assignservice-omni-queue-members-assignservice-omni-supervisor-users-create通过Anonymous Apex在Salesforce org上创建N个代理用户,以便Omni-Channel拥有可路由工作的代理。用户名遵循基于org的确定性模式,检测基于SOQL实现,且该技能仅插入缺失的用户——因此可安全重复运行。它会在启用Omni-Channel后,由调用;分配权限集()和将用户添加到队列()是独立的分支流程。管理员用户由生成。
service-omni-base-settings-configureservice-omni-channel-setup-coordinateservice-omni-permission-set-assignservice-omni-queue-members-assignservice-omni-supervisor-users-createInputs
输入参数
Confirm once, up front:
- (required, no default) — must resolve via
org-alias.sf org display - User count (optional, default , range
3).1..10 - Profile name (optional, default for portability). The coordinator overrides this to a Service Cloud profile so agents consume Service Cloud licenses; on many CDOs the Salesforce license pool is saturated while Service Cloud has free slots.
Standard User
Usernames and passwords are never accepted from the operator — both are generated (usernames from the org suffix, passwords via Anonymous Apex). Operator-supplied credentials would break re-run detection and risk weak or leaked secrets.
需预先确认以下参数:
- (必填,无默认值)——必须可通过
org-alias解析。sf org display - 用户数量(可选,默认值,范围
3)。1..10 - 配置文件名称(可选,默认值为以保证可移植性)。协调器会将其覆盖为Service Cloud配置文件,以便代理使用Service Cloud许可证;在许多CDO中,Salesforce许可证池已饱和,但Service Cloud仍有可用额度。
Standard User
用户名和密码从不接受操作员输入——两者均自动生成(用户名基于org后缀,密码通过Anonymous Apex生成)。操作员提供的凭据会破坏重复运行的检测逻辑,并存在弱密码或密钥泄露风险。
Preconditions and safety
前置条件与安全机制
- Target org authenticated via CLI (My Domain URL, not
sf), Service Cloud license present,.lightning.force.comCLI ≥ 2.139.6.sf - The executing user has and
PermissionsModifyAllData(standard on System Administrator).PermissionsManagePasswordPolicies - Production guardrail: the detect script computes as
safe_to_writeORIsSandboxORTrialExpirationDate != nullin {Developer Edition, Base Edition}, and the skill blocks with no override when it is false. CDOs, scratch orgs, and dev orgs are permitted.OrganizationType
Password handling (fail-closed). Passwords are set by Anonymous Apex ( cannot target Apex-inserted users — it fails with ). The password literal appears in the inline executeAnonymous debug log and, only when a debug-log TraceFlag is active for the running user, in a queryable . The wrapper therefore fails closed before the first : it proves via a SOQL-filtered Tooling API query () that no active TraceFlag exists. If safety cannot be positively proven — the running user is unresolved, the query fails or is unparseable, or any active TraceFlag exists — it generates no password at all; the user is left ACTIVE, flagged , and a explains why. It never deletes logs, so no plaintext can reach an and unrelated audit logs are untouched. If itself fails for a user, that user is kept ACTIVE and flagged for reset.
System.setPasswordsf user password generateNamedOrgNotFoundErrorApexLogSystem.setPasswordExpirationDate > nowpassword_status:"reset_required"security_warningApexLogSystem.setPassword- 目标org已通过CLI认证(使用My Domain URL,而非
sf),具备Service Cloud许可证,且.lightning.force.comCLI版本≥2.139.6。sf - 执行用户拥有和
PermissionsModifyAllData权限(系统管理员默认具备)。PermissionsManagePasswordPolicies - 生产环境防护:检测脚本会计算,当org为沙箱环境(
safe_to_write)、试用版(IsSandbox)或组织类型为开发者版/基础版时,TrialExpirationDate != null为true;若为false,该技能会直接阻止操作且无覆盖选项。CDO、临时org和开发org均允许操作。safe_to_write
密码处理(默认失败关闭)。密码通过Anonymous Apex的设置(无法针对Apex插入的用户生效——会触发)。密码明文会出现在内联executeAnonymous调试日志中,且仅当运行用户的调试日志TraceFlag处于激活状态时,才会出现在可查询的中。因此,包装器会在首次调用前执行失败关闭检查:通过带SOQL过滤的Tooling API查询()验证是否存在激活的TraceFlag。若无法确认安全性——运行用户身份未解析、查询失败或无法解析、存在任何激活的TraceFlag——则不会生成任何密码;用户会保持ACTIVE状态,标记为,并通过说明原因。该工具从不删除日志,因此明文不会进入,且不会触及无关的审计日志。若对某个用户设置失败,该用户仍会保持ACTIVE状态并标记为需要重置密码。
System.setPasswordsf user password generateNamedOrgNotFoundErrorApexLogSystem.setPasswordExpirationDate > nowpassword_status:"reset_required"security_warningApexLogSystem.setPasswordRun
运行方式
bash
undefinedbash
undefinedread-only preview (never writes)
只读预览模式(永不写入数据)
bash scripts/detect-and-create.sh plan <org-alias> [count] [profile-name]
bash scripts/detect-and-create.sh plan <org-alias> [count] [profile-name]
detect, enforce safe_to_write, then insert only the missing users
检测、验证safe_to_write,仅插入缺失的用户
bash scripts/detect-and-create.sh run <org-alias> [count=3] [profile-name="Standard User"]
`detect-and-create.sh` is the canonical entry point: it re-runs detection, enforces the production guard, and only then inserts. Do not call `scripts/run-create.sh` directly — it is internal and does not enforce the guard on its own.bash scripts/detect-and-create.sh run <org-alias> [count=3] [profile-name="Standard User"]
`detect-and-create.sh`是标准入口:它会重新执行检测、执行生产环境防护检查,之后才会插入用户。请勿直接调用`scripts/run-create.sh`——它是内部脚本,不会自行执行防护检查。Behavior
行为逻辑
Detection. The detector derives an 8-char suffix from (, lowercased), resolves the profile by name, and queries for to find which of the slot indexes are occupied. A stable, deterministic pattern is what makes re-runs idempotent — the suffix is never a timestamp or UUID.
Organization.Idsubstring(10,18)Useragent{i}.<suffix>@example.comcountInsertion. The Apex loads , substitutes //, and inserts only the missing indexes. It re-checks existing users inside the transaction, which prevents a single run from double-inserting; across concurrent runs the in-transaction check is not a guarantee (both can pass their pre-query before either commits), so duplicate protection there relies on the global username-uniqueness constraint plus the retry (see references/apex-template-notes.md). It enables the Service Cloud feature () so users can go online in Omni; if the profile's license does not allow it, the Apex strips the flag and retries (users are still created, but need a Service-Cloud-license profile for full Omni). Each created user is reported via (no password in the marker — passwords are set by the separate submission).
assets/create-users.apex.template__COUNT____PROFILE_ID____SUFFIX__DUPLICATE_USERNAMEUserPermissionsSupportUser=trueAGENT_USER_CREATED|<id>|<username>|<email>System.setPasswordVerification. After insertion the detector re-runs and must show ; otherwise the skill fails (the Apex reported success but the users did not persist).
missing_count == 0检测。检测器从中提取8字符后缀(,小写),按名称解析配置文件,并查询对象中格式的用户,以确定个插槽索引中哪些已被占用。稳定、确定的模式是实现幂等重复运行的关键——后缀绝不会是时间戳或UUID。
Organization.Idsubstring(10,18)Useragent{i}.<suffix>@example.comcount插入。Apex加载,替换//变量,仅插入缺失的索引。它会在事务内重新检查现有用户,避免单次运行中重复插入;但对于并发运行,事务内的检查无法提供完全保障(两个进程可能在提交前都通过了预查询),因此此处的重复保护依赖全局用户名唯一性约束加上重试机制(详见references/apex-template-notes.md)。它会启用Service Cloud功能(),以便用户可在Omni中上线;若配置文件的许可证不允许该操作,Apex会移除该标志并重试(用户仍会被创建,但需要具备Service Cloud许可证的配置文件才能实现完整的Omni功能)。每个创建的用户都会通过报告(标记中不包含密码——密码由单独的操作设置)。
assets/create-users.apex.template__COUNT____PROFILE_ID____SUFFIX__DUPLICATE_USERNAMEUserPermissionsSupportUser=trueAGENT_USER_CREATED|<id>|<username>|<email>System.setPassword验证。插入完成后,检测器会重新运行,必须显示;否则该技能会执行失败(Apex报告成功但用户未持久化)。
missing_count == 0Output contract
输出约定
detect-and-create.shstatuscreatedpartialreusedaction_neededblockeddetectcreatenullreused_userscreated_countreused_counttotal_present_afterusers_needing_password_resetaction_requiredsafe_to_writereused_users- — every missing index landed with a working password.
created - — some landed but not all, or any user needs a manual password reset, or inactive occupants were found.
partial - — all requested users already existed; nothing created.
reused - — plan mode only; reports missing indexes without writing.
action_needed - — precondition failed (
blocked, unresolved profile/suffix, or nothing inserted).safe_to_write=false
create.created_users[].passwordSystem.setPasswordpassword_status:"reset_required"createdpartialaction_neededreusedblockedGenerated passwords are a secret: the returned JSON is the only place they appear. Any caller that persists stdout must write it only to a restricted (mode 0600), redact it from every other artifact, and delete it after distribution — the coordinator does this automatically; standalone callers own it. Reused users' passwords are not retrievable; recover via Setup → Users → Reset Password.
CREDENTIALS.jsondetect-and-create.shstatuscreatedpartialreusedaction_neededblockeddetectcreatenullreused_userscreated_countreused_counttotal_present_afterusers_needing_password_resetaction_requiredsafe_to_writereused_users- ——所有缺失的索引均已创建且密码可用。
created - ——部分索引已创建但未全部完成,或存在需要手动重置密码的用户,或发现已占用的非活跃用户。
partial - ——所有请求的用户已存在;未创建任何内容。
reused - ——仅计划模式;报告缺失的索引但不写入数据。
action_needed - ——前置条件不满足(
blocked、配置文件/后缀未解析或未插入任何内容)。safe_to_write=false
create.created_users[].passwordSystem.setPasswordpassword_status:"reset_required"createdpartialaction_neededreusedblocked生成的密码为机密信息:返回的JSON是其唯一出现的位置。任何持久化标准输出的调用方必须仅将其写入受限制的文件(权限模式0600),在所有其他工件中对其进行脱敏,并在分发后删除——协调器会自动执行此操作;独立调用方需自行处理。无法检索复用用户的密码;可通过Setup → Users → Reset Password恢复。
CREDENTIALS.jsonLimitations
限制
- Username pattern and org suffix are fixed and never operator-configurable — that determinism is what enables idempotent re-runs.
- Creates only agent users on the given profile; it never deletes, deactivates, or mutates existing users.
- Common User errors (,
DUPLICATE_USERNAME,INVALID_EMAIL) are translated into operator-friendly messages rather than surfaced raw.LICENSE_LIMIT_EXCEEDED
- 用户名模式和org后缀是固定的,不支持操作员配置——这种确定性是实现幂等重复运行的基础。
- 仅在指定配置文件上创建代理用户;从不删除、停用或修改现有用户。
- 常见的用户错误(、
DUPLICATE_USERNAME、INVALID_EMAIL)会转换为操作员友好的提示信息,而非直接显示原始错误。LICENSE_LIMIT_EXCEEDED
References
参考文档
| File | When to read |
|---|---|
| Before running the Apex — Apex structure, User field defaults, password policy, and the profile-localization risk |
| When user creation returns a duplicate, license, or password error — explains template substitutions and retry behavior |
| Loaded by |
| Loaded by the canonical entry point for the read-only org, profile, safety, and existing-user checks |
| Run after changing the user-creation scripts to verify production refusal and password-handling contracts |
| 文件 | 阅读时机 |
|---|---|
| 运行Apex前——介绍Apex结构、User字段默认值、密码策略和配置文件本地化风险 |
| 用户创建返回重复、许可证或密码错误时——解释模板替换和重试行为 |
| 需插入缺失代理用户时,由 |
| 标准入口加载,用于只读的org、配置文件、安全检查和现有用户检查 |
| 修改用户创建脚本后运行,验证生产环境拒绝逻辑和密码处理约定 |