You need to enable JavaScript to run this app.
导航
事件推送
最近更新时间:2024.11.01 14:03:09首次发布时间:2024.11.01 14:03:09

事件推送是指火山引擎内容定制服务调用客户提供的接口,推送变更事件。

请求方式

  • HTTPS
  • Method:POST
  • Content-Type:application/json

签名校验

客户侧通过检验 signature 对请求进行校验(下面有校验方式),以确认请求来自内容定制系统。

签名参数

参数描述

timestamp

unix时间戳,单位:秒。为保证安全,与当前时间戳绝对值不要超过3600s。
从请求头中获取,键为:X-Content-Timestamp

nonce

请求随机串。随机串长度为6-32位数字和字母的组合,大小写敏感。
从请求头中获取,键为:X-Content-Nonce

signature

签名字符串。
从请求头中获取,键为:X-Content-Signature

payload业务数据。请求体body字节流。
secret_key鉴权密钥。客户侧可以在内容定制平台的【内容同步】页面,点击【同步配置】的【回调配置】查看。

签名算法

Hmac_SHA256算法

签名步骤

  1. 将 timestamp、nonce 和 payload 依次进行拼接;

  2. 使用 secret_key 对上述拼接的字符串进行 hmac sha256 加密,然后转成十六进制字符串 ;

  3. 得到加密后的字符串可与 signature 对比,标识该请求来源于内容定制的内容事件推送。

签名示例

检验signature的Java示例代码:

public static String genSignature(String timestamp, String nonce, String body, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
    // 按照 timestamp,nonce,body 顺序拼接签名字符串
    String signatureStr = timestamp + nonce + body;
    // 进行 hmac sha256 加密
    Mac hmacSha256 = hmacSha256 = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
    hmacSha256.init(secretKeySpec);
    byte[] signatureBytes = hmacSha256.doFinal(signatureStr.getBytes(StandardCharsets.UTF_8));
    // 将 sha256 字节数组转成16进制字符串
    StringBuilder signatureBuilder = new StringBuilder();
    for (byte signatureByte : signatureBytes) {
        String hex = Integer.toHexString(signatureByte & 0xFF);
        if (hex.length() == 1) {
            signatureBuilder.append('0');
        }
        signatureBuilder.append(hex);
    }
    return signatureBuilder.toString();
}

检验signature的Go示例代码:

func GenSignature(timestamp, nonce, body, secretKey string) string {
    // 按照 timestamp,nonce,body 顺序拼接签名字符串
    signatureStr := timestamp + nonce + body
    // 进行 hmac sha256 加密
    hmacSha256 := hmac.New(sha256.New, []byte(secretKey))
    hmacSha256.Write([]byte(signatureStr))
    // 将 sha256 字节数组转成16进制字符串
    signature := fmt.Sprintf("%x", hmacSha256.Sum(nil))
    return signature
}

请求参数

请求方指“火山引擎-内容定制”。

KEYVALUE/说明
MethodPOST
Content-Typeapplication/json
X-Content-Timestampunix时间戳(单位:秒)
X-Content-Nonce随机串(6-32位数字、字母组成)
X-Content-Signature回调签名(生成逻辑见上文)

Body

  • 事件结构见事件章节

  • 事件具体枚举件POI事件和内容事件部分

响应参数

响应方指“客户侧”。

字段名字段类型说明
retnumber响应状态码。0-成功;非0-失败,并在msg中补充说明。
msgstring响应信息。例如:成功时提供"success";失败时提供失败相关信息。

请求示例

POST / HTTP/1.1
Host: xxx.xxx.xxx
Content-Type: application/json
X-Content-Timestamp: 1690366367
X-Content-Nonce: kfcv50
X-Content-Signature: 2d3891cee3dcc777ba27a29f70758c581e93f21f3dad1deeaadf11aa440fe4b2
Body: ${参考事件章节中的事件结构部分}

注意: 这里的Body应该作为一个字符串接收。不要利用引入的SDK或者框架的能力作为一个JSONObject接收,再转为字符串,这样可能导致Body的字符串内容不一致,从而导致签名计算出来的最终结果不一致。

响应示例

客户侧服务端返回给火山引擎侧的响应数据

{
    "ret": 0, // 响应状态码
    "msg": "success" // 响应信息
}
事件

公共部分

[{
    "Product": "interest_map", // 业务线,本场景中统一为interest_map
    "EventId": "7339149900963496457", // 事件唯一ID
    "EventType": "poi_created", // 事件类型
    "EntityType": "poi", // 事件主体
    "EntityId": "7339149900963496450", // 事件主体ID
    "EventTimeMillisec": "1708940969000", // 事件产生时间
    "EventData": "" // 事件数据,经过序列化后的事件结构体,不同事件类型下不同
}]

领域事件

领域事件事件结构说明备注

POI

POI新增

{
    "Product": "interest_map",
    "EventId": "7339149900963496457",
    "EventType": "poi_created",
    "EntityType": "poi",
    "EntityId": "7339149900963496450",
    "EventTimeMillisec": "1708940969000"
}
  • 建议处理方式:重新拉取POI做添加

POI变更

{
    "Product": "interest_map",
    "EventId": "7339149900963496457",
    "EventType": "poi_updated",
    "EntityType": "poi",
    "EntityId": "7339149900963496450",
    "EventTimeMillisec": "1708940969000"
}
  • 建议处理方式:重新拉取POI做更新覆盖

POI移除

// Event
{
    "Product": "interest_map",
    "EventId": "7339149900963496457",
    "EventType": "poi_removed",
    "EntityType": "poi",
    "EntityId": "7339149900963496450",
    "EventTimeMillisec": "1708940969000"
}
  • 建议处理方式:从系统中移除该POI

  • 注意:内容变更不会引起POI变更事件