.NET开发企业微信应用接收用户消息

本文档详细介绍了如何在企业微信中接收和处理菜单点击事件,包括配置API、设置菜单、消息加密解密的步骤。使用C#库实现接收和回复消息,并展示了处理点击事件来获取并回复图片的示例代码。同时,针对POST请求可能出现的415错误给出了解决方案。
摘要由CSDN通过智能技术生成

这一章主要讲应用菜单点击事件的接收

要接收企业微信消息,首先要配置API,这里不进行详细介绍了,具体请参考企业微信官方文档
接收消息

另外还需要用代码设置菜单,菜单点击事件无法手动设置,至少要用代码设置一次之后才能手动设置点击事件,需要设置菜单代码的可以留言联系方式

企业微信接收与回复消息需要加密以及解密,官方有提供算法库,目前已有 c++/python/php/java/golang/c# 等语言版本,我用的是C#库

1.封装接收消息帮助类

private string sToken { get; set; }
        private string sEncodingAESKey { get; set; }
        Tencent.WXBizMsgCrypt Wxcpt { get; set; }

        public  ReceiveMsgHelper(string sToken, string sEncodingAESKey)
        {
            this.sToken = sToken;
            this.sEncodingAESKey = sEncodingAESKey;
            this.Wxcpt = new Tencent.WXBizMsgCrypt(sToken, sEncodingAESKey, corpid);
        }

        /// <summary>
        /// 获取响应消息对象
        /// </summary>
        /// <param name="RequestStr"></param>
        /// <returns></returns>
        public HttpResponseMessage getHttpRespMsg(string RequestStr)
        {
            return new HttpResponseMessage
            {
                Content = new StringContent(RequestStr, Encoding.GetEncoding("UTF-8"), "text/xml")
            };
        }

        /// <summary>
        /// 验证VerifyURL
        /// </summary>
        /// <returns></returns>
        public  string VerifyURL(string msg_signature, string timestamp, string nonce, string echostr)
        {

            string sEchoStr = "";
            int ret = Wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr, ref sEchoStr);
            if (ret != 0)
            {
                LogHelper.Error("ERR: VerifyURL fail, ret: " + ret);
                return string.Empty;
            }

            return sEchoStr;
        }

        /// <summary>
        /// DecryptMsg,解密
        /// </summary>
        /// <returns></returns>
        public  string DecryptMsg(string msg_signature, string timestamp, string nonce, string ciphertext)
        {

            string sEchoStr = "";
            int ret = Wxcpt.DecryptMsg(msg_signature, timestamp, nonce, ciphertext, ref sEchoStr);
            if (ret != 0)
            {
                LogHelper.Error("ERR: DecryptMsg fail, ret: " + ret);
                return string.Empty;
            }

            return sEchoStr;
        }


        /// <summary>
        /// EncryptMsg ,加密
        /// </summary>
        /// <returns></returns>
        public string EncryptMsg(string timestamp, string nonce, string text)
        {

            string sEchoStr = "";
            int ret = Wxcpt.EncryptMsg(text, timestamp, nonce, ref sEchoStr);
            if (ret != 0)
            {
                LogHelper.Error("ERR: EncryptMsg fail, ret: " + ret);
                return string.Empty;
            }

            return sEchoStr;
        }

这里我的应用id,以及接收配置字符串都写在了配置文件里

2.接收消息接口

private ReceiveMsgHelper wx
        {
            get { return new ReceiveMsgHelper(base.sToken, base.sEncodingAESKey); }
        }
		[AllowAnonymous, HttpPost, HttpGet]
        public HttpResponseMessage Receive()
        {
            var msg_signature = HttpContext.Current.Request.QueryString["msg_signature"].ToString();
            var timestamp = HttpContext.Current.Request.QueryString["timestamp"].ToString();
            var nonce = HttpContext.Current.Request.QueryString["nonce"].ToString();
            var RequestStr = "";//回复消息内容

            //验证URL
            if (HttpContext.Current.Request.HttpMethod.ToUpper() == "GET")
            {
                var echostr = HttpContext.Current.Request.QueryString["echostr"].ToString();
                var sEchoStr = wx.VerifyURL(msg_signature, timestamp, nonce, echostr);
                RequestStr = sEchoStr;
            }
            else
            {
                //捕捉事件
                var evnentXml = string.Empty;
                using (StreamReader sr = new StreamReader(HttpContext.Current.Request.InputStream))
                {
                    //读取
                    evnentXml = sr.ReadToEnd();
                }

                //解密
                evnentXml = wx.DecryptMsg(msg_signature, timestamp, nonce, evnentXml);
                LogHelper.Debug(evnentXml);

                //转xml对象
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(evnentXml);

                //获取回复消息内容
                RequestStr = this.getRespDataImg(xmlDoc, timestamp, nonce);
                if (string.IsNullOrEmpty(RequestStr))
                {
                    return null;
                }
            }
            //响应消息
            return wx.getHttpRespMsg(RequestStr);
        }

企业微信在配置的时候发送的请求是GET方式,但在接收时的请求是POST方式,所以API要同时允许两种请求方式

获取回复消息方法

private string getRespDataImg(XmlDocument xmlDoc, string timestamp, string nonce)
        {
            var sRespData = "";//回复消息文本 

            var ToUserName = xmlDoc.DocumentElement.SelectSingleNode("ToUserName").InnerText;
            var FromUserName = xmlDoc.DocumentElement.SelectSingleNode("FromUserName").InnerText;
            var CreateTime = xmlDoc.DocumentElement.SelectSingleNode("CreateTime").InnerText;

            var MsgType = xmlDoc.DocumentElement.SelectSingleNode("MsgType").InnerText;//消息类型
            if (MsgType != "event")//事件类型消息
            {
                return null;
            }

            var Event = xmlDoc.DocumentElement.SelectSingleNode("Event").InnerText;//事件类型
            if (Event != "click")//点击事件
            {
                return null;
            }

            var EventKey = xmlDoc.DocumentElement.SelectSingleNode("EventKey").InnerText;//点击事件值

            //获取图片的媒体id
            string media_id = powerBIHelper.getMedia_idByTaskId(EventKey);
            if (!string.IsNullOrEmpty(media_id))
            {
                sRespData = $@"<xml>
                <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
                <FromUserName><![CDATA[{FromUserName}]]></FromUserName> 
                <CreateTime>{CreateTime}</CreateTime>
                <MsgType><![CDATA[image]]></MsgType>
                <Image>
                    <MediaId><![CDATA[{media_id}]]></MediaId>
                </Image>
               </xml>";
            }
            else
            {
                //查不到报表
                sRespData = $@"<xml>
                <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
                <FromUserName><![CDATA[{FromUserName}]]></FromUserName> 
                <CreateTime>{CreateTime}</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[没有查询到报表哦!如有问题可以联系开发人员]]></Content>
               </xml>";
            }
            //加密并返回
            return wx.EncryptMsg(timestamp, nonce, sRespData);
        }

更多消息格式请参考企业微信官方文档

如果在post接收企业微信消息时出现415错误,可以尝试在WebApiConfig文件中加上如下代码

var formatter = GlobalConfiguration.Configuration.Formatters.Where(f => f is System.Net.Http.Formatting.JsonMediaTypeFormatter).FirstOrDefault();
            if (!formatter.SupportedMediaTypes.Any(mt => mt.MediaType == "text/xml"))
                formatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));

            config.Formatters.Add(formatter);
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迪士尼在逃码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值