使用微信公众号模板消息发送(基于.NET开发)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LYTIT/article/details/72511521

使用微信公众号模板消息发送,能够在用户操作网站时对指定用户发送消息提示,不仅能够及时反馈,还能用户一个好的体验,还可以节约短息推送的成本;
下面是比较重要的部分我做了一个截取展示,详细接口介绍请移步到, 微信官网地址:https://mp.weixin.qq.com/wiki

获得模板ID,从行业模板库选择模板到帐号后台,获得模板ID的过程可在微信公众平台后台完成。为方便第三方开发者,提供通过接口调用的方式来

获取模板ID,具体如下:

接口调用请求说明 http请求方式: POST
https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=ACCESS_TOKEN
POST数据说明

POST数据示例如下:
      {
           "template_id_short":"TM00015"
       }

参数说明
参数是否必须说明access_token是接口调用凭证template_id_short是模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式
返回码说明 在调用模板消息接口后,会返回JSON数据包。正常时的返回JSON数据包示例:

       {
           "errcode":0,
           "errmsg":"ok",
           "template_id":"Doclyl5uP7Aciu-qZ7mJNPtWkbkYnWBWVja26EGbNyk"
       }

发送模板消息 接口调用请求说明 http请求方式: POST
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
POST数据说明

POST数据示例如下:

     {
           "touser":"OPENID",
           "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
           "url":"http://weixin.qq.com/download",  
           "miniprogram":{
             "appid":"xiaochengxuappid12345",
             "pagepath":"index?foo=bar"
           },          
           "data":{
                   "first": {
                       "value":"恭喜你购买成功!",
                       "color":"#173177"
                   },
                   "keynote1":{
                       "value":"巧克力",
                       "color":"#173177"
                   },
                   "keynote2": {
                       "value":"39.8元",
                       "color":"#173177"
                   },
                   "keynote3": {
                       "value":"2014年9月22日",
                       "color":"#173177"
                   },
                   "remark":{
                       "value":"欢迎再次购买!",
                       "color":"#173177"
                   }
           }
       }

参数说明

参数是否必填说明touser是接收者openidtemplate_id是模板IDurl否模板跳转链接miniprogram否跳小程序所需数据,不需跳小程序可不用传该数据appid是所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系)pagepath是所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar)data是模板数据
注:url和miniprogram都是非必填字段,若都不传则模板无跳转;若都传,会优先跳转至小程序。开发者可根据实际需要选择其中一种跳转方式即可。当用户的微信客户端版本不支持跳小程序时,将会跳转至url。

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

      {
           "errcode":0,
           "errmsg":"ok",
           "msgid":200228332
       }

下面是我利用.NET实现的关键代码(注:这只是实现会员注册成功后的信息推送模板,其他模板相同处理)
调用方式,如下:

 string strJSON = WeixinTemplateHelper.GetJoinMember(weiXinAccount.User.Userid, weiXinAccount.UserName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), SiteConfigManager.GetConfigStringByKey("weixinH5Domain"));//这里是获取数据库中保存的模板信息组装成接口需要发送的格式
                    if (strJSON != "")
                    {                       
                        WeixinTemplateHelper.SendMessage(strJSON);//调用微信接口发送
                    }

组装为微信标准格式的信息

///组装为微信标准格式的信息
 public static string GetJoinMember(long UserID, string MemberNO, string JoinTime, string Url = "")
        {
            string UserAccount = "";
            if (IsWeiXinUser(UserID, ref UserAccount))//获取用户在微信中OpeId信息
            {
                WeiXinMsgConfig model = new WeiXinMsgConfigBLL().GetModelByTemplateNO(WeixinTemplateType.ChengWeiHuiYuan);//这里我是将自定义模板信息保存到数据的,后台做了一个管理,这个方法是获取我配置的推送消息模板
                if (model.IsSend == 0)
                {
                    return "";
                }
                var obj = new
                {
                    touser = UserAccount,
                    template_id = model.TemplateID,
                    url = Url,
                    topcolor = "#FF0000",
                    data = new
                    {
                        first = new { value = model.TemplateFirst, color = "#173177" },
                        keyword1 = new { value = MemberNO, color = "#173177" },
                        keyword2 = new { value = JoinTime, color = "#173177" },
                        remark = new { value = model.TemplateRemark, color = "#173177" }
                    }
                };               
                return obj.GetJsonByObj();
            }
            else
            {
                return "";
            }
        }

发送组装的信息给指定的用户

  //发送组装的信息给指定的用户
   public static string SendMessage(string JsonData)
        {
            try
            {
                HttpClientHelper httpclient = new HttpClientHelper();
                string strUrl = string.Format(CommonUtilities.H5Constants.WeixinApi.WeiXinSendMessage, GetAccess_Token(appid, appsecret));//根据微信的接口请求组装相应的路径
                string strResult = httpclient.SendPostRequest(strUrl, JsonData);//通过Post请求访问接口
                return WebHelper.ParseFormJson<SendMessageResult>(strResult).errmsg;//获取返回信息
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

获取微信的Access_Token

//获取微信的Access_Token
 public static string GetAccess_Token(string appID, string appSecret)
        {
            //if (appID == appid && appSecret == appsecret && access_token != "" && (DateTime.Now - access_token_time).Seconds < 7000)
            //{
            //}
            //else
            //{

            DataRow dr = new DeveloperInfoDAL().GetDeveloperInfo(CommonUtilities.DataBase.DataFactory.CreateDataBase());//这是获取保存在数据中微信公众号的appID和appSecret 
            appid = dr != null ? dr["AppId"].ToString() : "";
            appsecret = dr != null ? dr["AppSecret"].ToString() : "";

            HttpClientHelper httpclient = new HttpClientHelper();
            httpclient.Url = string.Format(CommonUtilities.H5Constants.WeixinApi.WeixinMenuGetAccessToken, appID, appSecret);//组装获取Access_Token的接口访问路径
            string strResult = httpclient.GetString();//采用GET请求访问接口
            access_token = WebHelper.JSONToObject<TokenResult>(strResult).access_token;
            access_token_time = DateTime.Now;
            //}
            return access_token;
        }

需要的基础方法的封装实现

      /// <summary>
        /// 发起一个POST类型的Web请求,并返回响应
        /// </summary>
        /// <param name="requestUri">请求地址</param>
        /// <param name="jsonData">json数据包</param>
        /// <returns>响应</returns>
        public string SendPostRequest(string requestUri, string jsonData)
        {
            if (requestUri.IfNull().ToLower().Trim().StartsWith("https"))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
            }
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUri);
            byte[] data = Encoding.UTF8.GetBytes(jsonData);
            httpWebRequest.Method = "POST";
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            httpWebRequest.ContentLength = data.Length;
            httpWebRequest.KeepAlive = true;

            using (var requestStream = httpWebRequest.GetRequestStream())
            {
                requestStream.Write(data, 0, data.Length);
            }

            HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
            string content = reader.ReadToEnd();
            reader.Close();
            responseStream.Close();
            response.Close();
            return content;
        }
 /// <summary>
        /// 发出一次新的请求,并以字节数组形式返回回应的内容
        /// 调用此方法会触发StatusUpdate事件
        /// </summary>
        /// <returns>包含回应主体内容的字节数组</returns>
        public byte[] GetBytes()
        {
            HttpWebResponse res = GetResponse();
            int length = (int)res.ContentLength;

            MemoryStream memoryStream = new MemoryStream();
            byte[] buffer = new byte[0x100];
            Stream rs = res.GetResponseStream();
            for (int i = rs.Read(buffer, 0, buffer.Length); i > 0; i = rs.Read(buffer, 0, buffer.Length))
            {
                memoryStream.Write(buffer, 0, i);
                OnStatusUpdate(new StatusUpdateEventArgs((int)memoryStream.Length, length));
            }
            rs.Close();

            return memoryStream.ToArray();
        }

        /// <summary>
        /// 发出一次新的请求,以Http头,或Html Meta标签,或DefaultEncoding指示的编码信息对回应主体解码
        /// 调用此方法会触发StatusUpdate事件
        /// </summary>
        /// <returns>解码后的字符串</returns>
        public string GetString()
        {
            byte[] data = GetBytes();
            string encodingName = GetEncodingFromHeaders();

            if (encodingName == null)
                encodingName = GetEncodingFromBody(data);

            Encoding encoding;
            if (encodingName == null)
                encoding = defaultEncoding;
            else
            {
                try
                {
                    encoding = Encoding.GetEncoding(encodingName);
                }
                catch (ArgumentException)
                {
                    encoding = defaultEncoding;
                }
            }
            return encoding.GetString(data);
        }

猜你喜欢

转载自blog.csdn.net/LYTIT/article/details/72511521