微信发送模板消息代码示例

最近一个微信的项目里需要发送微信模板消息给卖家或者供应商等,微信开发其实也就按照微信的官方接口要求组装起来即可,下面简单介绍一下我的微信模板发送代码。

1.获取access token,至于access token是什么,大家可以自行微信接口文档看一下,这边不多说

获取access token我这边主要是用定时器没大概2分钟获取一次,每天获取的次数是100000次,用法如下:

 1 #region
 2 
 3 using System;
 4 using System.Timers;
 5 
 6 #endregion
 7 
 8 namespace OAO2O.BusinessService.BLL
 9 {
10     public class WeChatTokenKeepBLL
11     {
12         /// <summary>
13         ///     用于存放获取的token
14         /// </summary>
15         private Timer _keepTokenTimer;
16 
17         #region access_token对象保持在线
18 
19         public void Initial()
20         {
21             //  初始化应用程序池时候,初始化token(第一次请求)
22             _KeepAccessToken();
23 
24             //初始化计时器
25             _keepTokenTimer = new Timer(TimeSpan.FromHours(1.55).TotalMilliseconds);
26                 //1.55   TimeSpan.FromHours(1.55).TotalMilliseconds
27             _keepTokenTimer.Elapsed += _keepTokenTimer_Elapsed;
28             _keepTokenTimer.Enabled = true;
29             _keepTokenTimer.Start();
30         }
31 
32         private void _keepTokenTimer_Elapsed(object sender, ElapsedEventArgs e)
33         {
34             _KeepAccessToken();
35         }
36 
37         /// <summary>
38         ///     获取token
39         /// </summary>
40         private void _KeepAccessToken()
41         {
42             string appid = ConfigBLL.APPID;
43             string appSecret = ConfigBLL.APPSECRET;
44             string token = WeChatBLL.GetAccessToken(appid, appSecret);
45 
46             ACCESS_TOKEN = token;
47             //Application[Consts.ACCESS_TOKEN] = token;
48         }
49         /// <summary>
50         /// ACCESS_TOKEN
51         /// </summary>
52         public static string ACCESS_TOKEN { private set; get; }
53 
54         #endregion
55     }
56 }
View Code

2.定义消息主体内容,区分大小写(经过测试必须小写,java的风格)

实体如下:

 1 #region
 2 
 3 using System;
 4 using System.Collections.Generic;
 5 
 6 #endregion
 7 
 8 namespace OAO2O.BusinessService.Entity
 9 {
10     [Serializable]
11     public sealed class WeChatTemplatecsMsg
12     {
13         public string touser { get; set; }
14         public string template_id { get; set; }
15         public string topcolor { get; set; }
16         public string url { get; set; }
17         public Dictionary<string, MessageData> data { get; set; }
18     }
19 
20     [Serializable]
21     public sealed class MessageData
22     {
23         public string value { get; set; }
24         public string color { get; set; } = "#1C86EE";
25     }
26 }
View Code

需要注意的是因为我们这边是内部调用不走soap协议,如果走soap协议, Dictionary<string, MessageData>是不能被二进制序列化的

3.编写发送微信消息方法

代码如下:

 1  public static string SendTempleteMessage(WeChatTemplatecsMsg messageInfo, string access_token)
 2         {
 3             try
 4             {
 5                 //临时测试脚本,正式使用将换成模板配置文件(等需求组确定模板之后)
 6                 string jsonDataParams = messageInfo == null
 7                     ? "" : SerializationEx.ToJson(messageInfo);
 8                 string requestUrl = string.Format(ConfigBLL.URL_POSTTEMELETETEXTMESSAGE, access_token);
 9                 return WebAPITransfer.Request(requestUrl,"POST", jsonDataParams);
10             }
11             catch (Exception ex)
12             {
13                 return ex.Message;
14             }
15         }

主要就是将实体转为json,没什么难度

4.定义xml配置文件

因为刚刚上面那个实体中,除了data和touser需要后期代码取值,三个是可以配置的,故写在配置文件中

 1 <Configs>
 2   <WeChatNodes>
 3     <!--(上级)新客户加入通知-->
 4     <WeChatNode name="AutoRegisterSuccess">
 5       <template_id>消息模板id</template_id>
 6       <topcolor>这个现在貌似没用了,但是还是要保留</topcolor>
 7       <url>收到消息下面有个详情,就是这边配置的地址</url>
 8     </WeChatNode>
 9     <!--(上级)订单支付完成-->
10     <WeChatNode name="PaySuccess">
11       <template_id>消息模板id</template_id>
12       <topcolor>这个现在貌似没用了,但是还是要保留</topcolor>
13       <url>收到消息下面有个详情,就是这边配置的地址</url>
14     </WeChatNode>
15     <!--(上级)订单取消通知-->
16     <WeChatNode name="OrderCancleSuccess">
17       <template_id>消息模板id</template_id>
18       <topcolor>这个现在貌似没用了,但是还是要保留</topcolor>
19       <url>收到消息下面有个详情,就是这边配置的地址</url>
20     </WeChatNode>
21     <!--(上级)订单退货通知-->
22     <WeChatNode name="OrderReturnSuccess">
23       <template_id>消息模板id</template_id>
24       <topcolor>这个现在貌似没用了,但是还是要保留</topcolor>
25       <url>收到消息下面有个详情,就是这边配置的地址</url>
26     </WeChatNode>
27     <!--(上级)营业额达标通知-->
28     <WeChatNode name="MonthSalesSuccess">
29       <template_id>消息模板id</template_id>
30       <topcolor>这个现在貌似没用了,但是还是要保留</topcolor>
31       <url>收到消息下面有个详情,就是这边配置的地址</url>
32     </WeChatNode>
33   </WeChatNodes>
34 </Configs>
View Code

5.编写反序列化xml文件到对象的类

首先需要编写一个与xml关联的类,代码如下:

 1 #region
 2 
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Xml.Serialization;
 6 
 7 #endregion
 8 
 9 namespace OAO2O.BusinessService.Entity
10 {
11     [XmlRoot("WeChatNode")]
12     public class WeChatNode
13     {
14         //定义NodeName属性的序列化为name节点的属性
15         [XmlAttribute("name")]
16         public string NodeName { get; set; }
17 
18         //设置TemplateId属性序列化为Xml子元素template_id
19         [XmlElement("template_id")]
20         public string TemplateId { get; set; }
21 
22         //设置Topcolor属性序列化为Xml子元素topcolor
23         [XmlElement("topcolor")]
24         public string Topcolor { get; set; }
25 
26         //设置Url属性序列化为Xml子元素url
27         [XmlElement("url")]
28         public string Url { get; set; }
29     }
30 
31     [XmlRoot("Configs")]
32     public class WeChatNodes
33     {
34         [XmlArray("WeChatNodes"), XmlArrayItem("WeChatNode")]
35         public WeChatNode[] WeChatNodeList { get; set; }
36     }
37 
38     /// <summary>
39     /// 节点名称枚举
40     /// </summary>
41     public enum EnumNodeName
42     {
43         /// <summary>
44         /// 自动注册成功
45         /// </summary>
46         AutoRegisterSuccess,
47         /// <summary>
48         /// 支付成功
49         /// </summary>
50         PaySuccess,
51         /// <summary>
52         /// 订单取消成功
53         /// </summary>
54         OrderCancleSuccess,
55         /// <summary>
56         /// 订单退货成功
57         /// </summary>
58         OrderReturnSuccess,
59         /// <summary>
60         /// 营业额达标成功
61         /// </summary>
62         MonthSalesSuccess
63     }
64 }
View Code

然后编写反序列化xml的公共类,放到公共类库中,代码如下:

1   public static T FromXmlFile<T>(string xmlFile)
2         {
3             if ( !File.Exists(xmlFile)) throw new ArgumentNullException(xmlFile, "文件不存在!");
4             using (FileStream fs = new FileStream(xmlFile, FileMode.Open, FileAccess.Read))
5             {
6                 XmlSerializer ser = new XmlSerializer(typeof(T));
7                 return (T)ser.Deserialize(fs);
8             }
9         }

6.因为微信模板消息体都是固定的五个参数,故把获取微信模板实体的方法放到一个公共的类中

代码如下:

  1    /// <summary>
  2     /// 构造微信模板消息体
  3     /// </summary>
  4     public class TemplateMsgConstructor
  5     {
  6         /// <summary>
  7         /// 从xml中获取所有的发送微信的节点集合
  8         /// </summary>
  9         public static WeChatNodes WeChatNodes = SerializationEx.FromXmlFile<WeChatNodes>(AppDomain.CurrentDomain.BaseDirectory + "\config\WechatMsgTemplate.xml");
 10 
 11         /// <summary>
 12         ///     (上级)新客户加入通知
 13         /// </summary>
 14         /// <param name="memberId"></param>
 15         /// <param name="memberName"></param>
 16         /// <returns></returns>
 17         public static WeChatTemplatecsMsg GetMemberRegistMsg(string memberId, string memberName)
 18         {
 19             #region 模板
 20 
 21             //            { { first.DATA} }
 22             //            会员编号:{ { keyword1.DATA} }
 23             //            加入时间:{ { keyword2.DATA} }
 24             //            { { remark.DATA} }
 25 
 26             #endregion
 27 
 28             //微信发送节点
 29             WeChatNode weChatNode = WeChatNodes.WeChatNodeList.FirstOrDefault(item => item.NodeName == EnumNodeName.AutoRegisterSuccess.ToString());
 30             var msg = new WeChatTemplatecsMsg
 31             {
 32                 template_id = weChatNode?.TemplateId,
 33                 touser = string.Empty,
 34                 topcolor = weChatNode?.Topcolor,
 35                 url = weChatNode?.Url,
 36                 data = new Dictionary<string, MessageData>
 37                 {
 38                     {"first", new MessageData {value = $"您推荐的客户【{memberName}】已经加入了南京宁商汇"}},
 39                     {"keyword1", new MessageData {value = memberId}},
 40                     {"keyword2", new MessageData {value = DateTime.Now.ToString("yyyy-MM-dd HH:mm")}},
 41                     {"remark", new MessageData {value = "感谢您的努力!"}}
 42                 }
 43             };
 44             return msg;
 45         }
 46 
 47         /// <summary>
 48         ///     (上级)订单支付完成
 49         /// </summary>
 50         /// <param name="orderId"></param>
 51         /// <param name="orderTotalMoney"></param>
 52         /// <param name="orderName"></param>
 53         /// <returns></returns>
 54         public static WeChatTemplatecsMsg GetOrderPayMsg(string orderId, string orderTotalMoney)
 55         {
 56             #region 模板
 57 
 58             //            { { first.DATA} }
 59             //
 60             //            支付金额:{ { orderMoneySum.DATA} }
 61             //            商品信息:{ { orderProductName.DATA} }
 62             //            { { Remark.DATA} }
 63 
 64             #endregion
 65 
 66             //微信发送节点
 67             WeChatNode weChatNode = WeChatNodes.WeChatNodeList.FirstOrDefault(item => item.NodeName == EnumNodeName.PaySuccess.ToString());
 68             var msg = new WeChatTemplatecsMsg
 69             {
 70                 template_id = weChatNode?.TemplateId,
 71                 touser = string.Empty,
 72                 topcolor = weChatNode?.Topcolor,
 73                 url = weChatNode?.Url,
 74                 data = new Dictionary<string, MessageData>
 75                 {
 76                     {"first", new MessageData {value = $"图牛有订单,请关注!(订单号:{orderId})"}},
 77                     {"orderMoneySum", new MessageData {value = orderTotalMoney + ""}},
 78                     {"orderProductName", new MessageData {value = orderId}},
 79                     {"Remark", new MessageData {value = " 如有问题请致电400 666 2060!"}}
 80                 }
 81             };
 82             return msg;
 83         }
 84 
 85         /// <summary>
 86         ///     (上级)订单取消通知
 87         /// </summary>
 88         /// <param name="orderId"></param>
 89         /// <returns></returns>
 90         public static WeChatTemplatecsMsg GetCancleOrderMsg(string orderId)
 91         {
 92             #region 模板
 93 
 94             //            { { first.DATA} }
 95             //            订单编号:{ { keyword1.DATA} }
 96             //            时间:{ { keyword2.DATA} }
 97             //            { { remark.DATA} }
 98 
 99             #endregion
100 
101             //微信发送节点
102             WeChatNode weChatNode = WeChatNodes.WeChatNodeList.FirstOrDefault(item => item.NodeName == EnumNodeName.OrderCancleSuccess.ToString());
103             var msg = new WeChatTemplatecsMsg
104             {
105                 template_id = weChatNode?.TemplateId,
106                 touser = string.Empty,
107                 topcolor = weChatNode?.Topcolor,
108                 url = weChatNode?.Url,
109                 data = new Dictionary<string, MessageData>
110                 {
111                     {"first", new MessageData {value = "订单被取消,请关注!"}},
112                     {"keyword1", new MessageData {value = orderId}},
113                     {"keyword2", new MessageData {value = DateTime.Now.ToString("yyyy-MM-dd HH:mm")}},
114                     {"remark", new MessageData {value = "如有问题请致电400 666 2060!"}}
115                 }
116             };
117             return msg;
118         }
119 
120         /// <summary>
121         ///     (上级)订单退货通知
122         /// </summary>
123         /// <param name="orderId"></param>
124         /// <param name="orderName"></param>
125         /// <param name="orderTotalMoney"></param>
126         /// <returns></returns>
127         public static WeChatTemplatecsMsg GetSalesReturnMsg(string orderId, string orderTotalMoney)
128         {
129             #region 模板
130 
131             //            { { first.DATA} }
132             //            订单编号:{ { keyword1.DATA} }
133             //            商品名称:{ { keyword2.DATA} }
134             //            订单金额:{ { keyword3.DATA} }
135             //            { { remark.DATA} }
136 
137             #endregion
138 
139             //微信发送节点
140             WeChatNode weChatNode = WeChatNodes.WeChatNodeList.FirstOrDefault(item => item.NodeName == EnumNodeName.OrderReturnSuccess.ToString());
141             var msg = new WeChatTemplatecsMsg
142             {
143                 template_id = weChatNode?.TemplateId,
144                 touser = string.Empty,
145                 topcolor = weChatNode?.Topcolor,
146                 url = weChatNode?.Url,
147                 data = new Dictionary<string, MessageData>
148                 {
149                     {"first", new MessageData {value = "订单被退货,请关注!"}},
150                     {"keyword1", new MessageData {value = orderId}},
151                     {"keyword2", new MessageData {value = orderId}},
152                     {"keyword3", new MessageData {value = orderTotalMoney + ""}},
153                     {"remark", new MessageData {value = DateTime.Now.ToString("yyyy-MM-dd HH:mm")}}
154                 }
155             };
156             return msg;
157         }
158 
159         /// <summary>
160         ///     (上级)营业额达标通知
161         /// </summary>
162         /// <param name="orderSumMoney"></param>
163         /// <param name="first"></param>
164         /// <returns></returns>
165         public static WeChatTemplatecsMsg GetOrderAmountUpToStandard(string orderSumMoney,
166             string first = "完善企业资质后,")
167         {
168             #region 模板
169 
170             //            { { first.DATA} }
171             //            汇总周期:{ { keyword1.DATA} }
172             //            营业额:{ { keyword2.DATA} }
173             //            { { remark.DATA} }
174 
175             #endregion
176 
177             //微信发送节点
178             WeChatNode weChatNode = WeChatNodes.WeChatNodeList.FirstOrDefault(item => item.NodeName == EnumNodeName.MonthSalesSuccess.ToString());
179             var msg = new WeChatTemplatecsMsg
180             {
181                 template_id = weChatNode?.TemplateId,
182                 touser = string.Empty,
183                 topcolor = weChatNode?.Topcolor,
184                 url = weChatNode?.Url,
185                 data = new Dictionary<string, MessageData>
186                 {
187                     {"first", new MessageData {value = $"您当月累计营业额已达标。{first}将于当月最后一日激活解冻资金。"}},
188                     {
189                         "keyword1",
190                         new MessageData
191                         {
192                             value =
193                                 new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).ToString("yyyy-MM-dd") + "-" +
194                                 DateTime.Now.ToString("yyyy-MM-dd")
195                         }
196                     },
197                     {"keyword2", new MessageData {value = orderSumMoney + ""}},
198                     {"remark", new MessageData {value = "感谢您的关注!"}}
199                 }
200             };
201             return msg;
202         }
203     }
View Code

7.找到需要发送微信的环节,添加发送微信消息的代码

代码如下:

 1  /// <summary>
 2         /// 新客户加入发送微信通知
 3         /// </summary>
 4         /// <param name="reg"></param>
 5         private static void SendRegistMsg(RegisterEntity reg)
 6         {
 7             try
 8             {
 9                 //获取WeChatTemplatecsMsg实体
10                 WeChatTemplatecsMsg entity = TemplateMsgConstructor.GetMemberRegistMsg(reg.MemberId, reg.MemberName);
11                 //设置被发送者openid
12                 entity.touser = GetMemberMasterOpenId(reg.MemberId);
13 
14                 CommonBLL.DebugLog(entity, "SendRegistMsg-Param");
15 
16                 if (!entity.touser.IsEmptyString())
17                 {
18                     //发送微信消息
19                     var result = WeChatBLL.SendTempleteMessage(entity, WeChatTokenKeepBLL.ACCESS_TOKEN);
20                     CommonBLL.DebugLog(result, "SendRegistMsg-Result");
21                 }
22             }
23             catch(Exception ex)
24             {
25                 CommonBLL.DebugLog(ex, "SendRegistMsg-Exception");
26             }
27         }
View Code

总结:

整个流程按步骤下来大家发现其实也没啥难度,第三方接口开发只要对方接口描述比较准确,各种规定比较明确,基本就是封装成接口需要的东西就完事了

相关推荐