C#微信公众号全攻略(4)--实现回复消息C#代码

接上文 这个函数把用户发来的内容交接给messageHelp来处理 最后返回messageHelp.ReturnMessage

private void Handle(string postStr)
{
    messageHelp help = new messageHelp(SqlConnectionString);
    string responseContent = help.ReturnMessage(postStr);

    HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
    HttpContext.Current.Response.Write(responseContent);
}

实现messageHelp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Xml;

public class messageHelp
{
    private string mySqlConnectionString;
    private WXHelper myWXHelper;

    public messageHelp(string SqlConnectionString)
    {
        mySqlConnectionString = SqlConnectionString;
        myWXHelper = new WXHelper(mySqlConnectionString);
    }


    public string ReturnMessage(string postStr)
    {
        string responseContent = "";
        XmlDocument xmldoc = new XmlDocument();
        try
        {
            xmldoc.Load(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(postStr)));
            XmlNode MsgType = xmldoc.SelectSingleNode("/xml/MsgType");

            if (MsgType != null)
            {
                switch (MsgType.InnerText)
                {
                    case "event":
                        responseContent = EventHandle(xmldoc);   //事件处理 关注和取消关注
                        break;
                    case "text":
                        responseContent = TextHandle(xmldoc);    //接受文本消息处理
                        break;
                    case "image":
                        responseContent = ImageHandle(xmldoc);   //接受图片消息处理
                        break;
                    default:
                        responseContent = DefaultHandle(xmldoc); //接受其他消息处理
                        break;
                }
            }
        }
        catch (Exception ex)
        {
            DateTime CreateTime = myWXHelper.GetCreateTime(xmldoc);
            //开发过程中保留一些出错状况进数据库 很简单的INSERT操作
            //myWXHelper.InsertHandleException(ex.Message, CreateTime);
        }

        return responseContent;
    }


    public string EventHandle(XmlDocument xmldoc)
    {
        string responseContent = "";
        XmlNode Event = xmldoc.SelectSingleNode("/xml/Event");
        if (Event != null)
        {
            myWXHelper.InsertEvent(xmldoc);
            responseContent = myWXHelper.GetEventResponse(xmldoc);
        }
        return responseContent;
    }

    public string TextHandle(XmlDocument xmldoc)
    {
        string responseContent = "";
        XmlNode Content = xmldoc.SelectSingleNode("/xml/Content");
        if (Content != null)
        {
            myWXHelper.InsertTextMsg(xmldoc);
            //先处理一些特殊功能
            responseContent = myWXHelper.GetEspecialTextResponse(xmldoc);
            if (string.IsNullOrEmpty(responseContent))
            {
                //如果不是特殊功能的则处理关键字和其他任意文本的回复
                responseContent = myWXHelper.GetTextResponse(xmldoc);
            }
        }
        return responseContent;
    }

    public string ImageHandle(XmlDocument xmldoc)
    {
        string responseContent = "";
        XmlNode PicUrl = xmldoc.SelectSingleNode("/xml/PicUrl");
        if (PicUrl != null)
        {
            myWXHelper.InsertImageMsg(xmldoc);
            responseContent = myWXHelper.GetImageResponse(xmldoc);
        }
        return responseContent;
    }

    public string DefaultHandle(XmlDocument xmldoc)
    {
        string responseContent = "";

        return responseContent;
    }

}

ReturnMessage中输入的是整个XML文档
MsgType节点表示消息类型
事件、文字、图片消息对应不同的处理
事件包括关注 和 取消关注 需要对用户表进行操作
文字需要保留用户发送的内容
图片需要保留用户发送的图片
GetEspecialTextResponse对某些特定字处理
InsertEvent GetEventResponse InsertTextMsg GetTextResponse InsertImageMsg GetImageResponse需要实现,看字面就能知道干什么用的

基本思路 得到XML文档,根据消息类型不同进行处理 文字和图片需要保存到数据库 关注和取消关注修改对应本地用户表 关注还需要回复给用户消息内容 对于特殊的文字 需要优先处理回复 比如发送问号得到菜单发送签到进行签到等功能。

仅示例

    public void InsertEvent(XmlDocument xmldoc)
    {
        XmlNode xnFromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
        string openid = xnFromUserName.InnerText;

        DateTime CreateTime = GetCreateTime(xmldoc);

        XmlNode xnEvent = xmldoc.SelectSingleNode("/xml/Event");
        string Event = xnEvent.InnerText;

        using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
        {
            //得到UserID 新用户的话就创建
            Int32 UserID = GetUserID(openid);

            StrSQL = "INSERT INTO [WX_Event] ([UserID], [CreateTime], [Event]) VALUES (";
            StrSQL += "@UserID, @CreateTime, @Event)";

            SqlCommand mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
            mySqlCommand.Parameters.AddWithValue("@UserID", UserID);
            mySqlCommand.Parameters.AddWithValue("@CreateTime", CreateTime);
            mySqlCommand.Parameters.AddWithValue("@Event", Event);

            mySqlConnection.Open();
            mySqlCommand.ExecuteNonQuery();
            mySqlConnection.Close();
        }
    }

数据库里对WX_Event表设置触发器 unsubscribe时 修改用户状态为未关注 修改用户的取消关注时间 设置用户的重关注标记等 这样当下一次关注时可以知道用记是不是首次关注 还是取消关注后再次关注 因为每个用户对于同一公众号openid不变

这里写图片描述

public string GetEventResponse(XmlDocument xmldoc)
    {
        string responseContent = "";
        StringBuilder sb = new StringBuilder();

        XmlNode ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName");
        XmlNode FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
        string openid = FromUserName.InnerText;
        XmlNode xnEvent = xmldoc.SelectSingleNode("/xml/Event");
        string Event = xnEvent.InnerText;

        Int32 UserID = GetUserID(openid);

        if (Event == "subscribe")
        {
            using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
            {
                mySqlConnection.Open();

                string Src = "";
                string nickname = "";
                SqlCommand mySqlCommand = new SqlCommand("SELECT * FROM [WX_User] WHERE [ID] = @UserID", mySqlConnection);
                mySqlCommand.Parameters.AddWithValue("@UserID", UserID);
                SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySqlCommand);
                DataTable myDataTable = new DataTable();
                mySqlDataAdapter.Fill(myDataTable);
                nickname = Convert.ToString(myDataTable.Rows[0]["nickname"]);
                mySqlCommand = new SqlCommand("SELECT COUNT(ID) AS SubscribeOrder FROM [view_WX_User_Subscirbe] WHERE ISNULL(SubscribeTime, '') <> ''", mySqlConnection);
                int SubscribeOrder = Convert.ToInt32(mySqlCommand.ExecuteScalar());

                if (myDataTable.Rows[0]["UnSubscribeTime"] == DBNull.Value)  //首次关注
                {
                    Src = "亲爱的 #nickname, 公众号 感谢您的关注!";
                    Src += String.Format("\r\n您是第 {0} 位客人", SubscribeOrder);
                    Src += "\r\n" + dictConstant.GetValue("subscribe", "");
                }
                else  //重新关注
                {
                    Src = "亲爱的 #nickname, 公众号曾经和您小别! 感谢您再次关注!";
                    Src += String.Format("\r\n您当前是第 {0} 位客人", SubscribeOrder);
                    Src += "\r\n" + dictConstant.GetValue("resubscribe", "");
                }
                Src = Src.Replace("#nickname", nickname);
                Src = Src.Replace("#openid", openid);

                sb.Append(RegexHelper.GetStringBuilderFromLineText(Src));
                responseContent = string.Format(ReplyType.Message_Text,
                            FromUserName.InnerText,
                            ToUserName.InnerText,
                            DateTime.Now.Ticks,
                            sb.ToString()
                        );
            }
        }

        return responseContent;
    }
    public class ReplyType
    {
        /// <summary>
        /// 普通文本消息
        /// </summary>
        public 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>";
            }
        }
    }
    public Int32 GetUserID(string openid)
    {
        Int32 Res = -1;
        if (!string.IsNullOrWhiteSpace(openid))
        {
            using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
            {
                SqlCommand mySqlCommand = new SqlCommand("SELECT * FROM [WX_User] WHERE [openid] = @openid", mySqlConnection);
                mySqlCommand.Parameters.AddWithValue("@openid", openid);
                SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySqlCommand);
                DataTable myDataTable = new DataTable();
                mySqlDataAdapter.Fill(myDataTable);
                if (myDataTable.Rows.Count != 0)
                {
                    Res = Convert.ToInt32(myDataTable.Rows[0]["ID"]);
                }
                else
                {
                    mySqlConnection.Open();

                    StrSQL = "BEGIN TRAN; INSERT INTO [WX_User] ([openid]) VALUES (@openid); SELECT IDENT_CURRENT('WX_User'); COMMIT TRAN;";
                    mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
                    mySqlCommand.Parameters.AddWithValue("@openid", openid);

                    Res = Convert.ToInt32(mySqlCommand.ExecuteScalar());

                    //该用户不存在于表中 需要 使用Token和Cookie获取关注用户的基本信息
                    string UserInfoJSON = "";
                    if (OHWXHelper.GetUserInfoJSON(openid, WXControllerToken, WXControllerCookie, out UserInfoJSON))
                    {
                        DataTable dtUserInfo = OHWXHelper.GetUserInfoDataTable(UserInfoJSON);
                        if (dtUserInfo.Rows.Count == 1)
                        {
                            string nickname, city, province, country, headimgurl, subscribe_time, signature;
                            int sex;
                            nickname = Convert.ToString(dtUserInfo.Rows[0]["user_name"]);
                            nickname = nickname.Replace(@"\""", @"""");
                            nickname = nickname.Replace(@"\/", @"/");
                            sex = Convert.ToInt16(dtUserInfo.Rows[0]["user_gender"]);
                            city = Convert.ToString(dtUserInfo.Rows[0]["user_city"]);
                            province = Convert.ToString(dtUserInfo.Rows[0]["user_province"]);
                            country = Convert.ToString(dtUserInfo.Rows[0]["user_country"]);
                            headimgurl = Convert.ToString(dtUserInfo.Rows[0]["user_head_img"]).Replace(@"\/", @"/");
                            subscribe_time = Convert.ToString(dtUserInfo.Rows[0]["user_create_time"]);
                            signature = Convert.ToString(dtUserInfo.Rows[0]["user_signature"]);
                            signature = signature.Replace(@"\""", @"""");
                            signature = signature.Replace(@"\/", @"/");

                            StrSQL = "UPDATE [WX_User] SET [openid] = @openid, [nickname] = @nickname, [sex] = @sex, [city] = @city, [province] = @province, [country] = @country, [headimgurl] = @headimgurl, [subscribe_time] = @subscribe_time, [signature] = @signature ";
                            StrSQL += "WHERE [ID] = @ID";
                            mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
                            mySqlCommand.Parameters.AddWithValue("@openid", openid);
                            mySqlCommand.Parameters.AddWithValue("@nickname", nickname);
                            mySqlCommand.Parameters.AddWithValue("@sex", sex);
                            mySqlCommand.Parameters.AddWithValue("@city", city);
                            mySqlCommand.Parameters.AddWithValue("@province", province);
                            mySqlCommand.Parameters.AddWithValue("@country", country);
                            mySqlCommand.Parameters.AddWithValue("@headimgurl", headimgurl);
                            mySqlCommand.Parameters.AddWithValue("@subscribe_time", subscribe_time);
                            mySqlCommand.Parameters.AddWithValue("@signature", signature);
                            mySqlCommand.Parameters.AddWithValue("@ID", Res);
                            mySqlCommand.ExecuteNonQuery();
                        }
                        else
                        {
                            mySqlCommand = new SqlCommand("UPDATE [WX_Controller] SET [InvalidTag] = 1, [InvalidTime] = GETDATE()", mySqlConnection);
                            mySqlCommand.ExecuteNonQuery();
                        }
                    }
                    else
                    {
                        mySqlCommand = new SqlCommand("UPDATE [WX_Controller] SET [InvalidTag] = 1, [InvalidTime] = GETDATE()", mySqlConnection);
                        mySqlCommand.ExecuteNonQuery();
                    }
                    mySqlConnection.Close();
                }
            }
        }
        return Res;
    }

代码仅示例 从我实际的项目中复制得来 可以在用户关注时回复给用户是第几位关注的用户 同时可以通过控制台的Token和Cookie 根据openid获取用户的一些基本信息昵称 性别 设置的地区 头像链接 微信中设置的签名等等(GetUserInfoJSON)功能实现将JSON直接转换成DataTable

    private Dictionary<string, string> dictConstant = new Dictionary<string, string>();
    private Dictionary<string, string> dictVariant = new Dictionary<string, string>();
    private Dictionary<string, string> dictKeyword = new Dictionary<string, string>();

自动回复采用了字典变量方式 在数据库中保留内容 可以随时直接改数据库 而不用写死在代码里,包括常量、变量、关键字 三大类型,用变量替换常量中的部分

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值