微信小程序订阅消息
概述
消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验。
- 订阅消息推送位置:服务通知
- 订阅消息下发条件:用户自主订阅
- 订阅消息卡片跳转能力:点击查看详情可提爱转至该小程序的页面
消息类型
- 一次性订阅消息
一次性订阅消息用于解决用户使用小程序后,后续服务环节的通知问题。用户自主订阅后,开发这可不限时间的下发一条对应的服务消息 ; 每条消息可单独订阅或退订(开发者自行控制发送)。 - 长期订阅消息
一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒,为便于服务,因此提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。
目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放。
使用步骤
第一步 选择/配置模板
在微信公众号平台配置并获取模板ID。
登录https://mp.weixin.qq.com 在功能 >订阅消息栏目,在我的模板中列出了当前用户定义的所有模板信息,
当不存在模板或没有合适的模板时,可在 公共模板 中申请添加新模板,待审核通过后便可使用。
第二步 订阅消息
在小程序中通过编码的方式调用微信接口 wx.requestSubscribeMessage 进行消息订阅。
示例
布局代码
<button bindtap="dingyue_message" >订阅消息</button>
js 代码
/**
* 订阅-消息
* @param {*} e
*/
dingyue_message : function(e){
wx.requestSubscribeMessage({
tmplIds: ['模板ID'],
success:function(res){
console.log('success:' + res.errMsg)
},
fail: function(res){
console.log('error:' + res.errMsg + " " + res.errCode)
}
})
}
实例中点击订阅消息
按钮,会弹出订阅消息界面,返回用户订阅消息的结果。
注意事项
- 一次性模板 Id 和永久模板 Id 不可同时使用
- 低版本基础库2.4.4~2.8.3 已支持订阅消息接口调用,仅支持传入一个一次性 tmplId / 永久 tmplId。
- 2.8.2 版本开始,用户发生点击行为或者发起支付回调后,才可以调起订阅消息界面。
- 2.10.0 版本开始,开发版和体验版小程序将禁止使用模板消息 formId。
- 一次授权调用里,每个tmplId对应的模板标题不能存在相同的,若出现相同的,只保留一个。
- 2.10.0 版本开始,支持订阅语音消息提醒
第三步 服务端消息发送
发送订阅消息的调用方式有 HTTPS调用 和 云调用 两种方式,本文只介绍 HTTPS调用。
请求地址
POST https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN
请求参数
参数名 | 类型 | 默认值 | 必须 | 说明 |
---|---|---|---|---|
access_token / cloudbase_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为正式版;默认为正式版 | |
string | 否 | 进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN |
返回值
属性 | 类型 | 说明 |
---|---|---|
errCode | number | 错误码 |
errMsg | string | 错误信息 |
errCode 代码说明
代码 | 说明 |
---|---|
0 | 成功 |
40003 | touser字段openid为空或者不正确 |
40037 | 订阅模板id为空不正确 |
43101 | 用户拒绝接受消息,如果用户之前曾经订阅过,则表示用户取消了订阅关系 |
47003 | 模板参数不准确,可能为空或者不满足规则,errmsg会提示具体是哪个字段出错 |
41030 | page路径不正确,需要保证在现网版本小程序中存在,与app.json保持一致 |
请求示例
/// <summary>
/// 微信发送消息
/// </summary>
public class MessageService : IMessageService
{
/// <summary>
/// 发送秒杀活动消息
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<ServiceResult<WeixinResultBase>> SendSeckillMessageAsync(SeckillMessageRequest request)
{
var goodsName = request.GoodsName;
if (goodsName.Length >= 20)
{
goodsName = request.GoodsName.Substring(0, 15) + "...";
}
var req = new SendMessageRequest
{
OpenId = request.OpenId,
TemplateId = request.TemplateId,
Page = $"{_seckillPagePath}?corpId={request.CorpId}&customerId={request.CustomerId}",
Data = new Dictionary<string, object>()
{
{"thing1",new { value = goodsName } },
{"time2",new { value = request.Time } },
{"thing3",new { value = "秒杀活动即将开始,支持一键发布到商店" } }
}
};
return await SendMessageAsync(req);
}
public async Task<ServiceResult<WeixinResultBase>> SendMessageAsync(SendMessageRequest request)
{
//先从缓存读取token
var accessToken = await _cache.GetStringAsync("store_assistant_accesstoken");
var url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={_appId}&secret={_appSecret}";
var response = await _httpClientFactory.GetClient().GetAsync(url);
var accessTokenResult = await response.Content.ReadAsAsync<WxAccessTokenQueryResult>();
if (accessTokenResult != null && accessTokenResult.ErrCode == 0)
accessToken = accessTokenResult.AccessToken;
var url = $"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={access_token.Result}";
var response = await _httpClientFactory.GetClient().PostDataAsync(url, request);
var responseTxt = await response.Content.ReadAsStringAsync();
var sendMsgResult = JsonConvert.DeserializeObject<WeixinResultBase>(responseTxt);
if (sendMsgResult != null && sendMsgResult.ErrCode == 0)
return ServiceResult.Succeed(sendMsgResult);
return ServiceResult.Failed(sendMsgResult, sendMsgResult.ErrCode, sendMsgResult.ErrMsg);
}
}
/// <summary>
/// 发送微信消息通知
/// </summary>
public class SendMessageRequest
{
/// <summary>
/// 用户openId
/// </summary>
[JsonProperty("touser")]
public string OpenId { get; set; }
/// <summary>
/// 订阅模板id
/// </summary>
[JsonProperty("template_id")]
public string TemplateId { get; set; }
/// <summary>
/// 跳转页面
/// </summary>
[JsonProperty("page")]
public string Page { get; set; }
/// <summary>
/// 模板类型
/// </summary>
[JsonProperty("data")]
public Dictionary<string, object> Data { get; set; }
/// <summary>
/// 跳转小程序类型 (eveloper为开发版;trial为体验版;formal为正式版;默认为正式版)
/// </summary>
[JsonProperty("miniprogram_state")]
public string MiniType { get; set; } = "formal";
/// <summary>
/// 语言类型(默认为zh_CN)
/// </summary>
[JsonProperty("lang")]
public string Lang { get; set; } = "zh_CN";
}