You need to enable JavaScript to run this app.
文档中心
增长营销平台

增长营销平台

复制全文
下载 pdf
webhook通道接入配置文档
【最新 GMP v5.11.0 以上】Webhook通道接入
复制全文
下载 pdf
【最新 GMP v5.11.0 以上】Webhook通道接入

1. 简介

1.1 名词解释

Webhook:Webhook 是一个「管道」,作为信息的桥梁,连接着不同的应用或系统。假设期望通过 GMP 营销平台对接某个系统,用来发 App Push,站内信、外呼触达,则可以通过这个「Webhook 管道」来实现消息的下发。
外接模版:触达模板,就是一段带占位符的字符串。对接触达模板可以使 Webhook 通道获得动态参数的能力,即可以基于触达模板中的参数动态产生多个通道参数。使得一个通道可以对接多个模板,而无需为每个模板配置一个通道,可以极大地减少重复配置和机械劳动。
触达回执:GMP 提供多种回执数据接收能力,用于接收 GMP 触达对象的后链路状态数据,通过消息 ID 机制关联到营销任务,统计营销任务的后链路分析指标(例如送达量、点击量等,业务按自身场景需求而定)。

1.2 使用场景/流程

GMP 触达任务和流程画布可以使用 Webhook 通道,其发送最小粒度是一条消息。
在 GMP 业务中一条消息应该 触达内容 + 触达对象,比如短信的内容或者 App Push 信息就是触达内容。
触达的对象则是 GMP 内的主体,可以是一个人或者一台设备。
具体场景为给某个人(对象)发送一条短信(内容)。


2. 对接概览

说明

包含 GMP 的业务流程、流程中提供的 SPI、对应系统的 API。

Image

2.1 配置清单(SPI/API/非接口类配置)

可选接入类型:

  1. 同步调用外部接口(SPI)
  2. 发送数据至消息队列(SPI)
  3. 从消息队列接收数据(SPI)
  4. 从 OpenAPI 接收数据(API)
  5. 主动轮询外部接口(SPI)
  6. Iframe 集成(SPI)
  7. 非接口类配置

节点名

接入类型

可选节点类型

是否必选

说明

拉取外接模版列表

SPI

  • 同步调用外部接口

否

如果触达通道有模板的概念(如:外呼模板等),则可以拉取触达模板,实现更加灵活的触达配置。

Webhook 触达

SPI

  • 同步调用外部接口
  • 发送数据至消息队列

是

触达接口,包含的原子信息为 触达对象 + 触达内容,支持批量触达。

触达回执

API 或 SPI

  • 从 OpenAPI 接收数据(推荐)
  • 从消息队列接收数据

否

回执接口,包含的原子信息为 触达对象 + 对象的触达后链路行为状态码,支持批量回执。
使用消息 ID 机制与触达进行关联。

2.2 接口定义

说明

SPI 需提供标准请求和标准响应的定义。
API 需提供 API 路径、鉴权、请求、响应的定义。

2.2.1【必选】Webhook 触达(SPI)

2.2.1.1 标准请求

  • 请求协议:http/https。
  • 请求方式:POST、application/json。
  • 请求体
// 批量形式,单批数量<=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"    // 配置字段:模版参数
        }
    }]
}

2.2.1.2 标准响应

//样例响应格式
[{
    "code":0, //0表示成功
    "msg":"success" //成功/失败原因
},{
    "code":0, //0表示成功
    "msg":"success" //成功/失败原因
}]

2.2.2【可选】拉取外接模版列表(SPI)

2.2.2.1 标准请求

  • 请求协议:http/https。
  • 请求方式:POST、application/json。
  • 请求体:

参数

类型

是否必选

说明

pageNo

数值

必选

页号,从 1 开始。

pageSize

数值

必选

页数,固定为 10。

key1

字符串

可选

模板过滤参数 key1。

key2

字符串

可选

模板过滤参数 key2。

2.2.2.2 标准响应

{
    "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"
        }
    ]
}

2.2.3【可选】触达回执(API)

API 接入形式的示例,其他形式参考 3.3.4

  • 回执接口地址:新建回执通道后自动生成。
  • 接口请求方式:POST、application/json。

2.2.3.1 请求参数

// 批量形式,需要配置批量响应,以及响应中数组jsonpath
[
    {
        "status_code":0, // 按状态码枚举定义
        "msg_id":"xzfasdfag" // GMP下发的时候带的“消息ID”值
    },
    {
        "status_code":0, // 按状态码枚举定义
        "msg_id":"xzfasdfaf" // GMP下发的时候带的“消息ID”值
    }
]

2.2.3.2 响应参数

[{
  "code": 0,    // 0代表成功,其他代表失败
  "extra_msg": "xxx" // code非零时,该字段说明详细错误原因
},{
  "code": 0,    // 0代表成功,其他代表失败
  "extra_msg": "xxx" // code非零时,该字段说明详细错误原因
}]

3. 接入流程

3.1 接入评估

适用于Webhook通道对接的评估项

3.1.1 外接模板对接配置

评估项

评估项解释

  • 是否需要对接客户消息模板

是,有模版链接:常规对接。
是,没有模版链接:无法对接客户消息模板的场景,需要评估定开webhook通道数量。

  • 模板列表查询: 接口至少返回3部分信息: 模板总数,模板内容,模板编号。

否:常规对接。

3.1.2 消息发送对接配置

评估项

评估项解释

  • 消息内容接入形式

站内信,APP推送,短信推送,客户自定义推动服务,消息队列对接。

  • 消息ID构造方式

如何构建消息ID。

  • 接口发送形式

单发 or 批量。

3.1.3 回执对接配置

评估项

评估项解释

  • 是否有回执接口

无:不开启对接。
有:

  • 确认 GMP 消息ID和客户消息ID如何转换。
  • 关注批量接口回执获取方式。
  • 是否是批量回执

无法对接场景:

  • GMP4.9之前: 只支持请求体[{"userId":"","msgId":"msgId"}]的格式,且客户接口需要回传msgId。
  • GMP4.9之后:支持大部分场景,当前客户接口无法自定义消息ID/批次ID的接口无法实现。
  • GMP5.3之后:支持从response中获取批次号ID来构造msgId。
  • 客户是否希望获取回执信息进行分析

常规场景: 支持客户回执中多种状态的上报和漏斗展示,但是不支持源数据报文的分析。

  • 客户是否对回执接口返回有要求

客户的系统在推送回执后希望得到处理结果响应,以确认推送是否成功。一般需要返回200,或者指定格式数据。配置好后,请务必找接口侧验证响应正确。


3.2 节点业务配置

「管理中心-通道管理-Webhook接入」,点击右侧,新建Webhook页面。
Image
选择Webhook主体对象并确认。
Image
进入到Webhook通道配置页面
Image

3.2.1 基础配置(通用)

Webhook 通道配置分四块:基础配置、外接模板配置、Webhook 请求响应配置、回执配置
Image
配置 Webhook 名称和 Webhook 类型:

  • 同一 GMP 项目下,Webhook 名称不允许重复。
  • Webhook 类型用于智能触达等功能模块,暂时可以不用关注。

Image

3.2.2 拉取外接模版列表

Image
Image

  • 模板数组的 jsonPath:我们默认客户侧提供的接口都会返回一个触达模板列表,因此需要提供这个模板数组在客户接口响应中的位置。
  • 模板数量的 jsonPath:我们希望客户接口返回当前搜索条件下的模板数量,以方便前端进行分页展示,因此需要提供这个数量在响应中的位置。
  • 模板内容的相对路径:我们理解的模板至少会有两个字段:模板id、模板内容,因此必定是一个 json对象。我们需要客户提供模板内容字段在模板中的路径,从而找出这个模板进行解析。
  • 占位符的正则表达式:客户模板千奇百怪,不同客户的模板中参数的占位符也可能不同,我们将基于客户配置的这个正则表达式对模板进行解析。
  • 列表展示字段:为了方便客户在配置触达任务时选择正确的模板,必须在模板列表中国展示模板中的一些信息,我们支持客户配置这样的 key-value 对,用以决定模板列表将展示那些字段,以及每个字段的值如何获取。
  • 模板内容字典:有时模板中有些字段可能很长,不方便在列表中展示,可以在此设置,以单独查看。

3.2.2.1 示例

模板列表请求响应如下:

{
    "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}形式,模版内容字段展示配置如下:

展示如下:


3.3 节点接口配置

3.3.1 基础配置

需要注意的是,对于body/header/query参数配置,其参数类型可选项如图所示:

  • 常量:顾名思义,就是个常量参数。
  • GMP 保留字:支持在请求中插入当前页码和页规格,以支持分页接口。
  • 字符串:将成为模板搜索页面的一个文本搜索项。
  • 下拉单选框:将成为模板搜索页面的一个下拉选择框。

参数配置需要按照客户接口实际情况完成。

3.3.2 外接模板配置(可选)

允许在客户侧拉取触达模板,实现更加灵活的触达配置。所谓触达模板,就是一段带占位符的字符串,如下所示。对接触达模板可以使 Webhook 通道获得动态参数的能力,即可以基于触达模板中的参数动态产生多个通道参数。使得一个通道可以对接多个模板,而无需为每个模板配置一个通道,可以极大地减少重复配置和机械劳动。

// 模板示例
【xx打车】司机已接单,${car},请尽快赶往上车点
尊敬的客户${username},您的礼包${gift}将于${expire_date}过期

外界模板配置界面:请求地址、鉴权方式、请求方法、Content-type、body/header/query配置、自定义请求/响应处理脚本、成功/失败响应配置等含义可见上文。

3.3.2.1 解析配置

  • 模板数组的 jsonPath:我们默认客户侧提供的接口都会返回一个触达模板列表,因此需要提供这个模板数组在客户接口响应中的位置。
  • 模板数量的 jsonPath:我们希望客户接口返回当前搜索条件下的模板数量,以方便前端进行分页展示,因此需要提供这个数量在响应中的位置。
  • 模板内容的相对路径:我们理解的模板至少会有两个字段:模板id、模板内容,因此必定是一个 json 对象。我们需要客户提供模板内容在模板内容在模板中的路径,从而找出这个模板进行解析。
  • 占位符的正则表达式:客户模版各有不同,不同客户的模板中参数的占位符也可能不同,我们将基于客户配置的这个正则表达式对模板进行解析。
  • 列表展示字段:为了方便客户在配置触达任务时选择正确的模板,必须在模板列表中国展示模板中的一些信息,我们支持客户配置这样的 key-value 对,用以决定模板列表将展示那些字段,以及每个字段的值如何获取。
  • 模板内容字典:有时模板中有些字段可能很长,不方便在列表中展示,可以在此设置,以单独查看:

3.3.2.2 示例

客户侧接口如下所示:

Webhook触达模板+发送回执通道

获取模板

获取模版列表简要信息:(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"
            }
        ]
    }
}

发送模板 :(post)[/api/v1/distribution/messages/single]

客户接口期望接收如下请求:

{
    "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]。
回执形式由客户自主设计,请求体中 需要至少带上两个信息:

  • 消息id:要与Webhook发送/响应阶段的消息id对应相同。
  • 到达状态:本次触达是否最终成功。

此外也可以给出错误码或可枚举的错误信息,以便GMP进行下游错误统计与归因。
示例请求体:

{
    "messageId": "xxx",    // 消息id,与推送时对应。
    "receiveStatus": 2,    // 到达状态。2=成功;其他等于失败
    "errorDetail": "xxx"   // 失败详情(可枚举)
}

其配置如图所示:

最终该通道的模板搜索页面,如图所示:

可查看的详细内容:


3.3.3 Webhook请求响应配置(必选)

请求响应配置如下。除了基础通用配置的配置项之外,有几点需要额外介绍。

3.3.3.1 接口发送方式 - 批量发送

可以选择本通道是单次发送还是批量发送,如果选择批量发送,则会出现如下额外配置:

3.3.3.1.1 每次发送ID数上限

顾名思义,就是每次http请求中可携带的消息数量上限。

3.3.3.1.2 批量发送处理脚本

批量发送处理脚本的函数原型与前文的自定义请求处理脚本一致。需要注意的是,这个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"
    }
    //...
]

3.3.3.2 支持的参数类型

类型

写入内容

样式

字符串

字符串

Image

文本

可以插入用户 id,用户属性,用户标签,短链

Image

数值

整数

Image

小数

小数

Image

数组

支持非对象

Image

对象

可以多层嵌套

Image

结构体数据

map 格式,value 只支持字符串或者文本,支持在任务触达配置中手动动态添加字段

Image

日期

前端传当前日期

Image

日期时分秒

前端传当前日期时分秒

Image

图片

将文件上传到 minio,Webhook 字段中存储minio的链接

Image

单选下拉选择框

需要配置的时候添加选项,支持文本上传配置选项

Image

多选下拉选择框

需要配置的时候添加选项,支持文本上传配置选项

Image

单选下拉输入框

需要配置的时候添加选项,支持文本上传配置选项。可以在任务配置的时候新增选项

Image

多选下拉输入框

需要配置的时候添加选项,支持文本上传配置选项。可以在任务配置的时候新增选项

Image

动态参数

仅能同时选择用户 id/用户属性/用户标签

Image

除此之外,还额外添加了一些参数类型:

3.3.3.2.1 外接模板占位符

依赖外接模版配置

如果客户在触达配置中选择了Webhook模板,则该参数的值将会由客户选择的模板参数及其值组成,至于如何组成取决于第三项下拉框的选择。假设客户接口请求体如上图中json配置所示,其选择的模板及填写的值如下图所示。

则在不同选项下产生的请求体如下:

  • 结构体:
{
    "params": {
        "address": "xx小区菜鸟驿站",
        "express": "顺丰"
    }
}
  • 编码:
{
    "params": "{\"address\":\"xx小区菜鸟驿站\",\"express\":\"顺丰\"}"
}
  • 展开:原字段params被删除,取而代之的是一组模板占位符参数。
{
    "address": "xx小区菜鸟驿站",
    "express": "顺丰"
}

3.3.3.2.2 外接模板参数

当您使用Webhook模板时,可能会希望GMP在进行Webhook发送时除了带上模板占位符参数,还会希望带上当前使用的模板自身的一些属性。此时可以使用外接模板参数满足需求,只需要在配置上所需参数在模板中的jsonPath便可。比如,假设您除了外界模板占位符,还需要我们传模板的code字段的值,则可如上图进行配置。

3.3.3.2.3 GMP保留字

GMP保留字机制为Webhook发送一些特殊的值预留了扩展空间,当前支持以下保留字。该列表可以持续扩展,如需扩展,欢迎联系火山引擎客户服务对接人。

消息 id

GMP 会基于 snowflake算法为每一次Webhook调用生成一个消息id,该消息id长度14字节

发送 id

发送目标在当前通道的发送 id 类型下的id

发送 id 类型

当前通道的发送 id 类型

任务创建人名称

当前触达任务/流程画布的任务创建人

任务所在资源组

当前触达任务/流程画布所在的资源组

任务创建人信息

可选参数值:

  • 任务创建人名称
  • 任务创建人部门信息

任务信息

可选参数值:

  • 任务类型
  • 任务所在资源组名称
  • 任务 ID
  • 任务名称
  • 任务分组名称
  • 子任务 ID
  • 策略器ID
  • 任务通知类型
  • 任务发送类型

通道信息

可选参数值:

  • 通道 ID
  • 通道名称

接口发送时间戳

可选参数值:

  • 秒级时间戳
  • 毫秒级时间戳

3.3.3.2.4 用户属性

用户属性是一种在通道配置中配置好的动态参数,设置好后将不出现在触达配置中,减少运营配置工作,并有效规避运营过程中的错误。

3.3.3.3 回执配置

打开「启用」开关,选择对应的回执通道:
Image
或「管理中心-通道管理-Webhook-Webhook回执配置」
Image


3.3.4 Webhook回执通道配置(可选)

GMP当前支持回执处理方式:

调用方向

自定义回执(客户系统=>GMP)

回执方式

http 推送

消息队列推送

Image

调用方向

GMP轮询(客户系统=>GMP)

回执方式

基于消息ID

定时触发轮询

基于批次ID轮询

基于任务ID

基于webhook请求

Image

3.3.4.1 自定义回执

3.3.4.1.1 基本配置

Image
配置名称:
回执的名称,不能重名
成功到达配置:
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。

3.3.4.1.2 消息处理与通道判定脚本

客户系统主动推送消息时,可能会存在通道复用的情况。简言之,如多个不同的回执通道的消息共用一个「物理通道」进入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
}

3.3.4.1.3 自定义响应生成脚本

由于自定义响应生成脚本是与回执通道强绑定的,因此其只能作用于独立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&timestamp=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
}

3.3.4.1.4 http接口

对于http推送回执,我们提供两种接口:

  • 独立api( ++推荐使用 ++):每个http回执通道都**同时​**拥有自己的独立 API ,即消息既可以通过统一 API 进入,也可以通过独立API 进入。由于独立 API 的消息在被 GMP 业务处理前不会检查data.Hit,因此如果确认消息只会通过独立 API 进入,请勿在「消息处理与通道判定脚本」中对该字段赋 true,以确保该通道屏蔽来自统一 API 的所有消息。可想而知,由于不需要遍历执行检查脚本进行确认,使用独立 API 能够得到更好的处理性能。能用独立 API 则尽量使用独立 API。
  • 统一API /GMP/webhook:所有http推送回执消息都可以通过该API进入GMP,但必须要能够通过「消息处理与通道判定脚本」确认之后,才能被相应通道及业务逻辑处理。

3.3.4.2 GMP轮询

调用方向

GMP轮询(客户系统=>GMP)

回执方式

基于消息ID

定时触发轮询

基于批次ID轮询

基于任务ID

基于webhook请求

Image

3.3.4.2.1 基本配置

GMP轮询机制的基本配置类似,都是需要一个外部接口调用基础通用配置,可通过阅读前文复习此处如何进行配置

3.3.4.2.2 消息id轮询

适用于针对消息id进行单个查找的回执接口。查询重试机制:

  • 命中某个失败响应规则,且该规则的被设置为可重试
  • 判定为失败,且未命中任何失败响应规则

每个消息id会在两天内不断重试,直至判定为查询成功,其重试规律与时间间隔参照RocketMQ的重试消费机制

3.3.4.2.3 定时轮询

适用于流式批量查询客户接口获取回执的场景。当前固定每分钟调用一次。GMP不维护当前游标,需要由客户接口维护。
对于更复杂的定时轮询机制欢迎与GMP产研进行探讨。

3.3.4.2.4 基于批次ID轮询

适用于按每次请求下游作为一个批次,回执数据按批次维度来查询的场景。回执查询接口根据每次请求的唯一id,返回该次请求的发送结果。批次ID,可以由GMP生成并透传给下游接口,也可以由请求下游时,由下游返回给GMP,GMP侧记录。

3.3.4.2.5 基于任务id

适用于按每个GMP侧任务作为整体的一个回执记录,通过任务id来查询该次任务下的所有回执记录

3.3.4.2.6 基于 webhook 请求

适用于特定场景下,需要定制化请求格式来查询回执数据。


3.3.5 消息队列配置

支持GMP通用Webhook通过kafka/rocketMq进行发送;也支持通过kafka/rocketMq接受回执。

说明

由于GMP使用的Kafka相关依赖包存在兼容性限制,当前仅支持Kafka版本<3.1.0。当版本≥3.1.0 时,下发与回执场景均无法保证可用性;若确需使用该版本,version需要填3.1.0,且需自行测试验证。

3.3.5.1 新增或编辑消息队列配置

  1. 设置消息队列配置名称
  2. 设置配置类型:
    1. 请求配置:GMP通用Webhook可以给予该配置将数据塞入指定的消息队列
    2. 回执配置:GMP将监听并消费该消息队列,从中得到通用Webhook的回执
  3. 配置代码:特定于具体的消息队列类型与配置类型,输入一段json,表明当前消息队列的一些参数:

务必不要创建两个完全一样的消息队列配置,否则无法创建producer,或无法启动consumer;即相同配置只能启动一个producer或consumer

  1. mq_type:消息队列类型,必填。当前支持的枚举值:rocketMq,kafka。
  2. rocketMq相关配置:
    1. 请求配置:
{
    "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": "" // 消费组
}
  1. kafka相关配置:
    1. 请求配置:
{
    "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版本
}

3.3.5.2 使用消息队列

  1. 在Webhook请求/响应配置中选择发送方式,然后选择对应的请求消息队列配置:
  1. 在Webhook回执中选择对应的回执消息配置:

3.3.6 Webhook鉴权配置

如果在Webhook请求时,下游通道需要有接口鉴权,Webhook支持多种鉴权能力。

3.3.6.1 秘钥鉴权

通过对秘钥进行加密处理后,传给下游接口,支持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 

3.3.6.2 Basic-auth鉴权

支持将用户名,密码通过basic-auth处理后,放入请求体的header/query中,进行请求鉴权

3.3.6.3 Oauth2.0鉴权

如果下游接口需要先通过账密等数据,先请求一个接口,获取到鉴权信息(token/cookie),再将鉴权信息给Webhook通道做鉴权。则需要使用Oauth2.0鉴权。

3.4 Webhook上行消息通道(可选)

  • 有效性判断:
    • 每条规则可以选择判断方式:前缀判断或者正则表达式判断。继而设置对应的表达式与命中该规则的消息的含义。
    • 可以设置多条消息有效性规则,自上而下使用每条规则对当前消息进行判断,如果判断命中,则为当前消息赋予一个“含义”,并进行后续处理。
  • 用户上行消息内容:​指用户上行消息在上行消息体中的jsonpath。
  • 上行消息匹配方式:​表示如何为当前上行消息寻找并匹配下行消息。通俗而言,即“查找用户是在回复哪条消息”。
    • 消息id:如果上行消息体中携带了「消息id」,而且是通过GMP自定义Webhook下发过的消息的消息id。则会直接找到该消息id对应的下行消息作为对应的下行消息。
  • 需要提供消息id在消息体中的jsonpath:
    • 用户id:如果上行消息中携带了用户id,如回复短信中携带了用户手机号,则GMP会找到近三天内对该用户下发的最后一条消息,作为匹配的下行消息。

在此情景下需要提供携带的用户id的id类型,及其在消息体中的jsonpath

需要注意的是,由于用户id匹配涉及到扫描对该用户的所有发送记录,因此当前存在性能问题,每秒的处理qps大约只有20。GMP会对收到的这类上行消息通过消息队列进行异步处理,因此可能会存在上报延迟,这一点需要客户知悉。该问题将在后续版本优化。

4. GMP(Webhook对接)标准协议

说明

GMP 侧定义的请求&响应协议,适用对象:新开发接口服务,且想按照 GMP的协议来开发接口服务的客户

4.1 接口定义参考2.2

4.2 样例配置

  • 消息下发

Image
最基本的接口下发格式

{
    "send_id":"123456", //下游接口需要的发送用户id
    "msg_id":"xzfasdfag", //发送记录id,标记每一条发送记录,用于数据回流的统计
    "param1":"param1" //下发的内容参数
}
  • 响应配置
//样例响应格式
{
    "code":0, //0表示成功
    "msg":"success" //成功/失败原因
}

启用回执之后,选择需要的回执配置,基本的回执配置可以看下面的【样例回执】
Image

  • 回执配置

【样例回执】格式,客户端请求GMP的格式

{
    "status_code":0, //0表示到达成功,非0表示到达失败
    "msg_id":"xzfasdfag" //GMP下发的时候带的msg_id值
}

通道配置使用默认配置
Image
GMP响应格式为

{
  "code": 0,    // 0代表成功,其他代表失败
  "extra_msg": "xxx" // code非零时,该字段说明详细错误原因
}

保存后,得到回执接口地址,拼上GMP域名之后,即可使用

最近更新时间:2026.10.16 11:15:40
这个页面对您有帮助吗?
有用
有用
无用
无用