service-omni-queue-members-assign

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

service-omni-queue-members-assign

service-omni-queue-members-assign

Bind N agent users into a Salesforce Queue via
GroupMember
Data API POSTs. Without queue membership, Omni-Channel routing sees an empty pool for the queue and never assigns work. Detection is SOQL-based (the same detect-then-POST shape as
service-omni-queue-routing-config-deploy
), so only missing memberships are created and the skill is safe to re-run. Agent users come from
service-omni-agent-users-create
, the queue from
service-omni-queue-deploy
, and the users' Omni permissions from
service-omni-permission-set-assign
.
通过
GroupMember
Data API POST请求将N个Agent用户绑定到Salesforce队列。如果没有队列成员,Omni-Channel路由会认为该队列为空池,从而永远不会分配工作。检测基于SOQL实现(与
service-omni-queue-routing-config-deploy
采用相同的“检测后POST”模式),因此只会创建缺失的成员关系,该Skill可安全重复运行。Agent用户来自
service-omni-agent-users-create
,队列来自
service-omni-queue-deploy
,用户的Omni权限来自
service-omni-permission-set-assign

Inputs

输入参数

bash
bash scripts/verify-and-bind.sh <org-alias> [queue-developer-name=CaseQueue] [count=3] [explicit-members-csv]
bash
bash scripts/verify-and-bind.sh <org-alias> [queue-developer-name=CaseQueue] [count=3] [explicit-members-csv]

demo agents (default):

演示Agent(默认):

bash scripts/verify-and-bind.sh myorg CaseQueue 3
bash scripts/verify-and-bind.sh myorg CaseQueue 3

real agents by username/id:

通过用户名/ID指定真实Agent:

bash scripts/verify-and-bind.sh myorg VoiceQueue "" "jdoe@acme.com,005XX000001abcd"

- `org-alias` (required).
- `queue-developer-name` (optional, default `CaseQueue`).
- `count` (optional, default `3`, range `1..10`) — must match the agent user count; ignored in explicit mode.
- `explicit-members-csv` (optional 4th positional, or `MEMBER_USERNAMES_CSV` / `MEMBER_USER_IDS_CSV`) — each token is a Username or a 15/18-char User Id; the count is derived from the list.
bash scripts/verify-and-bind.sh myorg VoiceQueue "" "jdoe@acme.com,005XX000001abcd"

- `org-alias`(必填)。
- `queue-developer-name`(可选,默认值`CaseQueue`)。
- `count`(可选,默认值3,范围1..10)——必须与Agent用户数量匹配;在显式模式下会被忽略。
- `explicit-members-csv`(可选的第4个位置参数,或通过`MEMBER_USERNAMES_CSV`/`MEMBER_USER_IDS_CSV`指定)——每个值为用户名或15/18位用户ID;数量由列表自动推导。

Preconditions and safety

前置条件与安全性

  • Target org authenticated via
    sf
    CLI (My Domain URL), Service Cloud license,
    sf
    CLI ≥ 2.139.6.
  • The executing user has
    PermissionsModifyAllData
    (standard on System Administrator).
  • The agent users exist (
    service-omni-agent-users-create
    ) and the queue exists (
    service-omni-queue-deploy
    ); a missing user set or queue blocks with a pointer to the right skill (queues cannot be created via the Data API).
  • The three-way
    safe_to_write
    production guard applies — adding users to a production queue mis-routes real customer work, so it blocks with no override.
  • 已通过
    sf
    CLI(My Domain URL)认证目标组织,具备Service Cloud许可证,且
    sf
    CLI版本≥2.139.6。
  • 执行用户拥有
    PermissionsModifyAllData
    权限(系统管理员默认具备)。
  • Agent用户已存在(需先运行
    service-omni-agent-users-create
    )且队列已存在(需先运行
    service-omni-queue-deploy
    );若缺少用户集或队列,会提示并指向对应的Skill(无法通过Data API创建队列)。
  • 启用三方
    safe_to_write
    生产环境防护机制——将用户添加到生产环境队列会导致真实客户工作路由错误,因此会直接阻止操作且无覆盖选项。

Run

运行流程

verify-and-bind.sh
runs the whole cycle:
  1. Compute
    safe_to_write
    ; derive the 8-char org suffix.
  2. Resolve the queue
    Group.Id
    by DeveloperName +
    Type='Queue'
    ; block if missing.
  3. Resolve the member set — generated mode queries
    User
    for
    agent{1..N}.<suffix>@example.com
    (block if any expected user is missing); explicit mode resolves each supplied token and requires every one to be an ACTIVE user.
  4. Query existing
    GroupMember
    for the queue; compute the users not yet bound.
  5. POST one
    GroupMember
    per missing user (individual POSTs, no
    allOrNone
    ).
  6. Re-query to confirm final membership and emit the report.
verify-and-bind.sh
会执行完整流程:
  1. 计算
    safe_to_write
    状态;推导8位组织后缀。
  2. 通过DeveloperName +
    Type='Queue'
    解析队列的
    Group.Id
    ;若缺失则终止操作。
  3. 解析成员集——生成模式下查询
    User
    表中
    agent{1..N}.<suffix>@example.com
    格式的用户(若任何预期用户缺失则终止操作);显式模式下解析每个传入的值,且要求所有值均对应活跃用户。
  4. 查询队列的现有
    GroupMember
    ;计算尚未绑定的用户。
  5. 为每个缺失的用户发送一个
    GroupMember
    POST请求(单独发送POST,不使用
    allOrNone
    参数)。
  6. 重新查询以确认最终成员关系并生成报告。

Behavior

行为特性

Two member sources, never mixed. The default generated pattern keeps the user-create → member-assign handoff deterministic; explicit mode is opt-in for real agents and takes over count derivation. In explicit mode, a token that does not resolve to an active user blocks the run — binding a typo'd or inactive user would silently under-populate the queue.
Idempotency and honesty. POSTs are individual so one failed binding (e.g. a race with another admin) never rolls back its successful siblings, and the skill re-queries after all POSTs — a 201 only means the write was accepted; a subsequent SOQL confirms the row is visible to the routing engine. The
before
snapshot includes members already present, even non-demo users added out-of-band, so the coordinator can see full membership state.
Non-destructive. Create-only; it never removes or reassigns existing members.
两种成员来源,不可混合使用。默认的生成模式确保“用户创建→成员分配”的流程具有确定性;显式模式为真实Agent场景的可选模式,且会自动推导成员数量。在显式模式下,若某个值无法解析为活跃用户,会终止运行——绑定错误或非活跃用户会导致队列成员数量不足且无提示。
幂等性与可靠性。POST请求单独发送,因此单个绑定失败(例如与其他管理员操作冲突)不会回滚已成功的绑定,且所有POST完成后会重新查询——201状态码仅表示写入已被接受;后续的SOQL查询会确认该行对路由引擎可见。“操作前”快照包含已存在的所有成员,包括通过其他方式添加的非演示用户,因此协调者可查看完整的成员状态。
非破坏性。仅执行创建操作;绝不会移除或重新分配现有成员。

Output contract

输出约定

A single JSON object with
status
bound
|
reused
|
partial
|
blocked
, the resolved
queue
,
org_suffix
,
member_source
(
generated_pattern
|
explicit
),
requested_count
, a
before
snapshot,
bound_this_run
/
bound_count
,
reused_count
, an
after
snapshot,
manual_actions
, and
blocking_issue
.
  • bound
    — at least one new member created; final state matches the expected count.
  • reused
    — all expected users were already members; nothing POSTed.
  • partial
    — some POSTs failed; the re-query shows fewer members than requested (details in
    blocking_issue
    ).
  • blocked
    — precondition failed (production org, missing queue, missing users, missing permissions).
bound_count + reused_count == requested_count
unless
partial
;
blocking_issue
is non-null only for
blocked
/
partial
.
返回单个JSON对象,包含
status
(取值为
bound
|
reused
|
partial
|
blocked
)、已解析的
queue
org_suffix
member_source
(取值为
generated_pattern
|
explicit
)、
requested_count
before
快照、
bound_this_run
/
bound_count
reused_count
after
快照、
manual_actions
blocking_issue
  • bound
    ——至少创建了一个新成员;最终状态与预期数量一致。
  • reused
    ——所有预期用户已为成员;未发送任何POST请求。
  • partial
    ——部分POST请求失败;重新查询显示成员数量少于请求值(详情见
    blocking_issue
    )。
  • blocked
    ——前置条件不满足(生产环境组织、队列缺失、用户缺失、权限不足)。
除非状态为
partial
,否则
bound_count + reused_count == requested_count
;仅当状态为
blocked
/
partial
时,
blocking_issue
不为空。

Limitations

局限性

  • Generated and explicit modes are mutually exclusive per run.
  • Create-only; removing or reassigning members is out of scope.
  • Does not create the queue or the users, and does not assign permission sets or presence configs.
  • 生成模式与显式模式每次运行只能二选一。
  • 仅支持创建操作;移除或重新分配成员不在功能范围内。
  • 不支持创建队列或用户,也不支持分配权限集或在线状态配置。

References

参考资料

FileWhen to read
references/api-notes.md
Before the detect/bind cycle — GroupMember schema, the queue-vs-public-group distinction, why
UserOrGroupId
is polymorphic, and common POST failures
scripts/tests/test_queue_members_contracts.py
When validating changes — run
python3 scripts/tests/test_queue_members_contracts.py
from this skill directory
文件阅读时机
references/api-notes.md
在执行检测/绑定流程之前——包含GroupMember Schema、队列与公共组的区别、
UserOrGroupId
为何是多态字段,以及常见POST请求失败原因
scripts/tests/test_queue_members_contracts.py
在验证变更时——从该Skill目录运行
python3 scripts/tests/test_queue_members_contracts.py