功能介绍
消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验。
- 订阅消息推送位置:服务通知
- 订阅消息下发条件:用户自主订阅
- 订阅消息卡片跳转能力:点击查看详情可跳转至该小程序的页面
使用说明
步骤一:获取模板 ID
在微信公众平台手动配置获取模板 ID:
登录 https://mp.weixin.qq.com 获取模板,如果没有合适的模板,可以申请添加新模板,审核通过后可使用。
步骤二:获取下发权限
wx.requestSubscribeMessage(Object object)
基础库 2.4.4 开始支持,低版本需做兼容处理。
调起客户端小程序订阅消息界面,返回用户订阅消息的操作结果。当用户勾选了订阅面板中的“总是保持以上选择,不再询问”时,模板消息会被添加到用户的小程序设置页,通过 wx.getSetting 接口可获取用户对相关模板消息的订阅状态。
注意事项
- 一次性模板 id 和永久模板 id 不可同时使用。
- 低版本基础库2.4.4~2.8.3 已支持订阅消息接口调用,仅支持传入一个一次性 tmplId / 永久 tmplId。
- 2.8.2 版本开始,用户发生点击行为或者发起支付回调后,才可以调起订阅消息界面。
- 2.10.0 版本开始,开发版和体验版小程序将禁止使用模板消息 fomrId。
参数
Object object
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
tmplIds | Array | 是 | 需要订阅的消息模板的id的集合,一次调用最多可订阅3条消息(注意:iOS客户端7.0.6版本、Android客户端7.0.7版本之后的一次性订阅/长期订阅才支持多个模板消息,iOS客户端7.0.5版本、Android客户端7.0.6版本之前的一次订阅只支持一个模板消息)消息模板id在[微信公众平台(mp.weixin.qq.com)-功能-订阅消息]中配置 | |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
object.success 回调函数
参数
Object res
属性 | 类型 | 说明 |
---|---|---|
errMsg | String | 接口调用成功时errMsg值为'requestSubscribeMessage:ok' |
TEMPLATE_ID | String | [TEMPLATE_ID]是动态的键,即模板id,值包括'accept'、'reject'、'ban'。'accept'表示用户同意订阅该条id对应的模板消息,'reject'表示用户拒绝订阅该条id对应的模板消息,'ban'表示已被后台封禁。例如 { errMsg: "requestSubscribeMessage:ok", zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: "accept"} 表示用户同意订阅zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE这条消息 |
object.fail 回调函数
参数
Object res
属性 | 类型 | 说明 |
---|---|---|
errMsg | String | 接口调用失败错误信息 |
errCode | Number | 接口调用失败错误码 |
错误码
errCode | errMsg | 说明 |
---|---|---|
10001 | TmplIds can't be empty | 参数传空了 |
10002 | Request list fai | 网络问题,请求消息列表失败 |
10003 | Request subscribe fail | 网络问题,订阅请求发送失败 |
10004 | Invalid template id | 参数类型错误 |
10005 | Cannot show subscribe message UI | 无法展示 UI,一般是小程序这个时候退后台了导致的 |
20001 | No template data return, verify the template id exist | 没有模板数据,一般是模板 ID 不存在 或者和模板类型不对应 导致的 |
20002 | Templates type must be same | 模板消息类型 既有一次性的又有永久的 |
20003 | Templates count out of max bounds | 模板消息数量超过上限 |
20004 | The main switch is switched off | 用户关闭了主开关,无法进行订阅 |
20005 | This mini program was banned from subscribing messages | 小程序被禁封 |
示例代码
wx.requestSubscribeMessage({
tmplIds: [''],
success (res) { }
})
步骤三:调用接口下发订阅消息
发送订阅消息
调用方式:
HTTPS 调用
请求地址
POST https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN
请求参数
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
access_token | string | 是 | 接口调用凭证 | |
touser | string | 是 | 接收者(用户)的 openid | |
template_id | string | 是 | 所需下发的订阅模板id | |
page | string | 否 | 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。 | |
data | Object | 是 | 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } } | |
miniprogram_state | string | 否 | 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 | |
lang | string | 否 | 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN |
获取ACCESS_TOKEN
public Map<String,Object> wxApiGetAccessToken(String appid,String secret) {
//这里直接写死就可以,不用改,用法可以去看api
String grant_type="client_credential";
//封装请求数据
Map<String, Object> map = new HashMap();
map.put("appid", appid);
map.put("secret", secret);
map.put("grant_type", grant_type);
//发送GET请求
String result = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", map);
// String result = HttpUtil.get("http://wx-api.jftyun.com/cgi-bin/token", map);
// String result = HttpUtil.get("https://proxy-api.jftyun.com/weixin/cgi-bin/token", map);
// 解析相应内容(转换成json对象)
Map<String,Object> maps= JSON.parseObject(result,Map.class);
return maps;
}
获取模板信息,推送消息
public static Map<String,Object> sendTemplateMsg(String token, Template template){
String requestUrl="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";
requestUrl=requestUrl.replace("ACCESS_TOKEN", token);
String templateJson = JSON.toJSONString(template);
String result = HttpUtil.postData(requestUrl, templateJson);//此处可更换自己的请求方式
Map<String,Object> maps= JSON.parseObject(result,Map.class);
return maps;
}
接收返回结果
private void sendWxMessage(Order order, User user,String templateId,Map<String,TemplateParam> TemplateParamMap,String descript) throws Exception{
Template template=new Template();
template.setTouser(user.getOpenId());
template.setTemplate_id(templateId);
template.setData(TemplateParamMap);
String accessToken = wxConfigService.getAccessToken(WXConst.SNOW_APP_ID, WXConst.SNOW_SECRET);
Map<String, Object> maps = SendTemplate.sendTemplateMsg(accessToken, template);
int errorCode=(Integer)maps.get("errcode");
String errorMessage=maps.get("errmsg").toString();
if(errorCode==0){
logger.info(descript+"通知发送成功:"+errorCode+","+errorMessage);
}else{
logger.error(descript+"通知发送失败:"+errorCode+","+errorMessage);
}
}
返回值
Object
返回的 JSON 数据包
属性 | 类型 | 说明 |
---|---|---|
errcode | number | 错误码 |
errmsg | string | 错误信息 |
errcode 的合法值
值 | 说明 | 最低版本 |
---|---|---|
40003 | touser字段openid为空或者不正确 | |
40037 | 订阅模板id为空不正确 | |
43101 | 用户拒绝接受消息,如果用户之前曾经订阅过,则表示用户取消了订阅关系 | |
47003 | 模板参数不准确,可能为空或者不满足规则,errmsg会提示具体是哪个字段出错 | |
41030 | page路径不正确,需要保证在现网版本小程序中存在,与app.json保持一致 |
接口限制
次数限制:开通支付能力的是3kw/日,没开通的是1kw/日。
请求示例
{
"touser": "OPENID",
"template_id": "TEMPLATE_ID",
"page": "index",
"miniprogram_state":"developer",
"lang":"zh_CN",
"data": {
"number01": {
"value": "339208499"
},
"date01": {
"value": "2015年01月05日"
},
"site01": {
"value": "TIT创意园"
} ,
"site02": {
"value": "广州市新港中路397号"
}
}
}
订阅消息参数值内容限制说明
参数类别 | 参数说明 | 参数值限制 | 说明 |
---|---|---|---|
thing.DATA | 事物 | 20个以内字符 | 可汉字、数字、字母或符号组合 |
number.DATA | 数字 | 32位以内数字 | 只能数字,可带小数 |
letter.DATA | 字母 | 32位以内字母 | 只能字母 |
symbol.DATA | 符号 | 5位以内符号 | 只能符号 |
character_string.DATA | 字符串 | 32位以内数字、字母或符号 | 可数字、字母或符号组合 |
time.DATA | 时间 | 24小时制时间格式(支持+年月日) | 例如:15:01,或:2019年10月1日 15:01 |
date.DATA | 日期 | 年月日格式(支持+24小时制时间) | 例如:2019年10月1日,或:2019年10月1日 15:01 |
amount.DATA | 金额 | 1个币种符号+10位以内纯数字,可带小数,结尾可带“元” | 可带小数 |
phone_number.DATA | 电话 | 17位以内,数字、符号 | 电话号码,例:+86-0766-66888866 |
car_number.DATA | 车牌 | 8位以内,第一位与最后一位可为汉字,其余为字母或数字 | 车牌号码:粤A8Z888挂 |
name.DATA | 姓名 | 10个以内纯汉字或20个以内纯字母或符号 | 中文名10个汉字内;纯英文名20个字母内;中文和字母混合按中文名算,10个字内 |
phrase.DATA | 汉字 | 5个以内汉字 | 5个以内纯汉字,例如:配送中 |
符号表示除中文、英文、数字外的常见符号,不能带有换行等控制字符。 时间格式支持HH:MM:SS或者HH:MM。 日期包含年月日,为y年m月d日,y年m月、m月d日格式,或者用‘-’、‘/’、‘.’符号连接,如2018-01-01,2018/01/01,2018.01.01,2018-01,01-01。 每个模板参数都会以类型为前缀,例如第一个数字模板参数为number01.DATA,第二个为number02.DATA
例如,模板的内容为
姓名: {{name01.DATA}}
金额: {{amount01.DATA}}
行程: {{thing01.DATA}}
日期: {{date01.DATA}}
则对应的json为
{
"touser": "OPENID",
"template_id": "TEMPLATE_ID",
"page": "index",
"data": {
"name01": {
"value": "某某"
},
"amount01": {
"value": "¥100"
},
"thing01": {
"value": "广州至北京"
} ,
"date01": {
"value": "2018-01-01"
}
}
}
注:模板所有的字段key均为微信申请模板时指定。