orchestrator
2024.10
false
Orchestrator 用户指南
Automation CloudAutomation Cloud Public SectorAutomation SuiteStandalone
Last updated 2024年10月21日

Webhooks

Webhook 用于在整个应用程序生态系统中更出色地集成 UiPath™ 自动化。您可以订阅 Orchestrator 事件并将其发送到任何外部 DCM、BPM 或 CRM 解决方案,同时通知不同的用户存在可供处理的新队列项目、触发器失败或已更新流程等事项。

Webhook 允许外部系统订阅和侦听不同类型的 Orchestrator 事件Webhooks 页面使您可以轻松地设置它们,以及查看先前创建的内容。您还可以禁用 Webhook,搜索特定的 Webhook,编辑或删除 Webhook。

事件适用于作业、机器人、队列、队列项目、流程和计划。有关事件类型的完整列表和一些示例,请查看此页面

每个事件都会向指定的 URL 发送包含信息的有效负载。一些属性是所有事件的通用属性,而另一些属性则特定于每种事件类型。

Webhook 事件按文件夹创建,因此,如果您有一个 Webhook 事件与在文件夹之间共享的资源(例如队列)相关联,则系统将为每个文件夹生成一个单独的 Webhook 事件。

If the request to forward an event fails, the circuit breaker for that particular webhook opens, disabling the webhook for one hour.

备注:
  • Any webhook events that should have been sent while the circuit breaker is open are skipped and not retried once the circuit breaker closes.
  • Webhook events are not stored, and cannot be retried or exported. Furthermore, if the call to the external platform fails, the event is lost. Webhooks are designed for real-time processing.

通用有效负载属性

属性名称

属性类型

说明和示例

名称

字符串

Webhook 的名称。

系统将为所有类型的事件显示此属性,并且此属性为必要项。

示例:

"Name":"update.event"

类型

字符串

触发通知的事件类型。

对于所有类型的事件,都会显示此属性。

示例:

"Type": "job.created"

"Type":"process.updated"

活动 ID

字符串

发生时为每个事件生成的唯一标识符。

对于所有类型的事件,都会显示此属性。

示例:

"EventId":"3e5af0113e674ae597c579cb35ed8630"

时间戳

RFC 8601 日期

生成事件的日期和时间。

对于所有类型的事件,都会显示此属性。

示例:

"Timestamp":"2018-11-02T11:47:48.5790797Z"

租户 ID

整数

在其中生成事件的租户的 ID。默认租户为 1。

对于所有类型的事件,都会显示此属性。

示例:

"TenantId":3

用户 ID

整数

操作触发事件的用户 ID。

如果事件是由机器人或触发器触发的,则不会显示此参数。

对于所有类型的事件,都会显示此属性。

示例:

"UserId": 4947

权限

要在“Webhook”页面上执行各种操作,需要获得对 Webhook 的相应权限:

身份验证

所有 Webhook HTTP 请求都使用您在创建 Webhook 时添加的密码进行身份验证。它通过 HMAC-SHA256 键控哈希与请求正文结合在一起。这将产生一个不包含任何密码信息的安全签名,该签名对于每个请求都是唯一的,并通过 X-UiPath-Signature HTTP 标头发送。

接收 Orchestrator 请求的客户端应用程序必须检查请求的真实性。请求签名遵循以下模式:

  • 客户端应用程序收到 Orchestrator 发出的 Webhook 请求;
  • 客户端应用程序根据请求计算签名;
  • 客户端应用程序尝试将其计算的签名与请求签名进行匹配:

    • 如果签名不匹配,则客户端应用程序不应处理请求。
    • 如果签名匹配,则客户端应用程序应处理请求。

签名计算应按以下步骤完成:

  1. 检索 X-UiPath-Signature HTTP 标头。
  2. 要获取原始签名字节,请从 Base64 解码标头的值。
  3. 检索原始请求正文。

    注意:Orchestrator 请求始终使用 UTF-8 编码。
  4. 使用 SHA256 和签名密钥(UTF-8 编码)计算哈希值。
  5. 将计算得出的签名与 X-UiPath-Signature HTTP 标头中的值进行比较:
    • 如果签名不匹配,则不会处理请求。
    • 如果签名匹配,则客户端应用程序应处理请求。

签名验证示例

using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
 
 
public async Task<bool> IsValidRequestAsync(HttpRequestMessage request, string secret)
{
    if (!request.Headers.TryGetValues("X-UiPath-Signature", out var headerValues))
        return false;
 
    var orchestratorSignature = Convert.FromBase64String(headerValues.First());
    using (var sha = new HMACSHA256(key: Encoding.UTF8.GetBytes(secret)))
    {
        var computedSignature = sha.ComputeHash(await request.Content.ReadAsByteArrayAsync());
        return ByteArrayEquals(orchestratorSignature, computedSignature);
    }
}using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
 
 
public async Task<bool> IsValidRequestAsync(HttpRequestMessage request, string secret)
{
    if (!request.Headers.TryGetValues("X-UiPath-Signature", out var headerValues))
        return false;
 
    var orchestratorSignature = Convert.FromBase64String(headerValues.First());
    using (var sha = new HMACSHA256(key: Encoding.UTF8.GetBytes(secret)))
    {
        var computedSignature = sha.ComputeHash(await request.Content.ReadAsByteArrayAsync());
        return ByteArrayEquals(orchestratorSignature, computedSignature);
    }
}
const { createServer } = require('http');
const { createHmac } = require('crypto');
 
const PORT = 9090
const WEBHOOK_SECRET = '<same secret as configured in Orchestrator>'
 
const isValidRequest = (body /* Buffer */, secret /* string */, expectedSignature /* string */) =>
    expectedSignature == null || createHmac('sha256', secret)
        .update(body)
        .digest('base64') === expectedSignature
 
const server = createServer((req, resp) => {
 
    let body = new Buffer([])
 
    req.on('data', chunk => body = Buffer.concat([body, chunk]))
 
    req.on('end', () => {
 
        if (!isValidRequest(body, WEBHOOK_SECRET, req.headers['x-uipath-signature'])) {
            console.error('Invalid signature')
            resp.statusCode = 401 // Unauthorized
        } else {
 
            let payload = JSON.parse(body.toString('utf8'))
 
            // Process request
            console.log(payload)
 
            resp.statusCode = 202 // Accepted
        }
 
        resp.end()
    })
 
})
 
server.listen(PORT)const { createServer } = require('http');
const { createHmac } = require('crypto');
 
const PORT = 9090
const WEBHOOK_SECRET = '<same secret as configured in Orchestrator>'
 
const isValidRequest = (body /* Buffer */, secret /* string */, expectedSignature /* string */) =>
    expectedSignature == null || createHmac('sha256', secret)
        .update(body)
        .digest('base64') === expectedSignature
 
const server = createServer((req, resp) => {
 
    let body = new Buffer([])
 
    req.on('data', chunk => body = Buffer.concat([body, chunk]))
 
    req.on('end', () => {
 
        if (!isValidRequest(body, WEBHOOK_SECRET, req.headers['x-uipath-signature'])) {
            console.error('Invalid signature')
            resp.statusCode = 401 // Unauthorized
        } else {
 
            let payload = JSON.parse(body.toString('utf8'))
 
            // Process request
            console.log(payload)
 
            resp.statusCode = 202 // Accepted
        }
 
        resp.end()
    })
 
})
 
server.listen(PORT)
  • 通用有效负载属性
  • 权限
  • 身份验证
  • 签名验证示例

此页面有帮助吗?

获取您需要的帮助
了解 RPA - 自动化课程
UiPath Community 论坛
Uipath Logo White
信任与安全
© 2005-2024 UiPath。保留所有权利。