• [.NET] 使用 Senparc.Weixin 接入微信公众号开发:简单实现自动回复


    使用 Senparc.Weixin 接入微信公众号开发:简单实现自动回复

    目录

    • 一、前提
    • 二、基本配置信息简析
    • 三、配置服务器地址(URL)
    • 四、请求处理

    一、前提

      先申请微信公众号的授权,找到或配置几个关键的信息(开发者ID、开发者密码、IP白名单、令牌和消息加解密密钥等)。

    二、基本配置信息简析

      开发者ID:固定的;

      开发者密码:自己扫一下就可以看到;

      IP白名单:设置自己配置服务器的地址;

      服务器地址(URL):稍后详解;

      令牌:随便写,按规则;

      消息加解密密钥:随便写,或者随机生成;

    三、配置服务器地址(URL)

      服务器地址(URL)应该怎么配置呢?图片上的配置的地址是:http://www.nidie.com.cn/wechat ,那么它对应的控制器应该是怎么样子的呢?

      在这里,我使用了第三方的包,需要通过 Nuget 来安装:

      <package id="Senparc.Weixin" version="4.22.1" targetFramework="net471" />
      <package id="Senparc.Weixin.MP" version="14.14.0" targetFramework="net471" />
      <package id="Senparc.Weixin.MP.MVC" version="5.4.5" targetFramework="net471" />

      接下来新建一个 WeChatController.cs:

    using System.Threading.Tasks;
    using System.Web.Mvc;
    using Senparc.Weixin.MP;
    using Senparc.Weixin.MP.Entities.Request;
    using Senparc.Weixin.MP.MvcExtension;
    using Wen.MvcDemo.Application.WeChat.MessageHandlers.CustomMessageHandlers;
    using Wen.MvcDemo.Infrastructure.Configuration;
    
    namespace Wen.MvcDemo.Web.Controllers
    {
        /// <summary>
        /// 微信
        /// </summary>
        public class WeChatController : Controller
        {
            #region private static field
    
            private static readonly string AppId = ApplicationSettingsFactory.GetApplicationSettings().WeChatAppId;
    
            private static readonly string EncodingAesKey = ApplicationSettingsFactory.GetApplicationSettings().WeChatEncodingAesKey;
    
            private static readonly string Token = ApplicationSettingsFactory.GetApplicationSettings().WeChatToken;
    
            #endregion private static field
    
            /// <summary>
            /// 微信后台验证地址
            /// </summary>
            /// <param name="signature"></param>
            /// <param name="timestamp"></param>
            /// <param name="nonce"></param>
            /// <param name="echostr"></param>
            /// <returns></returns>
            [HttpGet]
            public ActionResult Index(string signature, string timestamp, string nonce, string echostr)
            {
                return Content(echostr);
            }
    
            /// <summary>
            /// 处理用户发送消息后
            /// </summary>
            /// <param name="postModel"></param>
            /// <returns></returns>
            [HttpPost]
            public async Task<ActionResult> Index(PostModel postModel)
            {
                //校验签名
                if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
                    return new WeixinResult("参数错误!");
    
                postModel.AppId = AppId;
                postModel.EncodingAESKey = EncodingAesKey;
                postModel.Token = Token;
    
                //接收消息,自定义 MessageHandler,对微信请求进行处理
                var messageHandler = new CustomMessageHandler(Request.InputStream, postModel);
    
                //执行微信处理过程
                await messageHandler.ExecuteAsync();
                //返回处理结果
                return new FixWeixinBugWeixinResult(messageHandler);
            }
        }
    }

       

      代码分析:

      里面主要包含了三个静态字段和两个 Index 方法。

      其中静态字段对应的就是基本配置信息里面对应的几个参数,平常都是写入配置文件中来进行读取。

      其中一个标识特性为 HttpGet 的 Index 方法,它是用来通过服务器地址(URL)验证的,当你成功部署到你的服务器后,再点击提交认证就可以通过了。注意的是,需要将代码先提交到服务器,再进行提交确认。

       可能你看到该方法好像只返回 return Content(echostr); 这么简单的代码感到质疑:这能行吗?“我”记得官方文档好像要调用很复杂的方法进行校验才行的!?

      上图就是官方文档,但是我只关心通过配置提交认证,也就是我用红圈着色的部分,即原样返回 echostr 参数内容即可。

      第二个是实现 Post 请求的 Index 方法,在这里我进行了签名校验(也就是上图文档的校验逻辑),因为使用了第三方库,我们知道传哪些参数过去就可以了,签名通过后就是读取请求信息并进行后续处理的步骤了。

    四、请求处理

      在上面的处理请求信息的代码中,我自定义了一个类 CustomMessageHandler 来处理消息。

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Linq;
    using Senparc.Weixin.MP.AppStore;
    using Senparc.Weixin.MP.AppStore.Utility;
    using Senparc.Weixin.MP.Entities;
    using Senparc.Weixin.MP.Entities.Request;
    using Senparc.Weixin.MP.MessageHandlers;
    
    namespace Wen.MvcDemo.Application.WeChat.MessageHandlers.CustomMessageHandlers
    {
        /// <summary>
        /// 自定义消息处理
        /// </summary>
        public class CustomMessageHandler : MessageHandler<CustomMessageContext>
        {
            public CustomMessageHandler(Stream inputStream, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(inputStream, postModel, maxRecordCount, developerInfo)
            {
            }
    
            public CustomMessageHandler(XDocument requestDocument, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(requestDocument, postModel, maxRecordCount, developerInfo)
            {
            }
    
            public CustomMessageHandler(RequestMessageBase requestMessageBase, PostModel postModel = null, int maxRecordCount = 0, DeveloperInfo developerInfo = null) : base(requestMessageBase, postModel, maxRecordCount, developerInfo)
            {
            }
    
            /// <summary>
            /// 默认
            /// </summary>
            /// <param name="requestMessage"></param>
            /// <returns></returns>
            public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
            {
                var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他类型
                responseMessage.Content = $"您好,目前使用的微信公众号仍处于开发阶段,现已接入了【图灵机器人】,您可以尝试和他(她)交流。";
                return responseMessage;
            }
        }
    }

      

      CustomMessageHandler 类继承了 MessageHandler 类,然后重写了 DefaultResponseMessage() 方法,返回固定的文本值。base.CreateResponseMessage<T>() 方法可以返回多种不同类型的结果值,如:

    ResponseMessageText - 对应文本消息
    
    ResponseMessageNews - 对应图文消息
    
    ResponseMessageMusic - 对应音乐消息
    
    ResponseMessageXXX - 其他类型以此类推

      

      上述方法只是一种默认的消息处理,我们也可以专门针对不同的请求类型做出不同的回应,比如重写 OnTextRequest(),其它重载需要自己观察基类成员:

            /// <summary>
            /// 文本请求
            /// </summary>
            /// <param name="requestMessage"></param>
            /// <returns></returns>
            public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
            {
                var responseMessage = base.CreateResponseMessage<ResponseMessageText>();
                responseMessage.Content = $"您刚才发送的文字信息是:{requestMessage.Content}。";  //
    用于换行,requestMessage.Content即用户发过来的文字内容
                return responseMessage;
            }

      因为在继承 MessageHandler<T> 类的同时,我创建了一个 CustomMessageContext 自定义消息上下文的类,该类内容如下,并没有包含其它方法,直接继承 MessageContext<IRequestMessageBase, IResponseMessageBase> 即可:

    using Senparc.Weixin.Context;
    using Senparc.Weixin.MP.Entities;
    
    namespace Wen.MvcDemo.Application.WeChat.MessageHandlers.CustomMessageHandlers
    {
        /// <summary>
        /// 自定义消息上下文
        /// </summary>
        public class CustomMessageContext : MessageContext<IRequestMessageBase, IResponseMessageBase>
        {
        }
    }

      

      这样,就完成了所有代码的编写,现在我们再次把代码部署好之后就可以开始进行测试了。

      因为我除了部署自己的站点之外,还接入了【图灵机器人】回复,所以你看到了两条信息。

  • 相关阅读:
    一些链接
    svn
    the source attachment does not contain the source for the file StrutsPrepareAndExecuteFilter.class
    hibernate学习
    hibernate
    mysql front查看所有数据库
    SSD: Single Shot MultiBox Detector 论文解读,附代码
    YOLO算法-论文笔记
    Deep Learning菜鸡篇,我的第一个深度神经网络
    小白成长之路:初识python(六) --python线程池
  • 原文地址:https://www.cnblogs.com/liqingwen/p/9219454.html
Copyright © 2020-2023  润新知