Beispiel #1
0
        /// <inheritdoc/>
        public async Task <UserDetails> GetUserDetails(string userId, string conversationId = null)
        {
            UserCacheEntry cacheEntry;
            bool           result = _userCache.TryGetValue(userId.ToLower(), out cacheEntry);

            if (result)
            {
                return(cacheEntry.user);
            }
            else
            {
                UserDetails currUser = new UserDetails();
                string      uri      = $"/users/{userId}";
                try
                {
                    HttpResponseMessage response = await MakeGetCallToFreshChat(uri);

                    string responseContent = await response.Content.ReadAsStringAsync();

                    var jsonResponse = JToken.Parse(responseContent);

                    currUser.Id          = userId;
                    currUser.ReferenceId = (string)jsonResponse["reference_id"];
                    currUser.FirstName   = !string.IsNullOrWhiteSpace(currUser.ReferenceId) && currUser.ReferenceId.Split("sites/").Length > 1 ? currUser.ReferenceId.Split("sites/")[1] : (string)jsonResponse["first_name"];
                    currUser.LastName    = string.Empty;
                    currUser.Email       = string.Empty;
                    currUser.Avatar      = new Avatar()
                    {
                        Url = (string)jsonResponse["avatar"].Value <JToken>("url")
                    };

                    // Add to cache for future lookups
                    AddOrUpdateUser(currUser.Id, currUser);

                    // Update the _resourceConversationCache
                    if (!string.IsNullOrWhiteSpace(conversationId))
                    {
                        AddOrUpdateResourceUri(conversationId, currUser.ReferenceId);
                    }

                    return(currUser);
                }
                catch (Exception ex)
                {
                    InternalEventBody kustoLog = new InternalEventBody();
                    kustoLog.EventType    = "FreshChatLoggingUnhandledException";
                    kustoLog.EventContent = $"FreshChatException. Unhandled {ex.GetType().ToString()} exception while calling FreshChat server to fetch sender details. URI: {uri}";
                    await LogToKusto(kustoLog);

                    throw ex;
                }
            }
        }
Beispiel #2
0
        /// <inheritdoc/>
        public async Task <AgentDetails> GetAgentDetails(string agentId)
        {
            AgentCacheEntry cacheEntry;
            bool            result = _agentCache.TryGetValue(agentId.ToLower(), out cacheEntry);

            if (result)
            {
                return(cacheEntry.agent);
            }
            else
            {
                AgentDetails currAgent = new AgentDetails();
                string       uri       = $"/agents/{agentId}";
                try
                {
                    HttpResponseMessage response = await MakeGetCallToFreshChat(uri);

                    string responseContent = await response.Content.ReadAsStringAsync();

                    var jsonResponse = JToken.Parse(responseContent);

                    currAgent.Id        = agentId;
                    currAgent.FirstName = (string)jsonResponse["first_name"];
                    currAgent.LastName  = (string)jsonResponse["last_name"];
                    currAgent.Email     = (string)jsonResponse["email"];
                    currAgent.Avatar    = new Avatar()
                    {
                        Url = (string)jsonResponse["avatar"].Value <JToken>("url")
                    };

                    // Add to cache for future lookups
                    AddOrUpdateAgent(currAgent.Id, currAgent);
                    return(currAgent);
                }
                catch (Exception ex)
                {
                    InternalEventBody kustoLog = new InternalEventBody();
                    kustoLog.EventType    = "FreshChatLoggingUnhandledException";
                    kustoLog.EventContent = $"FreshChatException. Unhandled {ex.GetType().ToString()} exception while calling FreshChat server to fetch sender details. URI: {uri}";
                    await LogToKusto(kustoLog);

                    throw ex;
                }
            }
        }
Beispiel #3
0
        public async Task <IActionResult> LogEvent([FromBody] InternalEventBody postBody)
        {
            var eventType    = postBody.EventType;
            var eventContent = postBody.EventContent;

            switch (postBody.EventType)
            {
            case "UnhandledException":
                var unhandledException = JsonConvert.DeserializeObject <InternalAPIException>(eventContent);
                DiagnosticsETWProvider.Instance.LogInternalAPIHandledException(unhandledException.RequestId, unhandledException.ExceptionType, unhandledException.ExceptionDetails);
                break;

            case "HandledException":
                var handledException = JsonConvert.DeserializeObject <InternalAPIException>(eventContent);
                DiagnosticsETWProvider.Instance.LogInternalAPIHandledException(handledException.RequestId, handledException.ExceptionType, handledException.ExceptionDetails);
                break;

            case "TrainingException":
                var trainingException = JsonConvert.DeserializeObject <InternalAPITrainingException>(eventContent);
                DiagnosticsETWProvider.Instance.LogInternalAPITrainingException(trainingException.RequestId, trainingException.TrainingId, trainingException.ProductId, trainingException.ExceptionType, trainingException.ExceptionDetails);
                break;

            case "Insights":
                var insights = JsonConvert.DeserializeObject <InternalAPIInsights>(eventContent);
                DiagnosticsETWProvider.Instance.LogInternalAPIInsights(insights.RequestId, insights.Message);
                break;

            case "APISummary":
                var apiSummary = JsonConvert.DeserializeObject <InternalAPISummary>(eventContent);
                DiagnosticsETWProvider.Instance.LogInternalAPISummary(apiSummary.RequestId, apiSummary.OperationName, apiSummary.StatusCode, apiSummary.LatencyInMilliseconds, apiSummary.StartTime, apiSummary.EndTime, apiSummary.Content);
                break;

            case "TrainingSummary":
                var trainingSummary = JsonConvert.DeserializeObject <InternalAPITrainingSummary>(eventContent);
                DiagnosticsETWProvider.Instance.LogInternalAPITrainingSummary(trainingSummary.RequestId, trainingSummary.TrainingId, trainingSummary.ProductId, trainingSummary.LatencyInMilliseconds, trainingSummary.StartTime, trainingSummary.EndTime, trainingSummary.Content);
                break;

            default:
                DiagnosticsETWProvider.Instance.LogInternalAPIMessage(eventContent);
                break;
            }

            return(Ok());
        }
Beispiel #4
0
        /// <inheritdoc/>
        public async Task <bool> LogToKusto(InternalEventBody logMessage)
        {
            try
            {
                string body     = JsonConvert.SerializeObject(logMessage);
                var    response = await _diagnosticClient.Execute("POST", "/internal/logger", body);

                response.EnsureSuccessStatusCode();
                return(true);
            }
            catch (JsonSerializationException jsException)
            {
                throw new JsonSerializationException("FreshChatException. Failed to serialize data while sending a request to log in Kusto.", jsException);
            }
            catch (HttpRequestException hException)
            {
                throw new HttpRequestException("FreshChatException. Failed to send a log in Kusto.", hException);
            }
            catch (Exception ex)
            {
                throw new Exception("FreshChatException. Unknown exception. Review for more details.", ex);
            }
        }
        public async Task <IActionResult> ChatHook([FromBody] JToken body)
        {
            if (body != null)
            {
                try
                {
                    DateTime          startTime       = DateTime.Now;
                    FreshChatPayload  incomingPayload = incomingPayload = body.ToObject <FreshChatPayload>();
                    ChatMessageToLog  logMsg          = null;
                    InternalEventBody kustoLog        = new InternalEventBody();
                    switch (incomingPayload.Action)
                    {
                    case Actions.MessageCreate:
                        MessageCreateData msgData = (MessageCreateData)incomingPayload.Data;

                        logMsg = new ChatMessageToLog(msgData.Message.Id, msgData.Message.ChannelId, msgData.Message.ConversationId, msgData.Message.CreatedTime, msgData.Message.MessageType);

                        logMsg.Sender = await GetMessageSenderDetails(msgData.Message.ActorId, msgData.Message.ActorType, logMsg.ConversationId);

                        logMsg.ResourceUri = _freshChatClientService.GetResourceUri(logMsg.ConversationId);

                        if (msgData.Message.MsgParts != null && msgData.Message.MsgParts.Count > 0)
                        {
                            logMsg.TextContent = ExtractAllTextContent(msgData.Message.MsgParts);
                            logMsg.ImageUrls   = ExtractAllImageUrls(msgData.Message.MsgParts);
                        }

                        if (msgData.Message.ReplyParts != null && msgData.Message.ReplyParts.Count > 0)
                        {
                            logMsg.TextContent = ExtractAllTextContent(msgData.Message.ReplyParts);
                            logMsg.ImageUrls   = ExtractAllImageUrls(msgData.Message.ReplyParts);
                        }

                        break;

                    case Actions.ConversationReopen:
                        ReopenDetails reopenData = ((ConvReopenData)incomingPayload.Data).Reopen;

                        logMsg = new ChatMessageToLog(string.Empty, reopenData.Conversation.ChannelId, reopenData.Conversation.ConversationId, incomingPayload.ActionTime, MessageTypes.Private);

                        logMsg.TextContent = new List <string>();
                        logMsg.Sender      = await GetMessageSenderDetails(reopenData.ReopenerId, reopenData.Reopener, logMsg.ConversationId);

                        logMsg.ResourceUri = _freshChatClientService.GetResourceUri(logMsg.ConversationId);

                        logMsg.TextContent.Add($"Conversation re-opened by {reopenData.Reopener.ToString()}.");
                        break;

                    case Actions.ConversationAssignment:
                        AssignmentDetails assignmentData = ((ConvAssignmentData)incomingPayload.Data).Assignment;

                        logMsg = new ChatMessageToLog(string.Empty, assignmentData.Conversation.ChannelId, assignmentData.Conversation.ConversationId, incomingPayload.ActionTime, MessageTypes.Private);

                        string assignedToDetails = string.Empty;
                        if (string.IsNullOrWhiteSpace(assignmentData.Conversation.AssignedAgentId))
                        {
                            // Conversation assigned to a group and waiting to be assigned to an agent
                            logMsg.Sender = await GetMessageSenderDetails(string.IsNullOrWhiteSpace(incomingPayload.Actor.ActorId)?assignmentData.Conversation.AssignedGroupId : incomingPayload.Actor.ActorId, incomingPayload.Actor.ActorType, logMsg.ConversationId);

                            logMsg.ResourceUri = _freshChatClientService.GetResourceUri(logMsg.ConversationId);

                            assignedToDetails = " to group";
                        }
                        else
                        {
                            // Conversation assigned to an agent.
                            logMsg.Sender = await GetMessageSenderDetails(string.IsNullOrWhiteSpace(incomingPayload.Actor.ActorId)?assignmentData.Conversation.AssignedGroupId : incomingPayload.Actor.ActorId, incomingPayload.Actor.ActorType, logMsg.ConversationId);

                            logMsg.ResourceUri = _freshChatClientService.GetResourceUri(logMsg.ConversationId);

                            PersonDetails assignedAgent = await GetMessageSenderDetails(assignmentData.Conversation.AssignedAgentId, ActorTypes.Agent, logMsg.ConversationId);

                            assignedToDetails = $" to agent {assignedAgent.FirstName} {assignedAgent.LastName} ({assignedAgent.Email})";
                        }

                        logMsg.TextContent = new List <string>();
                        logMsg.TextContent.Add($"Conversation assigned {assignedToDetails}.");
                        break;

                    case Actions.ConversationResolution:
                        ResolveDetails resolveData = ((ConvResolutionData)incomingPayload.Data).Resolve;

                        logMsg = new ChatMessageToLog(string.Empty, resolveData.Conversation.ChannelId, resolveData.Conversation.ConversationId, incomingPayload.ActionTime, MessageTypes.Private);

                        logMsg.Sender = await GetMessageSenderDetails(resolveData.ResolverId, resolveData.Resolver, logMsg.ConversationId);

                        logMsg.ResourceUri = _freshChatClientService.GetResourceUri(logMsg.ConversationId);

                        logMsg.TextContent = new List <string>();
                        logMsg.TextContent.Add($"Conversation resolved by {resolveData.Resolver.ToString()}.");
                        break;

                    default:
                        kustoLog.EventType = "FreshChatLoggingUnhandledException";

                        // Remove PII function will likely garble the text body and make the object non serializable however it will be helpful for a human to debug the problem.
                        kustoLog.EventContent = $"FreshChatException. Unhandled message type {incomingPayload.Action.ToString()}. Unable to handle. Body : {_freshChatClientService.RemovePII(JsonConvert.SerializeObject(body))}";
                        _freshChatClientService.LogToKusto(kustoLog);

                        throw new Exception($"FreshChatException. Unhandled message type {incomingPayload.Action.ToString()}. Unable to handle.");
                    }

                    if (logMsg == null)
                    {
                        return(new BadRequestResult());
                    }
                    else
                    {
                        logMsg.TimeInMilliSeconds = DateTime.Now.Subtract(startTime).TotalMilliseconds;

                        kustoLog.EventType    = "FreshChatMessage";
                        kustoLog.EventContent = JsonConvert.SerializeObject(logMsg);
                        _freshChatClientService.LogToKusto(kustoLog);

                        return(Content(JsonConvert.SerializeObject(logMsg)));
                    }
                }
                catch (JsonSerializationException sException)
                {
                    InternalEventBody kustoLog = new InternalEventBody();
                    kustoLog.EventType = "FreshChatLoggingUnhandledException";

                    // Remove PII function will likely garble the text body and make the object non serializable however it will be helpful for a human to debug the problem.
                    kustoLog.EventContent = JsonConvert.SerializeObject(new JsonSerializationException("FreshChatException. Failed to deserialize the incoming data.", sException));
                    _freshChatClientService.LogToKusto(kustoLog);

                    throw new JsonSerializationException("FreshChatException. Failed to deserialize the incoming data.", sException);
                }
                catch (Exception ex)
                {
                    InternalEventBody kustoLog = new InternalEventBody();
                    kustoLog.EventType = "FreshChatLoggingUnhandledException";

                    // Remove PII function will likely garble the text body and make the object non serializable however it will be helpful for a human to debug the problem.
                    kustoLog.EventContent = JsonConvert.SerializeObject(new ArgumentException("FreshChatException. Unknwon error while trying to read the incoming post body ", ex));
                    _freshChatClientService.LogToKusto(kustoLog);

                    throw new ArgumentException("FreshChatException. Unknwon error while trying to read the incoming post body ", ex);
                }
            }
            else
            {
                return(BadRequest("Empty post body"));
            }
        }