1. 程式人生 > >[.NET] 簡單接入微信公眾號開發:實現自動回復

[.NET] 簡單接入微信公眾號開發:實現自動回復

ring echo AC tin 處理過程 文本消息 n) () token

簡單接入微信公眾號開發:實現自動回復

一、前提

  先申請微信公眾號的授權,找到或配置幾個關鍵的信息(開發者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}。";  //\r\n用於換行,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>
    {
    }
}

  

  這樣,就完成了所有代碼的編寫,現在我們再次把代碼部署好之後就可以開始進行測試了。

技術分享圖片

  因為我除了部署自己的站點之外,還接入了【圖靈機器人】回復,所以你看到了兩條信息。

[.NET] 簡單接入微信公眾號開發:實現自動回復