事件通知

启用事件通知

平台授权模式:联系我们开通并提供事件通知回调地址,例:https://www.example.com/smb/callbacks

客户端授权模式:获取 access_token 时传入事件通知回调地址 callback_uri

事件通知回调格式

消息通知回调以 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
}

条 "" 的搜索结果

    没有 "" 的搜索结果