/// <summary> /// 注册 IServiceCollection,并返回 RegisterService,开始注册流程(必须) /// </summary> /// <param name="serviceCollection">IServiceCollection</param> /// <param name="certName">证书名称,必须全局唯一,并且确保在全局 HttpClientFactory 内唯一</param> /// <param name="certSecret">证书密码</param> /// <param name="certPath">证书路径(物理路径)</param> /// <param name="checkValidationResult">设置</param> /// <returns></returns> public static IServiceCollection AddSenparcHttpClientWithCertificate(this IServiceCollection serviceCollection, string certName, string certSecret, string certPath, bool checkValidationResult = false) { //添加注册 if (!string.IsNullOrEmpty(certPath)) { if (File.Exists(certPath)) { try { var cert = new X509Certificate2(certPath, certSecret, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet); return(AddSenparcHttpClientWithCertificate(serviceCollection, certName, cert, checkValidationResult)); } catch (Exception ex) { LogTrace.SendCustomLog($"添加微信支付证书发生异常", $"certName:{certName},certPath:{certPath}"); LogTrace.BaseExceptionLog(ex); return(serviceCollection); } } else { LogTrace.SendCustomLog($"已设置微信支付证书,但无法找到文件", $"certName:{certName},certPath:{certPath}"); return(serviceCollection); } } return(serviceCollection); }
/// <summary> /// 发送文本客服消息 /// </summary> /// <param name="accessTokenOrAppId"></param> /// <param name="openId"></param> /// <param name="content"></param> /// <returns></returns> public override ApiResult SendText(string accessTokenOrAppId, string openId, string content) { LogTrace.SendCustomLog("wxTest-sendText", "openID:" + openId + " || appID:" + accessTokenOrAppId + "|| content:" + content); var result = AdvancedAPIs.CustomApi.SendText(accessTokenOrAppId, openId, content); return(new ApiResult((int)result.errcode, result.errmsg, result)); }
public APMException(string message, string domain, string kindName, string method, Exception inner = null) : base(message, inner, true) { LogTrace.SendCustomLog("APM 执行出错", $@"Domain: {domain} KindName: {kindName} Message: {message} Exception: {inner?.ToString()}"); }
/// <summary> /// 获取响应类型实例,并初始化 /// </summary> /// <typeparam name="T">需要返回的类型</typeparam> /// <param name="requestMessage">请求数据</param> /// <param name="enlighten">MessageEntityEnlighten,当 T 为接口时必须提供</param> /// <returns></returns> public static T CreateFromRequestMessage <T>(IRequestMessageBase requestMessage, MessageEntityEnlightener enlighten = null) where T : IResponseMessageBase { try { T responseMessage = default(T); var tType = typeof(T); if (tType.IsInterface) { //是接口,需要使用 Enlightener if (enlighten == null) { throw new MessageHandlerException("MessageEntityEnlighten 不能为 null"); } var responseName = tType.Name.Replace("IResponseMessage", "").Replace("ResponseMessage", ""); //请求名称 ResponseMsgType msgType = (ResponseMsgType)Enum.Parse(typeof(ResponseMsgType), responseName); responseMessage = (T)CreateFromRequestMessage(requestMessage, msgType, enlighten); } else { //非接口,直接初始化 //Senparc.CO2NET.Helpers.ReflectionHelper. responseMessage = (T)Activator.CreateInstance(tType); } if (responseMessage != null) { responseMessage.ToUserName = requestMessage.FromUserName; responseMessage.FromUserName = requestMessage.ToUserName; responseMessage.CreateTime = SystemTime.Now; //使用当前最新时间 } return(responseMessage); } catch (Exception ex) { LogTrace.SendCustomLog("CreateFromRequestMessage异常调试", typeof(T).FullName); throw new BaseException("ResponseMessageBase.CreateFromRequestMessage<T>过程发生异常!", ex); } }
/// <summary> /// 设置数据 /// </summary> /// <param name="kindName">统计类别名称</param> /// <param name="value">统计值</param> /// <param name="data">复杂类型数据</param> /// <param name="tempStorage">临时储存信息</param> /// <param name="dateTime">发生时间,默认为当前系统时间</param> /// <returns></returns> public async Task <DataItem> SetAsync(string kindName, double value, object data = null, object tempStorage = null, DateTimeOffset?dateTime = null) { if (!OFoodConfig.EnableAPM) { return(null);//不启用,不进行记录 } try { var dt1 = SystemTime.Now; var cacheStragety = CacheStrategyFactory.GetObjectCacheStrategyInstance(); var finalKey = BuildFinalKey(kindName); //使用同步锁确定写入顺序 using (await cacheStragety.BeginCacheLockAsync("SenparcAPM", finalKey).ConfigureAwait(false)) { var dataItem = new DataItem() { KindName = kindName, Value = value, Data = data, TempStorage = tempStorage, DateTime = dateTime ?? SystemTime.Now }; var list = await GetDataItemListAsync(kindName).ConfigureAwait(false); list.Add(dataItem); await cacheStragety.SetAsync(finalKey, list, OFoodConfig.DataExpire, true).ConfigureAwait(false); await RegisterFinalKeyAsync(kindName).ConfigureAwait(false);//注册Key if (LogTrace.RecordAPMLog) { LogTrace.SendCustomLog($"APM 性能记录 - DataOperation.Set - {_domain}:{kindName}", (SystemTime.Now - dt1).TotalMilliseconds + " ms"); } return(dataItem); } } catch (Exception e) { new APMException(e.Message, _domain, kindName, $"DataOperation.Set - {_domain}:{kindName}"); return(null); } }
/// <summary> /// NeuChar 请求 /// </summary> public virtual async Task <IResponseMessageBase> OnNeuCharRequestAsync(RequestMessageNeuChar requestMessage) { try { var path = ServerUtility.ContentRootMapPath("~/App_Data/NeuChar"); //SenparcTrace.SendCustomLog("OnNeuCharRequest path", path); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var file = Path.Combine(path, "NeuCharRoot.config"); bool success = true; string result = null; var configFileExisted = File.Exists(file); if (!configFileExisted) { using (var fs = new FileStream(file, FileMode.CreateNew)) { using (var sw = new StreamWriter(fs)) { await sw.WriteLineAsync(NeuralSystem.DEFAULT_CONFIG_FILE_CONENT).ConfigureAwait(false); } await fs.FlushAsync().ConfigureAwait(false); } } switch (requestMessage.NeuCharMessageType) { case NeuCharActionType.GetConfig: { if (configFileExisted) { //文件刚创建,但不再读取,此时读取可能会发生“无法访问已关闭文件”的错误 using (var fs = FileHelper.GetFileStream(file)) { using (var sr = new StreamReader(fs, Encoding.UTF8)) { var json = await sr.ReadToEndAsync().ConfigureAwait(false); result = json; } } } else { result = NeuralSystem.DEFAULT_CONFIG_FILE_CONENT; //TODO:初始化一个对象 } } break; case NeuCharActionType.SaveConfig: { var configRootJson = requestMessage.ConfigRoot; LogTrace.SendCustomLog("收到NeuCharRequest", "字符串长度:" + configRootJson.Length.ToString()); var configRoot = SerializerHelper.GetObject <ConfigRoot>(configRootJson); //这里只做序列化校验 //TODO:进行验证 if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } var fileTemp = Path.Combine(path, $"NeuCharRoot.temp.{SystemTime.Now.ToString("yyyyMMdd-HHmmss")}.config"); //TODO:后期也可以考虑把不同模块分离到不同的文件中 using (var fs = new FileStream(fileTemp, FileMode.Create)) { using (var sw = new StreamWriter(fs)) { await sw.WriteAsync(configRootJson).ConfigureAwait(false); await sw.FlushAsync().ConfigureAwait(false); } } //历史文件备份,并替换临时文件 File.Move(file, file.Replace(".config", $".bak.{SystemTime.Now.ToString("yyyyMMdd-HHmmss")}.config")); File.Move(fileTemp, file); //刷新数据 var neuralSystem = NeuralSystem.Instance; neuralSystem.ReloadNode(); } break; case NeuCharActionType.CheckNeuChar: { //TODO:进行有效性检验 var configRoot = requestMessage.ConfigRoot?.GetObject <APMDomainConfig>(); if (configRoot == null || configRoot.Domain.IsNullOrWhiteSpace()) { success = false; result = "未指定 Domain!"; break; } var co2netDataOperation = new DataOperation(configRoot.Domain); //获取所有数据 var dataItems = await co2netDataOperation.ReadAndCleanDataItemsAsync(configRoot.RemoveData, true).ConfigureAwait(false); result = dataItems.ToJson(); } break; case NeuCharActionType.PushNeuCharAppConfig: //推送 NeuChar App 配置 { var configFileDir = Path.Combine(path, "AppConfig"); if (!Directory.Exists(configFileDir)) { Directory.CreateDirectory(configFileDir); //这里也可以不创建,除非是为了推送 } //还原一次,为了统一格式,并未后续处理提供能力(例如调整缩进格式) var requestData = requestMessage.RequestData.GetObject <PushConfigRequestData>(); var mainVersion = requestData.Version.Split('.')[0]; //主版本号 //配置文件路径:~/App_Data/NeuChar/AppConfig/123-v1.config var configFilePath = Path.Combine(configFileDir, $"{requestData.AppId}-v{mainVersion}.config"); using (var fs = new FileStream(configFilePath, FileMode.Create)) { using (var sw = new StreamWriter(fs, Encoding.UTF8)) { var json = requestData.Config.ToJson(true); //带缩进格式的 JSON 字符串 await sw.WriteAsync(json).ConfigureAwait(false); //写入 Json 文件 await sw.FlushAsync().ConfigureAwait(false); } } result = "OK"; } break; case NeuCharActionType.PullNeuCharAppConfig: //拉取 NeuCharApp 配置 { var requestData = requestMessage.RequestData.GetObject <PullConfigRequestData>(); var mainVersion = requestData.Version.Split('.')[0]; //主版本号 var configFileDir = Path.Combine(path, "AppConfig"); //配置文件路径:~/App_Data/NeuChar/AppConfig/123-v1.config var configFilePath = Path.Combine(configFileDir, $"{requestData.AppId}-v{mainVersion}.config"); if (!File.Exists(configFilePath)) { //文件不存在 result = $"配置文件不存在,请先推送或设置配置文件,地址:{configFilePath}"; success = false; } else { //读取内容 using (var fs = FileHelper.GetFileStream(configFilePath)) { using (var sr = new StreamReader(fs, Encoding.UTF8)) { var json = await sr.ReadToEndAsync().ConfigureAwait(false); //带缩进格式的 JSON 字符串(文件中的原样) result = json; } } } } break; default: break; } var successMsg = new { success = success, result = result }; TextResponseMessage = successMsg.ToJson(); } catch (Exception ex) { var errMsg = new { success = false, result = ex.Message }; TextResponseMessage = errMsg.ToJson(); } return(null); }
/// <summary> /// 获取并清空该 Domain 下的所有数据 /// </summary> /// <returns></returns> /// <param name="removeReadItems">是否移除已读取的项目,默认为 true</param> /// <param name="keepTodayData">当 removeReadItems = true 时有效,在清理的时候是否保留当天的数据</param> public async Task <List <MinuteDataPack> > ReadAndCleanDataItemsAsync(bool removeReadItems = true, bool keepTodayData = true) { try { var dt1 = SystemTime.Now; var cacheStragety = CacheStrategyFactory.GetObjectCacheStrategyInstance(); Dictionary <string, List <DataItem> > tempDataItems = new Dictionary <string, List <DataItem> >(); var systemNow = SystemTime.Now.UtcDateTime; //统一UTC时间 var nowMinuteTime = SystemTime.Now.AddSeconds(-SystemTime.Now.Second).AddMilliseconds(-SystemTime.Now.Millisecond); // new DateTimeOffset(systemNow.Year, systemNow.Month, systemNow.Day, systemNow.Hour, systemNow.Minute, 0, TimeSpan.Zero); //快速获取并清理数据 foreach (var item in KindNameStore[_domain]) { var kindName = item.Key; var finalKey = BuildFinalKey(kindName); using (await cacheStragety.BeginCacheLockAsync("SenparcAPM", finalKey).ConfigureAwait(false)) { var list = await GetDataItemListAsync(item.Key).ConfigureAwait(false); //获取列表 var completedStatData = list.Where(z => z.DateTime < nowMinuteTime).ToList(); //统计范围内的所有数据 tempDataItems[kindName] = completedStatData; //添加到列表 if (removeReadItems) { //筛选需要删除的数据 var tobeRemove = completedStatData.Where(z => keepTodayData ? z.DateTime < SystemTime.Today : true); //移除已读取的项目 if (tobeRemove.Count() == list.Count()) { //已经全部删除 await cacheStragety.RemoveFromCacheAsync(finalKey, true).ConfigureAwait(false);//删除 } else { //部分删除 var newList = list.Except(tobeRemove).ToList(); await cacheStragety.SetAsync(finalKey, newList, OFoodConfig.DataExpire, true).ConfigureAwait(false); } } } } //开始处理数据(分两步是为了减少同步锁的时间) var result = new List <MinuteDataPack>(); foreach (var kv in tempDataItems) { var kindName = kv.Key; var domainData = kv.Value; var lastDataItemTime = DateTimeOffset.MinValue; MinuteDataPack minuteDataPack = new MinuteDataPack(); minuteDataPack.KindName = kindName; result.Add(minuteDataPack); //添加一个指标 MinuteData minuteData = null; //某一分钟的指标 foreach (var dataItem in domainData) { if (DataHelper.IsLaterMinute(lastDataItemTime, dataItem.DateTime)) { //新的一分钟 minuteData = new MinuteData(); minuteDataPack.MinuteDataList.Add(minuteData); minuteData.KindName = dataItem.KindName; minuteData.Time = new DateTimeOffset(dataItem.DateTime.Year, dataItem.DateTime.Month, dataItem.DateTime.Day, dataItem.DateTime.Hour, dataItem.DateTime.Minute, 0, TimeSpan.Zero); minuteData.StartValue = dataItem.Value; minuteData.HighestValue = dataItem.Value; minuteData.LowestValue = dataItem.Value; } minuteData.EndValue = dataItem.Value; minuteData.SumValue += dataItem.Value; if (dataItem.Value > minuteData.HighestValue) { minuteData.HighestValue = dataItem.Value; } if (dataItem.Value < minuteData.LowestValue) { minuteData.LowestValue = dataItem.Value; } minuteData.SampleSize++; lastDataItemTime = dataItem.DateTime; } } //if (SenparcTrace.RecordAPMLog) { LogTrace.SendCustomLog("APM 记录 - DataOperation.ReadAndCleanDataItems", (SystemTime.Now - dt1).TotalMilliseconds + " ms"); } return(result); } catch (Exception e) { new APMException(e.Message, _domain, "", "DataOperation.ReadAndCleanDataItems"); return(null); } }
/// <summary> /// 【异步方法】执行微信请求 /// </summary> public override async Task BuildResponseMessageAsync(CancellationToken cancellationToken) { #region NeuChar 执行过程 var weixinAppId = this._postModel == null ? "" : this._postModel.AppId; switch (RequestMessage.MsgType) { case RequestMsgType.Text: { try { var requestMessage = RequestMessage as RequestMessageText; ResponseMessage = await CurrentMessageHandlerNode.ExecuteAsync(requestMessage, this, weixinAppId) ?? ((await(OnTextOrEventRequestAsync(requestMessage)) ?? (await OnTextRequestAsync(requestMessage)))); } catch (Exception ex) { LogTrace.SendCustomLog("mp-response error", ex.Message + "\r\n|||\r\n" + (ex.InnerException != null ? ex.InnerException.ToString() : "")); } } break; case RequestMsgType.Location: ResponseMessage = await OnLocationRequestAsync(RequestMessage as RequestMessageLocation); break; case RequestMsgType.Image: WeixinTrace.SendCustomLog("NeuChar Image", $"appid:{weixinAppId}"); ResponseMessage = await CurrentMessageHandlerNode.ExecuteAsync(RequestMessage, this, weixinAppId) ?? await OnImageRequestAsync(RequestMessage as RequestMessageImage); break; case RequestMsgType.Voice: ResponseMessage = await OnVoiceRequestAsync(RequestMessage as RequestMessageVoice); break; case RequestMsgType.Video: ResponseMessage = await OnVideoRequestAsync(RequestMessage as RequestMessageVideo); break; case RequestMsgType.Link: ResponseMessage = await OnLinkRequestAsync(RequestMessage as RequestMessageLink); break; case RequestMsgType.ShortVideo: ResponseMessage = await OnShortVideoRequestAsync(RequestMessage as RequestMessageShortVideo); break; case RequestMsgType.File: ResponseMessage = await OnFileRequestAsync(RequestMessage as RequestMessageFile); break; case RequestMsgType.NeuChar: ResponseMessage = await OnNeuCharRequestAsync(RequestMessage as RequestMessageNeuChar); break; case RequestMsgType.Unknown: ResponseMessage = await OnUnknownTypeRequestAsync(RequestMessage as RequestMessageUnknownType); break; case RequestMsgType.Event: { var requestMessageText = (RequestMessage as IRequestMessageEventBase).ConvertToRequestMessageText(); ResponseMessage = await CurrentMessageHandlerNode.ExecuteAsync(RequestMessage, this, weixinAppId) ?? await OnTextOrEventRequestAsync(requestMessageText) ?? (await OnEventRequestAsync(RequestMessage as IRequestMessageEventBase)); } break; default: WeixinTrace.SendCustomLog("NeuChar", "未知的MsgType请求类型" + RequestMessage.MsgType); //throw new UnknownRequestMsgTypeException("未知的MsgType请求类型", null); break; } #endregion }
/// <summary> /// 执行NeuChar判断过程,获取响应消息 /// </summary> /// <param name="requestMessage"></param> /// <param name="messageHandler"></param> /// <param name="accessTokenOrApi"></param> /// <returns></returns> public IResponseMessageBase Execute <TC, TRequest, TResponse>(IRequestMessageBase requestMessage, IMessageHandlerWithContext <TC, TRequest, TResponse> messageHandler, string accessTokenOrApi) where TC : class, IMessageContext <TRequest, TResponse>, new() where TRequest : IRequestMessageBase where TResponse : IResponseMessageBase { //if (accessTokenOrApi == null) //{ // throw new ArgumentNullException(nameof(accessTokenOrApi)); //} var messageHandlerEnlightener = messageHandler.MessageEntityEnlightener; var appDataNode = messageHandler.CurrentAppDataNode; IResponseMessageBase responseMessage = null; //SenparcTrace.SendCustomLog("neuchar trace", "3"); //进行APP特殊处理 //判断状态 var context = messageHandler.CurrentMessageContext; AppDataItem currentAppDataItem = null; switch (context.AppStoreState) { case AppStoreState.None: //未进入任何应用 case AppStoreState.Exit: currentAppDataItem = null; break; case AppStoreState.Enter: //判断是否已过期 if (context.CurrentAppDataItem != null) { if (context.LastActiveTime.HasValue && context.LastActiveTime.Value.AddMinutes(context.CurrentAppDataItem.MessageKeepTime) < SystemTime.Now) { //没有上一条活动,或者对话已过期,则设置为退出状态 context.AppStoreState = AppStoreState.None; context.CurrentAppDataItem = null; //退出清空 } else { //继续保持应用状态 currentAppDataItem = context.CurrentAppDataItem; if (requestMessage is IRequestMessageText || requestMessage is IRequestMessageEventKey requestClick) { var content = (requestMessage is IRequestMessageText requestText) ? requestText.Content : (requestMessage as IRequestMessageEventKey).EventKey; if (!context.CurrentAppDataItem.MessageExitWord.IsNullOrEmpty() && context.CurrentAppDataItem.MessageExitWord.Equals(content, StringComparison.OrdinalIgnoreCase)) { //执行退出命令 context.AppStoreState = AppStoreState.None; context.CurrentAppDataItem = null; //退出清空 //currentAppDataItem = context.CurrentAppDataItem;//当前消息仍然转发(最后一条退出消息) } } } } else { //已经进入App状态,但是没有标记退出,此处强制退出 context.AppStoreState = AppStoreState.None; } break; default: break; } //TODO:暂时限定类型 if (currentAppDataItem == null) { if (requestMessage is IRequestMessageText || requestMessage is IRequestMessageEventKey requestClick) { var content = (requestMessage is IRequestMessageText requestText) ? requestText.Content : (requestMessage as IRequestMessageEventKey).EventKey; currentAppDataItem = appDataNode.Config.AppDataItems .FirstOrDefault(z => z.ExpireDateTime > SystemTime.Now && !z.MessageEnterWord.IsNullOrEmpty() && z.MessageEnterWord.Equals(content, StringComparison.OrdinalIgnoreCase)); if (currentAppDataItem != null && currentAppDataItem.MessageKeepTime > 0) { //初次进入应用 context.AppStoreState = AppStoreState.Enter; context.CurrentAppDataItem = currentAppDataItem; } } } if (currentAppDataItem != null) //已经锁定某个App { //NeuralSystem.Instance.NeuCharDomainName = "https://www.neuchar.com"; //转发AppData消息 var neuCharUrl = $"{NeuralSystem.Instance.NeuCharDomainName}/App/Weixin?appId={currentAppDataItem.Id}&neuralAppId={appDataNode.NeuralAppId}"; try { responseMessage = MessageAgent.RequestResponseMessage(messageHandler, neuCharUrl, "Senparc", requestMessage.ConvertEntityToXmlString()); } catch (Exception ex) { LogTrace.SendCustomLog("NeuChar 远程调用 APP 失败", ex.Message); } } //APP特殊处理结束 if (responseMessage != null) { if (messageHandler.MessageEntityEnlightener.PlatformType == PlatformType.WeChat_MiniProgram && responseMessage is IResponseMessageText) { //小程序 messageHandler.ApiEnlightener.SendText(accessTokenOrApi, messageHandler.WeixinOpenId, (responseMessage as IResponseMessageText).Content); return(new SuccessResponseMessage()); } else { return(responseMessage); } } //处理普通消息回复 switch (requestMessage.MsgType) { case RequestMsgType.Text: { try { //SenparcTrace.SendCustomLog("neuchar trace", "3.1"); var textRequestMessage = requestMessage as IRequestMessageText; //遍历所有的消息设置 foreach (var messagePair in Config.MessagePair.Where(z => z.Request.Type == RequestMsgType.Text)) { //遍历每一个消息设置中的关键词 var pairSuccess = messagePair.Request.Keywords.Exists(keyword => keyword.Equals(textRequestMessage.Content, StringComparison.OrdinalIgnoreCase)); if (pairSuccess) { responseMessage = GetResponseMessage(requestMessage, messagePair.Responses, messageHandler, accessTokenOrApi); } if (responseMessage != null) { break; } } } catch (Exception ex) { LogTrace.SendCustomLog("neuchar text error", ex.Message + "\r\n|||\r\n" + (ex.InnerException != null ? ex.InnerException.ToString() : "")); } } break; case RequestMsgType.Image: { var imageRequestMessage = requestMessage as IRequestMessageImage; //遍历所有的消息设置 foreach (var messagePair in Config.MessagePair.Where(z => z.Request.Type == RequestMsgType.Image)) { responseMessage = GetResponseMessage(requestMessage, messagePair.Responses, messageHandler, accessTokenOrApi); if (responseMessage != null) { break; } } } break; case RequestMsgType.Event: { //菜单或其他系统事件 if (requestMessage is IRequestMessageEvent eventRequestMessage) { var eventType = eventRequestMessage.EventName.ToUpper(); //构造返回结果 List <Response> responses = new List <Response>(); switch (eventType) { case "CLICK" when requestMessage is IRequestMessageEventKey clickRequestMessage: { //TODO:暂时只支持CLICK,因此在这里遍历 foreach (var messagePair in Config.MessagePair.Where(z => z.Request.Type == RequestMsgType.Event)) { var pairSuccess = messagePair.Request.Keywords.Exists(keyword => keyword.Equals(clickRequestMessage.EventKey, StringComparison.OrdinalIgnoreCase)); if (pairSuccess) { try { responseMessage = GetResponseMessage(requestMessage, messagePair.Responses, messageHandler, accessTokenOrApi); } catch (Exception ex) { LogTrace.SendCustomLog("CLICK 跟踪 1.1", ex.Message + "\r\n" + ex.StackTrace); } } if (responseMessage != null) { break; } } } break; default: break; } } else { //下级模块中没有正确处理 requestMessage 类型 } } break; default: //不作处理 //throw new UnknownRequestMsgTypeException("NeuChar未支持的的MsgType请求类型:"+ requestMessage.MsgType, null); break; } //SenparcTrace.SendCustomLog("neuchar trace", "4"); return(responseMessage); }
/// <summary> /// 执行API /// </summary> /// <param name="response"></param> /// <param name="materialData"></param> /// <param name="requestMessage"></param> /// <param name="accessTokenOrAppId"></param> /// <param name="openId"></param> /// <returns></returns> public ApiResult ExecuteApi(Response response, MaterialData materialData, IRequestMessageBase requestMessage, string accessTokenOrAppId, string openId, IMessageHandlerEnlightener enlightener) { if (response == null) { return(new ApiResult(-1, "未获取到响应消息设置", null)); } ApiResult apiResult = null; try { switch (response.Type) { case ResponseMsgType.Unknown: break; case ResponseMsgType.Text: var cotnent = NeuralNodeHelper.FillTextMessage(response.GetMaterialContent(materialData)); apiResult = ApiEnlighten.SendText(accessTokenOrAppId, openId, cotnent); break; case ResponseMsgType.News: { var articles = NeuralNodeHelper.FillNewsMessage(response.MaterialId /*"9DAAC45C|6309EAD9"*/, materialData); if (articles == null) { apiResult = ApiEnlighten.SendText(accessTokenOrAppId, openId, "您要查找的素材不存在,或格式定义错误!"); } else { apiResult = ApiEnlighten.SendNews(accessTokenOrAppId, openId, articles); } } break; case ResponseMsgType.Music: break; case ResponseMsgType.Image: var mediaId = NeuralNodeHelper.GetImageMessageMediaId(requestMessage, response.GetMaterialContent(materialData)); LogTrace.SendCustomLog("ExecuteApi-Image", $"mediaId:{mediaId}"); if (true) { //TODO:其他mediaId的情况 } apiResult = ApiEnlighten.SendImage(accessTokenOrAppId, openId, mediaId); break; case ResponseMsgType.Voice: break; case ResponseMsgType.Video: break; case ResponseMsgType.Transfer_Customer_Service: break; case ResponseMsgType.MpNews: break; case ResponseMsgType.MultipleNews: break; case ResponseMsgType.LocationMessage: break; case ResponseMsgType.NoResponse: break; case ResponseMsgType.SuccessResponse: break; case ResponseMsgType.UseApi: apiResult = ApiEnlighten.CustomApi(response, materialData, requestMessage.FromUserName); break; default: apiResult = new ApiResult(-1, "未找到支持的响应消息类型", null); break; } } catch (Exception ex) { new MessageHandlerException("NeuChar API调用过程发生错误:" + ex.Message, ex); return(new ApiResult(-1, "API调用过程发生错误!", null)); } return(apiResult); }