微信公众号模板开发实例教程

微信公众号模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。具体模板消息运营规则请读模板消息运营规范

关于使用规则,请注意:

1、所有服务号都可以在功能->添加功能插件处看到申请模板消息功能的入口,但只有认证后的服务号才可以申请模板消息的使用权限并获得该权限;2、需要选择公众账号服务所处的2个行业,每月可更改1次所选行业;3、在所选择行业的模板库中选用已有的模板进行调用;4、每个账号可以同时使用15个模板。5、当前每个账号的模板消息的日调用上限为10万次,单个模板没有特殊限制。【2014年11月18日将接口调用频率从默认的日1万次提升为日10万次,可在MP登录后的开发者中心查看】。当账号粉丝数超过10W/100W/1000W时,模板消息的日调用上限会相应提升,以公众号MP后台开发者中心页面中标明的数字为准。

关于接口文档,请注意:

1、模板消息调用时主要需要模板ID和模板中各参数的赋值内容;

2、模板中参数内容必须以".DATA"结尾,否则视为保留字;

3、模板保留符号"{{ }}"。

一、首先我们要在公众号里面添加我们所需要用到的模板,先假设您已经在MP中设置好了所属行业;



二、然后我们要定义一些请求模板消息时所要使用的实体类

/// <summary>
/// 公众号模板消息
/// </summary>
public class TemplateMessage
{
    public TemplateMessage()
    {
        topcolor = "#FF0000";
    }
    /// <summary>
    /// 接收者微信OpenId
    /// </summary>
    public string touser { get; set; }
    /// <summary>
    /// 模板Id
    /// </summary>
    public string template_id { get; set; }
    /// <summary>
    /// 跳转url
    /// </summary>
    public string url { get; set; }
    /// <summary>
    /// 顶部颜色
    /// </summary>
    public string topcolor { get; set; }
    /// <summary>
    /// 具体模板数据
    /// </summary>
    public object data { get; set; }
}
      

数据项data

public class TemplateDataItem
{
    /// <summary>
    /// 项目值
    /// </summary>
    public string value { get; set; }
    /// <summary>
    /// 16进制颜色代码,如:#FF0000
    /// </summary>
    public string color { get; set; }

    /// <summary>
    ///
    /// </summary>
    /// <param name="v">value</param>
    /// <param name="c">color</param>
    public TemplateDataItem(string v, string c = "#173177")
    {
        value = v;
        color = c;
    }
}

这里就是我们上面在公众号中添加的一些模板:

public class MessageTemplate
{
    /// <summary>
    /// 领取通知消息模板(优惠券领取成功通知)
    /// </summary>
    /// <param name="first">通知标题</param>
    /// <param name="keyword1">券名称</param>
    /// <param name="keyword2">来源商家</param>
    /// <param name="keyword3">过期时间</param>
    /// <param name="keyword4">使用说明</param>
    /// <param name="remark">备注</param>
    /// <returns></returns>
    public static object NoticeTemplate(string first, string keyword1, string keyword2, string keyword3, string keyword4, string remark)
    {
        var data = new
        {
            first = new TemplateDataItem(first, "#3990eb"),
            keyword1 = new TemplateDataItem(keyword1, "#feb91a"),
            keyword2 = new TemplateDataItem(keyword2, "#feb91a"),
            keyword3 = new TemplateDataItem(keyword3, "#feb91a"),
            keyword4 = new TemplateDataItem(keyword4, "#000000"),
            remark = new TemplateDataItem(remark, "#fe5627")
        };
        return data;
    }

    /// <summary>
    /// (订单支付成功)消息模板---->>面向消费者
    /// </summary>
    /// <param name="first">标题</param>
    /// <param name="orderMoneySum">支付金额</param>
    /// <param name="orderProductName">商品信息</param>
    /// <param name="Remark">备注</param>
    /// <returns></returns>
    public static object NoticeOrderPaySuccess(string first, string orderMoneySum, string orderProductName, string Remark)
    {
        var data = new
        {
            first = new TemplateDataItem(first, "#3990eb"),
            orderMoneySum = new TemplateDataItem(orderMoneySum, "#feb91a"),
            orderProductName = new TemplateDataItem(orderProductName, "#feb91a"),
            Remark = new TemplateDataItem(Remark, "#fe5627")
        };
        return data;
    }

    /// <summary>
    /// (新订单通知)消息模板---->>面向商家
    /// </summary>
    /// <param name="first">消息标题</param>
    /// <param name="keyword1">下单时间</param>
    /// <param name="keyword2">配送地址</param>
    /// <param name="keyword3">订单金额</param>
    /// <param name="keyword4">订单备注</param>
    /// <param name="remark"></param>
    /// <returns></returns>
    public static object NoticeOrderPaySuccess(string first, string keyword1, string keyword2, string keyword3, string keyword4, string remark)
    {
        var data = new
        {
            first = new TemplateDataItem(first, "#3990eb"),
            keyword1 = new TemplateDataItem(keyword1, "#feb91a"),
            keyword2 = new TemplateDataItem(keyword2, "#feb91a"),
            keyword3 = new TemplateDataItem(keyword3, "#feb91a"),
            keyword4 = new TemplateDataItem(keyword4, "#000000"),
            remark = new TemplateDataItem(remark, "#fe5627")
        };
        return data;
    }
}


还有一个消息发送之后微信返回码的一个实体:

public class TemplateDataItem
{
    /// <summary>
    /// 项目值
    /// </summary>
    public string value { get; set; }
    /// <summary>
    /// 16进制颜色代码,如:#FF0000
    /// </summary>
    public string color { get; set; }

    /// <summary>
    ///
    /// </summary>
    /// <param name="v">value</param>
    /// <param name="c">color</param>
    public TemplateDataItem(string v, string c = "#173177")
    {
        value = v;
        color = c;
    }
}

/// <summary>
/// JSON返回结果(用于微信响应接口等)
/// </summary>
public class WxJsonResult
{
    public ReturnCode errcode { get; set; }
    public string errmsg { get; set; }
}

/// <summary>
/// 发送模板消息结果
/// </summary>
public class TemplateMessageResult:WxJsonResult
{
    /// <summary>
    /// msgid
    /// </summary>
    public int msgid { get; set; }
}

三、所有实体建好之后我们就需要去写发送模板消息的服务了;

public class SendTemplateMessageService
{
    /// <summary>
    /// 公众号相关信息
    /// </summary>
    private const string AppId = "wxdcabc123456xyz";
    private const string AppSecret = "086323crd33xd23gc524fd93428b4ed9";
    /// <summary>
    /// 发送模板消息API
    /// </summary>
    private const string SendMessageApi = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}";
    /// <summary>
    /// 获取用信息API
    /// </summary>
    private const string GetBaseUserInfoApi = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN";
    /// <summary>
    /// 公众号发送模板消息方法
    /// </summary>
    /// <param name="appId"></param>
    /// <param name="appSecret"></param>
    /// <param name="templateId">模板ID</param>
    /// <param name="openId">微信openId</param>
    /// <param name="url">点击详情跳转路径</param>
    /// <param name="data"></param>
    public static void SendTemplateMessage(string templateId, string openId, string url, object data)
    {
        var accessToken = AccessTokenContainer.TryGetToken(AppId,AppSecret);
        var getInfoUrl = string.Format(GetBaseUserInfoApi, accessToken, openId);
        var userInfo = HttpClientHelper.GetResponse<WeixinUserInfoResult>(getInfoUrl);
        //判断用户是否关注公众号
        switch (userInfo.subscribe)
        {
            case 0:
                break;
            default:
                var sendUrl = string.Format(SendMessageApi, accessToken);
                var msg = new TemplateMessage
                {
                    template_id = templateId,
                    touser = openId,
                    url = url,
                    data = data
                };
                //序列化实体为json
                string json = JsonConvert.SerializeObject(msg, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

                //调用消息发送接口
                var result = HttpClientHelper.PostResponse<TemplateMessageResult>(string.Format(sendUrl, accessToken), json);
                LoggerHelper.Log(string.Format("【微信公众号发送模板消息接口调用】返回参数:errcode:{0},erromsg:{1},misgid:{2}", result.errcode, result.errmsg, result.msgid));
                break;
        }
    }
}

四、最后一步就是调用我们上面的这个方法发送模板消息了

//判断是否是在微信浏览器中
if (isWechat)
{
     var url = "http://m.xdd.wquan.cn/findcp";
     var endDate = "2015年08月20日";
     var first = string.Format("恭喜您,获得了100元现金抵用券");
     var keyword4 = StrUtil.HtmlDiscode(ecList.ECouponDetail.Usage);
     var remark = "点击“详情”查看优惠券,欢迎再次使用享叮当!";
     //得到所需要的模板数据
     var data = MessageTemplate.NoticeTemplate(first, ecList.ProductName, ecList.CorpName, endDate, keyword4, remark);
     //调用发送模板消息的方法,模板Id存储在config中
     SendTemplateMessageService.SendTemplateMessage(noticeTemplateId, oAuthAccessTokenResult.openid, url, data);
}

最后来看一下效果:

实例二

1、模板消息解释

微信为防止服务号对用户进行恶意骚扰和营销,而服务号在某些场景又必须给用户发送消息时(如购物成功、支付成功),这时候就可以应用微信提供的模板消息来给用户进行提醒。

比如:


2、怎么添加模板消息?

在微信公众号后台菜单里面有模板消息一栏,点击进去后可以看到模板库,可以根据自己的实际需要添加自己需要的模板消息,模板涵盖各行各业,暂不可自己编辑模板。


微信限制最多只能选择8个模板,应该也够用了。选中模板后就可以看到模板ID、标题等,这里已购买成功为列,查看详情时:


可以看到该模板需要提供的相关参数,这样就可以拼装请求的参数了。

这一步主要是要拿到模板的ID和该模板需要的参数名。

3、怎么请求发送模板?

第一步:获取模板ID
通过在模板消息功能的模板库中使用需要的模板,可以获得模板ID。第二步:请求接口请注意,URL置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
POST请求
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN

其中的POST请求中需要两个基本的技术要点:

1、获取ACCESS_TOKEN。

2、如何提交POST请求。

具体请参考开发教程系列获取ACCESS_TOKEN篇,http://kangliang.iteye.com/admin/blogs/21617

然后组装需要的JSON信息:

如:

{
"touser":"OPENID",
"template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
"url":"http://weixin.qq.com/download",
"topcolor":"#FF0000",
"data": {
"firstData": {
"value":"恭喜您购物成功!",
"color":"#173177"
},
"product": {
"value":"韩版西服",
"color":"#173177"
},
"price": {
"value":"149元",
"color":"#173177"
},
"time": {
"value":"2014-12-04 13:09:17",
"color":"#173177"
},
"remark": {
"value":"感谢您的光临,我们将尽快发货!",
"color":"#173177"
}
}
}

因模板消息属于固定格式,可在代码中写死拼装方式:

组装json信息:

/**
商品购买成功

 * templateId 模板ID

 * orderId 订单id

*

*/

String toTemplateMsgText(String orderId,String templateId){

OrderResponse response=getOrderByOrderId(orderId);

//查询订单信息

Order order=response.getOrder();

String first="您好,欢迎在新礼特购物!";

String remark="您的收货信息:"+order.getReceiver_name()+"电话:"+order.getReceiver_mobile()+"地址:"+order.getReceiver_city()+order.getReceiver_zone()+order.getReceiver_address()+"我们将尽快发货,祝您购物愉快!";

String jsonText="{"touser":"OPENID","template_id":"templateId","url":"","topcolor":"#FF0000","data":{"first": {"value":"firstData","color":"#173177"},"product": {"value":"productData","color":"#173177"},"price": {"value":"priceData","color":"#173177"},"time": {"value":"timeData","color":"#173177"},"remark": {"value":"remarkData","color":"#173177"}}}";

jsonText= jsonText.replace("firstData", first).replace("templateId", templateId).replace("OPENID", order.getBuyer_openid()).replace("productData", order.getProduct_name()).replace("priceData",order.getOrder_total_price()/100f+"元").replace("timeData", order.getOrder_create_time()).replace("remarkData", remark);

 return jsonText;

}

发送消息:

/**

 * 发送模板消息

 * @param accessToken

 * @param jsonData

*/

public static void sendTemplateMsg(String accessToken,String jsonData){

String requestUrl=send_templatemsg_url.replace("ACCESS_TOKEN", accessToken);

JSONObject jsonObject = httpRequest(requestUrl,"GET", jsonData);

if(jsonObject!=null){

if("0".equals(jsonObject.getString("errcode"))){

System.out.println("发送模板消息成功!");

}else{

System.out.println(jsonObject.getString("errcode"));

}

}

}

另附上httpRequest请求方法:

/**

 * 发起https请求并获取结果

*

 * @param requestUrl 请求地址

 * @param requestMethod 请求方式(GET、POST)

 * @param outputStr 提交的数据

 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)

*/

public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {

JSONObject jsonObject = null;

StringBuffer buffer = new StringBuffer();

try {

// 创建SSLContext对象,并使用我们指定的信任管理器初始化

TrustManager[] tm = { new MyX509TrustManager() };

SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE");

sslContext.init(null, tm, new java.security.SecureRandom());

// 从上述SSLContext对象中得到SSLSocketFactory对象

SSLSocketFactory ssf = sslContext.getSocketFactory();

URL url = new URL(requestUrl);

HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();

httpUrlConn.setSSLSocketFactory(ssf);

httpUrlConn.setDoOutput(true);

httpUrlConn.setDoInput(true);

httpUrlConn.setUseCaches(false);

// 设置请求方式(GET/POST)

httpUrlConn.setRequestMethod(requestMethod);

if ("GET".equalsIgnoreCase(requestMethod))

httpUrlConn.connect();

// 当有数据需要提交时

if (null != outputStr) {

OutputStream outputStream = httpUrlConn.getOutputStream();

// 注意编码格式,防止中文乱码

outputStream.write(outputStr.getBytes("UTF-8"));

outputStream.close();

}

// 将返回的输入流转换成字符串

InputStream inputStream = httpUrlConn.getInputStream();

InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"utf-8");

BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String str = null;

while ((str = bufferedReader.readLine()) != null) {

buffer.append(str);

}

bufferedReader.close();

inputStreamReader.close();

// 释放资源

inputStream.close();

inputStream = null;

httpUrlConn.disconnect();

jsonObject = JSONObject.fromObject(buffer.toString());

} catch (ConnectException ce) {

} catch (Exception e) {

}

return jsonObject;

}

事件推送

在模版消息发送任务完成后,微信服务器会将是否送达成功作为通知,发送到开发者中心中填写的服务器配置地址中。

1、送达成功时,推送的XML如下:

<xml>
<ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
<FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]&g;</FromUserName>
<CreateTime>1395658920</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
<MsgID>200163836</MsgID>
<Status><![CDATA[success]]></Status>
</xml>
2、送达由于用户拒收(用户设置拒绝接收公众号消息)而失败时,推送的XML如下:

<xml>
<ToUserName><![CDATA[gh_7f083739789a]]></ToUserName>
<FromUserName><![CDATA[oia2TjuEGTNoeX76QEjQNrcURxG8]]></FromUserName>
<CreateTime>1395658984</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[TEMPLATESENDJOBFINISH]]></Event>
<MsgID>200163840</MsgID>
<Status><![CDATA[failed:user block]]></Status>
</xml>

在调用模板消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:

{

"errcode":0,

"errmsg":"ok",

"msgid":200228332

}

在根据相应的事件监听,就可以获取发送的状态,而及时对消息进行重复或其他的操作。

时间: 2024-10-30 21:18:03

微信公众号模板开发实例教程的相关文章

那里有微信公众号免费开发的教程

问题描述 那里有微信公众号免费开发的教程我们的CSDN论坛,怎么不搞一下微信公众号开发的版块,这些目前市面上比较好,资料不好找,其它论坛也有,到处注册账号,烦死人.. 解决方案 解决方案二:该回复于2016-07-10 23:47:53被版主删除解决方案三:我有一些整理解决方案四:该回复于2016-07-10 23:48:03被版主删除解决方案五:csdn早就有微信开发论坛了.

nodejs微信公众号支付开发_node.js

odeJs 微信公众号功能开发,移动端 H5页面调用微信的支付功能.这几天根据公司的需要使用 node 和 h5页面调用微信的支付功能完成支付需求.现在把开发过程重新捋一遍,以帮助更多的开发者顺利的完成微信支付功能的开发.(微信暂时还没有提供 node 的支付功能) 一.请求CODE 请求 code 的目的就是获取用户的 openid(用户相对于当前公众号的唯一标识) 和access_token,请求的API:https://open.weixin.qq.com/connect/oauth2/a

微信公众号模板消息无限报47001

问题描述 微信公众号模板消息无限报47001 {touser"":""OPENID""template_id"":""ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY""url"":""http://weixin.qq.com/download"" data"":{fir

使用Nodejs开发微信公众号后台服务实例_node.js

摘要: 微信,庞大的用户基数,极强的用户粘性,在近两年吸引了无数的开发者注意力. Nodejs,近两年发展非常快的开发工具,尤其适合构建移动后台.本文就以笔者自己开发的实例,来描述如何基于Nodejs开发属于自己的微信公众号.在这个实例中,主要使用到了express, wechat, mongodb, monk等模块. 前期准备: 1.申请微信公众号,前往 https://mp.weixin.qq.com/  申请,这里不做过多阐述. 2. 购买服务器, 这里推荐Amazon的EC2,首次用户可

使用开源库MAGICODES.WECHAT.SDK进行微信公众号支付开发

    概要 博客使用Word发博,发布后,排版会出现很多问题,敬请谅解.可加群获取原始文档. 本篇主要讲解微信支付的开发流程,相关业务基于MAGICODES.WECHAT.SDK实现.通过本篇教程,您可以很方便的快速完成微信公众号支付的开发. 关于Magicodes.WeChat.SDK MAGICODES.WECHAT.SDK为心莱团队封装的轻量级微信SDK,现已全部开源,开源库地址为:https://github.com/xin-lai/Magicodes.WeChat.SDK 更多介绍,

微信公众号模板消息群发php实例代码

微信模板消息只能发给一个人,如果要群发,需要通过php循环,依次发送. 注意,如果模板消息发信息时有时无,不稳定,可能你的access_token令牌更新缓存不及时,过期了.可以根据日志文件查看.建议300秒更新一下.否则会很烦. 模板id需要自己去公众号中设置行业后得到.    代码如下 复制代码 <?php  //使用方法.直接在页面的逻辑中增加fahuo_wechat();即可.函数要事先引用.  functionfahuo_wechat($shopid){       if(_cfg(&qu

微信公众号模板消息群发php代码示例

微信模板消息只能发给一个人,如果要群发,需要通过php循环,依次发送. 注意,如果模板消息发信息时有时无,不稳定,可能你的access_token令牌更新缓存不及时,过期了.可以根据日志文件查看.建议300秒更新一下.否则会很烦. 模板id需要自己去公众号中设置行业后得到. <?php //使用方法.直接在页面的逻辑中增加fahuo_wechat();即可.函数要事先引用. function fahuo_wechat($shopid){ if(_cfg("sendmobile")

.net实现微信公众账号接口开发实例代码_实用技巧

说起微信公众帐号,大家都不会陌生,使用这个平台能给网站或系统增加一个新亮点,直接进入正题吧,在使用之前一定要仔细阅读官方API文档.API文档地址:http://mp.weixin.qq.com/wiki/index.php 使用.net实现的方法://微信接口地址 页面代码: 复制代码 代码如下: weixin _wx = new weixin();  string postStr = "";  if (Request.HttpMethod.ToLower() == "po

关于微信公众号开发的问题 请教大神

问题描述 我负责公司微信公众号的开发,上线快一年了,调用微信公众平台API用的是httpclient.之前调微信API的时候很快的,5秒内就会响应,不知道为什么最近突然变的很慢,30-40秒才有响应.可是我没改过代码,服务器的配置也没改过,可为什么就是慢呢?有可能是微信服务器那边的问题吗?或者微信公众平台有什么更新?哪位大神了解这方面的或者碰到同样问题的? 解决方案 解决方案二:打时间戳,看你从给微信发消息到微信返回响应的时间差是多少,还有你的微信SDK是什么版本?现在更新很多了,有公众号,服务