菜单

Webhook触发任务

标签:webhook ,api ,api

功能介绍

什么是Webhook

Webhook是一种web回调或者http的push API,是向APP或者其他应用提供实时信息的一种方式。是一种基于 HTTP 的回调函数,可在 2 个应用编程接口(API)之间实现轻量级的事件驱动通信。

八爪鱼RPA的Webhook有什么功能

八爪鱼RPA可以针对每个RPA应用生成不同的Webhook接口,您可以在自己的业务系统里通过代码调用这个Webhook接口,触发对应的应用,让其在指定的机器人上运行;同时支持修改应用中的自定义变量。目前该接口的请求频率是:每秒最多5次,每分钟最多20次。

简单说就是:启动应用,修改应用中的参数。

如何创建Webhook

在使用Webhook之前,我们首先需要通过【触发器】栏目下的Webhook触发任务来创建Webhook,具体操作如下图:

 

之后填写触发器名称=>指定运行的机器人=>选择要运行的应用=>点确定

创建成功后我们就能看到Webhook的信息

到这里Webhook触发器就传建好了,我们可以把Webhook地址签名复制下来,放到调用触发器的代码了面,同时需要勾选上启动触发器,这样Webhook才能生效。

如何调用Webhook

Webhook接口接收的Json格式的数据,Json格式为

{
    "sign": "timestamp + "\n" + 签名校验",  //注释:时间戳与签名进行算法加密,即将timestamp + "\n" + 密钥 当做签名字符串;先使用 HmacSHA256 算法计算签名,再进行 Base64 编码。
    "params": {
        "应用参数1": "被触发任务任务的自定义参数",
        "应用参数2": "被触发任务任务的自定义参数"
    },
    "SpecifiedBot":"机器人Id",
    "timestamp": "当前时间的时间戳"
}
 

sign为签名校验,可以为空,当Webhook触发器的安全设置没有勾选使用签名校验时,该sign的值为空。

params为需要传递给应用的启动数据,同样为Json,其中Key为对应用的某一个自定义变量名称,Value为需要传递的变量值。

SpecifiedBot用于指定应用到特定的机器人上运行

timestamp为当前时间的时间戳(秒)。

 

例如下面这个应用为例:

如何传递传递参数

我们通过Webhook启动这个应用,同时需要把变量1变量2变量3的的值通过webhook传递过来,此时请求的Json数据为

{
    "sign": "时间戳与签名进行算法加密,即将timestamp + "\n" + 密钥当做签名字符串,使用 HmacSHA256 算法计算签名,再进行 Base64 编码",
    "params": {
        "变量1": "AAA",
        "变量2": "BBBB",
        "变量3": 10,
    },
    "timestamp": "当前时间的时间戳"
}
 

这是应用的运行结果为弹出两个弹窗框,其中第一的标题和内容为:“AAA”和“BBBB”,第二个为:“计算”和“5

 

如何获取机器人Id

  • 客户端上切换到企业身份->打开管理后台

  • 打开机器人管理界面-> 点开详情

  • 在机器人详情页面复制机器人Id

 

调用Webhook的示例代码

C#示例代码

//.net6 及以上平台示例代码
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using WebhookDemo.Dtos;
var key = "替换为校验签名";
var url = "Webhook地址";
using var client = new HttpClient();
try
{
    var @params = new Dictionary<string, object>
    {
        { "应用参数1", "参数1的值" },
        { "应用参数2", "参数2的值" }
    };
    var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
    var rpaWebhook = new RpaWebhookDto(
        timestamp.ToString(),
        GetSign(key, timestamp),
        @params);
    var result = await client.PostAsync(url,
        new StringContent(JsonSerializer.Serialize(rpaWebhook), Encoding.UTF8, "application/json"));
    if (result.IsSuccessStatusCode)
    {
        Console.WriteLine("调用成功");
        return;
    }
    var res = JsonSerializer.Deserialize<WebhookInvokeFailureDto>(
        await result.Content.ReadAsStringAsync(),
         new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
    );
    Console.WriteLine("调用失败");
    Console.WriteLine($"失败原因:{res!.Description}");
    Console.WriteLine($"失败Code:{res!.Code}");
}
catch (Exception ex)
{
    Console.WriteLine($"Exception:{ex.Message}");
    throw;
}
static string GetSign(string secret, long timestamp)
{
    string stringToSign = timestamp + "\n" + secret;
    using HMACSHA256 hmac = new(Encoding.UTF8.GetBytes(stringToSign));
    byte[] signData = hmac.ComputeHash(Array.Empty<byte>());
    return Convert.ToBase64String(signData);
}
namespace WebhookDemo.Dtos
{
    public sealed record RpaWebhookDto(
        string Timestamp,
        string Sign,
        Dictionary<string, object>? Params
    );
    public sealed record WebhookInvokeFailureDto(
        string Code,
        string Description,
        string? RequestId
    );
}
 

Python示例代码

import requests
import json
import hashlib
import hmac
import base64
import time

key = "替换为校验签名"
url = "Webhook地址"

payload = {
    "应用参数1": "被触发任务任务的自定义参数",
    "应用参数2": "被触发任务任务的自定义参数"
}

timestamp = str(int(time.time()))

def get_sign(secret, timestamp):
    string_to_sign = timestamp + f"\n" + secret
    sign_data = hmac.new(string_to_sign.encode(),None, hashlib.sha256).digest()
    return base64.b64encode(sign_data).decode()

rpa_webhook = {
    "timestamp": timestamp,
    "sign": get_sign(key, timestamp),
    "params": payload
}

try:
    headers = {'Content-Type': 'application/json'}
    response = requests.post(url, data=json.dumps(rpa_webhook), headers=headers)
    if response.status_code == 200:
        print("调用成功")
    else:
        res = response.json()
        print("调用失败")
        print(f"失败原因:{res['description']}")
        print(f"失败Code:{res['code']}")
except Exception as ex:
    print(f"Exception: {ex}")
    raise

 

Java 示例代码

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Instant;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

import com.google.gson.Gson;

public class Main {
    static HttpClient client = HttpClient.newHttpClient();

    public static void main(String[] args) throws NoSuchAlgorithmException, IOException, InterruptedException {
        String key = "替换为校验签名";
        String url = "Webhook地址";

        long timestamp = Instant.now().getEpochSecond();
        String sign = getSign(key, timestamp);

        Map<String, Object> params = new HashMap<>();
        params.put("应用参数1", "参数1的值");
        params.put("应用参数2", "参数2的值");

        RpaWebhookDto rpaWebhook = new RpaWebhookDto(Long.toString(timestamp), sign, params);

        String requestBody = new Gson().toJson(rpaWebhook);

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        if (response.statusCode() == 200) {
            System.out.println("调用成功");
            return;
        }

        WebhookInvokeFailureDto res = new Gson().fromJson(response.body(), WebhookInvokeFailureDto.class);
        System.out.println("调用失败");
        System.out.println("失败原因:" + res.getDescription());
        System.out.println("失败Code:" + res.getCode());
    }

    static String getSign(String secret, long timestamp) {
        String stringToSign = timestamp + "\n" + secret;
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKeySpec = new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            mac.init(secretKeySpec);
            byte[] result = mac.doFinal();
            return Base64.getEncoder().encodeToString(result);
        } catch (Exception e) {
            throw new RuntimeException("getSign error", e);
        }
    }

    static class RpaWebhookDto {
        String Timestamp;
        String Sign;
        Map<String, Object> Params;

        public RpaWebhookDto(String timestamp, String sign, Map<String, Object> params) {
            Timestamp = timestamp;
            Sign = sign;
            Params = params;
        }
    }

    static class WebhookInvokeFailureDto {
        String Code;
        String Description;
        String RequestId;
    }
}
上一个
本地触发任务
下一个
API接口
最近修改: 2024-05-28