微信企业号接收消息并自动响应

2023-11-07

花了2天时间做了企业号接收消息功能测试,微信官方的文档给了我很大的帮助,但是恰恰卡时间最长的,也是官方文档上的一段有误导性的说明。带我细细道来

首先把微信发送信息到企业号服务器,然后企业号自动响应的过程图示下,网上找的,感觉描述的很好:


这里有几个地方很重要,在开发过程中不能搞错,不然会浪费很多测试时间:

1、消息的回调url就是每个应用模式选择中,回调模式里面设置的url。要使用一般处理程序要接收数据,*.ashx

2、完整的回调url是:url?msg_signature=ASDFQWEXZCVAQFASDFASDFSS&timestamp=13500001234&nonce=123412323,比回调模式验证开启操作时少了个echostr

3、根据消息的不同类型(文本、图片、声音...),post数据的xml格式不同,下面均是以text演示

4、整个过程概括起来就是:微信发消息含xml的post数据到回调url》》企业号服务器接收post数据(用stream接收转换)》》解密post,获取text类xml的数据,如下:》》写入数据库》》如果需要自动响应,那么根据解密的xml数据,做操作判断,执行不同操作,返回不同的加密xml返回给微信服务器,微信服务器再转发给微信客户端

<xml>
    <ToUserName>
        <![CDATA[wx6ce30be442e8cf9c]]>
    </ToUserName>
    <FromUserName>
        <![CDATA[wzwl005]]>
    </FromUserName>
    <CreateTime>1485134274</CreateTime>
    <MsgType>
        <![CDATA[text]]>
    </MsgType>
    <Content>
        <![CDATA[哦无聊]]>
    </Content>
    <MsgId>2792547595104851615</MsgId>
    <AgentID>5</AgentID>
</xml>

实际操作:

应用后台设置的网址加入为:www.aaa.com/weixin/auth.ashx

那么我在服务器上要有对应这个网址的响应文件auth.ashx,文件代码如下:

下面代码实现,对发送过来的数据做了解密,但是并没有写入数据库,然后不管发过来什么数据,统一回复了“你好!!”

    public class auth : IHttpHandler
    {
        const string sToken = "***";             //应用配置中随机生成的Token
        const string sCorpID = "***";      //企业号的CorpID
        const string sEncodingAESKey = "******";     //应用配置中随机生成的EncodingAESKey
        pub.WXBizMsgCrypt wxcpt = new pub.WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);

        public void ProcessRequest(HttpContext context)
        {
            if (HttpContext.Current.Request.HttpMethod.ToUpper() == "GET")
            {
                //HttpContext.Current.Response.Write(pub.DataCache.GetCache("yuanwen"));
                //HttpContext.Current.Response.Write(pub.DataCache.GetCache("jiemihou"));
                //HttpContext.Current.Response.Write(pub.DataCache.GetCache("fasong"));
                UrlAuth();
            }
            else
            {
                string postString = "";
                using (Stream stream = HttpContext.Current.Request.InputStream)
                {
                    Byte[] postBytes = new Byte[stream.Length];
                    stream.Read(postBytes, 0, (Int32)stream.Length);
                    postString = Encoding.UTF8.GetString(postBytes);
                }

                if (!string.IsNullOrEmpty(postString))
                {
                    Execute(postString);
                }
            }
        }

        private void Execute(string postStr) {
            //接收企业号回调信息
            string sVerifyMsgSig = pub.DNTRequest.GetQueryString("msg_signature");
            string sVerifyTimeStamp = pub.DNTRequest.GetQueryString("timestamp");
            string sVerifyNonce = pub.DNTRequest.GetQueryString("nonce");

            //对收到的密文进行解析处理
            string sMsg = "";  // 解析之后的明文
            int flag = wxcpt.DecryptMsg(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, postStr, ref sMsg);
            if (flag != 0)
            {
                //解密失败
                return;
            }
            //加密后并发送
            string encryptResponse = "";
            sVerifyTimeStamp = pub.DataConverter.timetoint(DateTime.Now).ToString();
            //组装xml响应消息
            wxcpt.EncryptMsg(ToXmlString("你好!!"), sVerifyTimeStamp, sVerifyNonce, ref encryptResponse);
            HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
            HttpContext.Current.Response.Write(encryptResponse);
        }

        private string ToXmlString(string content)
        {
            string timestamp = pub.DataConverter.timetoint(DateTime.Now).ToString();
            string s = "<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime><MsgType><![CDATA[{3}]]></MsgType><Content><![CDATA[{4}]]></Content></xml>";
            s = string.Format(s,"wzwl005", "wx6ce30be442e8cf9c", timestamp, "text", content);
            return s;
        }

        private void UrlAuth()
        {
            //接收企业号回调信息
            string sVerifyMsgSig = pub.DNTRequest.GetQueryString("msg_signature");
            string sVerifyTimeStamp = pub.DNTRequest.GetQueryString("timestamp");
            string sVerifyNonce = pub.DNTRequest.GetQueryString("nonce");
            string sVerifyEchoStr = pub.DNTRequest.GetQueryString("echostr");
            sVerifyEchoStr = sVerifyEchoStr.Replace(" ", "+");

            int ret = 0;
            string sEchoStr = "";
            ret = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr, ref sEchoStr);
            if (ret != 0)
            {
                return;
            }
            HttpContext.Current.Response.Write(sEchoStr);
            HttpContext.Current.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微信企业号接收消息并自动响应 的相关文章

  • 如何在 Visual Studio 2010 中增强 XAML 设计器?

    当我使用 XAML 设计器时 进入设计器和退出设计器是如此困难和缓慢 当我这样做时 Visual Studio 卡了一段时间 有什么方法可以增强 XAML 设计器和编辑器吗 Ant 保存 XAML 文件时非常慢 这通常意味着您可能有复杂的
  • c和java语言中的换行符

    现在行分隔符取决于系统 但在 C 程序中我使用 n 作为行分隔符 无论我在 Windows 还是 Linux 中运行它都可以正常工作 为什么 在java中 我们必须使用 n 因为它与系统相关 那么为什么我们在c中使用 n 作为新行 而不管我
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 如何读取扩展文件属性/文件元数据

    因此 我按照教程使用 ASP net core 将文件 上传 到本地路径 这是代码 public IActionResult About IList
  • 如何在 C# 中从 UNIX 纪元时间转换并考虑夏令时?

    我有一个从 unix 纪元时间转换为 NET DateTime 值的函数 public static DateTime FromUnixEpochTime double unixTime DateTime d new DateTime 19
  • 单元测试一起运行时失败,单独运行时通过

    所以我的单元测试遇到了一些问题 我不能只是将它们复制并粘贴到这里 但我会尽力而为 问题似乎是 如果我一项一项地运行测试 一切都会按预期进行 但如果我告诉它一起运行测试 则 1 5 将通过 TestMethod public void Obj
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • ASP.NET:获取自 1970 年 1 月 1 日以来的毫秒数

    我有一个 ASP NET VB NET 日期 我试图获取自 1970 年 1 月 1 日以来的毫秒数 我尝试在 MSDN 中寻找方法 但找不到任何东西 有谁知道如何做到这一点 从 NET 4 6 开始 该方法ToUnixTimeMillis
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • Rx 中是否有与 Task.ContinueWith 运算符等效的操作?

    Rx 中是否有与 Task ContinueWith 运算符等效的操作 我正在将 Rx 与 Silverlight 一起使用 我正在使用 FromAsyncPattern 方法进行两个 Web 服务调用 并且我想这样做同步地 var o1
  • 如何将整数转换为 void 指针?

    在 C 中使用线程时 我面临警告 警告 从不同大小的整数转换为指针 代码如下 include
  • PlaySound 可在 Visual Studio 中运行,但不能在独立 exe 中运行

    我正在尝试使用 Visual Studio 在 C 中播放 wav 文件 我将文件 my wav 放入项目目录中并使用代码 PlaySound TEXT my wav NULL SND FILENAME SND SYNC 我按下播放按钮 或
  • 如何使用 watin 中的 FileUploadDialogHandler 访问文件上传对话框

    我正在使用 IE8 和 watin 并尝试通过我的网页测试上传文件 我不能简单地使用 set 方法设置上传文件 例如 ie FileUpload Find ById someId Set C Desktop image jpg 因为上传文本
  • Visual Studio 中的测试单独成功,但一组失败

    当我在 Visual Studio 中单独运行测试时 它们都顺利通过 然而 当我同时运行所有这些时 有些通过 有些失败 我尝试在每个测试方法之间暂停 1 秒 但没有成功 有任何想法吗 在此先感谢您的帮助 你们可能有一些共享数据 检查正在使用
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • .NET中的LinkedList是循环链表吗?

    我需要一个循环链表 所以我想知道是否LinkedList是循环链表吗 每当您想要移动列表中的 下一个 块时 以循环方式使用它的快速解决方案 current current Next current List First 电流在哪里Linke
  • gcc 的配置选项如何确定默认枚举大小(短或非短)?

    我尝试了一些 gcc 编译器来查看默认枚举大小是否很短 至少一个字节 强制使用 fshort enums 或无短 至少 4 个字节 强制使用 fno short enums user host echo Static assert 4 si
  • 为什么在setsid()之前fork()

    Why fork before setsid 守护进程 基本上 如果我想将一个进程与其控制终端分离并使其成为进程组领导者 我使用setsid 之前没有分叉就这样做是行不通的 Why 首先 setsid 将使您的进程成为进程组的领导者 但它也
  • 如何在按钮单击时模拟按键 - Unity

    我对 Unity 中的脚本编写非常陌生 我正在尝试创建一个按钮 一旦单击它就需要模拟按下 F 键 要拾取一个项目 这是我当前的代码 在编写此代码之前我浏览了所有统一论坛 但找不到任何有效的东西 Code using System Colle
  • 如何正确使用 std::condition_variable?

    我很困惑conditions variables以及如何 安全 使用它们 在我的应用程序中 我有一个创建 gui 线程的类 但是当 gui 是由 gui 线程构造时 主线程需要等待 情况与下面的函数相同 主线程创建互斥体 锁和conditi

随机推荐

  • 怎么用Wireshark抓包QQ的到对方的IP地址

    怎么用Wireshark抓包QQ的到对方的IP地址 通过wireshark抓包工具得到对方的IP 一 wireshark Wireshark 前称Ethereal 是一个网络封包分析软件 网络封包分析软件的功能是撷取网络封包 并尽可能显示出
  • matlab 画图

    转 matlab 画图plot 标记符大小调整和填充 2014 01 15 21 00 23 转载 标签 it 分类 Matlab 原文地址 http xiangyan0212 blog 163 com blog static 207037
  • ajax代码复用,可重用的JS ajax模式(jquery)

    我想知道是否有更好的方法来为jquery创建可重用的ajax对象 这是我未经测试的代码 var sender function ajax url type dataType callback ajax url url type type d
  • 【计算机视觉40例】案例22:目标检测(YOLO方法、SSD方法)

    导读 本文是专栏 计算机视觉40例简介 的第22个案例 目标检测 YOLO方法 SSD方法 该专栏简要介绍李立宗主编 计算机视觉40例 从入门到深度学习 OpenCV Python 一书的40个案例 目前 该书已经在电子工业出版社出版 大家
  • 21天Jenkins打卡Day10-自动触发项目构建

    参考文档 http istester com jenkins 437 html
  • 【atlas】atlas 编译报错整理(全)

    前言 最近在编译 apache altas 1 1版本 在编译过程中遇到很多报错 这里整理并记录一下 问题一 org restlet jee 包找不到 问题原因 Maven主仓库中找不到包的解决办法 如org restlet jee not
  • Linux 管道pipeline

    管道符 tar归档目录 gzip压缩 ssh传输并用cat读取标准输入到文件 tar cf kernel linux 6 4 7 gzip ssh user 192 168 123 144 cat gt destination tar gz
  • PyQt学习笔记:使用QtWidgets.qApp实现在程序中随时访问应用的方法

    PyQt学习笔记 使用QtWidgets qApp实现在程序中随时访问应用的方法 在PyQt中 QtWidgets qApp是一个全局变量 它提供了一种在程序中随时访问应用的方法 通过使用qApp 我们可以轻松地获取到应用的实例 并且可以使
  • 模式识别——特征提取(表达)

    特征表达 特征是机器学习系统的原材料 对最终模型的影响是毋庸置疑的 如果数据被很好地表达成了特征 通常线性模型就能达到满意的精度 关于特征 需要考虑以下三方面 1 特征表示的粒度 需要考虑 模型在一个什么程度上的特征表示 才能发挥效果 以图
  • tomcat堆栈中10大常见线程详解

    Tomcat作为一个服务器来讲 必然运行着很多的线程 而每一个线程究竟是干什么的 这个需要非常的清楚 无论是打印断点 还是通过jstack进行线程栈分析 这都是必须要掌握的技能 本文带你基于Tomcat7 8 9的版本 识别Tomcat堆栈
  • Cool! TineEye 图片逆向搜索

    Tineye 是世界上第一个逆向图片搜索引擎 可以根据你提交的图片在Internet找到类似图片 下面是Tineye网站上的一些搜索例子 很神奇吧 Cool Searches click image to search This page
  • 爱心代码(web前端)陈飞宇李峋同款

    文章目录 前言 一 效果图 二 操作步骤 第一步 第二步 第三步 第四步 第五步 第六步 源码 前言 最近随着电视剧 点燃我温暖你 的火热播出 剧中帅气学霸李洵的炫酷爱心代码也迅速火出了圈 爱心素材也异常火爆 我在这里整理了一份大家有需自取
  • 使用YOLOv5检测大宽高比(细长目标)时无法检测问题的解决方法

    在深度学习的工程中总会遇到许许多多的奇奇怪怪的问题 使人头大 上周五Franpper在使用yolov5 5 0训练时就遇到了这么一个奇怪的问题 在训练过程中labels一直为0 表示没有读进去标签 虽然可以训练 但是是无效训练 因为网络也不
  • 【硬件】对电源模块的梳理(包括DC-DC、LDO等不同芯片应用电路)

    目录 1 DC DC 变换器 ME3116 24V转5V JW5017S 18V转5V CX802 输入电压 4 5 80V 输出电压5V 输出电流1 2A LM2596S ADJ 输入电压3 3 40V 输出电压5V 2 LDO 低压差
  • java中网络编程UDP在线咨询案例(DatagramSocket)

    方法1 单线程 单方向发送接收 发送端 UdpTalkClient java 步骤流程 1 使用DatagramSocket 指定端口 创建发送端 2 准备数据一定转成字节数组 3 封装DatagramSocket包裹 需要指定目的地 4
  • java流程控制语句

    一 顺序结构 顺序结构 按照代码的顺序 自上而下执行 二 选择结构 A if语句 格式 a if 关系表达式 语句体 详细情况 if 关系表达式 如果关系表达式的结果是true 执行大括号中的语句 如果关系表达式的结果是false 就跳过不
  • 北航计算机学院编译技术,北航编译技术在线作业一二三

    北航编译技术在线作业一二三 由会员分享 可在线阅读 更多相关 北航编译技术在线作业一二三 16页珍藏版 请在人人文库网上搜索 1 北航编译技术在线作业一一 单选题 共 14 道试题 共 56 分 1 LR 1 文法都是 C A 无二义性且无
  • CentOS修改默认的root账号名称

    最近云服务器老是提示被爆破 为了安全起见 设置了一下hosts deny 另外还更改了默认的root账号名称 这里记录root账号修改过程 1 修改密码文件中的用户名 vi etc passwd 第一行第一个root字符修改成你想要的用户名
  • 深度学习 多分类roc曲线的绘制

    对于多分类问题 ROC曲线的获取主要有两种方法 假设测试样本个数为m 类别个数为n 在训练完成后 计算出每个测试样本的在各类别下的概率或置信度 得到一个 m n 形状的矩阵P 每一行表示一个测试样本在各类别下概率值 按类别标签排序 相应地
  • 微信企业号接收消息并自动响应

    花了2天时间做了企业号接收消息功能测试 微信官方的文档给了我很大的帮助 但是恰恰卡时间最长的 也是官方文档上的一段有误导性的说明 带我细细道来 首先把微信发送信息到企业号服务器 然后企业号自动响应的过程图示下 网上找的 感觉描述的很好 这里