Ejemplo n.º 1
0
 /// <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);
 }
Ejemplo n.º 2
0
        /// <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));
        }
Ejemplo n.º 3
0
        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()}");
        }
Ejemplo n.º 4
0
        /// <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);
            }
        }
Ejemplo n.º 5
0
        /// <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);
            }
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 7
0
        /// <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);
            }
        }
Ejemplo n.º 8
0
        /// <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
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        /// <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);
        }