WebhookWebhook 消息订阅是从 KOOK 获取事件的另一种方式。在用户量较多的情况下,Webhook 可以提供更好的并发性能。 你需要做的只是告诉我们该向哪里(URL)发送消息。当消息发生时,KOOK 开放平台会以 HTTP POST 请求的方式将消息内容推送到你设置的回调地址。
配置 Webhook配置 WebHook 回调地址在 Webhook 模式下,为了能够接收推送消息,你必须在开发者后台配置回调地址。 当 KOOK 中发生了你的机器人应该得到的事件时,开放平台会向该回调地址发送相应的
处理 Challenge 请求点击 '重试' 按钮或上线机器人时,开放平台将会向你配置的网址推送一个
{
's': 0, // 信令类型
'd': {
'type': 255,
'channel_type': 'WEBHOOK_CHALLENGE', //表示这是一个验证请求
'challenge' : 'bkes654x09XY' , //客户端需要原样返回的 Challenge 值
'verify_token': 'xxxxxx', //机器人的 verify token(不是机器人用于访问 KOOK HTTP API 的 token,请注意分辨)
}
}
当你收到开放平台 POST 验证请求时,你需要解析出
{
'challenge': 'bkes654x09XY' // 应用需要原样返回的值,这只是示例
} 接收并响应事件当有消息发生时,开放平台将会通过 HTTP POST 请求发送 json 格式的事件数据到你预先提供的回调地址。 注意事项
消息格式及说明参见事件格式说明 配置消息加密如果你对消息有较高的安全需求,可以通过 Encrypt Key 来加密数据。 配置消息加密的 Encrypt Key
当你配置好消息加密,你收到的请求内容应该是这样子的:
解密消息事件消息采用了 aes-256-cbc 算法来加密数据。主要解密逻辑如下
注意! 即使你配置了消息加密,在没有通过上文提供的方法停用压缩时,KOOK 开放平台仍会在已加密的消息上再做一次压缩。 代码示例Python 代码示例from Crypto.Cipher import AES
import base64
class Encrypt:
def __init__(self, key, bs=32):
pad = lambda s: s + (bs-len(s))*'\0'
key = pad(key)
self.key = key.encode('utf-8')
def aes_decrypt(self, content):
str = base64.b64decode(content)
iv = str[0:16]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return cipher.decrypt(base64.b64decode(str[16:])).decode('utf-8') PHP 代码示例
C# 代码示例using System.Security.Cryptography;
using System.Text;
namespace YourBot
{
public class CryptUtil
{
public static string Decrypt(string data, string encryptKey)
{
// 在 encrypKey 右侧填充 \0 到 32 位
encryptKey = encryptKey.PadRight(32, '\0');
// 用 base64 解析原密文
var originCipher = Encoding.UTF8.GetString(Convert.FromBase64String(data));
// 取前 16 位为 iv,16 位后的文本为新密文
var iv = originCipher.Substring(0, 16);
var newCipher = originCipher.Substring(16);
// 用 base64 解密新密文
var newCipherByte = Convert.FromBase64String(newCipher);
// 使用 aes-256-cbc 解密数据
using (var aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(encryptKey);
aes.IV = Encoding.UTF8.GetBytes(iv);
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (var memoryStream = new MemoryStream(newCipherByte))
using (var csDecrypt = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
using (var reader = new StreamReader(csDecrypt))
return reader.ReadToEnd();
}
}
}
} Java 代码示例
|
|