微信公众平台开发教程(四) 实例入门:机器人(附源码)

微信公众平台开发教程(四) 实例入门:机器人(附源码)

上一篇文章,写了基本框架,可能很多人会觉得晕头转向,这里提供一个简单的例子来予以说明,希望能帮你解开谜团。

一、功能介绍

通过微信公众平台实现在线客服机器人功能。主要的功能包括:简单对话、查询天气等服务。

这里只是提供比较简单的功能,重在通过此实例来说明公众平台的具体研发过程。只是一个简单DEMO,如果需要的话可以在此基础上进行扩展。

当然后续我们还会推出比较复杂的应用实例。

二、具体实现

1、提供访问接口

这里不再赘述,参照上一章,微信公众账号开发教程(二) 基础框架搭建
http://www.cnblogs.com/yank/p/3392394.html

2、签名认证和分发请求

这里不再赘述,参照上一章,微信公众账号开发教程(二) 基础框架搭建
http://www.cnblogs.com/yank/p/3392394.html

3、处理请求,并响应

1)关注

当微信用户关注公众账号时,可以给其适当的提示。可以是欢迎词,可以是帮助提示。

直接上代码:

    class EventHandler : IHandler
    {
        /// <summary>
        /// 请求的xml
        /// </summary>
        private string RequestXml { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="requestXml"></param>
        public EventHandler(string requestXml)
        {
            this.RequestXml = requestXml;
        }
        /// <summary>
        /// 处理请求
        /// </summary>
        /// <returns></returns>
        public string HandleRequest()
        {
            string response = string.Empty;
            EventMessage em = EventMessage.LoadFromXml(RequestXml);
            if (em.Event.Equals("subscribe",StringComparison.OrdinalIgnoreCase))
            {
                //回复欢迎消息
                TextMessage tm = new TextMessage();
                tm.ToUserName = em.FromUserName;
                tm.FromUserName = em.ToUserName;
                tm.CreateTime = Common.GetNowTime();
                tm.Content = "欢迎您关注***,我是大哥大,有事就问我,呵呵!\n\n";
                response = tm.GenerateContent();
            }

            return response;
        }
    }

2)问候

简单的交流问候,比如你好、帮助等等,跟我们使用微信聊天一样,不过回应是由我们的程序响应。具体功能,可以根据自己的需要进行添加。
微信本来就是沟通的平台。这个案例,可以用于在线服务机器人,类似于淘宝的客服机器人,可是我们这个是微信版的。呵呵
其实,很简单,获取请求消息,根据关键字来匹配回应。当然这里可能要做的工作很多,如何支持智能匹配,如何支持模糊匹配等。

代码如下:

    /// <summary>
    /// 文本信息处理类
    /// </summary>
    public class TextHandler : IHandler
    {
        /// <summary>
        /// 请求的XML
        /// </summary>
        private string RequestXml { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="requestXml">请求的xml</param>
        public TextHandler(string requestXml)
        {
            this.RequestXml = requestXml;
        }
        /// <summary>
        /// 处理请求
        /// </summary>
        /// <returns></returns>
        public string HandleRequest()
        {
            string response = string.Empty;
            TextMessage tm = TextMessage.LoadFromXml(RequestXml);
            string content = tm.Content.Trim();
            if (string.IsNullOrEmpty(content))
            {
                response = "您什么都没输入,没法帮您啊,%>_<%。";
            }
            else
            {
                if (content.StartsWith("tq", StringComparison.OrdinalIgnoreCase))
                {
                    string cityName = content.Substring(2).Trim();
                    response = WeatherHelper.GetWeather(cityName);
                }
                else
                {
                    response = HandleOther(content);
                }
            }
            tm.Content = response;
            //进行发送者、接收者转换
            string temp = tm.ToUserName;
            tm.ToUserName = tm.FromUserName;
            tm.FromUserName = temp;
            response = tm.GenerateContent();
            return response;
        }
        /// <summary>
        /// 处理其他消息
        /// </summary>
        /// <param name="tm"></param>
        /// <returns></returns>
        private string HandleOther(string requestContent)
        {
            string response = string.Empty;
            if (requestContent.Contains("你好") || requestContent.Contains("您好"))
            {
                response = "您也好~";
            }
            else if (requestContent.Contains("傻"))
            {
                response = "我不傻!哼~ ";
            }
            else if (requestContent.Contains("逼") || requestContent.Contains("操"))
            {
                response = "哼,你说脏话! ";
            }
            else if (requestContent.Contains("是谁"))
            {
                response = "我是大哥大,有什么能帮您的吗?~";
            }
            else if (requestContent.Contains("再见"))
            {
                response = "再见!";
            }
            else if (requestContent.Contains("bye"))
            {
                response = "Bye!";
            }
            else if (requestContent.Contains("谢谢"))
            {
                response = "不客气!嘿嘿";
            }
            else if (requestContent == "h" || requestContent == "H" || requestContent.Contains("帮助"))
            {
                response = @"查询天气,输入tq 城市名称\拼音\首字母";
            }
            else
            {
                response = "您说的,可惜,我没明白啊,试试其他关键字吧。";
            }

            return response;
        }
    }

3)查询天气

这个功能需要请求实时查询的,请求官方的天气发布网站,然后解析其返回值,按照我们需要的格式,组织天气信息,最后发送给微信客户。
采用文本消息方式处理。
用户请求,只需输入:tq 城市名称/拼音/首字母,即可获取消息。

回复的消息:(以北京为例)

北京
2013年11月6日 星期三
今天:(17℃~4℃)晴北风4-5级转3-4级4-5级转3-4级
24小时穿衣指数:天气冷,建议着棉服、羽绒服、皮夹克加羊毛衫等冬季服装。年老体弱者宜着厚棉衣、冬大衣或厚羽绒服。
明天:(14℃~3℃)晴转多云微风小于3级
48小时穿衣指数:天气冷,建议着棉服、羽绒服、皮夹克加羊毛衫等冬季服装。年老体弱者宜着厚棉衣、冬大衣或厚羽绒服。

来看源码吧:

    class WeatherHelper
    {
        /// <summary>
        /// 城市集合字段
        /// </summary>
        private static Dictionary<string, City> mCities;
        /// <summary>
        /// 城市集合
        /// </summary>
        public static Dictionary<string, City> Cities
        {
            get
            {
                if (mCities == null)
                {
                    LoadCities();
                }

                return mCities;
            }
        }
        /// <summary>
        /// 加载城市
        /// </summary>
        private static void LoadCities()
        {
            mCities = new Dictionary<string, City>();
            mCities.Clear();
            mCities.Add("101010100", new City() { Code = "101010100", Name = "北京", PinYin = "beijing", FristLetter = "bj" });
            mCities.Add("101020100", new City() { Code = "101020100", Name = "上海", PinYin = "shanghai", FristLetter = "sh" });
            mCities.Add("101200101", new City() { Code = "101200101", Name = "武汉", PinYin = "wuhai", FristLetter = "wh" });

        }
        /// <summary>
        /// 获取城市的天气
        /// </summary>
        /// <param name="name">城市名称、拼音或首字母</param>
        /// <returns></returns>
        public static string GetWeather(string name)
        {
            string result = string.Empty;
            string cityCode = string.Empty;
            //获取城市编码
            IEnumerable<string> codes = from item in Cities
                                        where item.Value != null
                                              && (item.Value.Name.Equals(name, StringComparison.OrdinalIgnoreCase)
                                                    || item.Value.PinYin.Equals(name, StringComparison.OrdinalIgnoreCase)
                                                    || item.Value.FristLetter.Equals(name, StringComparison.OrdinalIgnoreCase))
                                        select item.Value.Code;
            if (codes != null && codes.Count() > 0)
            {
                cityCode = codes.First<string>();
            }

            //http请求,获取天气
            if (!string.IsNullOrEmpty(cityCode))
            {
                string url = "http://m.weather.com.cn/data/{0}.html";
                url = string.Format(url, cityCode);
                WebRequest request = HttpWebRequest.Create(url);
                //超时时间为:2秒
                request.Timeout = 2000;
                request.Credentials = CredentialCache.DefaultCredentials;
                WebResponse response = request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                string weahterInfo = reader.ReadToEnd();
                if (string.IsNullOrEmpty(weahterInfo))
                {
                    result = "暂时没有取到天气数据,请稍后再试";
                }
                else
                {
                    XmlDocument doc = JsonConvert.DeserializeXmlNode(weahterInfo);
                    if (doc != null)
                    {
                        XmlNode node = doc.DocumentElement;
                        if (node != null)
                        {
                            StringBuilder builder = new StringBuilder();
                            builder.Append(node["city"].InnerText).Append("\n");
                            builder.Append(node["date_y"].InnerText).Append(" ").Append(node["week"].InnerText).Append("\n");
                            builder.Append("今天:").Append("(").Append(node["temp1"].InnerText).Append(")").Append(node["weather1"].InnerText).Append(node["wind1"].InnerText).Append(node["fl1"].InnerText).Append("\n");
                            builder.Append("24小时穿衣指数:").Append(node["index_d"].InnerText).Append("\n");
                            builder.Append("明天:").Append("(").Append(node["temp2"].InnerText).Append(")").Append(node["weather2"].InnerText).Append(node["wind2"].InnerText).Append(node["fl2"].InnerText).Append("\n");
                            builder.Append("48小时穿衣指数:").Append(node["index48_d"].InnerText).Append("\n");
                            result = builder.ToString();
                        }
                    }
                    #region 天气json数据格式
                    /*

                {
   "weatherinfo": {
       "city": "北京",
       "city_en": "beijing",
       "date_y": "2013年11月4日",
       "date": "",
       "week": "星期一",
       "fchh": "11",
       "cityid": "101010100",
       "temp1": "17℃~5℃",
       "temp2": "16℃~5℃",
       "temp3": "18℃~4℃",
       "temp4": "17℃~5℃",
       "temp5": "14℃~6℃",
       "temp6": "14℃~2℃",
       "tempF1": "62.6℉~41℉",
       "tempF2": "60.8℉~41℉",
       "tempF3": "64.4℉~39.2℉",
       "tempF4": "62.6℉~41℉",
       "tempF5": "57.2℉~42.8℉",
       "tempF6": "57.2℉~35.6℉",
       "weather1": "晴转多云",
       "weather2": "多云",
       "weather3": "多云转晴",
       "weather4": "晴转多云",
       "weather5": "多云转阴",
       "weather6": "阴转晴",
       "img1": "0",
       "img2": "1",
       "img3": "1",
       "img4": "99",
       "img5": "1",
       "img6": "0",
       "img7": "0",
       "img8": "1",
       "img9": "1",
       "img10": "2",
       "img11": "2",
       "img12": "0",
       "img_single": "0",
       "img_title1": "晴",
       "img_title2": "多云",
       "img_title3": "多云",
       "img_title4": "多云",
       "img_title5": "多云",
       "img_title6": "晴",
       "img_title7": "晴",
       "img_title8": "多云",
       "img_title9": "多云",
       "img_title10": "阴",
       "img_title11": "阴",
       "img_title12": "晴",
       "img_title_single": "晴",
       "wind1": "微风",
       "wind2": "微风",
       "wind3": "微风",
       "wind4": "微风",
       "wind5": "微风",
       "wind6": "北风4-5级",
       "fx1": "微风",
       "fx2": "微风",
       "fl1": "小于3级",
       "fl2": "小于3级",
       "fl3": "小于3级",
       "fl4": "小于3级",
       "fl5": "小于3级",
       "fl6": "4-5级",
       "index": "较冷",
       "index_d": "建议着大衣、呢外套加毛衣、卫衣等服装。体弱者宜着厚外套、厚毛衣。因昼夜温差较大,注意增减衣服。",
       "index48": "冷",
       "index48_d": "天气冷,建议着棉服、羽绒服、皮夹克加羊毛衫等冬季服装。年老体弱者宜着厚棉衣、冬大衣或厚羽绒服。",
       "index_uv": "中等",
       "index48_uv": "弱",
       "index_xc": "适宜",
       "index_tr": "适宜",
       "index_co": "舒适",
       "st1": "17",
       "st2": "5",
       "st3": "17",
       "st4": "5",
       "st5": "18",
       "st6": "6",
       "index_cl": "适宜",
       "index_ls": "适宜",
       "index_ag": "极不易发"
   }
}
                */
                    #endregion

                }
            }
            else
            {
                result = "没有获取到该城市的天气,请确定输入了正确的城市名称,如\‘北京\‘或者\‘beijing\‘或者\‘bj\‘";
            }

            //返回
            return result;
        }
        /// <summary>
        /// 内部类:城市
        /// </summary>
        internal class City
        {
            /// <summary>
            /// 编码
            /// </summary>
            public string Code { get; set; }
            /// <summary>
            /// 名称
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// 拼音
            /// </summary>
            public string PinYin { get; set; }
            /// <summary>
            /// 拼音首字母
            /// </summary>
            public string FristLetter { get; set; }
        }
    }

三、源码

这里可是可执行的代码哦。应大家的需求,这里提供全部的源代码。

http://files.cnblogs.com/yank/Yank.WeiXin.Robot.zip

时间: 2024-10-13 02:37:38

微信公众平台开发教程(四) 实例入门:机器人(附源码)的相关文章

微信公众平台开发-access_token获取及应用(含源码)

微信公众平台开发-access_token获取及应用(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 很多系统中都有access_token参数,对于微信公众平台的access_token参数,微信服务器判断该公众平台所拥有的权限,允许或者禁止公众平台进行当前的操作. 一.access_token作用及使用场景 (一)access_token的作用 access_token由公众号的AppID和AppSecret组成,所以具有识别公众号的作用. (二)access_token的使用场景

Senparc.Weixin.MP SDK 微信公众平台开发教程(十四):请求消息去重

原文:Senparc.Weixin.MP SDK 微信公众平台开发教程(十四):请求消息去重 为了确保信息请求消息的到达率,微信服务器在没有及时收到响应消息(ResponseMessage)的情况下,会多次发送同一条请求消息(RequestMessage),包括MsgId等在内的所有文本内容都是一致的. 这种机制确保了在诸如网络状况不佳的情况下消息的回复成功率,但是有时候由于服务器负荷.本身请求过程就需要好几秒才能完成等情况,多次重复的消息反而成了服务器的负担,甚至对业务和数据也可能造成影响.

Senparc.Weixin.MP SDK 微信公众平台开发教程(四):Hello World

Senparc.Weixin.MP SDK 微信公众平台开发教程(四):Hello World =============  以下写于2013-07-20 ============= 这一篇文章其实可以写在很前面,不过我还是希望开发者们尽多地了解清楚原理之后再下手. 通过上一篇Senparc.Weixin.MP SDK 微信公众平台开发教程(三):微信公众平台开发验证,我们已经使微信客户端发来的信息都可以转发到我们自己的服务器上. 下面将介绍如何处理这些请求,并且返回符合规定格式的数据.当然,这

微信公众平台开发教程目录

1.微信公众平台开发教程(一) 微信公众账号注册流程 2.微信公众平台开发教程(二) 基本原理及消息接口 3.微信公众账号开发教程(三) 基础框架搭建 4.微信公众平台开发教程(四) 实例入门:机器人(附源码) 5.微信公众平台开发教程(五)自定义菜单 6.微信公众平台开发教程(六)获取个性二维码 7.微信公众平台开发教程(七)安全策略 8.微信公众平台开发教程(八)Session处理 9.微信公众平台开发教程(九)微信公众平台通用开发框架 10.微信公众平台开发教程(十) 订阅号与服务号的区别

微信公众平台开发教程(三) 基础框架搭建

微信公众平台开发教程(三) 基础框架搭建 上一章,我们已经初步讲解了微信公众账号开发的基本原理,今天我们来探索设计实现. 首先我们设计了模块层次图,当然图中只是给出一种实现方式,不局限于此.具体见下图. 主要功能介绍如下: 1)请求接口层.处理HTTP请求,及响应 2)分发层.由接口层传入请求,然后具体分析请求类型,分发至不同的处理器 3)业务逻辑层.这里是我们的具体业务逻辑了,根据请求,实现具体的业务逻辑. 4)数据层.我们在实现某个应用时可能需要访问数据,可以是数据库或者是文件.如果是简单应

微信公众平台开发教程(八)Session处理

微信公众平台开发教程(八)Session处理 在微信窗口,输入的信息有限,我们需要将一些信息分多次请求. 比如:在进行用户绑定时,我们需要输入用户的相关信息,比如:用户名.密码,或者姓名.电话号码,服务端验证通过,即可将系统用户与微信用户绑定. 然后,此微信账户就有一定的功能权限了,可以查积分,消费记录等.服务号:招商银行信用卡,就有很多功能. 微信客户端无法缓存信息,而且输入信息有限,需要进行多次请求,在服务端保存当前会话状态.这就需要Session. 本文以用户认证,绑定账号为例,来说明具体

微信公众平台开发教程(二) 基本原理及消息接口

微信公众平台开发教程(二) 基本原理及消息接口 一.基本原理 在开始做之前,大家可能对这个很感兴趣,但是又比较茫然.是不是很复杂?很难学啊? 其实恰恰相反,很简单.为了打消大家的顾虑,先简单介绍了微信公众平台的基本原理. 微信服务器就相当于一个转发服务器,终端(手机.Pad等)发起请求至微信服务器,微信服务器,然后将请求转发给自定义服务(这就里就是我们的具体实现). 服务处理完毕,然后挥发给微信服务器,微信服务器再将具体响应回复到终端. 通信协议为:HTTP 数据格式为:XML 具体的流程如下图

微信公众平台开发教程(九)微信公众平台通用开发框架

微信公众平台开发教程(九)微信公众平台通用开发框架 一.思考 开发了几个微信项目,一直在思考:如何将微信相关的处理与业务系统联系在一起?如何做到彼此分离,且易于扩展?能否开发一套独立的微信服务框架,支持各种业务应用? 二.现有常用的服务框架 支持多种业务应用,我们通过分层的方式来实现.将复杂的系统进行分层,将一些功能或者特有的逻辑进行封装,封装为不同的基础服务或中间件.业务层无需关心底层具体实现,只需进行简单调用.组装,即可支撑强大的业务应用.这样保证了层级独立,也使得系统易于维护和扩展.在一个

微信公众平台开发教程(七)安全策略

微信公众平台开发教程(七)安全策略 尽管处理微信请求的服务器,处于微信服务器的后端,但是安全问题依然不可小觑. 大概总结以下几个方面,希望引起注意. 一.设置高复杂度的Token,尽量隐藏服务地址URL URL:即为处理微信请求的链接地址Token:用户身份凭证 申请成为开发者或者修改URL\Token时,微信会通过Get请求访问URL,验证签名,其中需要Token. 过程相当于一次握手,如果握手成功,可进行后续的通信. 成为开发者后,我们也可以进行修改 面临的危险:  1.如URL和Token