微信企业号开发:接收消息和事件

  1.    /// <summary>  
  2.        /// 将微信POST过来的数据转化成实体对象  
  3.        /// </summary>  
  4.        /// <param name="token"></param>  
  5.        /// <returns></returns>  
  6.        public static ReceiveMessageBase ConvertMsgToObject(string msgBody = "")  
  7.        {            
  8.             
  9.            if (string.IsNullOrWhiteSpace(msgBody))  
  10.            {  
  11.                Stream s = System.Web.HttpContext.Current.Request.InputStream;  
  12.                byte[] b = new byte[s.Length];  
  13.                s.Read(b, 0, (int)s.Length);  
  14.                msgBody = Encoding.UTF8.GetString(b);  
  15.            }  
  16.            string CorpToken = AppIdInfo.GetToken();  
  17.            string corpId = AppIdInfo.GetCorpId();  
  18.            string encodingAESKey = AppIdInfo.GetEncodingAESKey();  
  19.            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(CorpToken, encodingAESKey, corpId);  
  20.            string msg_signature = HttpContext.Current.Request.QueryString["msg_signature"];  
  21.            string timestamp = HttpContext.Current.Request.QueryString["timestamp"];  
  22.            string nonce = HttpContext.Current.Request.QueryString["nonce"];  
  23.            string sMsg = "";  // 解析之后的明文  
  24.            int flag = wxcpt.DecryptMsg(msg_signature, timestamp, nonce, msgBody, ref sMsg);  
  25.            if (flag == 0)  
  26.            {  
  27.                msgBody = sMsg;  
  28.                LogInfo.Info("解密后的消息为" + sMsg);  
  29.            }  
  30.            else  
  31.            {  
  32.                LogInfo.Error("解密消息失败!flag=" + flag);  
  33.            }             
  34.            if (string.IsNullOrWhiteSpace(msgBody))  
  35.            {  
  36.                return null;  
  37.            }  
  38.            XmlDocument doc = null;  
  39.            MsgType msgType = MsgType.UnKnown;  
  40.            EventType eventType = EventType.UnKnown;  
  41.            ReceiveMessageBase msg = new ReceiveMessageBase();  
  42.            msg.MsgType = msgType;  
  43.            msg.MessageBody = msgBody;  
  44.            XmlNode node = null;  
  45.            XmlNode tmpNode = null;  
  46.            try  
  47.            {  
  48.   
  49.                doc = new XmlDocument();  
  50.                doc.LoadXml(msgBody);//解密后才是需要处理的XML数据,读取XML字符串  
  51.                XmlElement rootElement = doc.DocumentElement;  
  52.                XmlNode msgTypeNode = rootElement.SelectSingleNode("MsgType");//获取字符串中的消息类型  
  53.   
  54.                node = rootElement.SelectSingleNode("FromUserName");  
  55.                if (node != null)  
  56.                {  
  57.                    msg.FromUserName = node.InnerText;  
  58.                }  
  59.                node = rootElement.SelectSingleNode("AgentID");  
  60.                if (node != null)  
  61.                {  
  62.                    msg.AgentID = Convert.ToInt32(node.InnerText);  
  63.                }  
  64.                node = rootElement.SelectSingleNode("ToUserName");  
  65.                if (node != null)  
  66.                {  
  67.                    msg.ToUserName = node.InnerText;  
  68.                }  
  69.                node = rootElement.SelectSingleNode("CreateTime");  
  70.                if (node != null)  
  71.                {  
  72.                    msg.CreateTime = Convert.ToInt64(node.InnerText);  
  73.                }  
  74.  
  75.                #region 获取具体的消息对象  
  76.   
  77.                string strMsgType = msgTypeNode.InnerText;  
  78.                string msgId = string.Empty;  
  79.                string content = string.Empty;  
  80.   
  81.                tmpNode = rootElement.SelectSingleNode("MsgId");  
  82.                if (tmpNode != null)  
  83.                {  
  84.                    msgId = tmpNode.InnerText.Trim();  
  85.                }  
  86.                string strMsgType2 = strMsgType.Trim().ToLower();  
  87.                switch (strMsgType2)  
  88.                {  
  89.                    case "text"://接收普通消息 text消息  
  90.                        msgType = MsgType.Text;  
  91.   
  92.                        tmpNode = rootElement.SelectSingleNode("Content");  
  93.                        if (tmpNode != null)  
  94.                        {  
  95.                            content = tmpNode.InnerText.Trim();  
  96.                        }  
  97.                        TextReceiveMessage txtMsg = new TextReceiveMessage(msg)  
  98.                        {                             
  99.                            MsgType = msgType,                          
  100.                            MsgId = Convert.ToInt64(msgId),  
  101.                            Content = content  
  102.                        };  
  103.                        txtMsg.AfterRead();  
  104.                        return txtMsg;  
  105.                    case "image"://接收普通消息 image消息  
  106.                        msgType = MsgType.Image;  
  107.                        ImageReceiveMessage imgMsg = new ImageReceiveMessage(msg)  
  108.                        {                             
  109.                            MsgId = Convert.ToInt64(msgId),  
  110.                            MsgType = msgType,                            
  111.                            MediaId = rootElement.SelectSingleNode("MediaId").InnerText,  
  112.                            PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText  
  113.                        };  
  114.                        imgMsg.AfterRead();  
  115.                        return imgMsg;  
  116.                    case "voice"://接收普通消息 voice消息  
  117.                        msgType = MsgType.Voice;  
  118.                        XmlNode node1 = rootElement.SelectSingleNode("Recognition");  
  119.                        if (node1 != null)  
  120.                        {  
  121.                            msgType = MsgType.VoiceResult;  
  122.                        }  
  123.   
  124.                        VoiceReceiveMessage voiceMsg = new VoiceReceiveMessage(msg)  
  125.                        {                             
  126.                            MsgId = Convert.ToInt64(msgId),  
  127.                            MsgType = msgType,  
  128.                            Recognition = node1 == null ? string.Empty : node1.InnerText.Trim(),  
  129.                            Format = rootElement.SelectSingleNode("Format").InnerText,  
  130.                            MediaId = rootElement.SelectSingleNode("MediaId").InnerText  
  131.                        };  
  132.                        voiceMsg.AfterRead();  
  133.                        return voiceMsg;  
  134.   
  135.                    case "video"://接收普通消息 video消息  
  136.                        msgType = MsgType.Video;  
  137.   
  138.                        VideoReceiveMessage videoMsg = new VideoReceiveMessage(msg)  
  139.                        {                            
  140.                            MediaId = rootElement.SelectSingleNode("MediaId").InnerText,                            
  141.                            MsgId = Convert.ToInt64(msgId),  
  142.                            MsgType = msgType,                            
  143.                            ThumbMediaId = rootElement.SelectSingleNode("ThumbMediaId").InnerText  
  144.                        };  
  145.                        videoMsg.AfterRead();  
  146.                        return videoMsg;  
  147.                    case "location"://接收普通消息 location消息  
  148.                        msgType = MsgType.Location;  
  149.   
  150.                        LocationReceiveMessage locationMsg = new LocationReceiveMessage(msg)  
  151.                        {                           
  152.                           
  153.                            MsgId = Convert.ToInt64(msgId),  
  154.                            MsgType = msgType,                         
  155.                            Label = rootElement.SelectSingleNode("Label").InnerText,  
  156.                            Location_X = rootElement.SelectSingleNode("Location_X").InnerText,  
  157.                            Location_Y = rootElement.SelectSingleNode("Location_Y ").InnerText,  
  158.                            Scale = rootElement.SelectSingleNode("Scale").InnerText  
  159.                        };  
  160.                        locationMsg.AfterRead();  
  161.                        return locationMsg;  
  162.                    case "event":// 接收事件  
  163.                        msgType = MsgType.Event;  
  164.                        eventType = EventType.UnKnown;  
  165.                        msg.MsgType = msgType;  
  166.   
  167.                        XmlNode eventNode = rootElement.SelectSingleNode("Event");  
  168.                        if (eventNode != null)  
  169.                        {  
  170.                            string eventtype = eventNode.InnerText.Trim().ToLower();  
  171.                            switch (eventtype)  
  172.                            {  
  173.                                case "subscribe"//接收事件 成员关注  
  174.                                    eventType = EventType.Subscribe;  
  175.                                     
  176.                                    SubscribeEventMessage subEvt = new SubscribeEventMessage(msg)  
  177.                                    {  
  178.                                        
  179.                                        EventType = EventType.Subscribe,                                        
  180.                                        MsgType = msgType,                                        
  181.                                    };  
  182.                                    subEvt.AfterRead();  
  183.                                    return subEvt;  
  184.                                case "unsubscribe"//接收事件 取消关注事件  
  185.                                    eventType = EventType.UnSubscribe;  
  186.                                    UnSubscribeEventMessage unSubEvt = new UnSubscribeEventMessage(msg)  
  187.                                    {  
  188.                                        
  189.                                        EventType = eventType,                                     
  190.                                        MsgType = msgType,                                       
  191.                                    };  
  192.                                    unSubEvt.AfterRead();  
  193.                                    return unSubEvt;  
  194.                                case "location"://接收事件 上报地理位置事件  
  195.                                    eventType = EventType.Location;  
  196.                                    UploadLocationEventMessage locationEvt = new UploadLocationEventMessage(msg)  
  197.                                    {                                         
  198.                                        EventType = eventType,                                        
  199.                                        Latitude = rootElement.SelectSingleNode("Latitude").InnerText,  
  200.                                        Longitude = rootElement.SelectSingleNode("Longitude").InnerText,                                       
  201.                                        MsgType = msgType,  
  202.                                        Precision = rootElement.SelectSingleNode("Precision").InnerText,  
  203.                                       
  204.                                    };  
  205.                                    locationEvt.AfterRead();  
  206.                                    return locationEvt;  
  207.                                case "click"//接收事件 上报菜单事件 点击菜单拉取消息的事件推送  
  208.                                    eventType = EventType.Click;  
  209.   
  210.                                    MenuEventMessage menuEvt = new MenuEventMessage(msg)  
  211.                                    {  
  212.                                      
  213.                                        EventKey = rootElement.SelectSingleNode("EventKey").InnerText,  
  214.                                        EventType = eventType,                                      
  215.                                        MsgType = msgType,  
  216.                                       
  217.                                    };  
  218.                                    menuEvt.AfterRead();  
  219.                                    return menuEvt;  
  220.                                case "view"//接收事件 上报菜单事件 点击菜单跳转链接的事件推送  
  221.                                    eventType = EventType.VIEW;  
  222.   
  223.                                    MenuEventVIEWEventMessage menuVIEWEvt = new MenuEventVIEWEventMessage(msg)  
  224.                                    {  
  225.                                        
  226.                                        EventKey = rootElement.SelectSingleNode("EventKey").InnerText,  
  227.                                        EventType = eventType,                                       
  228.                                        MsgType = msgType,                                     
  229.                                    };  
  230.                                    menuVIEWEvt.AfterRead();  
  231.                                    return menuVIEWEvt;  
  232.                                case "scancode_push"://接收事件 上报菜单事件 扫码推事件的事件推送  
  233.                                    eventType = EventType.scancode_push;  
  234.   
  235.                                    ScanCodePushEventMessage scanCodePushEventMessage = new ScanCodePushEventMessage(msg)  
  236.                                    {                                       
  237.                                        EventKey = rootElement.SelectSingleNode("EventKey").InnerText,  
  238.                                        EventType = eventType,                                       
  239.                                        MsgType = msgType,                                      
  240.                                        ScanCodeInfo = new ScanCodeInfo(rootElement.SelectSingleNode("ScanCodeInfo"))  
  241.                                    };  
  242.                                    scanCodePushEventMessage.AfterRead();  
  243.                                    return scanCodePushEventMessage;  
  244.                                case "scancode_waitmsg"://接收事件 上报菜单事件 扫码推事件且弹出“消息接收中”提示框的事件推送  
  245.                                    eventType = EventType.scancode_waitmsg;  
  246.   
  247.                                    ScanCodeWaitMsgEventMessage scanCodeWaitMsgEventMessage = new ScanCodeWaitMsgEventMessage(msg)  
  248.                                    {                                        
  249.                                        EventKey = rootElement.SelectSingleNode("EventKey").InnerText,  
  250.                                        EventType = eventType,                                        
  251.                                        MsgType = msgType,                                        
  252.                                        ScanCodeInfo = new ScanCodeInfo(rootElement.SelectSingleNode("ScanCodeInfo"))  
  253.                                    };  
  254.                                    scanCodeWaitMsgEventMessage.AfterRead();  
  255.                                    return scanCodeWaitMsgEventMessage;  
  256.                                case "pic_sysphoto"://接收事件 上报菜单事件 弹出系统拍照发图的事件推送  
  257.                                    eventType = EventType.pic_sysphoto;  
  258.   
  259.                                    PicSysPhotoEventMessage picSysPhotoEventMessage = new PicSysPhotoEventMessage(msg)  
  260.                                    {                                      
  261.                                        EventKey = rootElement.SelectSingleNode("EventKey").InnerText,                                        
  262.                                        MsgType = msgType,                                        
  263.                                        SendPicsInfo = new SendPicsInfo(rootElement.SelectSingleNode("SendPicsInfo"))  
  264.                                    };  
  265.   
  266.                                    picSysPhotoEventMessage.AfterRead();  
  267.                                    return picSysPhotoEventMessage;  
  268.                                case "pic_photo_or_album"://接收事件 上报菜单事件 弹出拍照或者相册发图的事件推送  
  269.                                    eventType = EventType.pic_photo_or_album;  
  270.   
  271.                                    PicPhotoOrAlbumEventMessage picPhotoOrAlbumEventMessage = new PicPhotoOrAlbumEventMessage(msg)  
  272.                                    {                                       
  273.                                        EventType = eventType,  
  274.                                        EventKey = rootElement.SelectSingleNode("EventKey").InnerText,                                    
  275.                                        MsgType = msgType,                                        
  276.                                        SendPicsInfo = new SendPicsInfo(rootElement.SelectSingleNode("SendPicsInfo"))  
  277.                                    };  
  278.                                    picPhotoOrAlbumEventMessage.AfterRead();  
  279.                                    return picPhotoOrAlbumEventMessage;  
  280.                                case "pic_weixin"://接收事件 上报菜单事件 弹出微信相册发图器的事件推送  
  281.                                    eventType = EventType.pic_weixin;  
  282.   
  283.                                    PicWeiXinEventMessage picWeiXinEventMessage = new PicWeiXinEventMessage(msg)  
  284.                                    {                                      
  285.                                        EventType = eventType,  
  286.                                        EventKey = rootElement.SelectSingleNode("EventKey").InnerText,                                        
  287.                                        MsgType = msgType,                                        
  288.                                        SendPicsInfo = new SendPicsInfo(rootElement.SelectSingleNode("SendPicsInfo"))  
  289.                                    };  
  290.                                    picWeiXinEventMessage.AfterRead();  
  291.                                    return picWeiXinEventMessage;  
  292.                                case "location_select"://接收事件 上报菜单事件 弹出地理位置选择器的事件推送  
  293.                                    eventType = EventType.location_select;  
  294.   
  295.                                    LocationSelectEventMessage locationSelectEventMessage = new LocationSelectEventMessage(msg)  
  296.                                    {                                      
  297.                                        EventType = eventType,  
  298.                                        EventKey = rootElement.SelectSingleNode("EventKey").InnerText,                                       
  299.                                        MsgType = msgType,                                        
  300.                                        SendLocationInfo = new SendLocationInfo(rootElement.SelectSingleNode("SendLocationInfo"))                                        
  301.                                    };  
  302.                                    locationSelectEventMessage.AfterRead();  
  303.                                    return locationSelectEventMessage;  
  304.                                case "enter_agent"//接收事件 成员进入应用的事件推送  
  305.                                    eventType = EventType.enter_agent;  
  306.                                    EnterAgentEventMessage EnterAgentEventMessage = new EnterAgentEventMessage(msg)  
  307.                                    {    
  308.                                        MsgType = msgType,                                      
  309.                                    };  
  310.                                    EnterAgentEventMessage.AfterRead();  
  311.                                    return EnterAgentEventMessage;  
  312.                                default:  
  313.                                    LogInfo.Error("事件类型" + eventtype + "未处理");  
  314.                                    break;  
  315.   
  316.                            }  
  317.                        }  
  318.   
  319.                        break;  
  320.                    default:  
  321.                        LogInfo.Error("消息类型" + strMsgType2 + "未处理");  
  322.                        break;  
  323.                }  
  324.                msg.MsgType = msgType;  
  325.                #endregion  
  326.            }  
  327.            catch (Exception ex)  
  328.            {  
  329.                LogInfo.Error("处理消息异常:" + msgBody, ex);  
  330.            }  
  331.            finally  
  332.            {  
  333.                if (doc != null)  
  334.                {  
  335.                    doc = null;  
  336.                }  
  337.            }  
  338.   
  339.            msg.MsgType = msgType;  
  340.            return msg;  
  341.        }  

发送被动响应文本消息:

[csharp]  view plain  copy
  1. /// <summary>  
  2.       /// 发送被动响应文本消息,需要先加密在发送  
  3.       /// </summary>  
  4.       /// <param name="fromUserName">发送方</param>  
  5.       /// <param name="toUserName">接收方</param>  
  6.       /// <param name="content">文本内容</param>  
  7.       public static void SendTextReplyMessage(string fromUserName, string toUserName, string content)  
  8.       {  
  9.           TextReplyMessage msg = new TextReplyMessage()  
  10.           {  
  11.               CreateTime = Tools.ConvertDateTimeInt(DateTime.Now),  
  12.               FromUserName = fromUserName,  
  13.               ToUserName = toUserName,  
  14.               Content = content  
  15.           };  
  16.         /*  LogInfo.Info("发送信息2sMsg=" + content);//也可以使用微信的接口发送消息 
  17.           TextMsg data = new TextMsg(content); 
  18.           data.agentid = "7"; 
  19.           data.safe = "0"; 
  20.           // data.toparty = "@all"; 
  21.           //   data.totag = "@all"; 
  22.           data.touser = toUserName; 
  23.           BLLMsg.SendMessage(data);*/  
  24.                
  25.           string CorpToken = AppIdInfo.GetToken();  
  26.           string corpId = AppIdInfo.GetCorpId();  
  27.           string encodingAESKey = AppIdInfo.GetEncodingAESKey();  
  28.           WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(CorpToken, encodingAESKey, corpId);  
  29.           string msg_signature = HttpContext.Current.Request.QueryString["msg_signature"];  
  30.           string timestamp = HttpContext.Current.Request.QueryString["timestamp"];  
  31.           string nonce = HttpContext.Current.Request.QueryString["nonce"];  
  32.           string encryptResponse = "";//加密后的文字  
  33.           string sMsg = msg.ToXmlString();//加密前的文字  
  34.           int isok = wxcpt.EncryptMsg(sMsg, timestamp, nonce, ref encryptResponse);//  
  35.           LogInfo.Info("发送信息sMsg=" + sMsg);  
  36.        //   LogInfo.Info("发送信息encryptResponse=" + encryptResponse);  
  37.           if (isok == 0 && !string.IsNullOrEmpty(encryptResponse))  
  38.           {  
  39.               HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;  
  40.               HttpContext.Current.Response.Write(encryptResponse);//被动相应消息不需要调用微信接口  
  41.           }  
  42.           else {  
  43.               LogInfo.Info("发送信息失败isok=" + isok);  
  44.           }     
  45.       }  

注释掉的代码就是主动发送消息,具体可参考微信企业号开发:主动发送消息

使用注释掉的代码也可以给用户发送消息,但这种方式不叫被动响应消息



被动响应消息实体

[csharp]  view plain  copy
  1. /// <summary>  
  2.    /// 被动响应消息类  
  3.    /// </summary>  
  4.    public abstract class ReplyMessage  
  5.    {  
  6.        public string ToUserName { getset; }  
  7.   
  8.        public string FromUserName { getset; }  
  9.   
  10.        public long CreateTime { getset; }  
  11.   
  12.        /// <summary>  
  13.        /// 将对象转化为Xml消息  
  14.        /// </summary>  
  15.        /// <returns></returns>  
  16.        public abstract  string ToXmlString();  
  17.    }  
  18.   
  19.    /// <summary>  
  20.    /// 被动响应文本消息  
  21.    /// </summary>  
  22.    public class TextReplyMessage : ReplyMessage  
  23.    {  
  24.        /// <summary>  
  25.        /// 回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)   
  26.        /// </summary>  
  27.        public string Content { getset; }  
  28.   
  29.        /// <summary>  
  30.        /// 将对象转化为Xml消息  
  31.        /// </summary>  
  32.        /// <returns></returns>  
  33.        public override string ToXmlString()  
  34.        {  
  35.            string s = "<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime><MsgType><![CDATA[{3}]]></MsgType><Content><![CDATA[{4}]]></Content></xml>";  
  36.            s = string.Format(s,  
  37.                ToUserName ?? string.Empty,  
  38.                FromUserName ?? string.Empty,  
  39.                CreateTime.ToString(),  
  40.                "text",  
  41.                Content ?? string.Empty  
  42.                );  
  43.            return s;  
  44.        }  
  45.    }  

配置的URL网页的代码:

[csharp]  view plain  copy
  1. public class TestWeixin : IHttpHandler {  
  2.     
  3.     public void ProcessRequest (HttpContext context) {        
  4.         if (context.Request.HttpMethod.ToLower() == "post")  
  5.         {  
  6.             try  
  7.             {  
  8.                 System.IO.Stream s = context.Request.InputStream;  
  9.                 byte[] b = new byte[s.Length];  
  10.                 s.Read(b, 0, (int)s.Length);  
  11.                 string postStr = System.Text.Encoding.UTF8.GetString(b);  
  12.                 if (!string.IsNullOrEmpty(postStr))  
  13.                 {  
  14.                     Execute(postStr);  
  15.                 }  
  16.             }catch(Exception e)  
  17.             {  
  18.                 new AppException("收到信息异常" + e.Message);  
  19.             }      
  20.   
  21.         }  
  22.         else //开启应用的回调模式调用 ,代码省略  
  23.         {              
  24.         }  
  25.     }  
  26.     private void Execute(string postStr)  
  27.     {  
  28.        ReceiveMessageBase basemsg = ConvertMsgToObject(postStr);  
  29.         if (basemsg.MsgType ==.MsgType.Text)  
  30.         {  
  31.           TextReceiveMessage txtMsg = basemsg as TextReceiveMessage;  
  32.             if (txtMsg != null)  
  33.             {  
  34.                 SendTextReplyMessage(txtMsg.ToUserName, txtMsg.FromUserName, "收到文本消息:" + txtMsg.Content);//发送被动消息  
  35.             }  
  36.         }  
  37.         
  38.          
  39.     }  
  40.       
  41.     public bool IsReusable {  
  42.         get {  
  43.             return false;  
  44.         }  
  45.     }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值