微信公众号服务器配置关注回调

1. 在微信公众号中,开发  -->  基本配置

2. post的服务器地址

protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                if (Request.HttpMethod.ToLower() == "post")
                {
                    string postStr = "";
                    postStr = PostInput();//获取xml数据
                    string weixin = "";
                    weixin = postStr;//获取xml数据
                    if (!string.IsNullOrEmpty(postStr) && !string.IsNullOrEmpty(weixin))
                    {
                        try
                        {//注册
                            XmlDocument doc1 = new XmlDocument();
                            doc1.LoadXml(weixin);//读取xml字符串
                            XmlNodeList list = doc1.GetElementsByTagName("xml");
                            XmlNode xn = list[0];
                            string Event = xn.SelectSingleNode("//Event").InnerText;
                            string FromUserName = xn.SelectSingleNode("//FromUserName").InnerText;
                            string EventKey = xn.SelectSingleNode("//EventKey").InnerText;
                        }
                        catch
                        {

                        }
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(postStr);//读取xml字符串
                                             //公众号发消息
                        XmlElement root = doc.DocumentElement;
                        ExmlMsg xmlMsg = GetExmlMsg(root);

                        ResponseMsg(xmlMsg);////调用消息适配器  
                    }
                }
                Valid();
            }
        }
#region 获取post请求数据
        /// <summary>
        /// 获取post请求数据
        /// </summary>
        /// <returns></returns>
        private string PostInput()
        {
            Stream s = System.Web.HttpContext.Current.Request.InputStream;
            byte[] b = new byte[s.Length];
            s.Read(b, 0, (int)s.Length);
            return Encoding.UTF8.GetString(b);
        }
        #endregion
#region 接收的消息实体类 以及 填充方法
        private class ExmlMsg
        {
            /// <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; }

        }

        private ExmlMsg GetExmlMsg(XmlElement root)
        {
            ExmlMsg xmlMsg = new ExmlMsg()
            {
                FromUserName = root.SelectSingleNode("FromUserName").InnerText,
                ToUserName = root.SelectSingleNode("ToUserName").InnerText,
                CreateTime = root.SelectSingleNode("CreateTime").InnerText,
                MsgType = root.SelectSingleNode("MsgType").InnerText,
            };
            if (xmlMsg.MsgType.Trim().ToLower() == "text")
            {
                xmlMsg.Content = root.SelectSingleNode("Content").InnerText;
            }
            else if (xmlMsg.MsgType.Trim().ToLower() == "event")
            {
                xmlMsg.EventName = root.SelectSingleNode("Event").InnerText;
            }
            return xmlMsg;
        }
        #endregion

// token验证

private void Valid()
        {
            string echoStr = Request.QueryString["echoStr"].ToString();
            if (CheckSignature())
            {
                if (!string.IsNullOrEmpty(echoStr))
                {
                    Response.Write(echoStr);
                    Response.End();
                }
            }
        }
        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;
            }
        }
#region 消息类型适配器
        private void ResponseMsg(ExmlMsg xmlMsg)// 服务器响应微信请求
        {
            string messageType = xmlMsg.MsgType;//获取收到的消息类型。文本(text),图片(image),语音等。
            try
            {
                switch (messageType)
                {
                    //当消息为文本时
                    case "text":
                        textCase(xmlMsg);
                        break;
                    case "event":
                        textCase1(xmlMsg);
                        break;
                    case "image":
                        textCase(xmlMsg);
                        break;
                    case "voice":
                        textCase(xmlMsg);
                        break;
                    case "vedio":
                        textCase(xmlMsg);
                        break;
                    case "location":
                        textCase(xmlMsg);
                        break;
                    case "link":
                        textCase(xmlMsg);
                        break;
                    default:
                        break;
                }
                Response.End();
            }
            catch (Exception)
            {

            }
        }
        #endregion

        #region 发送消息 操作文本消息 + void textCase(XmlElement root)

        private string getText(ExmlMsg xmlMsg)
        {
            madmin = badmin.GetModel(3);

            System.Text.StringBuilder retsb = new StringBuilder(200);
            retsb.Append(madmin.receivename);
            //retsb.Append("接收到的消息:" + xmlMsg.Content);
            //retsb.Append("用户的OPEANID:" + xmlMsg.FromUserName);

            return retsb.ToString();
        }
        private void textCase(ExmlMsg xmlMsg)
        {
            int nowtime = ConvertDateTimeInt(DateTime.Now);
            string msg = "";
            msg = getText(xmlMsg);
            string resxml = "<xml><ToUserName><![CDATA[" + xmlMsg.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + xmlMsg.ToUserName + "]]></FromUserName><CreateTime>" + nowtime + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + msg + "]]></Content><FuncFlag>0</FuncFlag></xml>";
            Response.Write(resxml);

            return;

        }
        #endregion

        #region 将datetime.now 转换为 int类型的秒
        /// <summary>
        /// datetime转换为unixtime
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        private int ConvertDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }
        private int converDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }

        /// <summary>
        /// unix时间转换为datetime
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <returns></returns>
        private DateTime UnixTimeToTime(string timeStamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }
        #endregion

 

### 配置微信公众号关注事件回调接口 为了实现微信公众号关注事件回调,需按照以下说明操作: #### 准备工作 确保服务器端已准备好接收来自微信公众平台的消息推送请求。该服务应能够处理HTTP POST请求并返回正确的响应给微信服务器。 #### 创建验证URL 当设置新的回调地址时,微信会发送GET请求来验证此链接的有效性。开发者需要解析查询参数中的`signature`, `timestamp`, `nonce`, 和 `echostr`字段,并通过特定算法计算签名以确认消息确实来源于微信[^1]。 ```php // PHP示例代码用于验证URL有效性 $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $echoStr = $_GET["echostr"]; token = "yourToken"; // 自定义令牌,在公众平台上设定 $array = array($token, $timestamp, $nonce); sort($array, SORT_STRING); $string = implode( '', $array ); if (sha1($string) === $signature){ echo $echoStr; } ``` #### 开发者模式开启与配置 进入微信公众平台后台->开发->基本配置页面,启用“开发者中心”。在此处输入刚才创建的服务器URL、Token(自定义的安全密钥)、以及加密方式(明文/兼容/AES)。保存更改后,微信将会向指定的URL发起上述提到的GET请求来进行校验[^2]。 #### 处理关注事件通知 一旦成功设置了有效的回调URL并通过了安全检验,则每当有新用户订阅或取消订阅您的公共账号时,微信都会POST XML数据包至您提供的API endpoint。此时可以在接收到的数据中找到相应的Event属性值为subscribe/unsubscribe表示用户的关注状态变化[^3]。 ```xml <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> </xml> ``` #### 获取用户基本信息 对于每次发生的关注事件,可以利用获得的OpenID调用 `/cgi-bin/user/info` 接口获取更多关于粉丝的信息,比如昵称、性别等公开资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值