OneUptime 集成 Microsoft Dynamics 365:基于 Workflow 与 Dataverse Web API 的双向工单同步实战指南
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
OneUptime 发生事件(Incident)时自动在 Microsoft Dynamics 365 中创建 Case,并在事件演进过程中持续同步、最终在事件解决时关闭 Case,同时把 Dynamics 侧对 Case 的修改反向推回 OneUptime——这正是本指南要解决的核心问题。整个方案完全基于 OneUptime 的 Workflow 能力构建:出站方向由 OneUptime 通过通用API 组件调用 Dataverse Web API,入站方向由 Dynamics 通过Webhook 触发器回调 OneUptime。阅读完本文,你将掌握完整的 Microsoft Entra ID 应用注册、Dynamics application user 创建、OAuth 2.0 client credentials 令牌获取,以及 Power Automate / 原生 Dataverse Webhook 两条入站通道的搭建方法。
整体架构:一条双向链路
本集成的数据流可以用一张图概括:
OneUptime Incident → On Create ──► API Post (token) ──► API Post (POST /api/data/v9.2/incidents) ──► Dynamics 365 Case Dynamics 365 Case changed ──► Power Automate flow (HTTP) ──► OneUptime Webhook trigger ──► Update One Incident关键的设计理念在于:没有任何 Dynamics 专属的插件块需要安装。出站方向,OneUptime 用通用 API 组件(本质是任意 HTTP 请求块)直接与 Dataverse Web API 对话;入站方向,Dynamics 通过 Webhook 触发器 把变更回调进 OneUptime。本文会覆盖两个方向,建议先搭建出站一半——它需要 Microsoft Entra ID 的整套配置,一旦打通,入站方向就是一个独立的工作流而已。
前置条件
动手之前,请确认以下四项就绪:
- 一个包含Case 表的Dynamics 365环境。Case 来自 Dynamics 365 Customer Service;没有该模块的纯 Dataverse 环境并不存在可供写入的
incident表。 - 环境的Web API endpoint。可在 Power Platform admin center 的环境Settings → Developer resources中查看,也可在 make.powerapps.com 的Settings → Developer resources中查看。其形态为
https://yourorg.crm.dynamics.com/api/data/v9.2/——中间的区域段因地域而异(北美为crm、南美为crm2、日本为crm7,以此类推)。 - 在Microsoft Entra ID中注册应用的权限,以及在 Dynamics 环境中创建application user的权限。这两者通常是两位不同的管理员。
- 一个允许创建 workflow 和全局变量(Global Variables)的 OneUptime 项目。
重要约定:下文全部使用 Dataverse 的表名,而不是 Dynamics 表单上的显示标签。一个 Case 对应
incident表,其在 URL 中的集合名是incidents,主键是incidentid,标题列是title。你在界面上看到的工单编号是ticketnumber。这与 OneUptime 侧数据组件使用记录自身列名(而非界面标签)的约定完全一致,参见 Components 文档 中 "Working with records" 一节。
第一步:在 Microsoft Entra ID 中注册应用
OneUptime 以应用身份、而非某个用户身份进行认证,因此使用的是 OAuth 2.0client credentials流程。
- 以 Dynamics 环境所在租户的管理员身份登录 Azure 门户,打开Microsoft Entra ID。
- 进入App registrations → New registration。命名为类似
OneUptime Integration的名称,Supported account types保持默认的Accounts in this organizational directory only,点击Register。 - 在应用的Overview页面,复制Application (client) ID与Directory (tenant) ID。
- 进入Certificates & secrets → Client secrets → New client secret。在离开页面之前复制该 secret 的Value——注意不是它的 ID,Value 一旦离开页面就再也看不到。Client secret 最长只能存活 24 个月,请把过期时间记在你一定会看到的地方。
有两件很多人会顺手添加、但这里并不需要的事:
- 不需要任何 API permission。在 client credentials 流程中没有已登录用户,因此委托权限(delegated permissions)不起任何作用。Dataverse 下的
user_impersonation就是委托权限,只适用于交互式应用。即便一个权限都不配,Microsoft Entra ID 也会照常为 Dataverse 签发 token——真正的访问控制发生在 Dynamics 一侧,也就是第二步。 - 不需要任何管理员同意(admin consent)步骤。理由同上。
微软在正式生产环境更推荐证书而非 client secret。但证书方案要求调用方自行构造并签名一个 JWT 断言,这是 workflow 无法做到的,因此 client secret 是这里的务实之选——请按它的敏感性对待:存入 secret 变量,并在过期前轮换。
第二步:在 Dynamics 中创建 application user
这是最容易被跳过、且跳过后果最隐蔽的一步:token 请求完全成功,但随后所有 Dataverse 调用都以403 Forbidden和错误码0x80072560失败,报错内容为"The user isn't a member of the organization."。原因在于 Entra ID 签发 token 时对 Dynamics 一无所知;Dynamics 随后会查找与该应用对应的用户行,而它并不存在。
- 打开 Power Platform admin center,选择Manage → Environments,然后选中你的环境。
- 进入Settings → Users + permissions → Application users。
- 点击+ New app user,然后+ Add an app,选择第一步注册的应用,点击Add。
- 选择Business unit,填写Email address,然后点击Security roles旁的编辑图标。
- 分配一个对Case表具有创建、读取、写入权限的自定义安全角色。application user 不能使用内置角色——微软强制要求自定义角色。如果没有合适的角色,复制一个现有角色后裁剪即可。
- 点击Save,再点击Create。
补充两点硬性约束:一个环境中,每个已注册应用只能有一个application user;application user 不消耗许可证,也不受环境安全组成员资格规则的限制。
第三步:在 OneUptime 中保存凭据
进入Flows de trabajo → Variables Globales → Create(即Workflows → Global Variables → Create),添加以下变量,并按标记开启Secret:
| 名称 | 值 | Secret |
|---|---|---|
DYNAMICS_TENANT_ID | 第一步中的 Directory (tenant) ID | 否 |
DYNAMICS_CLIENT_ID | 第一步中的 Application (client) ID | 否 |
DYNAMICS_CLIENT_SECRET | 第一步中 client secret 的Value | 是 |
DYNAMICS_URL | https://yourorg.crm.dynamics.com—— 不带结尾斜杠 | 否 |
请原样粘贴 Entra ID 给出的 client secret。OneUptime 会替你编码表单请求体(form body),不要手动做 URL 编码。
在任意块中通过{{global.variables.DYNAMICS_CLIENT_ID}}引用这些变量。关于 secret 如何从运行日志(run logs)中被擦除、以及全局变量的创建/删除语义(变量只支持创建与删除、不支持界面编辑),详见 Variables 文档——其中还说明了对命名规则的要求:变量名至少两个字符、不含空格、仅限字母数字与连字符/下划线,UPPER_SNAKE_CASE是推荐习惯。
第四步:获取访问令牌
每次执行(run)都会获取属于自己的 token。token 有效期为 60~90 分钟,而 client credentials 流程从不签发 refresh token,所以无需缓存、无需续期——每次执行多一次 HTTP 调用就是全部成本。
打开Workflows → Create Workflow,命名为
Incidents → Dynamics 365,进入Builder(画布编辑器)。点击虚线占位符,添加On Create Incident触发器,并在其Select Fields中请求你想发送的列:
{ "_id": true, "title": true, "description": true, "incidentNumber": true, "incidentSeverity": { "name": true } }保持其Identifier为默认的
incident-on-create-1。点击Add Component,添加一个API Post (JSON)块,把触发器上的Success触点连接到它,打开设置。将它的Identifier设为
get-token,然后配置:URL:
https://login.microsoftonline.com/{{global.variables.DYNAMICS_TENANT_ID}}/oauth2/v2.0/tokenRequest Headers:
{ "Content-Type": "application/x-www-form-urlencoded" }Request Body:
{ "client_id": "{{global.variables.DYNAMICS_CLIENT_ID}}", "client_secret": "{{global.variables.DYNAMICS_CLIENT_SECRET}}", "scope": "{{global.variables.DYNAMICS_URL}}/.default", "grant_type": "client_credentials" }
请把请求头名称严格写成Content-Type,保持这个精确的大小写。这正是告诉 OneUptime 以 form post 而非 JSON 发送请求体的信号,而 form post 是微软 token 端点唯一接受的形态。小写的content-type无法匹配,请求会以 JSON 发出并得到400响应。
scope必须是你的环境 URL 后跟/.default——这是机密客户端(confidential client)的标准形式。此处环境 URL 写错是AADSTS70011: The provided value for the input parameter 'scope' is not valid最常见的诱因。
令牌此后可在下游以如下引用获得:
{{local.components.get-token.returnValues.response-body.access_token}}关于引用语法本身:{{local.components.COMPONENT_ID.returnValues.FIELD_ID}}中的COMPONENT_ID是块的 Identifier(不是显示名),FIELD_ID是所选返回值的 id。建议使用编辑器中的组件值选择器(component-value picker)插入引用,它会写入 runner 期望的精确 id——详见 Variables 文档 的 "Component outputs" 一节。
第五步:创建 Case
添加第二个API Post (JSON)块,把get-token的Success触点连接到它,将Identifier设为create-case。
URL:
{{global.variables.DYNAMICS_URL}}/api/data/v9.2/incidents?$select=incidentid,ticketnumberRequest Headers:
{ "Authorization": "Bearer {{local.components.get-token.returnValues.response-body.access_token}}", "OData-MaxVersion": "4.0", "OData-Version": "4.0", "Accept": "application/json", "If-None-Match": "null", "Prefer": "return=representation" }Request Body:
{ "title": "OneUptime #{{local.components.incident-on-create-1.returnValues.model.incidentNumber}}: {{local.components.incident-on-create-1.returnValues.model.title}}", "description": "{{local.components.incident-on-create-1.returnValues.model.description}}", "caseorigincode": 3, "prioritycode": 1, "customerid_account@odata.bind": "/accounts(00000000-0000-0000-0000-000000000000)" }
把账户 GUID 替换为这些工单实际归属的账户。customerid在 Case 上是真正必填的——它是 Dataverse 对任何编程式写入都强制要求的列之一,缺少它的创建会被直接拒绝。由于它既可能指向账户(account)也可能指向联系人(contact),因此你永远不要写customerid@odata.bind,而必须写customerid_account@odata.bind或customerid_contact@odata.bind,且这些名字是区分大小写的。title则是另一种"必填":Dynamics 表单要求它,API 并不要求,但无论如何都请发送。
Prefer: return=representation是让这个调用在 workflow 里真正可用关键:没有它,一次成功的创建只返回204 No Content,并把新记录 URI 放在OData-EntityId响应头里,你还得自己从 GUID 中抠出来;有了它,响应变成201 Created且携带记录本体,于是下一个块可以直接读取:
{{local.components.create-case.returnValues.response-body.incidentid}} {{local.components.create-case.returnValues.response-body.ticketnumber}}现在开启这个 workflow——Overview → Edit Workflow → Enabled——声明一个测试事件,然后在Runs & Logs中阅读执行记录。create-case块应显示201以及包含新incidentid的响应体。画布上的修改是自动保存的;没有保存按钮。
映射严重度与状态
Dynamics 自带的severitycode只有一个选项 "Default Value",因此并不存在开箱即用的严重度刻度可供映射。请改用prioritycode;如果你想要按严重度映射优先级,可以用If / Else块对{{local.components.incident-on-create-1.returnValues.model.incidentSeverity.name}}进行分支。OneUptime 的 If / Else 块支持==、!=、>、>=、<、<=、contains、starts with、ends with等运算符,并输出Yes/No两个分支,参见 Components 文档。
Dataverse 中 Case 相关的常用选项集值如下:
| 列 | 值 |
|---|---|
prioritycode | 1高,2普通,3低 |
caseorigincode | 1电话,2电子邮件,3Web,2483Facebook,3986Twitter,700610000IoT |
casetypecode | 1问题,2故障,3请求 |
statecode | 0活动,1已解决,2已取消 |
statuscode | 1进行中,2挂起,3等待详情,4调查中,5问题已解决,6已取消,1000已提供信息,2000已合并 |
注意statuscode是可自定义的,你的租户可能添加了自己的值。发送整数,不要发送标签。
第六步:让事件与工单互相可寻址
后续的一切操作——评论、解决、反向同步——都要求两个系统中的一方持有另一方的标识符。建议把这条链接放在 Dynamics 一侧。
给 Case 表添加一个单行文本列,例如new_oneuptimeincidentid,并在创建工单时写入它:
"new_oneuptimeincidentid": "{{local.components.incident-on-create-1.returnValues.model._id}}"之后任何 workflow 都可以用过滤器找到对应工单:
{{global.variables.DYNAMICS_URL}}/api/data/v9.2/incidents?$select=incidentid,ticketnumber&$filter=new_oneuptimeincidentid eq '<the incident id>'如果把这列定义为 Case 表的备用键(alternate key),你可以完全跳过查找,直接PATCH到incidents(new_oneuptimeincidentid='<id>')——这是一个 upsert:工单不存在则创建,存在则更新。备用键必须先完成构建(其状态变为Active)才能使用;备用键值不能包含/ < > * % & : \ ? + #这些字符。OneUptime 的 id 是普通 UUID,因此完全安全。
反向方向——把 Dynamics 的工单 id 存到 OneUptime 事件上——也可行:用一个Update One Incident块写入customFields。但要小心:customFields是单一 JSON 列,写入它会整体替换该事件所有自定义字段的值,而不仅是你的那一个。把链接放在 Dynamics 一侧可以完全规避这个问题。
第七步:事件解决时关闭工单
请把它构建成第二个独立 workflow,这样这里的失败不可能阻断工单的创建。
Create Workflow,命名为
Incident resolved → Close Dynamics case,添加On Update Incident触发器。在触发器的Listen on中填入
{"currentIncidentStateId": true},让 workflow 只在状态变更时唤醒,而不是每次编辑都触发。在Select Fields中请求{"_id": true, "currentIncidentState": {"name": true}}。OneUptime 事件触发器提供 On Create / On Update / On Delete 三类,将完整记录传给下一个块,详见 Triggers 文档。添加一个If / Else块。Input 1为
{{local.components.incident-on-update-1.returnValues.model.currentIncidentState.name}},Operator为==,Input 2为Resolved——或者你的项目中已解决状态的实际名称。可参考 事件状态与严重度。从Yes分支出发,重复第四步的
get-token块。添加一个API Get (JSON)块,将Identifier设为
find-case,填入第六步的$filterURL。Dataverse 查询返回的是一个value数组,而 workflow 引用可以用方括号索引数组,因此工单 id 是{{local.components.find-case.returnValues.response-body.value[0].incidentid}}。添加一个用于关闭工单的API Post (JSON)块:
URL:
{{global.variables.DYNAMICS_URL}}/api/data/v9.2/CloseIncidentRequest Headers:与第五步相同,去掉
Prefer。Request Body:
{ "IncidentResolution": { "@odata.type": "Microsoft.Dynamics.CRM.incidentresolution", "subject": "Resolved in OneUptime", "incidentid@odata.bind": "/incidents(<the case id>)" }, "Status": 5 }Status是已解决状态下的一个statuscode值——5即Problem Solved。在依赖这个请求体之前,请先针对你自己的环境测试它。
CloseIncident接收IncidentResolution和Status两个参数,但微软没有发布任何针对它的 HTTP 示例——所有官方样例都是 C# 的。上面的形态是惯用翻译。如果你的环境拒绝它,可以尝试用简单的"incidentid": "<the case id>"属性(而非@odata.bind形式)来标识工单——微软其他 action 示例引用现有记录的方式正是前者。
为什么不能简单地PATCH工单到statecode: 1?技术上可以——微软将statecode与statuscode的PATCH文档化为旧 SetState 消息的 Web API 等价物,它是在活动状态之间移动工单的正确工具。但它不会创建已解决工单在 Dynamics 365 Customer Service 中所期望的Case Resolution活动,并且在管理员配置了自定义状态转换的环境中会被直接拒绝。用CloseIncident解决;其余情况用PATCH。而且无论何时写入statecode,都要在同一次请求中设置statuscode——否则 Dynamics 会静默应用该状态的默认statuscode。
CloseIncident来自 Dynamics 365 Customer Service 而非基础 Dataverse,它不在 Dataverse 的动作参考列表里。如果返回404,请通过拉取{{global.variables.DYNAMICS_URL}}/api/data/v9.2/$metadata并搜索CloseIncident来确认它存在于你的环境中。
对于任何尚未达到关闭工单程度的变更——一条备注、一次优先级提升、一个标题修改——请使用API Patch (JSON)块访问{{global.variables.DYNAMICS_URL}}/api/data/v9.2/incidents(<the case id>),并带上If-Match: *请求头,它可阻止意外的 upsert 创建新工单。只发送你正在修改的列。
入站方向:从 Dynamics 365 到 OneUptime
现在处理另一个方向:有人在 Dynamics 里关闭了工单,或代理添加了备注,OneUptime 应当感知到。
先构建接收方 workflow
Create Workflow,命名为
Dynamics 365 → OneUptime,添加Webhook触发器。Webhook 触发器会为每个 workflow 生成唯一 URL,任何请求头、查询参数和请求体都会被传入,URL 同时接受GET和POST——详见 Triggers 文档。打开该 workflow 的Settings,复制Webhook Secret Key。你的 URL 是:
https://oneuptime.com/workflow/trigger/<webhook secret key>在自托管安装中,替换为你自己的主机名。请把这条 URL 当作密码对待——任何持有它的人都能启动这个 workflow。你可以在同一页面重置密钥。
添加一个If / Else块,在任何其他逻辑之前先校验共享密钥。Input 1为
{{local.components.webhook-1.returnValues.request-headers.x-oneuptime-secret}},Operator为==,Input 2为{{global.variables.DYNAMICS_WEBHOOK_SECRET}}——这是一个你自己发明并保存为 secret 全局变量的值。从Yes分支,添加一个Update One Incident块:
- Query:
{"_id": "{{local.components.webhook-1.returnValues.request-body.oneuptimeIncidentId}}"} - Data (JSON Object):该工单变更在 OneUptime 中应产生的效果——状态变更、一条备注、一个标签。
要把事件移动到某个状态,你需要该状态的 id:用一个Find One Incident State块,查询
{"name": "Resolved"},即可得到{{local.components.incident-state-find-one-1.returnValues.model._id}},把它写入currentIncidentStateId。数据组件的查询始终限定在 workflow 所在项目内,列名以记录自身列名为准,ID 列是_id(id拼写可作为别名),参见 Components 文档。- Query:
保持它启用并就绪。现在给 Dynamics 一个可以调用的目标。
方案 A——Power Automate 流(推荐)
这是大多数团队应当选择的路径:你可以完全控制负载(payload),并且无需安装任何东西。
在 Power Automate 中创建一个Automated cloud flow。
触发器:Microsoft Dataverse → When a row is added, modified or deleted。
- Change type:
Modified - Table name:
Cases - Scope:
Organization——任何更窄的范围只会在行属于你或你的业务单元时触发。 - Select columns:
statecode,statuscode。这是仅针对更新(Update)的过滤器,值得认真配置。此处不支持查找(lookup)列;绝不要列出每次更新都会出现的列(例如主键),否则流会在每次保存时都触发。
- Change type:
添加Microsoft Dataverse → Get a row by ID,表为
Cases,行 id 取触发器输出,Select columns设为incidentid,ticketnumber,title,statecode,statuscode,new_oneuptimeincidentid。这第二次调用物有所值。在更新事件中,触发器只携带发生变更的列,因此你用于匹配的标识符可能根本不在其中。
添加内置的HTTP动作:
Method:
POSTURI:上文提到的 OneUptime webhook URL
Headers:
Content-Type: application/json和X-OneUptime-Secret: <the same secret>Body:基于Get a row by ID的输出构建,例如
{ "oneuptimeIncidentId": "<new_oneuptimeincidentid>", "caseId": "<incidentid>", "caseNumber": "<ticketnumber>", "statecode": "<statecode>", "statuscode": "<statuscode>" }
保存并启用该流。
在承诺这条路之前值得了解的几点:
- Microsoft Dataverse 连接器是 premium(付费)的。对于自动化流,只有流的所有者需要许可证,而非所有接触工单的人——但如果所有者的许可证过期,流会静默停止。
- Dataverse 触发器是push 推送式,而非轮询——Dynamics 注册一个回调并触发它。投递通常在数秒内完成;超过五分钟说明异步服务已积压,可以在管理中心的Settings → System Jobs中查看。
- 自定义请求头可以存活。Power Automate 会从 HTTP 动作中剥离多种标准请求头族(大多数
Accept-*和Content-*头、Host、Origin、Cookie),但X-OneUptime-Secret这类你自己的请求头会被原样传递。 - 流必须与其监视的表位于同一个环境中。
- 请求会计入你租户的 Power Platform 请求配额,连接器限流在流运行内部表现为
429。
方案 B——Dataverse 原生 Webhook
如果 Power Automate 不可用,Dataverse 可以直接调用 OneUptime。使用 Plug-in Registration Tool 注册端点:Register New WebHook,填入 OneUptime 的 URL,选择HttpHeader认证,并添加携带你的 secret 的X-OneUptime-Secret。然后在incident表上为Update消息注册一个步骤(step),Filtering Attributes只限于你在意的列,阶段(stage)为PostOperation,执行模式为Asynchronous。
走这条路时请保持清醒:
- 只支持 80 和 443 端口。自托管在其他端口的 OneUptime 无法注册。
- Dataverse 不会验证你的 secret。它只负责发送请求头;拒绝未携带该头的请求完全是你的 workflow 的职责——这正是接收方 workflow 里那个If / Else块的用途。
- 负载不是一个友好的 JSON 对象。它是序列化后的
RemoteExecutionContext:InputParameters是{key, value}对组成的数组,被修改的行位于Target键下,其列又分布在另一个Attributes数组中。预计需要添加一个Run Custom JavaScript块来扁平化它,之后其他块才能读取。 - 更新事件只包含被修改的列,因此如果你需要
ticketnumber或你的 OneUptime id 列,请注册一个Post Image。 - 超过 256 KB 后,关键部分会被剥离——
InputParameters、PreEntityImages和PostEntityImages全部消失,请求会携带x-ms-dynamics-msg-size-exceeded请求头。PrimaryEntityId和PrimaryEntityName得以保留,因此退路是通过 Web API 重新读取该行。 - 投递几乎毫无宽容度。Dataverse 等待 60 秒以获取
2xx,并且仅对502、503、504重试一次。其他任何情况——包括来自你侧的500——都不会重试,最终落地为一个失败的 System Job。 - 选择 Asynchronous(异步)。同步步骤会把代理的保存阻塞在你的端点上,而且如果之后事务回滚,请求已经发出、无法撤回。
Dynamics 经典的后台 workflow 完全没有 HTTP 或 webhook 步骤,因此它们在这里不算第三种选择。
用同样的方式处理告警(Alert)
以上所有内容都是围绕事件(Incident)展开的,因为这是最常见场景,但告警(Alert)的工作方式完全相同——换一下记录类型,其他什么都不用变:
| 事件 (Incident) | 告警 (Alert) |
|---|---|
On Create Incident(incident-on-create-1) | On Create Alert(alert-on-create-1) |
On Update Incident(incident-on-update-1) | On Update Alert(alert-on-update-1) |
incidentNumber、currentIncidentState、incidentSeverity | alertNumber、currentAlertState、alertSeverity |
| Find One Incident State | Find One Alert State |
| Update One Incident | Update One Alert |
一个 workflow 恰好只有一个触发器,因此事件和告警各自需要独立 workflow。如果两者要做的工作相同,可以把 Dynamics 那一半只构建一次,然后通过Execute Workflow组件从两个 workflow 中分别调用它——该组件以异步方式运行被调用的 workflow,用于共享公共逻辑,参见 Components 文档。
故障排查指南
首先阅读Runs & Logs中失败的那个块——微软的两个端点都会返回带有说明的 JSON 响应体,而 API 组件会把它保存在response-body中。
token 请求以400和invalid_request或不支持的授权类型失败。Content-Type请求头不是精确的Content-Type: application/x-www-form-urlencoded,导致请求体以 JSON 发出。检查大小写。
400并伴随AADSTS70011: The provided value for the input parameter 'scope' is not valid。scope不是"你的环境 URL 加上/.default"。从Developer resources复制 URL,去掉任何结尾斜杠以及任何/api/data/...路径。
来自 Dynamics 的401 Unauthorized。Authorization请求头缺失、格式错误,或者 token 在运行中途过期。它必须是Bearer <token>,且中间只有一个空格。
403 Forbidden并伴随0x80072560,报错 "The user isn't a member of the organization"。第二步被跳过,或者 application user 绑定到了另一个应用注册。token 本身没有问题;是 Dynamics 侧的用户不存在。
403 Forbidden并伴随权限错误。application user 存在,但其自定义安全角色缺少对Case的 Create、Read 或 Write 权限。
400 Bad Request并提及客户(customer)。customerid是必填的。请按精确拼写设置customerid_account@odata.bind或customerid_contact@odata.bind,URI 以斜杠开头,例如/accounts(<guid>)。
/CloseIncident返回404 Not Found。该动作来自 Dynamics 365 Customer Service。在假设其可用之前,先在你的环境$metadata中搜索它。
412 Precondition Failed并伴随DuplicateRecord。有重复检测规则命中。要么收窄该规则,要么停止发送它所匹配的字段。
429 Too Many Requests。这是 Dataverse 的服务保护限制——大致为每个用户、每个 Web 服务器在任何五分钟窗口内约 6,000 次请求和 20 分钟执行时间。响应会携带以秒为单位的Retry-After。如果某个 workflow 正在突发请求,请在其中加入Delay块,或者把工作转移到可批处理的定时 workflow。
OneUptime 侧什么都没有到达。自己用curl向 webhook URL 发送一个请求,然后检查 workflow 的Runs & Logs。如果你自己的请求出现了、而 Dynamics 的请求没有出现,问题就在上游:对 Power Automate,查看流自身的运行历史;对原生 webhook,查看Settings → System Jobs并过滤失败项。
workflow 运行了,但事件没有变化。当查询没有匹配到任何记录时,Update One Incident块会报告Items Updated: 0——这是成功,不是错误。请检查负载中的 id 是否为 OneUptime 的事件 id,以及你查询的确实是_id。这与 Components 文档 中"Success/Error 报告的是查询是否执行,而非是否找到记录"的行为一致。
延伸阅读
- 集成概览——入站与出站模式,以及快速认证速查。
- Jira 集成——针对 Jira 的同一个双向构建。
- Workflow 概览与创建工作流——画布、Identifier,以及如何开启一个 workflow。
- 组件——API 块、If / Else,以及 OneUptime 数据组件。
- 变量——secret,以及如何从一个块读取下一个块的输出。
- 配置与安全——webhook 安全与出站网络访问。
- IP 地址——OneUptime 的出站 IP 段,适用于 Dynamics 位于白名单之后的场景。
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考