前一阵子,想着给我的站点集成一个微信登录,由于我之前从未有过微信相关的开发,所以我自己跟着网上的资料,一步一步的慢慢的探索,过程难免的遇到了很多坑,才把我的网站微信登录集成完成,所以这里分享一下我的探索的过程。由于我的是订阅号,所以一下的内容均针对订阅号而言的。
一、相识微信的交互流程
这里假设我们都已经申请号了微信开发的相关信息,那么我们就要设置微信认证服务器地点(api地点),这一步是必须的,微信与我们交互都是都是通过这一个地点,开始我一直不知道,我以为自己要对每一个功能都要写一个api,其实不需要的。我们只需要完成我们的微信认证服务器地点,然后里面处理我们相关的业务逻辑。
sequenceDiagram 用户->>微信: 发送消息“hello!” 微信->>我的网站: 认证服务api校验 我的网站-)微信: 校验乐成 微信->>我的网站: 发送“hello!”到认证服务api 我的网站-)业务逻辑: 认证服务api接收“hello!”而且处理业务逻辑 我的网站-->> 用户: 也可返回给用户相关信息用我的话就是
假设我的认证api是:/api/check
1.用户发送消息”你好“到微信公众号
2.微信公众号发起Get请求调用 /api/check 进行认证
3.认证乐成时微信公众号再次Post请求调用/api/check,而且携带”你好“信息
4./api/check接口里面处理相关业务逻辑,或者返回特定信息给用户
二、集成相关sdk
对于微信的消息处理,其实有点复杂,这里我网上搜了一下,大部门推荐的是盛派微信sdk,博客园也有相关的教程https://www.cnblogs.com/szw/archive/2013/05/20/3089479.html,个人用起来我觉得还是可以的,可以省去我们大部门工作,专注处理业务逻辑。
封装CustomMessageHandler
首先我是要对盛派微信sdk的封装,所以我新建了一个CustomMessageHandler,然后继续自MessageHandler,然后重新DefaultResponseMessage方法,这里比较简单,直接
public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
{
var responseMessage = base.CreateResponseMessage();
return responseMessage;
}
处理用户关注事件
当微信用户关注公众号时我需要发送问候语给用户,那么这里就需要重写OnEvent_SubscribeRequestAsync
public override Task OnEvent_SubscribeRequestAsync(RequestMessageEvent_Subscribe requestMessage)
{
var responseMessage = base.CreateResponseMessage();
responseMessage.Content = “接待关注”;
return Task.FromResult(responseMessage as IResponseMessageBase);
}
处理用户关键字
当微信用户给公众号发送特点消息(关键字)时,我需要回复用户,那么就重写OnTextRequestAsync
public override Task OnTextRequestAsync(RequestMessageText requestMessage)
{
var responseMessage = base.CreateResponseMessage();
return Task.FromResult(responseMessage as IResponseMessageBase);
}
抽离业务逻辑方法
在开发中,我们往往希望封装一个功能时,不需要牵扯太多业务逻辑,就例如不想在CustomMessageHandler里去写业务逻辑,那么我这里采用的委托的形式,新建一个CustomParam,然后里面定义一个两个委托- public class CustomParam
- {
- /// <summary>
- /// 普通文本事件处理
- /// </summary>
- public Func<RequestMessageText, ResponseMessageText, string, ResponseMessageText> OnTextFunc;
- /// <summary>
- /// 订阅事件处理
- /// </summary>
- public Func<string> OnSubscribeFunc;
- }
复制代码 然后通过CustomMessageHandler的构造函数传入- private CustomParam customParam;
- public CustomMessageHandler(CustomParam customParam)
- {
- this.customParam = customParam;
- }
复制代码 然后在具体的处理事件里面调用这个委托
通过接口调用微信CustomMessageHandler的方法
我接着在建一个接口,里面包含了认证,消息处理,创建CustomMessageHandler的方法,来给业务调用- using Core.WeXin.WxOfficial;
- using Senparc.Weixin.AspNet.MvcExtension;
- using Senparc.Weixin.MP.Entities;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace Core.WeXin
- {
- public interface IWxCommonHandler
- {
- /// <summary>
- /// 校验服务
- /// </summary>
- /// <returns></returns>
- bool CheckSign(string signature, string timestamp, string nonce, string echostr);
- /// <summary>
- /// 创建消息处理器
- /// </summary>
- /// <param name="inputStream"></param>
- /// <param name="messageAbsService"></param>
- void CreateMessageHandler(Stream inputStream, CustomParam param);
- /// <summary>
- /// 公众号消息处理
- /// </summary>
- /// <param name="inputStream"></param>
- /// <returns></returns>
- Task<WeixinResult> ExecuteMessageHandler();
- /// <summary>
- /// 获取当前opentid
- /// </summary>
- /// <returns></returns>
- string GetOpenId();
- /// <summary>
- /// 获取微信消息
- /// </summary>
- /// <returns></returns>
- string GetMessgeText();
- }
- }
复制代码- using Core.Log;
- using Core.WeXin.WxOfficial;
- using Microsoft.Extensions.Configuration;
- using Senparc.NeuChar;
- using Senparc.NeuChar.Entities;
- using Senparc.Weixin.AspNet.MvcExtension;
- using Senparc.Weixin.MP;
- using Senparc.Weixin.MP.Entities;
- using System;
- namespace Core.WeXin
- {
- internal class WxCommonHandler:IWxCommonHandler
- {
- private CustomMessageHandler customMessageHandler = null;
- private IConfiguration configuration;
- public WxCommonHandler(IConfiguration configuration)
- {
- this.configuration = configuration;
- }
- public bool CheckSign(string signature, string timestamp, string nonce, string echostr)
- {
- string token = configuration.GetSection("SenparcWeixinSetting:Token").Value;
- return CheckSignature.Check(signature, timestamp, nonce, token);
- }
- public void CreateMessageHandler(Stream inputStream,CustomParam customParam)
- {
- customMessageHandler = new CustomMessageHandler(inputStream, null, customParam);
- customMessageHandler.OmitRepeatedMessage = true;
- }
- public async Task<WeixinResult> ExecuteMessageHandler()
- {
- await customMessageHandler.ExecuteAsync(new CancellationToken());
- string result = "";
- if (customMessageHandler.ResponseDocument != null)
- {
- result = customMessageHandler.ResponseDocument.ToString();
- }
- return new WeixinResult(result);
- }
- public string GetOpenId()
- {
- return customMessageHandler.OpenId;
- }
- public string GetMessgeText()
- {
- var requestMsg= customMessageHandler.RequestMessage;
- if (requestMsg.MsgType == RequestMsgType.Text)
- {
- RequestMessageText requestText = requestMsg as RequestMessageText;
- return requestText.Content;
- }
- return string.Empty;
- }
- }
- }
复制代码 注册微信sdk相关内容
- using Core.Log;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.DependencyInjection;
- using Newtonsoft.Json;
- using Senparc.CO2NET;
- using Senparc.CO2NET.AspNet;
- using Senparc.Weixin.AspNet;
- using Senparc.Weixin.Entities;
- using Senparc.Weixin.MP;
- using Senparc.Weixin.RegisterServices;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace Core.WeXin
- {
- public static class ConfigureWxService
- {
- public static IServiceCollection AddWxOfficialServices(this IServiceCollection services, IConfiguration configuration)
- {
- services.AddScoped<IWxCommonHandler, WxCommonHandler>();
- services.AddSenparcWeixinServices(configuration);
- return services;
- }
- public static void UseWxOfficial(this WebApplication app, ConfigurationManager configuration)
- {
- var registerService = app.UseSenparcWeixin(app.Environment, null, null, register => { },
- (register, weixinSetting) =>
- {
- register.RegisterMpAccount(weixinSetting, configuration.GetSection("WxOfficialName").Value);
- });
- }
- }
- }
复制代码 二、新建认证api(Get请求)
前面说到,我们和微信打交道始终是这一个微信,所以我们需要用一个api既能接收认证又能接收消息,所以我先建一个Get请求的方法- [HttpGet("handler")]
- public ContentResult Handler()
- {
- string signature = Request.Query["signature"];
- string timestamp = Request.Query["timestamp"];
- string nonce = Request.Query["nonce"];
- string echostr = Request.Query["echostr"];
- if (wxCommonHandler.CheckSign(signature, timestamp, nonce, echostr))
- {
- return new ContentResult()
- {
- Content = echostr
- };
- }
- else
- {
- return new ContentResult()
- {
- Content = "false"
- };
- }
- }
复制代码 三、新建微信处理的Service
关注事件业务
我想在用户关注时发送对应的问候语,则我直接新建一个方法OnSubscribeEvent
[code] public string OnSubscribeEvent() { StringBuilder sb = new StringBuilder(); sb.Append("您好!接待关注【闲蛋】
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |