事件通知
启用事件通知
平台授权模式:联系我们开通并提供事件通知回调地址
客户端授权模式:获取
access_token
时传入事件通知回调地址callback_uri
, 或在团队设置->第三方应用->添加第三方应用时填入事件推送URL
事件通知回调格式
消息通知回调以 HTTP/HTTPS POST 请求发送给你的服务器,请求的body
格式为 JSON。字符编码为 UTF-8。
消息通知回调的header
中包含以下字段:
字段名 | 值 |
---|---|
Content-Type | application/json |
Smb-Signature | 签名值 |
消息通知回调的body
中包含以下字段:
字段名 | 类型 | 描述 |
---|---|---|
event | String | 事件类型,例: "interview_ended" |
ts | integer | 消息通知服务器向你的服务发出回调请求的 Unix 时间戳,单位为秒,例:1593676655。 Note:通知重试时会更新该时间。 |
tid | integer | 团队id |
payload | JSON Object | 事件内容 |
重试机制
当事件推送请求收到非 httpCode 200 的请求结果时,系统会触发重试机制,最多重试三次,间隔分别为 15s, 15s, 30s
验证签名
使用 client_secret 作为秘钥,基于 HMAC/SHA1 算法对包体做散列得到字符串,转大写得到 Smb-Signature 签名 ,验证签名时你可以参考如下代码:
Ruby 版
# 拿到事件通知的 raw requestion body(反序列化之前的binary byte array) 并对其计算签名
requestion_body = '{"event":"interview_ended","ts":1593676655,"payload":{"uid":"ABCDEF","rate":5}}'
secret = 'secret'
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), secret, requestion_body).upcase
p signature # => 9B3EF6548095106634DA41E326747C0251761C62
Java 版
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class HmacSha {
// 将加密后的字节数组转换成字符串
public static String bytesToHex(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() < 2) {
sb.append(0);
}
sb.append(hex);
}
return sb.toString();
}
//HMAC/SHA1 加密,返回加密后的字符串
public static String hmacSha1(String message, String secret) {
try {
SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes("utf-8"), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(message.getBytes("utf-8"));
return bytesToHex(rawHmac);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
//拿到事件通知的 raw requestion body(反序列化之前的binary byte array) 并对其计算签名
String request_body = "{\"event\":\"interview_ended\",\"ts\":1593676655,\"payload\":{\"uid\":\"ABCDEF\",\"rate\":5}}";
String secret = "secret";
System.out.println(hmacSha1(request_body, secret).toUpperCase()); //9B3EF6548095106634DA41E326747C0251761C62
}
}
Golang 版
package main
import (
"crypto/hmac"
"crypto/sha1"
"fmt"
"strings"
)
func HmacSha1(data string, secret string) string {
h := hmac.New(sha1.New, []byte(secret))
h.Write([]byte(data))
return string(h.Sum(nil))
}
func CheckSig(sig string, rawData string, secretKey string) bool {
hashed := fmt.Sprintf("%x", HmacSha1(rawData, secretKey))
return strings.ToUpper(hashed) == sig
}
func main() {
str := "{\"event\":\"interview_ended\",\"ts\":1593676655,\"payload\":{\"uid\":\"ABCDEF\",\"rate\":5}}"
secret := "secret"
sign := "9B3EF6548095106634DA41E326747C0251761C62"
fmt.Print(CheckSig(sign, str, secret)) // true
}