接口调用请求说明
http请求方式: POST
https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN
POST数据说明
POST数据示例如下:
{ "touser": "OPENID", "template_id": "TEMPLATE_ID", "page": "index", "form_id": "FORMID", "data": { "keyword1": { "value": "339208499" }, "keyword2": { "value": "2015年01月05日 12:30" }, "keyword3": { "value": "腾讯微信总部" }, "keyword4": { "value": "广州市海珠区新港中路397号" } }, "emphasis_keyword": "keyword1.DATA"}
在调用模板消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:
{ "errcode": 0, "errmsg": "ok", "template_id": "wDYzYZVxobJivW9oMpSCpuvACOfJXQIoKUm0PY397Tc"}
更多文档细节请查看小程序官方文档: 小程序文档
看了发送消息模板的API文档,我们知道了 要发送模板消息有两种途径,要么是通过Submit 表单提交时带上 formId,要么支付场景下的prepay_id。本次代码讲解以预约场景下的表单提交为主。下面看看如何实现这个。
首先看看小程序端 提交按钮:
<form report-submit bindsubmit="BtnCommit"> <button class="btncommit" hover-class="btn-hover" form-type="submit" > <text class="btnText">确认预约</text> <image src="../../images/ic_next.png" class="btnCommitRightImage" /> </button></form>
上述我们给按钮类型绑定了表单事件,然后再表单头部打上 report-submit 标记,这说明,当点击此按钮时,小程序内部会自动将此次事件以模板消息类型识别,并随机生成一个formId用于模板消息发送的id。
注:模板消息测试只能再真机上进行,模拟器上是没办法获取到的。
然后我们看看js中如何实现的:
BtnCommit: function (e) { console.log(e); let that = this; //验证 if (!that.verifyData(that, e)) return; var fId = e.detail.formId;//获取到formId console.log(‘formId‘ + fId); let info = e.currentTarget.dataset;
httpApiQuery(queryApi, (res) => { //success wx.hideLoading(); let data = that.objectData(res.id, fId, that,info); const sendTemplateApiObj = { url: that.sendTemplateData(), data: data, method: ‘POST‘ }; //预约成功发送模板消息 httpApiQuery(sendTemplateApiObj, (res) => { console.log(res); }); let resultOrder = { id: res.id, orderIdString: that.checkNumber(res.id, 8), } let newInfo = _.assignIn(info, resultOrder); nvgt.navigateTo(‘../successful_appointment/index‘, newInfo); }, (res) => { //fail tip.showToast(‘预约失败,原因:‘ + res.errorMsg); });}
其中objectData方法就是返回的模板消息格式数据,
objectData: (options, fId, that) => { let objectData = { openId: app.data.userInfo.openId, touser: ‘‘, template_id: api.sendTempalteId, page: ‘pages/memberPage/index‘, form_id: fId, data: { keyword1: { value: options }, keyword2: { value: that.data.time }, keyword3: { value: "教练安排项目" }, keyword4: { value: "2小时" }, keyword5: { value: "不指定教练" }, keyword6: { value: "1" } }, color: ‘‘, emphasis_keyword: ‘‘ } return objectData; },
而sendTemplateData 方法返回的则是模板消息对应的ID,这个在小程序后台可以查看到
界面展示如下:
到这里,小程序端的工作就完成了,但是事情还没有结束,因为API也该咱实现(苦笑.JPG)。那我们接着来看看在API端有哪些需要处理的活:
首先我们要新建发送模板的PostSendTemplete 模型
public class PostSendTemplete { public string openId { get; set; } public string touser { get; set; } public string template_id { get; set; } public string page { get; set; } public string form_id { get; set; } public object data { get; set; } public string color { get; set; } public string emphasis_keyword { get; set; } }
和一个返回的TemplateResultModel 模型
public class TemplateResultModel{ public int errcode { get; set; } public string errmsg { get; set; } public string template_id { get; set; }}
第一步,我们新建一个SendTemplateMessage 的业务 接口如下:
Task<TemplateResultModel> SendTemplateMessage(PostSendTemplete tmModel);
第二步,实现这个业务接口:
public async Task<TemplateResultModel> SendTemplateMessage(PostSendTemplete tmModel){ WxaTempleteModel model = tmModel.TranslateToSendTemplateDto(); var result = await _template.SendTemplateMessage(model, tmModel.openId); return result;}
第三步,上述标红的是新建的一个数据接口,接口如下:
Task<TemplateResultModel> SendTemplateMessage(WxaTempleteModel tmModel,string code);
第四步,实现上述的数据接口:
public async Task<TemplateResultModel> SendTemplateMessage(WxaTempleteModel tmModel,string openid){ tmModel.touser = openid; var url = _config[ConfigurationKeys.TEMPLATE_SEND_RUL]; var accesstoken = MinTokenContext.AccessToken;//注:此处用到的appId和密匙都是小程序的 string queryUrl = string.Format(url, accesstoken); var objectdata = JsonConvert.SerializeObject(tmModel); var data = Httphelper.SendPostHttpRequest(queryUrl, contentType, objectdata.ToString()); TemplateResultModel userCard = JsonConvert.DeserializeObject<TemplateResultModel>(data); if (userCard.errcode == Invalid_token) { MinTokenContext.RefreshAccessToken(); _logger.LogInformation(string.Format(@"模板消息: Access Token 刷新,时间 {0}", DateTime.Now.ToString("yy-MM-dd HH:mm"))); data = Httphelper.SendPostHttpRequest(queryUrl, contentType, objectdata); userCard = JsonConvert.DeserializeObject<TemplateResultModel>(data); } return userCard;}
上述方法实现中,都需要将接口和实现在初始化的时候绑定,然后注入:
//Startup中
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
//Configure中:
services.AddScoped<ITemplateMessage, TemplateMessage>();
需要引入:
using Microsoft.Extensions.Configuration;
End