• C#微信公众号开发 -- (三)用户关注之后自动回复


     通过了上一篇文章之后的微信开发者验证之后,我们就可以做微信公众号的代码开发了。

    当我们点击关注某个公众号的时候,有时候会发现他会自动给我们回复一条消息,比如欢迎关注XXX公众号。这个功能其实是在点击关注的时候,用户触发了微信定义的事件,同时微信会返回给我们一个XML数据包,微信官方的解释如下:

    推送XML数据包示例:

    <xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[FromUser]]></FromUserName>
    <CreateTime>123456789</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[subscribe]]></Event>
    </xml>

    参数说明:

    参数描述
    ToUserName 开发者微信号
    FromUserName 发送方帐号(一个OpenID)
    CreateTime 消息创建时间 (整型)
    MsgType 消息类型,event
    Event 事件类型,subscribe(订阅)、unsubscribe(取消订阅)

     从示例中可以看出,如果我们想要处理用户点击的关注事件,那么必须要知道消息类型MsgType,事件类型Event。所以我们可以仿照着微信给我们的XML示例用C#建立一下事件接受的类,具体代码如下:

    public class wxmessage
        {
            /// <summary>
            /// 本公众帐号
            /// </summary>
            public string ToUserName { get; set; }
            /// <summary>
            /// 用户帐号
            /// </summary>
            public string FromUserName { get; set; }
            /// <summary>
            /// 发送时间戳
            /// </summary>
            public string CreateTime { get; set; }
            /// <summary>
            /// 发送的文本内容 
            /// </summary>
            public string Content { get; set; }
            /// <summary>
            /// 消息的类型
            /// </summary>
            public string MsgType { get; set; }
            /// <summary>
            /// 事件名称
            /// </summary>
            public string EventName { get; set; }
            
            //这两个属性会在后面的讲解中提到
            public string Recognition { get; set; }
            public string EventKey { get; set; } 
        }

    事件类建立完成之后,我们就可以在wxapi.aspx页面中做事件处理的逻辑操作了,请看下面的代码:

    public partial class wxapi : System.Web.UI.Page
        {
            const string _token = "在微信公众测试号后台写的那个Token";
            private const string _myOpenid = "你自己微信公众测试号的appID";
            string postStr = "";
            protected void Page_Load(object sender, EventArgs e)
            {
    
                //************** 验证成为开发者的时候将此代码注释 ***********//
                //对微信的信息进行处理和应用
                WXOpera();
    
                //***********  验证成为开发者之后将此代码注释 *************//
                //string httpMethod = Request.HttpMethod.ToLower();
                //if (httpMethod == "post")
                //{
                //    //第一次验证的时候开启
                //    FirstValid();
                //}
                //else
                //{
                //    Valid();  //如果不是post请求就去做开发者验证
                //}
            }
    
            /// <summary>
            /// 验证成为开发者
            /// </summary>
            private void Valid()
            {
                string echoStr = Request.QueryString["echoStr"].ToString();
                if (CheckSignature())
                {
                    if (!string.IsNullOrEmpty(echoStr))
                    {
                        Response.Write(echoStr);
                        Response.End();
                    }
                }
            }
    
            /// <summary>
            /// 验证微信签名
            /// </summary>
            /// * 将token、timestamp、nonce三个参数进行字典序排序
            /// * 将三个参数字符串拼接成一个字符串进行sha1加密
            /// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。
            /// <returns></returns>
            private bool CheckSignature()
            {
                string signature = Request.QueryString["signature"].ToString();
                string timestamp = Request.QueryString["timestamp"].ToString();
                string nonce = Request.QueryString["nonce"].ToString();
                string[] ArrTmp = { _token, timestamp, nonce };
                Array.Sort(ArrTmp);     //字典排序
                string tmpStr = string.Join("", ArrTmp);
                tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
                tmpStr = tmpStr.ToLower();
                if (tmpStr == signature)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
    
            /// <summary>
            /// 第一次验证配置
            /// </summary>
            private void FirstValid()
            {
                Stream s = System.Web.HttpContext.Current.Request.InputStream;
                byte[] b = new byte[s.Length];
                s.Read(b, 0, (int)s.Length);
                postStr = Encoding.UTF8.GetString(b);
                if (!string.IsNullOrEmpty(postStr))
                {
                    ResponseMsg(postStr);
                }
            }
    
            /// <summary>
            /// 返回信息结果(微信信息返回)
            /// </summary>
            /// <param name="weixinXML"></param>
            private void ResponseMsg(string weixinXML)
            {
                //回复消息的部分:你的代码写在这里
            }
    
            /// <summary>
            /// 微信操作
            /// </summary>
            private void WXOpera()
            {
                wxmessage wx = GetWxMessage();
                string res = "";
                if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "subscribe")
                {
                    //刚关注时的时间,用于欢迎词
                    string content = "";
                    content = "您好,欢迎关注XXX公众号";                
                    res = sendTextMessage(wx, content);
    
                    HttpContext.Current.Response.Write(res);
                    HttpContext.Current.Response.End();
                }
            }
        /// <summary>
            /// 获取和设置微信类中的信息
            /// </summary>
            /// <returns></returns>
            private wxmessage GetWxMessage()
            {
                wxmessage wx = new wxmessage();
                StreamReader str = new StreamReader(Request.InputStream, Encoding.UTF8);
                XmlDocument xml = new XmlDocument();
                xml.Load(str);
                str.Close();
                str.Dispose();
                wx.ToUserName = xml.SelectSingleNode("xml").SelectSingleNode("ToUserName").InnerText;
                wx.FromUserName = xml.SelectSingleNode("xml").SelectSingleNode("FromUserName").InnerText;
                wx.MsgType = xml.SelectSingleNode("xml").SelectSingleNode("MsgType").InnerText;
                if (wx.MsgType.Trim() == "text")
                {
                    wx.Content = xml.SelectSingleNode("xml").SelectSingleNode("Content").InnerText;
                }
                if (wx.MsgType.Trim() == "event")
                {
                    wx.EventName = xml.SelectSingleNode("xml").SelectSingleNode("Event").InnerText;
                    wx.EventKey = xml.SelectSingleNode("xml").SelectSingleNode("EventKey").InnerText;
                }
                return wx;
            }
         /// <summary>  
            /// 发送文字消息  
            /// </summary>  
            /// <param name="wx" />获取的收发者信息  
            /// <param name="content" />内容  
            /// <returns></returns>  
            private string sendTextMessage(wxmessage wx, string content)
            {
                string res = string.Format(Message_Text,
                    wx.FromUserName, wx.ToUserName, DateTime.Now.Ticks, content);
                return res;
            }
        /// <summary>
            /// 普通文本消息
            /// </summary>
            private static string Message_Text
            {
                get
                {
                    return @"<xml>
                                <ToUserName><![CDATA[{0}]]></ToUserName>
                                <FromUserName><![CDATA[{1}]]></FromUserName>
                                <CreateTime>{2}</CreateTime>
                                <MsgType><![CDATA[text]]></MsgType>
                                <Content><![CDATA[{3}]]></Content>
                                </xml>";
                }
            }
    }

    其中:Message_Text属性,是微信定义的发送文本消息格式,下面是微信官方给出的解释:

    文本消息格式:

    <xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[fromUser]]></FromUserName>
    <CreateTime>12345678</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[你好]]></Content>
    </xml>

    文本消息格式说明:
    参数是否必须描述
    ToUserName 接收方帐号(收到的OpenID)
    FromUserName 开发者微信号
    CreateTime 消息创建时间 (整型)
    MsgType text
    Content 回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)

    注:有的朋友可能会将这里的ToUserName和FromUserName,与接收事件的ToUserName和FromUserName混淆,可能你看出来了sendTextMessage()方法中参数顺序与Message_Text属性中的顺序不一致。

    然后重新将wxapi.aspx页面发布到服务器上面,随后用自己的微信号关注测试公众号(扫描测试公众号的二维码),关注完成之后,如果你能看到:您好,欢迎关注XXX公众号 ,则说明自动回复设置成功!

  • 相关阅读:
    优化页面响应时间
    php性能优化
    加快compser install 和update的方法
    好用的类库
    php会话(session)实现原理
    mysql引擎
    数据库事物四大特性
    数据库索引
    insert和insertSelective区别
    java面试题之int和Integer的区别
  • 原文地址:https://www.cnblogs.com/Violety/p/9814681.html
Copyright © 2020-2023  润新知