run in this way,   no why,   only for you heart
CSDN博客(点击进入) CSDN
51CTO(点击进入) 51CTO

微信公众号开发--消息接收与回复

在上篇文章中已经说明如何接入微信服务器,此篇直接接着上篇文章介绍公众号的消息接收与回复,可以结合上篇文章阅读本文,微信公众号开发–服务器接入

微信公众号开发接口文档: https://mp.weixin.qq.com

1.如何接收公众号的消息
在接入验证微信服务器时,公众号平台是通过我们填写的URL发送Get请求与我们的开发平台验证,接收消息也是通过该URL,当微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到我们填写的URL上。其中消息分为普通消息和事件消息,普通消息包含文本,图片,语音等消息,事件消息包含用户关注,取消关注等消息, 具体可以阅读微信公众号的开发API。

2.如何回复用户消息
当用户发送消息给公众号时(即接收公众号的消息),会产生一个POST请求,我们回复的消息处理成特定的XML包来对该消息进行响应。

3.消息接收与回复
  3.1接收消息

	public void Wx(string signature, string timestamp, string nonce, string echostr)
        { 
            //Post请求处理           
            if (System.Web.HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
            {
                Stream requestStream = System.Web.HttpContext.Current.Request.InputStream;
                byte[] requestByte = new byte[requestStream.Length];
                requestStream.Read(requestByte, 0, (Int32)requestStream.Length);
                string requestStr = Encoding.UTF8.GetString(requestByte);

                if (!string.IsNullOrEmpty(requestStr))
                {
                    //封装请求类
                    XmlDocument requestDocXml = new XmlDocument();
                    requestDocXml.LoadXml(requestStr);
                    XmlElement rootElement = requestDocXml.DocumentElement;
                    NewsModel newsModel = new NewsModel();
                    newsModel.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;
                    newsModel.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
                    newsModel.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;
                    newsModel.MsgType = rootElement.SelectSingleNode("MsgType").InnerText;
                    switch (newsModel.MsgType)
                    {
                        case "text"://文本
                            newsModel.Content = rootElement.SelectSingleNode("Content").InnerText;
                            break;
                        case "image"://图片
                            newsModel.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;
                            break;
                        case "event"://事件
                            newsModel.Event = rootElement.SelectSingleNode("Event").InnerText;
                            if (newsModel.Event == "subscribe")//关注类型
                            {
                                newsModel.EventKey = rootElement.SelectSingleNode("EventKey").InnerText;
                            }
                            break;
                        default:
                            break;
                    }
                    ResponseXML(newsModel); //回复消息
                    //bs.Close();
                    //return Encoding.UTF8.GetString(buff);
                }
            }
        }

  3.2回复消息

	private void ResponseXML(NewsModel newsModel)
        {
            string XML = "";
            switch (newsModel.MsgType)
            {
                case "text"://文本回复
                    XML = ReText(newsModel.FromUserName, newsModel.ToUserName, newsModel.Content);                   
                    break;
                case "image"://图片回复
                    XML = ReImage(newsModel.FromUserName, newsModel.ToUserName, newsModel.PicUrl);
                    break;
                case "event"://事件回复
                    XML = ReEvent(newsModel.FromUserName, newsModel.ToUserName, newsModel.Event);
                    break;
                default://默认回复
                    break;
            }
            System.Web.HttpContext.Current.Response.Write(XML);
            System.Web.HttpContext.Current.Response.End();
        }
        #endregion

        #region 文本格式
        /// <summary>
        /// 回复文本
        /// </summary>
        /// <param name="FromUserName">发送给谁(openid)</param>
        /// <param name="ToUserName">来自谁(公众账号ID)</param>
        /// <param name="Content">回复类型文本</param>
        /// <returns>拼凑的XML</returns>
        public static string ReText(string FromUserName, string ToUserName, string Content)
        {
            string XML = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName>";//发送给谁(openid),来自谁(公众账号ID)
            XML += "<CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";//回复时间戳
            XML += "<MsgType><![CDATA[text]]></MsgType>";//回复类型文本
            XML += "<Content><![CDATA[" + Content + "]]></Content><FuncFlag>0</FuncFlag></xml>";//回复内容 FuncFlag设置为1的时候,自动星标刚才接收到的消息,适合活动统计使用
            return XML;
        }
        #endregion

        #region 图片格式
        public static string ReImage(string FromUserName, string ToUserName, string PicUrl)
        {
            //回复用户图片信息,需要使用素材管理,必须含有参数 access_token,media_id
            //现在公众号接收到消息,先回复文本消息。
            string XML = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName>";//发送给谁(openid),来自谁(公众账号ID)
            XML += "<CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";//回复时间戳
            //XML += "<MsgType><![CDATA[image]]></MsgType>";//回复类型文本
            //XML += "<PicUrl><![CDATA[" + PicUrl + "]]></PicUrl>";
            XML += "<MsgType><![CDATA[text]]></MsgType>";
            XML += "<Content><![CDATA[亲,已经接收到您的图片,图片消息回复接口暂时未开通。]]></Content>";
            XML += "<FuncFlag>0</FuncFlag></xml>";//回复内容 FuncFlag设置为1的时候,自动星标刚才接收到的消息,适合活动统计使用
            return XML;
        }
        #endregion

        #region 事件格式
        public static string ReEvent(string FromUserName, string ToUserName, string Event)
        {
            
            string XML = "<xml><ToUserName><![CDATA[" + FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName + "]]></FromUserName>";//发送给谁(openid),来自谁(公众账号ID)
            XML += "<CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";//回复时间戳
            XML += "<MsgType><![CDATA[text]]></MsgType>";//回复类型文本
            if (Event == "subscribe")
            {
                XML += "<Content><![CDATA[感谢关注,茫茫人海中,能与您在此相识是我的荣幸。]]></Content><FuncFlag>0</FuncFlag></xml>";//回复内容 FuncFlag设置为1的时候,自动星标刚才接收到的消息,适合活动统计使用
            }
            else {
                XML += "<Content><![CDATA[谢谢您的包容,祝您生活愉快,身体健康。]]></Content><FuncFlag>0</FuncFlag></xml>";
            }
            return XML;
        } 
        #endregion

        #region 时间戳处理
        /// <summary>
        /// DateTime时间格式转换为Unix时间戳格式
        /// </summary>
        /// <param name="time"> DateTime时间格式</param>
        /// <returns>Unix时间戳格式</returns>
        public static int ConvertDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        } 
        #endregion

在接收消息时,代码有针对消息类别的识别,以及回复消息的XML格式等,这些是根据微信公众号开发文档所规定格式,可以综合开发文档看上面的代码。该项目工程在我的GitHub中,感兴趣可以下载源码或者加入 https://github.com/wangqilong1225/WeChat

4.最后求关注
本以为可以开发出一个完整功能的公众号,当想去处理公众号底部菜单栏等功能时,发现这些接口必须要经过微信的认证才有权限开发,而微信认证需要300RMB,有点心疼,所以开发到此先暂停了,后面有机会(钱),再继续下去。最后感兴趣的小伙伴可以关注下我的公众号,谢谢。
在这里插入图片描述

posted @ 2019-02-24 12:42  _小龙人  阅读(469)  评论(0编辑  收藏  举报