C#微信公众号自动回复源码

    /// <summary>
    /// WechartInterface这里使用一般处理程序 这个写好然后在公众号后台配置地址就好了
    /// </summary>
    public class WechartInterface : IHttpHandler
    {
        protected string TOKEN = "0000"; //TOKEN 必须跟你在微信公众平台上写的token是一致的
        
 
        public void ProcessRequest(HttpContext context)
        {

            //context.Response.ContentType = "text/plain";
            context.Response.Clear(); //清除所有之前生成的Response内容
            Handlewinxin(context);  //进入专业微信处理程序
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="content"></param>
        public void Handlewinxin(HttpContext context)
        {
         
            if (context.Request.HttpMethod.ToUpper() == "GET")
            {
              
                // 微信加密签名  
                string signature = context.Request.QueryString["signature"];
                // 时间戳  
                string timestamp = context.Request.QueryString["timestamp"];
                // 随机数  
                string nonce = context.Request.QueryString["nonce"];
                // 随机字符串  
                string echostr = context.Request.QueryString["echostr"];
                if (CheckSignature(signature, timestamp, nonce))
                {
                    CreateMenu(context);
                    context.Response.Write(echostr);
                }

            }
            else if (context.Request.HttpMethod.ToUpper() == "POST")
            {

                StreamReader stream = new StreamReader(context.Request.InputStream);
                string xml = stream.ReadToEnd();

                processRequest(xml, context);
            }
        }
        /// <summary>
        /// 验证签名
        /// </summary>
        /// <param name="signature"></param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <returns></returns>
        public bool CheckSignature(String signature, String timestamp, String nonce)
        {
            String[] arr = new String[] { TOKEN, timestamp, nonce };
            // 将token、timestamp、nonce三个参数进行字典序排序  
            Array.Sort<String>(arr);

            StringBuilder content = new StringBuilder();
            for (int i = 0; i < arr.Length; i++)
            {
                content.Append(arr[i]);
            }

            String tmpStr = SHA1_Encrypt(content.ToString());


            // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信  
            return tmpStr != null ? tmpStr.Equals(signature) : false;
        }


        /// <summary>
        /// 使用缺省密钥给字符串加密
        /// </summary>
        /// <param name="Source_String"></param>
        /// <returns></returns>
        public static string SHA1_Encrypt(string Source_String)
        {
            byte[] StrRes = Encoding.Default.GetBytes(Source_String);
            HashAlgorithm iSHA = new SHA1CryptoServiceProvider();
            StrRes = iSHA.ComputeHash(StrRes);
            StringBuilder EnText = new StringBuilder();
            foreach (byte iByte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", iByte);
            }
            return EnText.ToString();
        }
        /// <summary>
        /// 处理微信发来的请求
        /// </summary>
        /// <param name="xml"></param>
        public void processRequest(String xml, HttpContext context)
        {

            try
            {
                LogHelper.Info("微信用户xml:" + xml);
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml)));  //postStr为微信服务器传过来的xml
                WxXmlModel wxXmlModel = new WxXmlModel();

               
                wxXmlModel.ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName").InnerText;
                wxXmlModel.FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName").InnerText;
                wxXmlModel.CreateTime = xmldoc.SelectSingleNode("/xml/CreateTime").InnerText;
                wxXmlModel.MsgType = xmldoc.SelectSingleNode("/xml/MsgType").InnerText;
                wxXmlModel.MsgId = xmldoc.SelectSingleNode("/xml/MsgId").InnerText;
                switch (wxXmlModel.MsgType)
                {
                    case "text":
                        wxXmlModel.Content = xmldoc.SelectSingleNode("/xml/Content").InnerText;
                         WeChatNewsSava(wxXmlModel);
                        wxXmlModel.Content = Context(wxXmlModel.Content);


                        HttpContext.Current.Response.Write(WxReplyContext(wxXmlModel));
                        HttpContext.Current.Response.End();
                        break;

                    case "image":
                        wxXmlModel.PicUrl = xmldoc.SelectSingleNode("/xml/PicUrl").InnerText;
                        WeChatNewsSava(wxXmlModel);
                        break;
                }
             
            }
            catch (Exception ex)
            {

                LogHelper.Info("微信用户发送消息错误消息:" + ex.Message);//写日志方便调试
            }
            //HttpContext.Current.Response.Write(wxXmlModel);
            //HttpContext.Current.Response.End();


        }


        /// <summary>       
        /// 10位时间戳转为C#格式时间       
        /// </summary>       
        /// <param name=”timeStamp”></param>       
        /// <returns></returns>       
        public  DateTime ConvertStringToDateTime(string timeStamp)
        {
            Int64 begtime = Convert.ToInt64(timeStamp) * 10000000;
            DateTime dt_1970 = new DateTime(1970, 1, 1, 8, 0, 0);
            long tricks_1970 = dt_1970.Ticks;//1970年1月1日刻度
            long time_tricks = tricks_1970 + begtime;//日志日期刻度
            DateTime dt = new DateTime(time_tricks);//转化为DateTime
            return dt;
        }

        /// <summary>
        /// 回复文本消息
        /// </summary>
        /// <param name="wxXml"></param>
        /// <returns></returns>
        public string WxReplyContext(WxXmlModel wxXml) 
        {
            string xml = "<xml>";
            xml += "<ToUserName><![CDATA["+ wxXml.FromUserName+ "]]></ToUserName>";
            xml += "<FromUserName><![CDATA[" + wxXml.ToUserName + "]]></FromUserName>";
            xml += "<CreateTime>" + GetTimestamp() + "</CreateTime>";
            xml += "<MsgType><![CDATA[" + wxXml.MsgType + "]]></MsgType>";
            xml += "<Content><![CDATA[" + wxXml.Content + "]]></Content>";
         
            xml += "</xml>";
            LogHelper.Info("微信回复用户文本:" + xml);
            return xml;
        }


        /// <summary>
        /// 将记录保存到数据库
        /// </summary>
        /// <param name="wxXmlModel"></param>
        public void WeChatNewsSava(WxXmlModel wxXmlModel)
        {
            Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
            keyValuePairs.Add(nameof(wxXmlModel.ToUserName), wxXmlModel.ToUserName);
            keyValuePairs.Add(nameof(wxXmlModel.FromUserName), wxXmlModel.FromUserName);
            keyValuePairs.Add(nameof(wxXmlModel.CreateTime), ConvertStringToDateTime(wxXmlModel.CreateTime));
            keyValuePairs.Add(nameof(wxXmlModel.MsgType), wxXmlModel.MsgType);
            keyValuePairs.Add(nameof(wxXmlModel.Content), wxXmlModel.Content);
            keyValuePairs.Add(nameof(wxXmlModel.PicUrl), wxXmlModel.PicUrl);
            keyValuePairs.Add(nameof(StationId), StationId);
            keyValuePairs.Add(nameof(CompanyId), CompanyId);
            new BasService().AddRowToDataByORM("tbWeChatNews", ref keyValuePairs);
            LogHelper.Info("微信用户发送消添加数据库表:tbWeChatNews");
        }

        /// <summary>
        /// 取当前时间戳十位数
        /// </summary>
        /// <returns></returns>
        public static long GetTimestamp()
        {
            TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1);//ToUniversalTime()转换为标准时区的时间,去掉的话直接就用北京时间
          //  return (long)ts.TotalMilliseconds; //精确到毫秒
            return (long)ts.TotalSeconds;//获取10位
        }

//自动回复 这里我是写死的 当然也可以取数据库的数据
        public string Context(string str)
        {
         string   strs = "";
            switch (str)
            {
                case "你好":
                    strs= "您好";
                    break;
                case "客服电话":
                    strs= "请联系站点客服";
                    break;
                case "客服":
                    strs= "您要转客服咨询嘛?请输入'人工客服'";
                    break;
                case "人工客服":
                    strs = "亲,当前客服繁忙,您可以留言您的问题,稍后我们客服会联系您";
                    break;
                default:

                    strs = "亲,没听懂您的意思哦";
                    break;

            }
            return strs;
        }

//配置公众号菜单  

public void CreateMenu(HttpContext context)
        {
            string access_token = “”;这个可以通过我前面的文章取获取,有写如何获取
            string posturl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + access_token;
            string menuStr = "";// " 菜单结构";
            using (StreamReader sr = new StreamReader(context.Server.MapPath("/WxMenu.json")))
            {
                menuStr = sr.ReadToEnd();
            }
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(posturl);
            request.Method = "POST";
            request.ContentType = "application/json";
        
            using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
            {
                dataStream.Write(menuStr);
                dataStream.Close();
            }
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string encoding = response.ContentEncoding;
            if (encoding == null || encoding.Length < 1)
            {
                encoding = "UTF-8"; //默认编码  
            }
            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
            string retString = reader.ReadToEnd();
        }
    }

//这个是配置公众号的菜单 这里是用着json数据    当然也可以用数据库或者文本    

{  

"button": [
    {
      "name": "外面按钮",
      "sub_button": [
        {
          "type": "view",
          "name": "子集按钮1",
          "url": "http://www.baidu.com"
        }
    
        {
          "type": "view",
          "name": "子集按钮2",
          "url": "http://www.baidu.com"
        }
      ]
    },
    {
      "type": "view",
      "name": "父级按钮1",
      "url": "http://www.baidu.com"
    }
 
  ]
}

}

不懂的可以留言


版权声明:本文为chenhaishi原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。