Webhook:Webhook 是一个「管道」,作为信息的桥梁,连接着不同的应用或系统。假设期望通过 GMP 营销平台对接某个系统,用来发 App Push,站内信、外呼触达,则可以通过这个「Webhook 管道」来实现消息的下发。
外接模版:触达模板,就是一段带占位符的字符串。对接触达模板可以使 Webhook 通道获得动态参数的能力,即可以基于触达模板中的参数动态产生多个通道参数。使得一个通道可以对接多个模板,而无需为每个模板配置一个通道,可以极大地减少重复配置和机械劳动。
触达回执:GMP 提供多种回执数据接收能力,用于接收 GMP 触达对象的后链路状态数据,通过消息 ID 机制关联到营销任务,统计营销任务的后链路分析指标(例如送达量、点击量等,业务按自身场景需求而定)。
GMP 触达任务和流程画布可以使用 Webhook 通道,其发送最小粒度是一条消息。
在 GMP 业务中一条消息应该 触达内容 + 触达对象,比如短信的内容或者 App Push 信息就是触达内容。
触达的对象则是 GMP 内的主体,可以是一个人或者一台设备。
具体场景为给某个人(对象)发送一条短信(内容)。
说明
包含 GMP 的业务流程、流程中提供的 SPI、对应系统的 API。
可选接入类型:
- 同步调用外部接口(SPI)
- 发送数据至消息队列(SPI)
- 从消息队列接收数据(SPI)
- 从 OpenAPI 接收数据(API)
- 主动轮询外部接口(SPI)
- Iframe 集成(SPI)
- 非接口类配置
节点名 | 接入类型 | 可选节点类型 | 是否必选 | 说明 |
|---|---|---|---|---|
拉取外接模版列表 | SPI |
| 否 | 如果触达通道有模板的概念(如:外呼模板等),则可以拉取触达模板,实现更加灵活的触达配置。 |
Webhook 触达 | SPI |
| 是 | 触达接口,包含的原子信息为 触达对象 + 触达内容,支持批量触达。 |
触达回执 | API 或 SPI |
| 否 | 回执接口,包含的原子信息为 触达对象 + 对象的触达后链路行为状态码,支持批量回执。 |
说明
SPI 需提供标准请求和标准响应的定义。
API 需提供 API 路径、鉴权、请求、响应的定义。
// 批量形式,单批数量<=100 { "msg_count": 1, // 本次请求的消息数量 "app_id": 1234, // 常量 "time_stamp": 1660825544000, // 请求发出的毫秒时间戳 "msg_list": [{ // 子请求列表 "send_id":"1371111123*", // 配置字段:保留字。下游接口需要的发送用户id "msg_id":"xzfasdfag", // 配置字段:保留字。发送记录id,标记每一条发送记录,用于数据回执的匹配统计(客户侧可用于幂等控制) "params":{ // 客户接口自定义所需要参数的map //"key1": "value1", // key1:自定义的keyname,value支持字符串、数值、数组、对象类型 "content": "短信内容" // 配置字段:模版参数 } },{ "send_id":"1371111123*", // 配置字段:保留字。下游接口需要的发送用户id "msg_id":"xzfasdfaf", // 配置字段:保留字。发送记录id,标记每一条发送记录,用于数据回执的匹配统计(客户侧可用于幂等控制) "params":{ // 客户接口自定义所需要参数的map //"key1": "value1", // key1:自定义的keyname,value支持字符串、数值、数组、对象类型 "content": "短信内容2" // 配置字段:模版参数 } }] }
//样例响应格式 [{ "code":0, //0表示成功 "msg":"success" //成功/失败原因 },{ "code":0, //0表示成功 "msg":"success" //成功/失败原因 }]
参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|
pageNo | 数值 | 必选 | 页号,从 1 开始。 |
pageSize | 数值 | 必选 | 页数,固定为 10。 |
key1 | 字符串 | 可选 | 模板过滤参数 key1。 |
key2 | 字符串 | 可选 | 模板过滤参数 key2。 |
{ "code":0, "msg":"success", "total":100, //模板总数量 "data":[ { "title": "密码已经重置", "template_content":"您好,您的密码已经重置为${password},请及时登录查看", "template_id":"123", "jump_url":"https://xxx" }, { "title": "送福利", "template_content":"送福利 激活好礼任您选,数量有限,先到先得", "template_id":"124", "jump_url":"https://xxx" }, { "title": "验证码", "template_content":"${111}验证码", "template_id":"125", "jump_url":"https://xxx" } ] }
API 接入形式的示例,其他形式参考 3.3.4
// 批量形式,需要配置批量响应,以及响应中数组jsonpath [ { "status_code":0, // 按状态码枚举定义 "msg_id":"xzfasdfag" // GMP下发的时候带的“消息ID”值 }, { "status_code":0, // 按状态码枚举定义 "msg_id":"xzfasdfaf" // GMP下发的时候带的“消息ID”值 } ]
[{ "code": 0, // 0代表成功,其他代表失败 "extra_msg": "xxx" // code非零时,该字段说明详细错误原因 },{ "code": 0, // 0代表成功,其他代表失败 "extra_msg": "xxx" // code非零时,该字段说明详细错误原因 }]
适用于Webhook通道对接的评估项
评估项 | 评估项解释 |
|---|---|
| 是,有模版链接:常规对接。
否:常规对接。 |
评估项 | 评估项解释 |
|---|---|
| 站内信,APP推送,短信推送,客户自定义推动服务,消息队列对接。 |
| 如何构建消息ID。 |
| 单发 or 批量。 |
评估项 | 评估项解释 |
|---|---|
| 无:不开启对接。
|
| 无法对接场景:
|
| 常规场景: 支持客户回执中多种状态的上报和漏斗展示,但是不支持源数据报文的分析。 |
| 客户的系统在推送回执后希望得到处理结果响应,以确认推送是否成功。一般需要返回200,或者指定格式数据。配置好后,请务必找接口侧验证响应正确。 |
「管理中心-通道管理-Webhook接入」,点击右侧,新建Webhook页面。
选择Webhook主体对象并确认。
进入到Webhook通道配置页面
Webhook 通道配置分四块:基础配置、外接模板配置、Webhook 请求响应配置、回执配置
配置 Webhook 名称和 Webhook 类型:
模板列表请求响应如下:
{ "code": 0, // 0为成功,其他为失败 "data": [ { "app_id": 1, // 项目id "template_type": 1, // 模板类型,1:通知类,2:营销类 "template_name": "打车通知", // 模板名称 "template_content": "【xx出行】已为您呼叫到司机${car_id}", // 模板内容 "creator": "taxi", // 创建人 "template_code": "5fukT5s5d6N" // 模板编码 }, { "app_id": 1, "template_type": 1, "template_name": "交易通知", "template_content": "【xx银行】您的账户${account_id}于${date}发生支付,金额${money}", "creator": "bank", "template_code": "5fukT5s5d6P" }, // 后续省略 ], "count": 36, // 模板总数 "msg": "", "extra_msg": "" }
从响应的内容可以看出,模板数组在 json 的 data 字段 jsonPath 应该为$.data,而模板内容在数组元素中的相对 jsonPath 则为$.template_content,模板的数量 jsonPath 则是在$.count,配置如下:
假设我们希望使用模板名称和模板类型进行搜索展示,那么query参数配置应该如下:
我们还希望列表展示模板名称,模板编号,模板类型,模版类型,那么列表展示配置如下:
模板类型配置成下拉单选框,并且设置对应的枚举类和展示名称,方便运营人员理解使用,模板列表框展示如下:
希望选择模板后展示模板内容作为填写提示,并且动态参数为${xxx}形式,模版内容字段展示配置如下:
展示如下:
需要注意的是,对于body/header/query参数配置,其参数类型可选项如图所示:
参数配置需要按照客户接口实际情况完成。
允许在客户侧拉取触达模板,实现更加灵活的触达配置。所谓触达模板,就是一段带占位符的字符串,如下所示。对接触达模板可以使 Webhook 通道获得动态参数的能力,即可以基于触达模板中的参数动态产生多个通道参数。使得一个通道可以对接多个模板,而无需为每个模板配置一个通道,可以极大地减少重复配置和机械劳动。
// 模板示例 【xx打车】司机已接单,${car},请尽快赶往上车点 尊敬的客户${username},您的礼包${gift}将于${expire_date}过期
外界模板配置界面:请求地址、鉴权方式、请求方法、Content-type、body/header/query配置、自定义请求/响应处理脚本、成功/失败响应配置等含义可见上文。
客户侧接口如下所示:
获取模版列表简要信息:(get)[/api/v1/distribution/templates/accounts/brief]
参数名 | 位置 | 含义 | |
|---|---|---|---|
tenantId | query | 客户为 GMP分配的一个常数 | |
name | query | 对模板名称进行模糊搜索 | |
code | query | 对模板编码进行模糊搜索 | |
smsType | query | 可选模板类型;1=通知类、2=营销类... | |
pageNo | query | 页码 | |
pageSize | query | 页规格 |
获取模板接口响应如下所示:
{ "status":200, // 200 = 成功; 其他 = 失败 "timeStamp":"1650450273", "data":{ "total":1, "data":[// 自定义模板列表 { "id":1, "code":"1", "name":"n1", "content":"验证码为${code};详情请点击${s_url}", "applyInfo":"123", "signature":"123", "smsType":"0", "relatedProductNum":123, "relatedAccountNum":123, "createTime":"1648520289539", "updateTime":"1648606689539" }, { "id":2, "code":"1", "name":"n1", "content":"验证码为${code};详情请点击${s_url_k}", "applyInfo":"123", "signature":"123", "smsType":"0", "relatedProductNum":123, "relatedAccountNum":123, "createTime":"1648520289539", "updateTime":"1648606689539" } ] } }
客户接口期望接收如下请求:
{ "tenantId": "xxx", "appId": "xxx", "recipient": "xxx", "templateCode": "xxx", "params": { // ... } }
其中,tenantId和appId是客户侧为GMP分配的常数;recipient用于填入目标手机号;templateCode填充客户当前选择的模板的编号;params中填充模板内容中的占位符参数。如对于示例模板,客户侧希望收到如下请求:
{ "tenantId": "xxx", "appId": "xxx", "recipient": "xxx", "templateCode": "xxx", "params": { "code": "xxxx", "s_url": "xxxx" } }
推送接口响应为:
{ "status": 200, // 200 = success; 400 = fail "error": "xxx", // 错误详情(可枚举) "data": "xxx" // 消息id }
客户侧在通道在确定用户已收到推送时,或者确定本次推送失败时,会向GMP发送回执。GMP侧固定回执路径为 [/GMP/Webhook]。
回执形式由客户自主设计,请求体中 需要至少带上两个信息:
此外也可以给出错误码或可枚举的错误信息,以便GMP进行下游错误统计与归因。
示例请求体:
{ "messageId": "xxx", // 消息id,与推送时对应。 "receiveStatus": 2, // 到达状态。2=成功;其他等于失败 "errorDetail": "xxx" // 失败详情(可枚举) }
其配置如图所示:
最终该通道的模板搜索页面,如图所示:
可查看的详细内容:
请求响应配置如下。除了基础通用配置的配置项之外,有几点需要额外介绍。
可以选择本通道是单次发送还是批量发送,如果选择批量发送,则会出现如下额外配置:
顾名思义,就是每次http请求中可携带的消息数量上限。
批量发送处理脚本的函数原型与前文的自定义请求处理脚本一致。需要注意的是,这个request是由本次发送的多个子请求组合而来,其中每个子请求都是经过请求组装和自定义请求处理脚本得到的。其组合方式为:请求头部和请求参数取自请求列表中的某一个子请求,而请求体是一个字符串数组的json编码,其中每个字符串都是一个子请求的请求体字符串。
假设客户接口请求体规范如下所示:
{ "msg_count": 1, // 本次请求的消息数量 "app_id": 1234, // 常量 "time_stamp": 1660825544000, // 请求发出的毫秒时间戳 "msg_list": [ // 子请求列表 { // ... } ] }
假设基础配置中得到的请求体是:
{ "target_id": "xxx", "messsage": "yyy" }
则批量脚本的输入中 request.Body为(假设每次发送id数为2):
[\"{\\\"target_id\\\":\\\"xx1\\\",\\\"messsage\\\":\\\"yyy1\\\"}\",\"{\\\"target_id\\\":\\\"xx2\\\",\\\"messsage\\\":\\\"yyy2\\\"}\"]
则其批量处理脚本:
function process (ctx, req) { let jsonBody = JSON.parse(req.Body) let bodyList = new Array() for (let i = 0; i < jsonBody.length; i ++) { // 输入的body是一个字符串数组,还需对每个字符串进行json解码,才能得到每个单独的请求 bodyList[i] = JSON.parse(jsonBody[i]) } let newBody = new Object() newBody.msg_count = bodyList.length newBody.app_id = 1234 newBody.msg_list = bodyList newBody.time_stamp = Date.parse(new Date()) req.Body = JSON.stringify(newBody) return req }
需要指出的是,如果不设置批量发送胶水层,则将发出的请求体是一个由所有子请求的请求体组成的json对象数组,如下所示:
[ { "targetId":"user1", "content": "content1" }, { "targetId":"user2", "content": "content2" } //... ]
类型 | 写入内容 | 样式 |
|---|---|---|
字符串 | 字符串 | |
文本 | 可以插入用户 id,用户属性,用户标签,短链 | |
数值 | 整数 | |
小数 | 小数 | |
数组 | 支持非对象 | |
对象 | 可以多层嵌套 | |
结构体数据 | map 格式,value 只支持字符串或者文本,支持在任务触达配置中手动动态添加字段 | |
日期 | 前端传当前日期 | |
日期时分秒 | 前端传当前日期时分秒 | |
图片 | 将文件上传到 minio,Webhook 字段中存储minio的链接 | |
单选下拉选择框 | 需要配置的时候添加选项,支持文本上传配置选项 | |
多选下拉选择框 | 需要配置的时候添加选项,支持文本上传配置选项 | |
单选下拉输入框 | 需要配置的时候添加选项,支持文本上传配置选项。可以在任务配置的时候新增选项 | |
多选下拉输入框 | 需要配置的时候添加选项,支持文本上传配置选项。可以在任务配置的时候新增选项 | |
动态参数 | 仅能同时选择用户 id/用户属性/用户标签 |
除此之外,还额外添加了一些参数类型:
依赖外接模版配置
如果客户在触达配置中选择了Webhook模板,则该参数的值将会由客户选择的模板参数及其值组成,至于如何组成取决于第三项下拉框的选择。假设客户接口请求体如上图中json配置所示,其选择的模板及填写的值如下图所示。
则在不同选项下产生的请求体如下:
{ "params": { "address": "xx小区菜鸟驿站", "express": "顺丰" } }
{ "params": "{\"address\":\"xx小区菜鸟驿站\",\"express\":\"顺丰\"}" }
{ "address": "xx小区菜鸟驿站", "express": "顺丰" }
当您使用Webhook模板时,可能会希望GMP在进行Webhook发送时除了带上模板占位符参数,还会希望带上当前使用的模板自身的一些属性。此时可以使用外接模板参数满足需求,只需要在配置上所需参数在模板中的jsonPath便可。比如,假设您除了外界模板占位符,还需要我们传模板的code字段的值,则可如上图进行配置。
GMP保留字机制为Webhook发送一些特殊的值预留了扩展空间,当前支持以下保留字。该列表可以持续扩展,如需扩展,欢迎联系火山引擎客户服务对接人。
消息 id | GMP 会基于 snowflake算法为每一次Webhook调用生成一个消息id,该消息id长度14字节 |
|---|---|
发送 id | 发送目标在当前通道的发送 id 类型下的id |
发送 id 类型 | 当前通道的发送 id 类型 |
任务创建人名称 | 当前触达任务/流程画布的任务创建人 |
任务所在资源组 | 当前触达任务/流程画布所在的资源组 |
任务创建人信息 | 可选参数值:
|
任务信息 | 可选参数值:
|
通道信息 | 可选参数值:
|
接口发送时间戳 | 可选参数值:
|
用户属性是一种在通道配置中配置好的动态参数,设置好后将不出现在触达配置中,减少运营配置工作,并有效规避运营过程中的错误。
打开「启用」开关,选择对应的回执通道:
或「管理中心-通道管理-Webhook-Webhook回执配置」
GMP当前支持回执处理方式:
调用方向 | 自定义回执(客户系统=>GMP) | |
|---|---|---|
回执方式 | http 推送 | 消息队列推送 |
调用方向 | GMP轮询(客户系统=>GMP) | ||||
|---|---|---|---|---|---|
回执方式 | 基于消息ID | 定时触发轮询 | 基于批次ID轮询 | 基于任务ID | 基于webhook请求 |
配置名称:
回执的名称,不能重名
成功到达配置:
jsonpath,写能判断成功的参数的路径。(如果是批量回执,是否批量=是,则这jsonpath的起始位置变成是明细数组的jsonpath的数组内子元素)
也支持「其他自定义回执配置」
失败到达配置:
jsonpath,写能判断成功的参数的路径。(如果是批量回执,是否批量=是,则这jsonpath的起始位置变成是明细数组的jsonpath的数组内子元素)
例如:
{ "code":0, "msg":"success", "data":{ "msg_id":"xxxx", "status":0 //失败非0 } }
成功失败配置样例
{ "code":0, "msg":"success", "data":[{ "msg_id":"xxxx", "status":0 //失败非0 },{ "msg_id":"xxxx1", "status":1 //失败非0 } ] }
成功失败配置样例
http推送方式配置:
消息队列推送方式:
客户系统主动将回执消息推送给GMP,可以选择通过http推送或者通过消息队列推送。两者配置内容类似。如果选择消息队列推送方式,需要额外选择该通道所消费的消息队列的配置id。
客户系统主动推送消息时,可能会存在通道复用的情况。简言之,如多个不同的回执通道的消息共用一个「物理通道」进入GMP。此时就需要为每一个通道配置一个「消息处理与判断脚本」来判断当前消息是否应当由当前回执通道进行处理
共用物理通道在此指经由同一个http接口进入GMP,或者通过同一个消息队列consumer消费进入GMP(topic、tag、consumerGroup等均相同)
举例而言,假设客户企业存在一个消息中台,GMP只能向其注册一个回执地址。该消息中台同时拥有站内信、短信、push、权益等多种用户触达能力,且均与GMP完成了webhook对接或权益对接。在GMP通过webhook通道或权益通道对用户完成任何一种触达、或者消息中台收到用户短信回复之后,消息中台均可能会向GMP主动推送对应回执,且这些回执的处理机制各不相同。但是这些回执都只能通过同一个http接口进入GMP。因此GMP需要一种可配置低代码的方式来表达如何对这些消息进行正确的分流。
基于以上例子,当客户消息中台向GMP发送一条push的回执之后,GMP会找到所有「http回执通道」(如果是通过消息队列发送,则会找到所有使用该消息队列配置的回执通道)。遍历这些通道,以当前消息为输入,逐个运行回执通道的「消息处理与通道判定脚本」,当某个通道的脚本返回true时,停止遍历,并由该回执通道的上层业务接收并处理该消息。
实际编写脚本逻辑如下:
函数参数data中包含以下字段:
字段名 | 数据类型 | 含义 |
|---|---|---|
Method | 字符串 | 请求方法 (Post 或 Get 等) |
Header | 字典 | 请求头 |
Scheme | 字符串 | url协议(http或https等) |
Host | 字符串 | 请求域名 |
Path | 字符串 | 请求url的path |
QueryParams | 字典 | 请求url中的参数 |
Body | 字符串(utf-8) | 原始请求体 |
编写该脚本时,需要基于所有可能共用物理通道的请求各方的特性进行判断,如一些关键字段的取值等。如果确认当前消息应当由当前通道处理,则为data.Hit赋值为true,在处理结束之后返回data即可。
举例而言,假设客户的回执消息结构如下所示:
{ "msg_type": "send_res", // 消息类型:send_res(发送结果,用于表征消息实际达到);user_reply(用户回复消息);coupon_write_off(权益核销) "send_channel": "sms" // 假如是消息类型是send_res,则该字段非空,可能是 sms\batch_sms\push\inbox // ... 其他字段 }
则对于push回执的回执通道,其脚本可做如下编写
function process(ctx, data) { var jsonBody = JSON.parse(data.Body) if (jsonBody.msg_type === 'send_res' && jsonBody.send_channel === 'push') { data.Hit = true } return data }
由于自定义响应生成脚本是与回执通道强绑定的,因此其只能作用于独立api;对于统一api,由于会存在多个回执通道,且所有消息处理逻辑,包括通道判定逻辑均是异步处理的,因此不支持自定义响应,此时GMP只会返回标准响应。
GMP收到客户系统的http请求后的http响应,在默认情况下,其状态码为200,其规范格式为:
{ "code": 0, // 0代表成功,其他代表失败 "extra_msg": "xxx" // code非零时,该字段说明详细错误原因 }
由于上行消息都采用异步处理,即简单进行消息封装后便塞入消息队列等待处理,因此绝大多数情况下响应都是成功的
然而在很多情况下,客户系统可能对GMP的响应存在要求,需要GMP接口的响应也符合客户系统的规范,为此,我们提供自定义响应生成脚本,支持客户基于GMP的标准响应和当前原始请求生成客户系统需要的自定义http响应。
脚本编写:该脚本的编写逻辑与其他脚本有所不同,其data数据组成如下:
{ "Header": { "xxx": "yyy" }, // 当前响应header,也是标准响应header入参。 "StatusCode": 200, //当前响应http状态码,也是标准响应http状态码入参 "Body": "xxx", // 当前响应体,也是标准响应体入参 "RawReq": { "Method": "GET", //原始请求的方法 GET/POST "Header": {}, // 原始请求的header map "Scheme": "", // 原始请求的协议(http/https) "Host": "", // 原始请求的url host "Path": "", // 原始请求的url path "QueryParams": {}, // 原始请求中的请求参数map "Body": "" // 原始请求体 }// 原始请求信息 }
示例:
假设客户主动上行数据请求体为:
userid=J10003&pwd=26dad7f364507df18f3841cc9c4ff94d×tamp=0803192020&cmd=MO_REQ&seqid=1003
要求GMP的响应格式为:
// 成功: { "cmd":"MO_RESP", "seqid":1003, "result":0 } // 失败: { "cmd":"MO_RESP", "seqid":1003, "result":-100999 }
则脚本可做如下编写:
function process(ctx, data) { // 详见dataConverter一节 var convRes = ctx.getDataConverter().bodyConv(data.RawReq.Body, 'url_encoded', 'json') if (convRes.ErrMsg !== '') { data.ErrMsg = convRes.ErrMsg return data } var jsonBodyStr = convRes.Output // 还原原始请求,取出其中用于构造自定义响应的数据 var jsonBody = JSON.parse(jsonBodyStr) // 构造新的自定义响应 var newBody = new Object() newBody['cmd'] = 'MO_RESP' newBody['seqid'] = jsonBody.seqid // 还原标准响应,基于标准响应了解当前是否处理成功 var standardJsonBody = JSON.parse(data.Body) if (standardJsonBody.code === 0) { newBody['result'] = 0 } else { newBody['result'] = -100999 } data.Body = JSON.stringify(newBody) return data }
对于http推送回执,我们提供两种接口:
data.Hit,因此如果确认消息只会通过独立 API 进入,请勿在「消息处理与通道判定脚本」中对该字段赋 true,以确保该通道屏蔽来自统一 API 的所有消息。可想而知,由于不需要遍历执行检查脚本进行确认,使用独立 API 能够得到更好的处理性能。能用独立 API 则尽量使用独立 API。/GMP/webhook:所有http推送回执消息都可以通过该API进入GMP,但必须要能够通过「消息处理与通道判定脚本」确认之后,才能被相应通道及业务逻辑处理。调用方向 | GMP轮询(客户系统=>GMP) | ||||
|---|---|---|---|---|---|
回执方式 | 基于消息ID | 定时触发轮询 | 基于批次ID轮询 | 基于任务ID | 基于webhook请求 |
GMP轮询机制的基本配置类似,都是需要一个外部接口调用基础通用配置,可通过阅读前文复习此处如何进行配置
适用于针对消息id进行单个查找的回执接口。查询重试机制:
每个消息id会在两天内不断重试,直至判定为查询成功,其重试规律与时间间隔参照RocketMQ的重试消费机制
适用于流式批量查询客户接口获取回执的场景。当前固定每分钟调用一次。GMP不维护当前游标,需要由客户接口维护。
对于更复杂的定时轮询机制欢迎与GMP产研进行探讨。
适用于按每次请求下游作为一个批次,回执数据按批次维度来查询的场景。回执查询接口根据每次请求的唯一id,返回该次请求的发送结果。批次ID,可以由GMP生成并透传给下游接口,也可以由请求下游时,由下游返回给GMP,GMP侧记录。
适用于按每个GMP侧任务作为整体的一个回执记录,通过任务id来查询该次任务下的所有回执记录
适用于特定场景下,需要定制化请求格式来查询回执数据。
支持GMP通用Webhook通过kafka/rocketMq进行发送;也支持通过kafka/rocketMq接受回执。
说明
由于GMP使用的Kafka相关依赖包存在兼容性限制,当前仅支持Kafka版本<3.1.0。当版本≥3.1.0 时,下发与回执场景均无法保证可用性;若确需使用该版本,version需要填3.1.0,且需自行测试验证。
务必不要创建两个完全一样的消息队列配置,否则无法创建producer,或无法启动consumer;即相同配置只能启动一个producer或consumer
{ "mq_type": "rocketMq", "name_svr_addr":[ "192.168.2.143:9876", "192.168.2.200:9876", "192.168.2.74:9876" ], "topic":"GMP_Webhookb_rmq", "tag":"tag1", // 有些客户会给,没给也可以不填 "credentials": { // 鉴权配置,如有鉴权设置,按照实际情况进行配置,回执配置同理 "enable": true, "access_key": "xxx", "secret_key": "xxx", "security_token": "xxxx" }, "group_name": "" // 消费组 }
2. 回执配置:
如无特殊要求,group_name应尽量彼此不同
{ "mq_type": "rocketMq", "name_svr_addr":[ "192.168.2.143:9876", "192.168.2.200:9876", "192.168.2.74:9876" ], "topic":"GMP_Webhookb_rmq_callback", "MessageSelector":{ // 有些客户会要求只消费带有某些tag的消息,此时可以在此如此配置。 "enable":true, "type":"TAG", "expression":"tag4 || tag5 || tag6"// 表示可以消费tag4或者tag5或者tag6, 根据实际要求填写,多tag可以使用||连接,表示“或” }, "group_name": "" // 消费组 }
{ "mq_type": "kafka", "send":{ "brokers":[ "192.168.2.137:9192", "192.168.2.143:9192", "192.168.2.200:9192", "192.168.2.213:9192", "192.168.2.65:9192", "192.168.2.74:9192" ], "topic":"GMP_Webhookb_send" }, "net":{ "sasl": { // 如果有开启相关kafka鉴权的话,可以在此配置,回执配置同理 "enabled": true, "mechanism": "PLAIN", // 支持PLAIN、SCRAM-SHA-256、SCRAM-SHA-512、GSSAPI "user": "xxx", "password": "xxx", // 在PLAIN、SCRAM-SHA-256、SCRAM-SHA-512模式下使用 "gssapi": { // gssapi相关鉴权配置,老实说这个模式我也没接触过,完全是照着sarama sdk开发的 // 如果业务上要用这个,也麻烦在配置的过程中,参照本文档进行配置的同时 // 也找相关GMPRD一同联调 // 感谢您与GMP一同成长 -- niezhicheng "auth_type": "KRB5_USER_AUTH", // 支持KRB5_USER_AUTH、KRB5_KEYTAB_AUTH "key_tab_path": "", "kerberos_config_path": "", "service_name": "", "username": "xxx", "password": "xxx", "realm": "xxx", "disable_pafxfast": "xxx" } } }, "version":"2.1.0" // kafka版本,可以先默认这个 }
2. 回执配置:
如无特殊要求,不同消息回执配置中的group应尽量不同
{ "mq_type": "kafka", "listen":{ "brokers":[ "192.168.2.137:9192", "192.168.2.143:9192", "192.168.2.200:9192", "192.168.2.213:9192", "192.168.2.65:9192", "192.168.2.74:9192" ], "topics":["GMP_Webhookb_callback"], "group": "" }, "version":"2.1.0" // kafka版本 }
如果在Webhook请求时,下游通道需要有接口鉴权,Webhook支持多种鉴权能力。
通过对秘钥进行加密处理后,传给下游接口,支持MD5_32,SHA-1,SHA-256,HMAC-SHA256加密算法,以及通过自定义Javascript脚本加密
将秘钥进行base64处理
let sourceString = "Hello World" let Crypto = require("crypto-js") let wordArray = Crypto.enc.Utf8.parse(sourceString) // 将字符串转换成 WordArray 类型 let base64String = Crypto.enc.Base64.stringify(wordArray) // Base64
支持将用户名,密码通过basic-auth处理后,放入请求体的header/query中,进行请求鉴权
如果下游接口需要先通过账密等数据,先请求一个接口,获取到鉴权信息(token/cookie),再将鉴权信息给Webhook通道做鉴权。则需要使用Oauth2.0鉴权。
在此情景下需要提供携带的用户id的id类型,及其在消息体中的jsonpath
需要注意的是,由于用户id匹配涉及到扫描对该用户的所有发送记录,因此当前存在性能问题,每秒的处理qps大约只有20。GMP会对收到的这类上行消息通过消息队列进行异步处理,因此可能会存在上报延迟,这一点需要客户知悉。该问题将在后续版本优化。
说明
GMP 侧定义的请求&响应协议,适用对象:新开发接口服务,且想按照 GMP的协议来开发接口服务的客户
最基本的接口下发格式
{ "send_id":"123456", //下游接口需要的发送用户id "msg_id":"xzfasdfag", //发送记录id,标记每一条发送记录,用于数据回流的统计 "param1":"param1" //下发的内容参数 }
//样例响应格式 { "code":0, //0表示成功 "msg":"success" //成功/失败原因 }
启用回执之后,选择需要的回执配置,基本的回执配置可以看下面的【样例回执】
【样例回执】格式,客户端请求GMP的格式
{ "status_code":0, //0表示到达成功,非0表示到达失败 "msg_id":"xzfasdfag" //GMP下发的时候带的msg_id值 }
通道配置使用默认配置
GMP响应格式为
{ "code": 0, // 0代表成功,其他代表失败 "extra_msg": "xxx" // code非零时,该字段说明详细错误原因 }
保存后,得到回执接口地址,拼上GMP域名之后,即可使用