service-omni-routing-flow-deploy
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseservice-omni-routing-flow-deploy
service-omni-routing-flow-deploy
Voice runtime proof depends on a provisioned Contact Center. Flow redeploys reporteven when the deployed configuration is unchanged.Changed
Deploy an Omni-Channel routing Flow via the Metadata API, confirm it lands Active, and prove it routes work — either by CLI invocation (the autolaunched dry-run) or by observing real routing side effects (the record-triggered variant). wires it in after has produced the target queue and its members are bound.
service-omni-channel-setup-coordinateservice-omni-queue-deployVoice运行时验证依赖已配置的Contact Center。即使部署的配置未发生变化,Flow重新部署仍会报告“Changed”。
通过Metadata API部署Omni-Channel路由流,确认其处于Active状态,并验证其路由功能——可通过CLI调用(自动启动的dry-run模式)或观察实际路由副作用(记录触发变体)来完成。会在生成目标队列并绑定成员后,完成路由流的配置。
service-omni-channel-setup-coordinateservice-omni-queue-deployVariants
变体
Four assets ship under — an autolaunched and a record-triggered variant for each of Case and VoiceCall. Selection is by (default Case) and .
assets/force-app/main/default/flows/--target Case|VoiceCall--trigger| Variant | Shape | Proves | Routes real work? |
|---|---|---|---|
| Autolaunched, | CLI invocability via Actions REST, no side effects | No |
| Record-triggered on insert, calls | Real routing — the insert creates | Yes |
The autolaunched variant de-risks the headless CLI path cheaply; the record-triggered variant proves real records reach a queue. A full steel thread deploys the record-triggered variant.
With , the record-triggered variant is drawn from a sibling asset that emits plus a non-null . The base trigger flows hardcode , so a skills-based-routing org config never takes effect at runtime — this variant is what makes it route by skill (W-24069467).
--trigger --routing-type SkillsBased<FlowDN>.SkillsBased.flow-meta.xmlroutingType=SkillsBasedskillOptionroutingType=QueueBasedassets/force-app/main/default/flows/--target Case|VoiceCall--trigger| 变体 | 类型 | 验证内容 | 是否路由实际工作项? |
|---|---|---|---|
| 自动启动, | 通过Actions REST实现CLI调用,无副作用 | 否 |
| 插入记录时触发,调用 | 实际路由——插入操作会生成 | 是 |
自动启动变体可低成本降低无头CLI路径的风险;记录触发变体可验证实际记录是否到达队列。完整核心流程会部署记录触发变体。
若使用参数,记录触发变体将从同级资源中获取,该资源会设置并指定非空。基础触发流硬编码为,因此基于技能的路由组织配置在运行时永远不会生效——此变体是实现按技能路由的关键(W-24069467)。
--trigger --routing-type SkillsBased<FlowDN>.SkillsBased.flow-meta.xmlroutingType=SkillsBasedskillOptionroutingType=QueueBasedInputs
输入参数
bash
bash scripts/deploy-and-report.sh <org-alias> [flow_developer_name] [--target Case|VoiceCall] [--trigger] [--routing-type QueueBased|SkillsBased] [--skill-option RunSBRRules|DefineSkillRequirements|Both] [--runtime-proof] [--require-proof] [--skip-invoke]bash
bash scripts/deploy-and-report.sh <org-alias> [flow_developer_name] [--target Case|VoiceCall] [--trigger] [--routing-type QueueBased|SkillsBased] [--skill-option RunSBRRules|DefineSkillRequirements|Both] [--runtime-proof] [--require-proof] [--skip-invoke]autolaunched smoke test (Case):
自动启动冒烟测试(Case):
bash scripts/deploy-and-report.sh myorg
bash scripts/deploy-and-report.sh myorg
record-triggered Voice routing with runtime proof:
带运行时验证的记录触发式Voice路由:
bash scripts/deploy-and-report.sh myorg --target VoiceCall --trigger --runtime-proof
bash scripts/deploy-and-report.sh myorg --target VoiceCall --trigger --runtime-proof
skills-based Case routing (platform evaluates WorkSkillRouting rules):
基于技能的Case路由(平台评估WorkSkillRouting规则):
bash scripts/deploy-and-report.sh myorg --target Case --trigger --routing-type SkillsBased --runtime-proof
- `--target Case|VoiceCall` (default Case) — selects the flow pair.
- `--trigger` — deploy the record-triggered variant with dynamic token resolution.
- `--routing-type QueueBased|SkillsBased` (default QueueBased; env `OMNI_ROUTING_TYPE`) — `SkillsBased` deploys the `<FlowDN>.SkillsBased` variant that calls `routeWork` with `routingType=SkillsBased`, so the org's skills-based routing config takes effect at runtime instead of being inert. It deploys under the same DeveloperName, replacing the QueueBased trigger (never two triggers on one object).
- `--skill-option RunSBRRules|DefineSkillRequirements|Both` (default `RunSBRRules`; env `OMNI_SKILL_OPTION`; SkillsBased only) — `RunSBRRules`/`Both` make the platform evaluate the org's `WorkSkillRouting` rules server-side and attach matching `SkillRequirement` rows to the PSR; `DefineSkillRequirements` uses only skills the flow itself passes. A SkillsBased deploy with an empty/invalid skillOption is **refused** (exit 2): a null skillOption NPEs the platform `routeWork` action and rolls back the triggering insert (W-24069761), so the asset always carries a non-null value.
- `--runtime-proof` (implies `--trigger`) — after deploy, insert a target record. QueueBased accepts a `PendingServiceRouting` or `AgentWork` row. SkillsBased requires a `PendingServiceRouting` with at least one `SkillRequirement`, proving that `RunSBRRules` evaluated the active `WorkSkillRouting` rule. Proof is fail-soft unless required. The record is always deleted afterward.
- `--require-proof` (implies `--runtime-proof`; also `OMNI_RUNTIME_PROOF_REQUIRED=1`) — makes that proof blocking; the release gate for the Voice steel thread.
- `--skip-invoke` (autolaunched only) — deploy + verify Active, no Actions REST call.
- Token overrides (`--trigger`): `QUEUE_DEVELOPER_NAME`, `ROUTING_CONFIG_DEVELOPER_NAME`, `SERVICE_CHANNEL_DEVELOPER_NAME`. The coordinator always supplies these three from the resources it established for the target, so the flow binds the same channel/queue/QRC rather than a guessed default.bash scripts/deploy-and-report.sh myorg --target Case --trigger --routing-type SkillsBased --runtime-proof
- `--target Case|VoiceCall`(默认值为Case)——选择对应的流组。
- `--trigger`——部署带有动态令牌解析的记录触发变体。
- `--routing-type QueueBased|SkillsBased`(默认值为QueueBased;环境变量`OMNI_ROUTING_TYPE`)——`SkillsBased`会部署`<FlowDN>.SkillsBased`变体,该变体调用`routeWork`时设置`routingType=SkillsBased`,因此组织的基于技能的路由配置会在运行时生效,而非处于闲置状态。它会以相同的DeveloperName部署,替换QueueBased触发流(同一对象永远不会有两个触发流)。
- `--skill-option RunSBRRules|DefineSkillRequirements|Both`(默认值为`RunSBRRules`;环境变量`OMNI_SKILL_OPTION`;仅SkillsBased模式可用)——`RunSBRRules`/`Both`会让平台在服务器端评估组织的`WorkSkillRouting`规则,并将匹配的`SkillRequirement`行附加到PSR;`DefineSkillRequirements`仅使用流自身传递的技能。若基于技能的部署中skillOption为空或无效,将被拒绝(退出码2):空skillOption会导致平台`routeWork`操作出现NPE并回滚触发的插入操作(W-24069761),因此资源始终携带非空值。
- `--runtime-proof`(隐含`--trigger`)——部署完成后,插入目标记录。QueueBased模式会检查`PendingServiceRouting`或`AgentWork`行。SkillsBased模式需要带有至少一个`SkillRequirement`的`PendingServiceRouting`,以此证明`RunSBRRules`已评估了活跃的`WorkSkillRouting`规则。除非设置了强制验证,否则验证失败不会阻断流程。记录始终会在之后被删除。
- `--require-proof`(隐含`--runtime-proof`;也可通过`OMNI_RUNTIME_PROOF_REQUIRED=1`设置)——使验证成为阻断性检查;是Voice核心流程的发布门槛。
- `--skip-invoke`(仅自动启动模式可用)——部署并验证Active状态,不执行Actions REST调用。
- 令牌覆盖(`--trigger`模式):`QUEUE_DEVELOPER_NAME`、`ROUTING_CONFIG_DEVELOPER_NAME`、`SERVICE_CHANNEL_DEVELOPER_NAME`。协调器始终会从为目标建立的资源中提供这三个参数,因此流会绑定相同的渠道/队列/QRC,而非猜测的默认值。Preconditions and safety
前置条件与安全
- Target org authenticated via CLI, Service Cloud license,
sfCLI ≥ 2.139.6,sf≥ 1.6.jq - Omni-Channel base settings enabled () — the routing action resolves only when Omni is on; the flow deploys without it but fails at runtime.
service-omni-base-settings-configure - Record-triggered runs need a deployed ServiceChannel (), Queue (
service-omni-service-channel-configure), and QueueRoutingConfig (service-omni-queue-deploy) to resolve their tokenized IDs; runtime proof additionally needs an agent online with a compatible presence status (service-omni-queue-routing-config-deploy).service-omni-presence-status-deploy - The three-way production guard applies.
safe_to_write
- 目标组织已通过CLI认证,拥有Service Cloud许可证,
sfCLI版本≥2.139.6,sf版本≥1.6。jq - Omni-Channel基础设置已启用()——仅当Omni启用时,路由操作才能解析;流可在未启用的情况下部署,但运行时会失败。
service-omni-base-settings-configure - 记录触发式运行需要已部署的ServiceChannel()、Queue(
service-omni-service-channel-configure)和QueueRoutingConfig(service-omni-queue-deploy)来解析其令牌化ID;运行时验证还需要在线且具有兼容状态的座席(service-omni-queue-routing-config-deploy)。service-omni-presence-status-deploy - 应用三方生产环境防护机制。
safe_to_write
Run
运行流程
deploy-and-report.sh- Resolve tokens (record-triggered only) — the committed asset carries ,
__QUEUE_ID__,__ROUTING_CONFIG_ID__, and channel name/label tokens. The skill resolves each by DeveloperName into a materialized copy that is never committed (the asset stays tokenized for portability). A ServiceChannel that does not resolve fails closed rather than embedding an empty id.__SERVICE_CHANNEL_ID__ - Deploy — ; the
sf project deploy start --metadata "Flow:<FlowDN>"maps tofiles[].state/reused/updated.created - Verify Active — retrieve the Flow and confirm its resource IDs, , and SkillsBased
routingTypestill match; otherwise redeploy. Confirm an active version exists.skillOption - Prove routing — autolaunched: POST to with
/actions/custom/flow/<FlowDN>and assert{"dryRun":true}andisSuccess. Record-triggered: insert a target record and observe routing. SkillsBased success additionally requires one or moredryRunOkrows on the PSR.SkillRequirement
deploy-and-report.sh- 解析令牌(仅记录触发模式)——提交的资源包含、
__QUEUE_ID__、__ROUTING_CONFIG_ID__以及渠道名称/标签令牌。脚本会根据DeveloperName将每个令牌解析为具体化的副本,且该副本不会被提交(资源保持令牌化以保证可移植性)。若ServiceChannel无法解析,会直接失败,而非嵌入空ID。__SERVICE_CHANNEL_ID__ - 部署——执行;
sf project deploy start --metadata "Flow:<FlowDN>"会映射为files[].state/reused/updated。created - 验证Active状态——获取Flow并确认其资源ID、以及SkillsBased模式下的
routingType仍与请求匹配;否则重新部署。确认存在活跃版本。skillOption - 验证路由功能——自动启动模式:向发送POST请求,参数为
/actions/custom/flow/<FlowDN>,并断言{"dryRun":true}和isSuccess为真。记录触发模式:插入目标记录并观察路由情况。SkillsBased模式成功还要求PSR上存在一个或多个dryRunOk行。SkillRequirement
Behavior
行为说明
Two shapes, two verification paths. "Can we invoke a routing flow headlessly?" and "do real records route to a queue?" are different questions. The autolaunched flow answers the first in one side-effect-free HTTP call — the flow must have a code path that succeeds without prerequisites, so takes an assignment step and returns . Record-triggered flows are not exposed as custom actions, so the only headless proof is inserting the source record and observing /. The PSR row alone proves the flow routed; agent assignment depends on Omni distribution, not the flow.
dryRundryRun=truedryRunOk=truePendingServiceRoutingAgentWorkActive-version round trip. For the record-triggered variant, component deploy state proves only the transaction, not that an active version exists. The skill prefers and falls back to the active Tooling row when that view is unavailable. It fails closed when neither source proves an active version, so is never reported without evidence.
FlowDefinitionView.ActiveVersionIdFlowflow_active:trueBinding-drift redeploy. means an active version already exists and its embedded queue/QRC/ServiceChannel IDs, routing type, and SkillsBased skill option match the request. If a binding or routing mode drifted, the skill redeploys instead of reusing. forces a redeploy.
reusedOMNI_FLOW_FORCE=1Idempotency quirk. Unlike most metadata types, deploys are not byte-idempotent — Salesforce reports on identical redeploys because every deploy is a potential version bump. Treat from this skill as "successfully redeployed," not "operator modified the flow."
FlowChangedupdatedSafety. Deploys use explicit (never ) so sibling flows are untouched, and the skill never overwrites a Flow it did not author — the coordinator supplies deliberately. is validated against because it is interpolated into the Actions REST URL path.
--metadata "Flow:<DN>"--source-dirflow_developer_nameflow_developer_name^[A-Za-z][A-Za-z0-9_]{0,79}$两种类型,两种验证路径。“能否无头调用路由流?”与“实际记录是否会路由到队列?”是两个不同的问题。自动启动的流通过一次无副作用的HTTP调用回答第一个问题——流必须有无需前置条件即可成功的代码路径,因此会执行赋值步骤并返回。记录触发流不会作为自定义操作暴露,因此唯一的无头验证方式是插入源记录并观察/。仅PSR行即可证明流已完成路由;座席分配取决于Omni分发机制,而非流本身。
dryRundryRun=truedryRunOk=truePendingServiceRoutingAgentWork活跃版本往返验证。对于记录触发变体,组件部署状态仅能证明事务完成,无法证明存在活跃版本。脚本优先使用,当该视图不可用时,回退到活跃的Tooling 行。若两个来源均无法证明存在活跃版本,会直接失败,因此只有在有证据的情况下才会报告。
FlowDefinitionView.ActiveVersionIdFlowflow_active:true绑定漂移重新部署。表示已存在活跃版本,且其嵌入的队列/QRC/ServiceChannel ID、路由类型以及SkillsBased模式下的skill选项与请求匹配。若绑定或路由模式发生漂移,脚本会重新部署而非复用。设置可强制重新部署。
reusedOMNI_FLOW_FORCE=1幂等性特性。与大多数元数据类型不同,部署并非字节级幂等——Salesforce会在相同内容重新部署时报告“Changed”,因为每次部署都可能产生版本更新。在此脚本中,应将视为“重新部署成功”,而非“操作人员修改了流”。
Flowupdated安全性。部署使用显式的(从不使用),因此不会影响同级流,且脚本永远不会覆盖非自身创建的Flow——协调器会特意提供。会验证是否符合规则,因为它会被插入到Actions REST URL路径中。
--metadata "Flow:<DN>"--source-dirflow_developer_nameflow_developer_name^[A-Za-z][A-Za-z0-9_]{0,79}$Output contract
输出约定
A single JSON object with ∈ | | | , , , , , , and . The autolaunched variant adds and (, , , ). The record-triggered variant adds , , , , (the skillOption when SkillsBased, else null), (queue/routing_config/service_channel), and (, , , , , , ). Under , also carries and — the rows the platform attached to the PSR (the skills-based acceptance signal).
statuscreatedreusedupdatedblockedflow_developer_nameflow_stateflow_activedeploy_idmanual_actionsblocking_issueverification_pathinvocation_smoke_testattemptedsuccessendpointdry_run_okmode: "record_triggered"targetflow_active_version_idrouting_typeskill_optionresolvedruntime_proofattemptedrequiredsuccessrecord_idpending_service_routingagent_workreason--routing-type SkillsBasedruntime_proofskill_requirement_countskill_requirementsSkillRequirement- — deploy failed; the flow is not Active; the autolaunched invocation failed; a queue/QRC could not be resolved; the ServiceChannel did not resolve; or
blockedwas set and the mode-specific proof was not observed. For SkillsBased, a PSR with zero--require-proofrows is not a passing proof. A plainSkillRequirementfailure remains fail-soft.--runtime-proof - is
runtime_proof.attemptedunlessfalse/--runtime-proofwas passed; the throwaway record is always cleaned up.--require-proof
返回一个JSON对象,包含 ∈ | | | 、、、、、和。自动启动变体还会添加和(包含、、、)。记录触发变体还会添加、、、、(SkillsBased模式下为skillOption,否则为null)、(包含queue/routing_config/service_channel)和(包含、、、、、、)。在模式下,还会包含和——平台附加到PSR的行(基于技能的验证信号)。
statuscreatedreusedupdatedblockedflow_developer_nameflow_stateflow_activedeploy_idmanual_actionsblocking_issueverification_pathinvocation_smoke_testattemptedsuccessendpointdry_run_okmode: "record_triggered"targetflow_active_version_idrouting_typeskill_optionresolvedruntime_proofattemptedrequiredsuccessrecord_idpending_service_routingagent_workreason--routing-type SkillsBasedruntime_proofskill_requirement_countskill_requirementsSkillRequirement- ——部署失败;流未处于Active状态;自动启动调用失败;队列/QRC无法解析;ServiceChannel无法解析;或设置了
blocked但未观察到对应模式的验证结果。对于SkillsBased模式,没有--require-proof行的PSR不算验证通过。仅设置SkillRequirement时,验证失败不会阻断流程。--runtime-proof - 仅在传递
runtime_proof.attempted/--runtime-proof参数时为--require-proof;临时记录始终会被清理。true
Limitations
局限性
- Case and VoiceCall only; extend by forking the closest asset and preserving the /
dryRuncontract (autolaunched) or thedryRunOk+ tokenized-ID pattern (record-triggered).routeWork - Does not register the Flow on a queue's routing configuration — that binding belongs to .
service-omni-queue-routing-config-deploy - Does not handle screen flows, platform-event-triggered flows, or Flow Tests.
- 仅支持Case和VoiceCall;可通过复制最接近的资源并保留/
dryRun约定(自动启动模式)或dryRunOk+令牌化ID模式(记录触发模式)进行扩展。routeWork - 不会在队列的路由配置上注册Flow——该绑定属于的功能。
service-omni-queue-routing-config-deploy - 不支持屏幕流、平台事件触发流或Flow测试。
References
参考资料
| File | When to read |
|---|---|
| On unexpected deploy or verification behavior — variant comparison, the token-resolution table, Flow schema, the Actions REST response shape, and record-DML verification |
| 文件 | 阅读场景 |
|---|---|
| 遇到意外的部署或验证行为时——变体对比、令牌解析表、Flow schema、Actions REST响应格式以及记录DML验证 |