/// <summary> /// 执行处理函数 /// </summary> /// <typeparam name="T">接受类型</typeparam> /// <param name="xmlStr">XML字符串</param> /// <returns></returns> private async Task <Tuple <ToMessageBase, IFromMessage> > ExecuteHandler <T>(string xmlStr) where T : class, IFromMessage { ToMessageBase toMessage = null; var type = typeof(T); var handler = serviceProvider.GetService <IWxEventsHandler>(); if (handler == null) { throw new WxSdkException($"接收公众号服务端事件消息需要先注册 {nameof(IWxEventsHandler)} !"); } IFromMessage fromMessage = XmlHelper.DeserializeObject <T>(xmlStr); if (fromMessage != null) { toMessage = await handler.Execute(fromMessage); } else { logger.LogWarning($"序列化类型【{type.FullName}】失败"); } return(new Tuple <ToMessageBase, IFromMessage>(toMessage, fromMessage)); }
/// <summary> /// 执行处理函数 /// </summary> /// <typeparam name="T">接受类型</typeparam> /// <param name="xmlStr">XML字符串</param> /// <returns></returns> private async Task <Tuple <ToMessageBase, IFromMessage> > ExcuteHandleFunc <T>(string xmlStr) where T : class, IFromMessage { ToMessageBase toMessage = null; IFromMessage fromMessage = null; var type = typeof(T); if (HandleFuncs.ContainsKey(type)) { fromMessage = XmlHelper.DeserializeObject <T>(xmlStr); if (fromMessage != null) { toMessage = await Task.FromResult(HandleFuncs[type] .Invoke(fromMessage)); } else { WeChatHelper.LoggerAction?.Invoke(nameof(ServerMessageHandler), string.Format("序列化类型【{0}】失败", type.FullName)); } } else { WeChatHelper.LoggerAction?.Invoke(nameof(ServerMessageHandler), string.Format("没有找到类型为【{0}】的处理函数", type.FullName)); } return(await Task.FromResult(new Tuple <ToMessageBase, IFromMessage>(toMessage, fromMessage))); }
/// <summary> /// 执行 /// </summary> /// <param name="fromMessage"></param> /// <returns></returns> public async Task <ToMessageBase> Execute(IFromMessage fromMessage) { if (fromMessage is FromTextMessage) { //返回多图文 var toMsg = new ToNewsMessage() { Articles = new List <ToNewsMessage.ArticleInfo>() { new ToNewsMessage.ArticleInfo() { Description = "最简洁最易于使用的微信Sdk,包括公众号Sdk、小程序Sdk、企业微信Sdk等,以及Abp VNext集成。", PicUrl = "https://www.xin-lai.com/imgs/xinlai-logo_9d2c29c2794e6a173738bf92b056ab69.png", Title = "Magicodes.Wx.Sdk简介", Url = "http://xin-lai.com" } }, FromUserName = "******", ToUserName = "******" }; return(await Task.FromResult(toMsg)); } else if (fromMessage is FromSubscribeEvent) { //返回文本消息 return(await Task.FromResult(new ToTextMessage() { Content = "欢迎关注!", })); } else if (fromMessage is FromTextMessage) { //返回文本 return(await Task.FromResult(new ToTextMessage() { Content = "Test", })); } return(await Task.FromResult(new ToNullMessage())); }
/// <summary> /// 处理消息 /// </summary> /// <param name="xmlStr">XML字符串</param> /// <returns>The <see cref="Task{ToMessageBase}"/></returns> public async Task <ToMessageBase> HandleMessage(string xmlStr) { ToMessageBase toMessage = null; logger.LogDebug(Environment.NewLine + xmlStr); var xmlElement = XElement.Parse(xmlStr); var msgTypeElement = xmlElement.Element("MsgType"); if (string.IsNullOrWhiteSpace(msgTypeElement?.Value)) { throw new WxSdkException("消息类型不能为空"); } var msgType = msgTypeElement.Value.Trim().ToLower(); //接收的消息 IFromMessage fromMessage = null; //处理结果 Tuple <ToMessageBase, IFromMessage> resulTuple; //处理事件消息 if (msgType == "event") { var fromEventTypeElement = xmlElement.Element("Event"); if (string.IsNullOrWhiteSpace(fromEventTypeElement?.Value)) { throw new WxSdkException("事件类型不能为空"); } var fromEvent = fromEventTypeElement.Value.Trim().ToLower(); //记录日志 logger.LogDebug("Event " + fromEvent); //处理微信服务器事件Key大小写不一致的问题 xmlStr = xmlStr.Replace("<Event><![CDATA[" + fromEventTypeElement.Value + "]]></Event>", "<Event><![CDATA[" + fromEvent + "]]></Event>"); var fromEventType = (FromEventTypes)Enum.Parse(typeof(FromEventTypes), fromEvent); resulTuple = fromEventType switch { FromEventTypes.subscribe => await ExecuteHandler <FromSubscribeEvent>(xmlStr), FromEventTypes.unsubscribe => await ExecuteHandler <FromUnsubscribeEvent>(xmlStr), FromEventTypes.scan => await ExecuteHandler <FromScanEvent>(xmlStr), FromEventTypes.location => await ExecuteHandler <FromLocationEvent>(xmlStr), FromEventTypes.click => await ExecuteHandler <FromClickEvent>(xmlStr), FromEventTypes.view => await ExecuteHandler <FromViewEvent>(xmlStr), FromEventTypes.view_miniprogram => await ExecuteHandler <FromViewMiniprogramEvent>(xmlStr), FromEventTypes.templatesendjobfinish => await ExecuteHandler <FromTemplateSendJobFinishEvent>(xmlStr), _ => throw new ArgumentOutOfRangeException(), }; } else { //记录日志 logger.LogDebug(msgType); //处理会话消息 var fromMessageType = (FromMessageTypes)Enum.Parse(typeof(FromMessageTypes), msgType); switch (fromMessageType) { case FromMessageTypes.text: resulTuple = await ExecuteHandler <FromTextMessage>(xmlStr); break; case FromMessageTypes.image: resulTuple = await ExecuteHandler <FromImageMessage>(xmlStr); break; case FromMessageTypes.voice: resulTuple = await ExecuteHandler <FromVoiceMessage>(xmlStr); break; case FromMessageTypes.video: resulTuple = await ExecuteHandler <FromVideoMessage>(xmlStr); break; case FromMessageTypes.shortvideo: resulTuple = await ExecuteHandler <FromShortVideoMessage>(xmlStr); break; case FromMessageTypes.location: resulTuple = await ExecuteHandler <FromLocationMessage>(xmlStr); break; case FromMessageTypes.link: resulTuple = await ExecuteHandler <FromLinkMessage>(xmlStr); break; default: throw new NotSupportedException("暂不支持类型为[" + msgType + "]的消息类型"); } } if (resulTuple != null) { fromMessage = resulTuple.Item2; toMessage = resulTuple.Item1; } if (toMessage is ToNewsMessage) { var news = toMessage as ToNewsMessage; if (news.Articles.Count > 10) { throw new NotSupportedException("图文消息不能超过10条"); } if (news.Articles.Count == 0) { throw new WxSdkException("至少需要包含一条图文消息"); } news.ArticleCount = news.Articles.Count; } if (toMessage is ToNullMessage) { return(null); } if (toMessage != null && toMessage.CreateTimestamp == default) { //设置时间戳 toMessage.CreateTimestamp = toMessage.CreateDateTime.ConvertToTimeStamp(); toMessage.FromUserName = fromMessage.ToUserName; toMessage.ToUserName = fromMessage.FromUserName; } return(await Task.FromResult(toMessage)); }
/// <summary> /// 处理消息 /// </summary> /// <param name="xmlStr">XML字符串</param> public async Task <ToMessageBase> HandleMessage(string xmlStr) { ToMessageBase toMessage = null; //记录日志 WeChatHelper.LoggerAction?.Invoke(nameof(ServerMessageHandler), xmlStr); var xmlElement = XElement.Parse(xmlStr); var msgTypeElement = xmlElement.Element("MsgType"); if (string.IsNullOrWhiteSpace(msgTypeElement?.Value)) { throw new ApiArgumentException("消息类型不能为空"); } var msgType = msgTypeElement.Value.Trim().ToLower(); //接收的消息 IFromMessage fromMessage = null; //处理结果 Tuple <ToMessageBase, IFromMessage> resulTuple = null; //处理事件消息 if (msgType == "event") { var fromEventTypeElement = xmlElement.Element("Event"); if (string.IsNullOrWhiteSpace(fromEventTypeElement?.Value)) { throw new ApiArgumentException("事件类型不能为空"); } var fromEvent = fromEventTypeElement.Value.Trim().ToLower(); //记录日志 WeChatHelper.LoggerAction?.Invoke(nameof(ServerMessageHandler), "Event " + fromEvent); var fromEventType = (FromEventTypes)Enum.Parse(typeof(FromEventTypes), fromEvent); switch (fromEventType) { case FromEventTypes.subscribe: resulTuple = await ExcuteHandleFunc <FromSubscribeEvent>(xmlStr); break; case FromEventTypes.unsubscribe: resulTuple = await ExcuteHandleFunc <FromUnsubscribeEvent>(xmlStr); break; case FromEventTypes.scan: resulTuple = await ExcuteHandleFunc <FromScanEvent>(xmlStr); break; case FromEventTypes.location: resulTuple = await ExcuteHandleFunc <FromLocationEvent>(xmlStr); break; case FromEventTypes.click: resulTuple = await ExcuteHandleFunc <FromClickEvent>(xmlStr); break; case FromEventTypes.view: resulTuple = await ExcuteHandleFunc <FromViewEvent>(xmlStr); break; default: throw new ArgumentOutOfRangeException(); } } else { //记录日志 WeChatHelper.LoggerAction?.Invoke(nameof(ServerMessageHandler), msgType); //处理会话消息 var fromMessageType = (FromMessageTypes)Enum.Parse(typeof(FromMessageTypes), msgType); switch (fromMessageType) { case FromMessageTypes.text: resulTuple = await ExcuteHandleFunc <FromTextMessage>(xmlStr); break; case FromMessageTypes.image: resulTuple = await ExcuteHandleFunc <FromImageMessage>(xmlStr); break; case FromMessageTypes.voice: resulTuple = await ExcuteHandleFunc <FromVoiceMessage>(xmlStr); break; case FromMessageTypes.video: resulTuple = await ExcuteHandleFunc <FromVideoMessage>(xmlStr); break; case FromMessageTypes.shortvideo: resulTuple = await ExcuteHandleFunc <FromShortVideoMessage>(xmlStr); break; case FromMessageTypes.location: resulTuple = await ExcuteHandleFunc <FromLocationMessage>(xmlStr); break; case FromMessageTypes.link: resulTuple = await ExcuteHandleFunc <FromLinkMessage>(xmlStr); break; default: throw new NotSupportedException("暂不支持类型为[" + msgType + "]的消息类型"); } } if (resulTuple != null) { fromMessage = resulTuple.Item2; toMessage = resulTuple.Item1; } #region 验证多图文格式 if (toMessage is ToNewsMessage) { var news = toMessage as ToNewsMessage; if (news.Articles.Count > 10) { throw new NotSupportedException("图文消息不能超过10条"); } if (news.Articles.Count == 0) { throw new ApiArgumentException("至少需要包含一条图文消息"); } news.ArticleCount = news.Articles.Count; } #endregion #region 设置回复消息的时间戳等内容 if (toMessage != null && toMessage.CreateTimestamp == default(long)) { //设置时间戳 toMessage.CreateTimestamp = toMessage.CreateDateTime.ConvertToTimeStamp(); toMessage.FromUserName = fromMessage.ToUserName; toMessage.ToUserName = fromMessage.FromUserName; } #endregion return(await Task.FromResult(toMessage)); }