专业版功能集成文档
主动消息回执
功能描述
主动消息回执是指友盟通过http协议调用开发者的服务,将消息的送达、点击事件回传给开发者,传递数据包含消息ID、目标设备ID、和目标设备在指定alias_type下的alias(需配置开通)等。
开通方式
联系商务或客服开通。
功能逻辑和使用
在U-Push portal后台可开启相关回执功能

Android端目前支持的回执类型有送达回执、点击回执、忽略回执和推送失败回执

iOS端目前支持的回执类型有发送回执(只有当消息类型是live activity时,消息实际发送APNs成功时才会有此回执)、送达回执、点击回执和推送失败回执
iOS送达回执功能需要先参考iOS集成文档集成送达插件才能实现。送达回执、点击回执和忽略回执属于U-Push专业版(Pro)高级能力;推送失败回执属于U-Push尊享版高级能力。
在发送消息时可以在appkey的同级增加回执相关参数。
{
"appkey":":"xx", //必填,应用唯一标识
.... //其它常规消息报文
"thirdparty_id":"xx", //可选,长度小于128字符的三方id, 字母数字下划线, 不含特殊字符
"callback_params": { //可选,自定义回执参数,不要含特殊字符
"name": "string",
"age": 26
}
}回执报文示例
友盟服务端在完成相关事件的处理后会调用开发者配置的服务地址POST一个JsonArray格式的报文。
[
{
"msg_id":"id1", //消息唯一ID
"thirdparty_id":"xxx", //发送消息时填写的thirdparty_id参数
"action_type":xx, //回执类型。-1:LA实际发送;0:送达;1:点击;2:忽略;21:厂商通道点击;8:推送失败回执
"device_tokens":"xxxxxx", //设备ID
"alias":"xxxxxx", //送达/点击消息的alias。(alias_type需要在开通回执服务的时候跟appkey一起约定)
"channel":"xxxxxx", //送达回执字段,送达通道。如 accs 、xiaomi、huawei、oppo、vivo
"notification_enable":"xx", //送达回执字段,通知权限状态。0:关闭状态;1:打开状态
"t":"1234567890123", //13位事件时间戳
"error_code":"xxxxxx", //推送失败回执字段。错误码说明详见下方表格
"callback_params": { //自定义回执参数
"name": "string",
"age": 26
}
},
{
"msg_id":"id2",
"thirdparty_id":"xxx",
"action_type":xx,
"device_tokens":"xxxxxx",
"alias":"xxxxxx",
"channel":"xxxxxx",
"notification_enable":"xx", //通知权限状态。0:关闭状态;1:打开状态
"t":"1234567890123", //13位事件时间戳
"error_code":"xxxxxx",
"callback_params": { //自定义回执参数
"name": "string",
"age": 26
}
}
]推送失败回执错误码:
error_code | 错误码说明 |
800001 | Android:设备未注册 |
800002 | Android:超出活跃期限 |
800003 | Android:友盟侧DeviceToken失效(Token发生了变化或设备已注销) |
800006 | Android:厂商返回设备Token失效,已转入友盟离线通道 |
810001 | iOS:APNs返回设备未注册 |
810002 | iOS:友盟检测DeviceToken长度错误 |
810003 | iOS:APNs返回DeviceToken与Bundle ID不匹配 |
810004 | iOS:APNs返回DeviceToken与证书环境(开发/生产)不匹配 |
810005 | iOS:APNs返回ProviderToken无效 |
810006 | iOS:APNs返回同一个DeviceToken请求次数过多 |
810007 | iOS:APNs返回该Bundle ID不被允许推送 |
810008 | iOS:APNs返回证书被拒、DeviceToken过期等 |
重试机制
消息回执报文可能会被开发者的网关当作爬虫或异常流量拦截,开发者需要联系自家网关系统保证服务通畅,在收到非200的响应码时友盟会对异常消息在一天时效期内执行多次重试,重试频次约1小时/次。对于200响应码的消息不会执行重试。
安全传输机制
回执报文的http header中增加了umeng-token字段,值为本次请求的签名,开发者可根据签名校验报文是否被篡改。
签名算法:
/**
* 计算回执签名
* @param url 开发者配置的回执地址, 包含queryString
* @param postData 回执报文字符串
* @param masterSecretKey 所属appkey的masterSecretKey
* @return
*/
private String createSig(String url, String postData, String masterSecretKey) {
return DigestUtils.md5Hex("POST" + url + postData + masterSecretKey);
}注:签名所用url是开发者配置的回执地址全文,支持RESTful格式,建议开发者使用url参数区分不同appkey的回执地址,如下面两张格式。
https://domain.company.com/umengcallback/$appkey
https://domain.company.com/umengcallback?appkey=$appkey
开发者服务质量反馈机制
为保护系统,友盟会对开发者的回执地址服务质量做不定期汇总分析,对异常情况如频繁大面积网络异常、url不可用、响应状态码明显异常的应用会采取临时封禁的措施。同时会通过商务、客户联系信息等方式尝试与开发者沟通解决。
注意事项
在回执数据传输过程中设备的alias可能发生变化,消息回执中的alias是友盟服务端在处理回执事件时根据device_token反查得到的最新alias,可能跟消息下发时的alias不一致。
根据device_token反查alias所使用的alias_type在高级功能开通时指定。
channel字段只有送达回执有,该功能需要提前联系商务经理或客服进行开通。
返回的事件时间戳由于上行数据的处理原因可能略晚于事件真实发生时间。
回执数据有可能重复,如需基于回执数据产出精确的统计指标,建议自行做去重处理。
API管理用户自定义标签(tag)
给设备打标签
POST (Content-Type: application/json)
https接口:https://msgapi.umeng.com/api/tag/add?sign=mysign
签名(sign=mysign)的计算方式参见附录。
调用参数
{
"appkey":"xxxxx", //你的appkey
"timestamp":xxxx, //时间戳
"device_tokens":"xxxxxxx", //单个device_token
"tag":"xxxx" //要添加的标签,如果有多个,以英文逗号分隔
}注意:上面这个addtag方法不会清掉原来设置的tag。
响应参数
// 正常响应
{"ret":"SUCCESS"}
// 失败响应
{
"ret": "FAIL",
"data":
{
"error_msg": "该app未开通服务端tag接口",
"error_code": "6001"
}
}查询设备tag列表
https接口:https://msgapi.umeng.com/api/tag/list?sign=mysign
签名(sign=mysign)的计算方式参见附录。
调用参数
{
"appkey":"xxxxxx",
"timestamp":xxxx,
"device_tokens":"xxxxx" //只支持一个device_token
}注意:只支持一个device_token。
响应参数
// 正常响应
{
"ret": "SUCCESS",
"data":
{
"data":
{
"tags": "000,111"
}
}
}
// 失败响应
{
"ret": "FAIL",
"data":
{
"error_msg": "该app未开通服务端tag接口",
"error_code": "6001"
}
}设置设备tag
https接口:https://msgapi.umeng.com/api/tag/set?sign=mysign
签名(sign=mysign)的计算方式参见附录。
调用参数
{
"appkey":"xxxx",
"timestamp":xxxx,
"device_tokens":"xxxxx", //只支持一个device_token
"tag":"xxxx"
}注意:上面这个settag方法会清掉原来设置的tag
响应参数
// 正常响应
{"ret":"SUCCESS"}
// 失败响应
{
"ret": "FAIL",
"data":
{
"error_msg": "该app未开通服务端tag接口",
"error_code": "6001"
}
}删除设备tag
https接口:https://msgapi.umeng.com/api/tag/delete?sign=mysign
签名(sign=mysign)的计算方式参见附录。
调用参数
{
"appkey":"xxxx",
"timestamp":xxxx,
"device_tokens":"xxxx", //只支持一个device_token
"tag":"xxxx"
}注意:只支持一个device_token
响应参数
// 正常响应
{"ret":"SUCCESS"}
// 失败响应
{
"ret": "FAIL",
"data":
{
"error_msg": "该app未开通服务端tag接口",
"error_code": "6001"
}
}清除设备tag
https接口:https://msgapi.umeng.com/api/tag/clear?sign=mysign
签名(sign=mysign)的计算方式参见附录。
调用参数
{
"appkey":"xxxx",
"timestamp":xxxx,
"device_tokens":"xxxx" //只支持一个device_token
}注意:只支持一个device_token
响应参数
// 正常响应
{"ret":"SUCCESS"}
// 失败响应
{
"ret": "FAIL",
"data":
{
"error_msg": "该app未开通服务端tag接口",
"error_code": "6001"
}
}API批量自定义标签
批量给设备打标签
POST (Content-Type: application/json)
https接口:https://msgapi.umeng.com/api/tag/batchAdd?sign=mysign
签名(sign=mysign)的计算方式参见附录。
调用参数
{
"appkey":"xxxxx", //你的appkey
"timestamp":xxxx, //时间戳
"device_tokens":"xxx", //要打标签的设备,如果有多个,以英文逗号分隔,最多500个
"tag":"xxxxx" //要添加的标签,如果有多个,以英文逗号分隔
}注意:
上面这个addtag方法不会清掉原来设置的tag。
如果同时添加的标签过多,会有轻微延时
响应参数
// 正确响应
{"ret":"SUCCESS"}
// 失败响应
{
"ret": "FAIL",
"data":
{
"error_msg": "该app未开通服务端tag接口",
"error_code": "6001"
}
}批量查询设备tag列表
https接口:https://msgapi.umeng.com/api/tag/batchList?sign=mysign
签名(sign=mysign)的计算方式参见附录。
调用参数
{
"appkey":"xxxxxx",
"timestamp":xxxx,
"device_tokens":"xxxx,xxx" //要查询的设备,如果有多个,以英文逗号分隔,最多500个
}响应参数
// 正确响应
{
"ret": "SUCCESS",
"data":
{
"tagList":
[
{
"device_token": "AsgHYmcRVgAddaC7xxxxxxxxxxxxlKaIf6WVpR_9A80g",
"tags": "000,111"
},
{
"device_token": "AhcbKytj4mOnxxxxxxxxxxxxxxxvS8n-y36c5hxb",
"tags": "222,333"
}
]
}
}
// 失败响应
{
"ret": "FAIL",
"data":
{
"error_msg": "该app未开通服务端tag接口",
"error_code": "6001"
}
}批量删除设备tag
https接口:https://msgapi.umeng.com/api/tag/batchDelete?sign=mysign
签名(sign=mysign)的计算方式参见附录。
调用参数
{
"appkey":"xxxx",
"timestamp":xxxx,
"device_tokens":"xxxx", //要删除标签的设备,如果有多个,以英文逗号分隔,最多500个
"tag":"xxxx" //要删除的标签,如果有多个,以英文逗号分隔
}响应参数
// 正确响应
{"ret":"SUCCESS"}
// 失败响应
{
"ret": "FAIL",
"data":
{
"error_msg": "该app未开通服务端tag接口",
"error_code": "6001"
}
}安卓厂商数据透出
目前只透出送出数(调用厂商接口成功数)、到达数(通过厂商回执计算的到达),发送失败的原因(分通道展示),错误原因作为参考,如果是客户端未集成成功导致无法下发,不会展示在这里。
https接口:https://msgapi.umeng.com/api/channel/data?sign=mysign
调用参数
{
"appkey":"5b480082a40fa37d1c0001e6", //android appkey
"timestamp":1595486465738, //十分钟内的时间戳
"task_id":"ushb5v1159547682100011" //task_id,只支持任务或在推送后台发的单播查询
}返回结果:
//成功:
{
"ret":"SUCCESS",
"data":{
"stats":[
{
"channel_arrive_count":127981,
"channel":"xiaomi",
"channel_sent_count":157562,
"errors":[
{
"error_code":"200001","error_info":"推送数量超过当日限额",
"num":"155699"
}
]
},{
"channel_arrive_count":307864,
"channel":"huawei",
"channel_sent_count":334637
},{
"channel_arrive_count":0,
"channel":"meizu",
"channel_sent_count":5062
},{
"channel_arrive_count":0,
"channel":"oppo",
"channel_sent_count":0
},{
"channel_arrive_count":0,
"channel":"vivo",
"channel_sent_count":0,
"errors":[
{
"error_info":"title超过vivo厂商限制长度40字符",
"num":"--"
},{
"error_info":"text超过vivo厂商限制长度100字符",
"num":"--"
}
]
}
]
}
}
失败:
{
"ret":"FAIL",
"data":{
"error_msg":"该app未开通channel_data功能",
"error_code":6017
}
}调用失败返回的错误码:
错误码 | 说明 |
6017 | 该app未开通厂商数据查询功能 |
6018 | 只有任务和推送后台发的消息可查询 |
6019 | 只有通知栏消息可查 |
6020 | 没有通过厂商通道下发,检查mipush,mi_activity字段 |
1014 | task_id对应的任务找不到 |
厂商通道错误码具体可参照厂商文档,如下表链接:
厂商 | 错误码参考文档 |
华为 | |
小米 | |
oppo | |
vivo |
厂商额度查询
厂商为了控制应用推送消息的频率,会根据应用在厂商的日联网数计算每天推送数量上限。目前已知小米、oppo、vivo都有每天的额度控制,额度可以在厂商后台查询。为了方便用户,我们汇总了三个平台的查询接口,供用户调用查询。
接口:https://msgapi.umeng.com/api/quota/query?sign=mysign
调用参数:
{
"appkey":"xxxx", //android appkey
"timestamp":1595486465738 //十分钟内的时间戳
}返回结果:
{
"ret":"SUCCESS",
"data":{
"vivoSysMsgCount":"10000", //vivo系统消息配置量
"xmAckedCount":"51514", //小米当日已送达数
"oppoTotalCount":"100000", //oppo当天允许推送数量
"xmQuotaCount":"50000", //小米当日可下发总数
"oppoPushCount":"47280", //oppo已经推送数量
"vivoMarketMsgCount":"10000", //vivo运营消息配置量
"oppoRemainCount":"52720" //oppo剩余推送数量
}
}模板消息功能
列播、自定义列播、文件播虽然支持批量发送但是不能满足千人千面的批量发送需求,即给不同的用户发送不同的内容(或设置不同的发送策略)。开发者在使用中只能自己拼凑报文调用单播接口来轮询操作,造成了大量冗余信息重复传输。为提高开发者体验,我们在/api/send接口的上层提供了模板消息功能,支持模板的增、删、查、发、用。
增加模板
https接口:https://msgapi.umeng.com/api/template/add?sign=mysign
签名(sign=mysign)的计算方式参见附录。调用参数示例:
//增加模板的接口入参在/api/send的基础上做了2点改动
//1.增加了template_name参数用来标识模板消息的名称。
//2.增加了变量机制用来将某个字段标识为模板变量,把属性设置成变量的规则为属性值设置成${属性名}。
{
"payload":{
"display_type":"notification",
"body":{
"after_open":"go_app",
"ticker":"it's ticker!",
"text":"${text}",
"title":"${title}"
}
},
"description":"it's description!",
"appkey":"appkey",
"type":"unicast",
"production_mode":"false",
"device_tokens":"${device_tokens}",
"timestamp":1234567890123,//13位时间戳
"template_name":"测试模板消息"
}返回结果
{
"ret":"SUCCESS",
"data":{
"template_keys":[ //被设置成变量的key
"text",
"title",
"device_tokens"
],
"template_id":"22825453714669568"//模板id
}
}模板变量的设置需要遵循以下约定
type=unicast时,必须设置${device_tokens}为变量。
type=customizedcast时,必须设置${alias}为变量。
不支持其它type类型的模板消息。
被设置成变量的属性必须是基础数据类型,不支持对复杂类型设置成变量,比如把整个payload.body设置成变量。
删除模板
https接口:https://msgapi.umeng.com/api/template/delete?sign=mysign
签名(sign=mysign)的计算方式参见附录。调用参数示例:
{
"appkey":"appkey", //必填,应用唯一标识
"timestamp":1234567890123, //必填,时间戳,10位或者13位均可,时间戳有效期为10分钟
"template_id":"22825453714669568"
}返回结果:
//模板存在删除成功
{
"ret":"SUCCESS",
"data":{}
}
//模板不存在
{
"ret":"FAIL",
"data":{}
}修改模板
安全原因不提供修改模板功能,防止修改模板导致旧版代码不可用。
获取单个模板
https接口:https://msgapi.umeng.com/api/template/get?sign=mysign
签名(sign=mysign)的计算方式参见附录。调用参数示例:
{
"appkey":"appkey", //必填,应用唯一标识
"timestamp":1234567890123, //必填,时间戳,10位或者13位均可,时间戳有效期为10分钟
"template_id":"22830558207803392"
}返回结果:
{
"ret":"SUCCESS",
"data":{
"template_name":"测试模板消息",
"template_info":"{\"payload\": {\"display_type\": \"notification\", \"body\": {\"after_open\": \"go_app\", \"ticker\": \"it's ticker!\", \"text\": \"${text}\", \"title\": \"${title}\"}}, \"description\": \"it's description!\", \"appkey\": \"5d68cb5e570df370bf000d36\", \"type\": \"unicast\", \"production_mode\": \"false\", \"device_tokens\": \"${device_tokens}\", \"timestamp\": 1598877128272, \"template_name\": \"\\u6d4b\\u8bd5\\u6a21\\u7248\\u6d88\\u606f\"}",
"template_keys":"[\"text\",\"title\",\"device_tokens\"]", //模板中被设置成变量的属性
"appkey":"appkey",
"template_id":"22830558207803392",
"id":1092 //模板的逻辑id,无业务含义,单个appkey的逻辑id必定不同
}
}获取模板列表
https接口:https://msgapi.umeng.com/api/template/list?sign=mysign
签名(sign=mysign)的计算方式参见附录。调用参数示例:
{
"appkey":"appkey", //必填,应用唯一标识
"timestamp":1234567890123, //必填,时间戳,10位或者13位均可,时间戳有效期为10分钟
"index":1, //分页编号,从第1页开始
"len":3 //每页拉取的长度
}返回结果:
{
"ret":"SUCCESS",
"data":{
"next":true, //是否有上一页
"pre":false, //是否有下一页
"total":8, //总数
"len":3, //当前页面长度
"index":1, //当前页面
"list":[
{
"template_name":"测试模板消息",
"template_info":"{\"payload\": {\"display_type\": \"notification\", \"body\": {\"after_open\": \"go_app\", \"ticker\": \"it's ticker!\", \"text\": \"${text}\", \"title\": \"${title}\"}}, \"description\": \"it's description!\", \"appkey\": \"5d68cb5e570df370bf000d36\", \"type\": \"unicast\", \"production_mode\": \"false\", \"device_tokens\": \"${device_tokens}\", \"timestamp\": 1598877128272, \"template_name\": \"\\u6d4b\\u8bd5\\u6a21\\u7248\\u6d88\\u606f\"}",
"template_keys":"[\"text\",\"title\",\"device_tokens\"]",
"appkey":"5d68cb5e570df370bf000d36",
"template_id":"22830558207803392",
"id":1092
},{
"template_name":"测试模板消息2号",
"template_info":"{\"alias_type\": \"${alias_type}\", \"template_name\": \"\\u79bb\\u660e\\u6d4b\\u8bd5123\\u2014\\u2014888\", \"payload\": {\"aps\": {\"badge\": \"${badge}\", \"alert\": {\"subtitle\": \"${subtitle}\", \"title\": \"${title}\", \"body\": \"${body}\"}, \"sound\": \"${sound}\", \"content-available\": \"${content-available}\", \"category\": \"${category}\"}}, \"alias\": \"${alias}\", \"description\": \"${description}\", \"appkey\": \"5d68cb5e570df370bf000d36\", \"type\": \"customizedcast\", \"production_mode\": \"${production_mode}\", \"timestamp\": 1598516268220}",
"template_keys":"[\"alias_type\",\"badge\",\"subtitle\",\"title\",\"body\",\"sound\",\"content-available\",\"category\",\"alias\",\"description\",\"production_mode\"]",
"appkey":"5d68cb5e570df370bf000d36",
"template_id":"21317001620226048",
"id":392
},{
"template_name":"测试模板消息3号",
"template_info":"{\"alias_type\": \"${alias_type}\", \"template_name\": \"\\u79bb\\u660e\\u6d4b\\u8bd5123\\u2014\\u2014888\", \"payload\": {\"aps\": {\"badge\": \"${badge}\", \"alert\": {\"subtitle\": \"${subtitle}\", \"title\": \"${title}\", \"body\": \"${body}\"}, \"sound\": \"${sound}\", \"content-available\": \"${content-available}\", \"category\": \"${category}\"}}, \"alias\": \"${alias}\", \"description\": \"${description}\", \"appkey\": \"5d68cb5e570df370bf000d36\", \"type\": \"customizedcast\", \"production_mode\": \"${production_mode}\", \"timestamp\": 1598515428918}",
"template_keys":"[\"alias_type\",\"badge\",\"subtitle\",\"title\",\"body\",\"sound\",\"category\",\"alias\",\"description\",\"production_mode\"]",
"appkey":"5d68cb5e570df370bf000d36",
"template_id":"21313481194078208",
"id":369
}
]
}
}发送模板消息
https接口:https://msgapi.umeng.com/api/template/send?sign=mysign
签名(sign=mysign)的计算方式参见附录。调用参数示例:
{
"appkey":"appkey",
"timestamp":1234567890123,
"template_id":"19163747587194880",
"params_data":[
{
"device_tokens":"An-lXbcmi3GDnZVWnfeEjT28WVmR3z8nYI3m3ec8CA-c",
"title":"这个是title",
"ticker":"这个是ticker",
"text":"这里是text",
},{
"device_tokens":"An-lXbcmi3GDnZVWnfeEjT28WVmR3z8nYI3m3ec8CA-c",
"title":"这个是title",
"ticker":"这个是ticker",
"text":"这里是text",
},{
"device_tokens":"An-lXbcmi3GDnZVWnfeEjT28WVmR3z8nYI3m3ec8CA-c",
"title":"这个是title",
"ticker":"这个是ticker",
"text":"这里是text",
}
]
}注:1、单个模板任务的设备上限是1000个。2、模板保留期限3个月。
返回结果:
{
"ret":"SUCCESS",
"data":{
"template_msg_id":"tm20238715871821824"
}
}查找真实消息id
https接口:https://msgapi.umeng.com/api/template/msg?sign=mysign
签名(sign=mysign)的计算方式参见附录。调用参数示例:
//第1次请求可以不传start_key
{
"appkey":"5d68cb5e570df370bf000d36", //必填,应用唯一标识
"timestamp":1234567890123, //必填,时间戳,10位或者13位均可,时间戳有效期为10分钟
"template_msg_id":"tm20238715871821824",
"len":2, //默认5
}
//后面的请求需要用上一页list中的最后1个msgId当作start_key
{
"appkey":"5d68cb5e570df370bf000d36", //必填,应用唯一标识
"timestamp":1234567890123, //必填,时间戳,10位或者13位均可,时间戳有效期为10分钟
"template_msg_id":"tm20238715871821824",
"len":2, //默认5
"start_key":"uu4rnpv159825918501301", //前一个列表的最后一行
}返回结果:
{
"ret":"SUCCESS",
"data":{
"list":[
{
"appkey":"5d68cb5e570df370bf000d36",
"index":2, //模板消息中使用的参数在发送时的索引
"msgId":"uu2fxwd159825918501401", //消息的真实msgId
"params":"{\"ticker\":\"这个是ticker\",\"text\":\"这里是text\",\"title\":\"这个是title\",\"device_tokens\":\"An-lXbcmi3GDnZVWnfeEjT28WVmR3z8nYI3m3ec8CA-c\"}",
"templateId":"19163747587194880", //模板id
"templateMsgId":"tm20238715871821824" //模板消息id
},{
"appkey":"5d68cb5e570df370bf000d36",
"index":1,
"msgId":"uu4rnpv159825918501301",
"params":"{\"ticker\":\"这个是ticker\",\"text\":\"这里是text\",\"title\":\"这个是title\",\"device_tokens\":\"An-lXbcmi3GDnZVWnfeEjT28WVmR3z8nYI3m3ec8CA-c\"}",
"templateId":"19163747587194880",
"templateMsgId":"tm20238715871821824"
}
]
}
}