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公众号 ,则说明自动回复设置成功!

时间: 2025-01-02 18:07:55

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

微信公众号开发获取用户信息

一.获取用户基本信息接口 在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同).公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称.头像.性别.所在城市.语言和关注时间. 获取用户基本信息 开发者可通过OpenID来获取用户基本信息.请使用https协议. 接口调用请求说明 http请求方式: GET https://api.weixin.qq.com/cgi-bin

接入微信公众平台开发之用户关注(取消)事件触发后台自定义消息体通知给用户的实现过程

1.需求:用户关注公众号后回复给用户一个字符串,字符串不能重复使用即如果a用户关注公众号后商户后台回复给用户字符串str1后,b用户关注就是其他字符串,且a用户取消关注再次关注不回复消息体 2.实现过程: ①首先配置服务器url并开启,再次过程中需要微信后台与商户后台进行通信,所以,微信后台会发送请求,商户平台自定义接口回复相关内容即可完成通信. ②原理图: ③代码实现: a.pcodecontroller:定义的一个接口类,用来处理微信服务器发送的请求 1 package com.java.z

微信公众号开发(三)----服务号客服消息

因为订阅号没有客服消息,所以只能在用户发送消息以后,进行被动的回复.而服务号可以通过客服消息主动给用户发消息,下面我就介绍一下这个功能怎么使用. 客服消息主要是向公众号服务器发送HTTPS请求,所以这部分的内容可以使用PostMan等工具进行测试和验证.那么下面就开始吧. 1. 获取AccessToken 发送客服消息需要用到AccessToken,可以用appId和AppSecrect来获取.获取的接口文档为获取AccessToken, AppId和AppSecrect可以在公众号主页--->

微信公众号开发--获取用户信息中文乱码的解决方案

在微信开发中我们会经常需要获取用户的信息. 微信给我们提供了获取用户信息的api, 地址为 https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN 将其中的access_token替换为我们的access_token openid为关注用户的openid就可以获取到用户的信息了. 问题描述 不过获取到的数据却是中文乱码 而用Java程序获取的结果也是一样的

微信公众号开发--网页用户授权

相信官方文档,以前的接口错误已经改正,用最新的即可,这几篇随笔是一个项目中拿出来的,缺什么方法去其他随笔里找找就有 1 import java.io.IOException; 2 import java.io.UnsupportedEncodingException; 3 import javax.servlet.ServletException; 4 import java.net.URLEncoder; 5 import java.util.ArrayList; 6 import java.

微信公众号开发(二)用户关注

微信公众号开发之用户关注   前面讲了基本配置,如果配置成功,那么现在就进入我们的微信公众号开发之旅吧! 这个旅程应该从哪里开始比较好呢?想想....首先说用户关注吧 !毕竟这是入口. 用户关注公众号可以通过三种方式: 1.扫公众号的二维码 2.搜索公众号的名称 3.扫带参数的二维码,但是第一个用户只能通过前面两种方式关注. 一.扫公众号的二维码 用户扫了二维码之后,点击关注,微信服务器会向我们的服务器发送一串数据(对象形式): reqMap:{ FromUserName:xx, EventKe

PHP 微信公众号开发 - 消息推送

项目微信公众号开发,需要做用户消息推送,记录下来以便日后使用 1,接上一篇文章,可以查看如何获取用户openid PHP 微信公众号开发 - 获取用户信息 2,添加模板消息 3,查看模板详情 根据模板详情设置对应推送消息 4,代码实现 1 <?php 2 // 字符编码 3 header("Content-Type:text/html; charset=utf-8"); 4 5 // 微信接口类 6 class WeChat{ 7 private static $appid; 8

微信公众号开发及时获取当前用户Openid及注意事项

目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 (四)微信公众号开发之网页授权获取用户基本信息 (五)微信公众号开发之网页中及时获取当前用户Openid及注意事项 前言 这篇主要是承接上篇的网页授权获取用户基本信息的后文,也是对第一种静默授权之后,用户点击公众号内链接时,如何再次取得当前用户的OpenId的大致讲解和一些注意事项. 看过上一篇的小伙伴都知道,我们在用户关注的时候就已经将该用户的基本信息存入数据库中,那么如果

C#微信公众号开发之网页授权oauth2.0获取用户基本信息(二)

C#微信公众号开发之网页授权oauth2.0获取用户基本信息(一) 中讲解了如果通过微信授权2.0snsapi_base获取已经关注用户的基本信息,然而很多情况下我们经常需要获取非关注用户的信息,方法如下: 第一步和之前讲的一样:获取code,但是scope使用方法是snsapi_userinfo; 第二步,根据code获取openid和access_token(此处的access_token是通过网页授权code换取的不是我们之前讲的全局的票据),代码: 1 /// <summary> 2

微信公众号开发(三)生成带参数的二维码

微信公众号开发之生成带参数的二维码 做微信公众号开发的人员都知道用户海报作为公众号吸引用户是常见的渠道,那么我就说说这个海报的生成. 看了好多公众号发现他们的海报都是大同小异,一个漂亮的背景+自己的头像+专属二维码. 背景就不阐述了,用户的头像可以由公众号开发文档提供的方式获取(根据用户的openId),今天主要讲用户的专属二维码 所谓专属即便是一对一的. 二维码分为两种,临时二维码和永久二维码 /*生成永久二维码*/ public static String getPerpetualQR(St