目录
此内容是否有帮助?

# Webhook 通道接入文档

# 简介

TE 运营模块的 Webhook 通道 定义了一种 API,其目的是在于连接下游客户方任何消息或类消息系统。

客户经过较为轻量的 REST API 对接开发,即可快速支持非 TE 运营模块内置的触发通道。

具体的调用链路参考下图:

  1. 首先 TE 运营模块(Engage)会读分析模块(Analytics)事件数据和用户数据,进行目标人群的计算。
  2. 结合目标人群,并且组装好消息的内容。TE 运营模块会分批发 HTTP 请求到您配置的一个 webhook 服务。
  3. 您自身的 webhook 服务接收到 http 的调用,获取到请求内容之后,可自行做格式转化、拼接其他业务数据,入异步处理队列 等操作,并最终调用其他任何内部或外部的消息/类消息系统,可能调用的系统举例:
  • 游戏邮件系统
  • 游戏公告系统
  • 封号系统
  • 短信系统
  • 第三方推送系统
  1. 处理完成之后(不包括异步处理流程),按照约定格式返回本次请求的处理结果,如果有处理失败的数据,明确标识序号和失败原因。
  2. 回执事件数据回收(可选)
  • 如果推送到游戏的邮件系统,那么可以在 游戏 App 的邮件中,埋上邮件的打开事件,使 TE 能得到点击推送的回执事件,便于后续的转化效果分析。

# Webhook 服务

为与 TE 运营模块的 Webhook 对接,您需要开发一个 HTTP Endpoint Server。其应遵循的 API 定义见下文。

# 入参出参格式定义

# Webhook Request

服务的入参,由 TE 运营模块构造生成,采用 POST 方式,Content-Type 设定为 application/json。请求体 request_body 是一个 JSONArray,支持一批次发送多条消息数据。 每条消息数据,代表给一个用户发送一个特定内容的消息。

参数示例如下:

// 请求入参格式
[
    {"push_id":"3e156c91-f039-4d48-9b6f-72b76111af24","custom_params":{"gameuid":"123acb123","name":"张三",...},"params":{"title":"每日活动",...},"#ops_receipt_properties":{"ops_task_id":"0050",...}}
    ,{"push_id":"5c190470-d81e-4f8e-841a-fe19b95ae47a","custom_params":{"gameuid":"123acb123","name":"李四",...},"params":{"title":"每日活动",...},"#ops_receipt_properties":{"ops_task_id":"0050",...}}
]

// 具体每条消息的入参格式
{
    //发送id,webhook通道的推送id
    "push_id": "3e156c91-f039-4d48-9b6f-72b76111af24",
    //模板参数,此参数下的具体参数内容可以在'TE运营模块-通道管理'侧定义
    "params": {
        "title": "每日活动",
        "content": "你好张三,快来参加活动吧!",
        //对象组
        "attachment": [
            {
                "item_id":"xx1",
                "count":"5"
            },
            {
                "item_id":"xx2",
                "count":"10"
            }
        ]
    },
    //自定义参数,可以带出用户属性,此参数下的具体参数内容可以在'TE运营模块-通道管理'侧定义
     "custom_params": {
         "gameuid":"123acb123",
         "name": "张三"
    },
    //通道回执属性,此参数由TE运营模块系统默认添加,用于后续数据统计,业务侧无需解析,透传到下游即可。下游上报时注意把这个json对象直接上报,不要toString之后再上报
    "#ops_receipt_properties": {
        "ops_request_id": "f7b66eb7-3363-4a46-a402-601a64b45f76",
        "ops_task_id": "0050",
        "ops_task_instance_id": "31",
        "ops_project_id": 1
    }
}
参数名 参数类型 是否必填 参数描述 备注
push_id
String

推送ID
具体参数字段可以在'TE运营模块-通道管理-推送ID'侧定义
params
Object

模板参数
需要在推送时候由运营填写的一些通道参数,比如推送的内容。
具体参数内容可以在'TE运营模块-通道管理-模板参数'侧定义
custom_params
Object

自定义参数
需要由系统自动带出的推送目标用户的用户属性
具体参数内容可以在'TE运营模块-通道管理-自定义参数'侧定义
#ops_receipt_properties
Object

TE运营模块回执字段
TE运营模块系统默认添加
下游系统如果需要观测消息点击率,则需要在点击事件中直接透传上报此字段
转化事件中,无需上报此字段

模板参数,自定义参数的 Key 的命名规范:采用下划线分隔命名,参数由字母数字下划线组成,且带头字符只能是下划线和字母

注意:在 params 和 custom_params 的参数中,对于任何类型的数据(如整数,小数,日期等类型),在发送请求时,所有的字段全部转为字符串进行处理

# Webhook Response

参数示例如下:

{
    "return_code": 0,
    "return_message": "success",
    "data": {
        // fail_list里面的每个元素是失败的对象信息,包含报错信息及报错对象的序号,报错对象序号从1开始。假设:发送5个对象信息,序号为1-5,成功3个失败2个,其中第2个和第4个失败,则返回如下
        "fail_list": [{
            "index": 2
            "message": "需要推送的玩家token信息不存在",
        }, {
            "index": 4
            "message": "push id not found",
        }]
    }
}
参数名 参数类型 是否必有 参数说明
return_code
Integer

返回码
0 代表成功(或者部分成功)
1 代表失败
return_message
String

返回信息
data
Object

返回数据
data.fail_list
Array

假如return_code=0,
data.fail_list为[]或null时,会认为全部成功
data.fail_list不为空,则为部分失败,失败的明细为list里定义的。
如果业务上不存在部分失败的情况,直接传[]就行;
注意:一些不可用的PushId校验,建议在接口处理逻辑里面做前置校验,以便在fail_list里返回给数数。这会让任务的触发成功指标统计更加准确。
失败列表里的对象index属性代表序号,编号从1开始,不是从0开始!假如return_code=1,无论data.fail_list里传了什么,都认为全部失败。

# 请求鉴权

如果 webhook 要支持鉴权,则 Server 端还要实现一段签名校验的逻辑。发送端会将签名添加到 http 头文件中,Key 为 X-TE-OPS-Signature。

服务端需要根据密钥与 Request Body 进行HmacSHA1签名并生成 signature,然后和服务端的签名进行比对,比对一致代表认证通过。

签名算法的 Java 实现如下:

import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
/*
   HmacSHA1签名算法

   secretKey是客户配置的密钥
   requestBody是请求内容的JSONString
*/
public static String HmacSHA1(String secretKey,String requestBody) throws Exception {
    String signature = (new HmacUtils(HmacAlgorithms.HMAC_SHA_1,secretKey)).hmacHex(requestBody)
    return signature;
}

# 请求并发性能

为了保证消息推送速度,webhook 服务支持的并发越高越好,建议可以支持 100 以上 TPS。同时,数数的智能运营模块可以按照下游 webhook 服务的并发能力上限,进行相应的限流配置。

# 请求和结果完整测试例子

// 请求信息
curl -X POST "http://localhost:8999/v1/hermes/webhook/test/sample"
-H "accept: */*"
-H "X-TE-OPS-Signature: 2e1ee1eeaDA121"
-H "Content-Encoding: gzip"
-H "Content-Type: application/json"
-d "[{\"push_id\":\"3e156c91-f039-4d48-9b6f-72b76111af24\",\"costom_params\":{\"name\":\"张三\"},\"params\":{\"title\":\"每日活动\",\"content\":\"你好张三,快来参加活动吧!\"},\"#ops_receipt_properties\":{\"ops_task_id\":\"0050\",\"ops_request_id\":\"f7b66eb7-3363-4a46-a402-601a64b45f76\",\"ops_task_instance_id\":\"31\",\"ops_project_id\":1}}]"

// 返回结果
{
  "data": {
      "fail_list": []
  },
  "return_code": 0,
  "return_message": "success"
}

# Webhook 通道可配置参数介绍

以下参数默认后台配置,如需修改可联系数数科技客户成功

配置项
可选值
默认值
配置描述
发送限流
-1,[1,10000]
不限流
单位:次/秒
设置为-1,代表不限流
设置为1-10000的数字,例如500,代表下游webhook服务器每秒钟最多接受500次请求
发送批大小
[1,500]
100
表示一次调用参数的JsonArray里包含多少个元素
批次大小设置大,可以提高发送的效率
批次大小设置小,发送速度会比较慢,但是在极端异常情况下的发送准确度上会提升
用户量不大,对推送的准确度有要求的情况下,推荐设置为1
用户量较大(>500w),对推送的速度有要求的情况下,推荐设置为100,最大设置为500
超时时间
[0,600]
60
单位:秒
http请求socket超时时间,默认是60s
如果设置了<=0,相当于不超时
失败重试次数
[0,10]
0
为了避免业务上重复推送,默认0次,即不重试
如果配置了>0的值,当接口超时或者接口返回return_code!=0会走重试逻辑
失败重试时间间隔
[0,600]
5
单位:秒
默认5s
返回值强校验
开启,不开启
开启
开启后,TE运营模块服务会校验下游服务器返回的response的格式,如果不符合上面webhook response参数定义规范认为失败
例子:假设超时时间设置为5s
如果不开启返回值强校验,webhook服务在5s内正常返回,且返回值HTTP 200 无 Body,TE运营模块认为本次调用成功
如果开启返回值强校验,webhook服务在5s内正常返回,且返回值HTTP 200 无 Body或者Body格式和约定的规范不一致,TE运营模块认为本次调用失败

# 通道配置页面示例

参数 说明 备注
通道名称
Webhook的名称(用于显示、选择)
唯一性校验
通道URL
接收消息推送的接口地址
支持同一个URL地址配置多个通道
发送ID
接收消息的目标用户ID类型,比如发送邮件用到的是用户的角色ID(role_id)
发送ID需要作为用户属性上报
在目标用户人数预估时会过滤发送ID为空的用户
通道鉴权
webhook鉴权方式
可选开启,目前支持Token密钥
触达漏斗设置
漏斗步骤关联的元事件名
可选开启
内容模板
该通道发给用户的具体内容的模板,支持文本、动态文本、数值和对象组等字段类型,如发送邮件通道可以通过对象组类型配置道具内容(道具ID和道具数量),在触达任务前端页面展示出来,供配置运营任务的的运营人员填写
字段:参数的名称,发送时消息体使用
字段名称:在创建任务的时候展示的字段
字段类型:文本、动态文本、数值和对象组等
提示文案:在创建任务的时候输入框提示(非必填)
是否必填:是/否(单选,默认是)
自定义参数
根据通道要求选择性添加,该参数为透传
非必填
字段: 参数的名称,发送时消息体使用
关联字段:字段关联的用户属性,发送消息体时字段值使用该属性值默认值: 可选,已设置默认值,当属性值为空时使用默认值;未设置默认值,属性值为空时返回空值

# 采集点击推送事件

通过 webhook 通道推送的消息可以按需在客户端/服务端采集点击事件,采集方式可参考数数数据接入手册中的上报事件的方式,事件名可以自定义,事件数据需要获取 webhook 下发消息中的 #ops_receipt_properties 字段并且整体作为一个对象属性上报即可。

注意:属性字段名一定是 #ops_receipt_properties,类型是对象,不可随意更改。改了字段名,修改了字段内部的内容或者误把字段作为一个文本属性上报,都会导致后续数据使用异常

代码示例:

JSONObject properties = new JSONObject();
//从webhook下发的message消息体中获取到json结构的#ops_receipt_properties对象,整体作为一个对象属性上报
JSONObject opsReceiptProperties = message.get("#ops_receipt_properties")
//注意:属性名必须是#ops_receipt_properties,不可随意更改。事件名可以自定义
properties.put("#ops_receipt_properties",opsReceiptProperties);
//properties对象内容示例: "#ops_receipt_properties":{"ops_task_id":"0062","ops_project_id":2,"ops_task_instance_id":"62","ops_request_id":"967ea854-2c42-490b-9c33-c1792ea637ec"}
instance.track("ops_push_click",properties);