예제 #1
0
        public async Task <IActionResult> GetToken()
        {
            try
            {
                ChatUserContext         userContext  = ChatUserContext.FromClaims(User.Claims, _config);
                TokenConversationResult conversation = await _directLineRestClient.GenerateToken(new TokenConversationParameters()
                {
                    User = userContext
                });

                if (conversation == null)
                {
                    return(StatusCode((int)HttpStatusCode.InternalServerError));
                }
                return(Ok(new ChatUserTokenContext()
                {
                    ConversationId = conversation.ConversationId,
                    Token = conversation.Token,
                    ExpiresIn = conversation.ExpiresIn,
                    UserContext = userContext
                }));
            }
            catch (Exception e)
            {
                _logger.LogError($"SecurityController: {e.Message}");
                return(StatusCode((int)HttpStatusCode.InternalServerError));
            }
        }
        protected override async Task HandleTurnAsync(ITurnContext turnContext, ChatUserContext userContext,
                                                      MessageRouter messageRouter, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
        {
            Activity activity = turnContext.Activity;

            if (turnContext.TurnState.TryGetValue(typeof(CommandSendMessageProperties).FullName, out object result))
            {
                CommandSendMessageProperties properties = (CommandSendMessageProperties)result;

                //Log broadcast
                if (properties.From.Role == ChatUserRole.Admin && properties.UserId == "*")
                {
                    var allConsumerConservations = await _routingDataManager.GetConsumerConversations();

                    foreach (var consumerConversation in allConsumerConservations)
                    {
                        await _reportDataManager.CreateOrUpdateChatReport(new ChatReportLogCreationModel()
                        {
                            User = properties.From.Role == ChatUserRole.Admin ? new ChatUserModel()
                            {
                                Id = consumerConversation.User.Id
                            } : properties.From,
                            Message = new ChatReportLogModel()
                            {
                                From        = properties.From,
                                Date        = activity.Timestamp.Value.DateTime,
                                Message     = activity.Text,
                                ReportType  = properties.ReportType,
                                Id          = activity.Id,
                                IsBroadcast = true
                            }
                        });
                    }
                }
                else
                {
                    //Log one message
                    ChatReportModel chatReportModel = await _reportDataManager.CreateOrUpdateChatReport(new ChatReportLogCreationModel()
                    {
                        User = properties.From.Role == ChatUserRole.Admin ? new ChatUserModel()
                        {
                            Id = properties.UserId
                        } : properties.From,
                        ChannelId = activity.ChannelId,
                        Message   = new ChatReportLogModel()
                        {
                            From       = properties.From,
                            Date       = activity.Timestamp.Value.DateTime,
                            Message    = activity.Text,
                            ReportType = properties.ReportType,
                            Id         = activity.Id
                        }
                    });

                    turnContext.TurnState.Add(typeof(ChatReportModel).FullName, chatReportModel);
                }

                await next(cancellationToken).ConfigureAwait(false);
            }
        }
예제 #3
0
        public IHttpActionResult SendMessage(ChatMessageDTO message)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            ChatUserContext context = _chatmanager.GetContextByUserId(message.SenderUserId);

            if (context == null)
            {
                return(BadRequest(string.Format("user context with id {0} not found", message.SenderUserId)));
            }

            Logger.Info("{0}({1}) sends {2}. ImageUrl={3}", context.User.Name, context.User.UserId, message.Message, message.ImageUrl ?? "<NONE>");

            message.SenderUserAvatar = context.User.Avatar;
            ChatHubContext.Current.SendChatMessage(message);

            // Sql Database Lab

            // Sql Database Lab

            return(Ok());
        }
        protected override async Task HandleTurnAsync(ITurnContext turnContext, ChatUserContext userContext,
                                                      MessageRouter messageRouter, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
        {
            Activity activity = turnContext.Activity;

            if (turnContext.TurnState.TryGetValue(typeof(CommandSendMessageProperties).FullName, out object result))
            {
                CommandSendMessageProperties properties       = (CommandSendMessageProperties)result;
                ConversationReference        selfConversation = activity.GetConversationReference();

                //Broadcast to many users
                IEnumerable <ConversationReference> conversations = await GetHandoffConversation(turnContext, activity, properties, selfConversation);

                //Send messages
                if (conversations != null)
                {
                    foreach (var conversation in conversations)
                    {
                        await messageRouter.SendMessageAsync(conversation, properties, activity.Text);
                    }
                }

                await next(cancellationToken).ConfigureAwait(false);
            }
        }
        public override Task OnConnected()
        {
            ChatUserContext context = _manager.AddSignalrConnection(UserId, this.Context.ConnectionId);

            _log.Info("Connect {0}..UserId={1};ConnectionId={2}", context.User.Name, context.User.UserId, this.Context.ConnectionId);

            Clients.Others.UsersChanged();
            return(base.OnConnected());
        }
        public override Task OnDisconnected(bool stopCalled)
        {
            ChatUserContext context = _manager.RemoveSignalrConnection(UserId, this.Context.ConnectionId);

            if (context != null)
            {
                _log.Info("Disconnect {0}..UserId={1};ConnectionId={2}", context.User.Name, context.User.UserId, this.Context.ConnectionId);
                Clients.Others.UsersChanged();
            }

            return(base.OnDisconnected(stopCalled));
        }
예제 #7
0
        public ChatUserContext AddSignalrConnection(string userId, string connectionId)
        {
            ChatUserContext context = GetContextByUserId(userId);

            if (context == null)
            {
                throw new ArgumentException(string.Format("user context with id {0} not found", userId));
            }

            context.AddConnection(connectionId);
            return(context);
        }
예제 #8
0
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
        {
            Activity activity = turnContext.Activity;

            if (activity.Type is ActivityTypes.Message)
            {
                //Add User Context in the turn context
                ConversationReference selfConversation = activity.GetConversationReference();
                ChatUserContext       userContext      = ChatUserContext.FromConversation(selfConversation);
                if (activity.ChannelId.ToLower() != _config.AdminChannel ||
                    !UserRoleCache.UserRoles.ContainsKey(userContext.Id))
                {
                    userContext.Role = ChatUserRole.Consumer;
                }
                else
                {
                    userContext.Role = UserRoleCache.UserRoles[userContext.Id];
                }
                selfConversation.User.Role = userContext.Role.ToString();
                turnContext.TurnState.Add(typeof(ChatUserContext).FullName, userContext);

                //Add Message router in the turn context
                ConnectorClient connectorClient = turnContext.TurnState.Get <ConnectorClient>(typeof(IConnectorClient).FullName);
                MessageRouter   messageRouter   = new MessageRouter(connectorClient, activity, _logger);
                turnContext.TurnState.Add(typeof(MessageRouter).FullName, messageRouter);

                //Ensure that each user only has one conversation active, and notify the other sessions where a conversation replaced it.
                IEnumerable <ConversationReference> otherConversations = await _routingDataManager.GetConversationsFromUser(selfConversation.User.Id);

                //Remove current conversation
                otherConversations = _routingDataManager.RemoveSelfConversation(otherConversations, selfConversation);
                //Send a notification to all old conversations
                if (otherConversations.Count() > 0)
                {
                    foreach (var otherConversation in otherConversations)
                    {
                        await messageRouter.SendErrorMessageAsync(otherConversation, "You were disconnected from this instance.");
                    }
                }
                //Store the new conversation
                await _routingDataManager.SaveConversationReference(selfConversation);

                //Leave this middleware
                await next(cancellationToken).ConfigureAwait(false);
            }
            if (activity.Type is ActivityTypes.EndOfConversation)
            {
                ConversationReference selfConversation = activity.GetConversationReference();
                _logger.LogInformation($"Conversation Ended: {selfConversation.Conversation.Id}");
            }
        }
예제 #9
0
        public ChatUserContext RemoveSignalrConnection(string userId, string connectionId)
        {
            ChatUserContext context = GetContextByUserId(userId);

            if (context != null)
            {
                context.RemoveConnection(connectionId);
                if (!context.HasConnections)
                {
                    _users.Remove(userId);
                    return(context);
                }
            }

            return(null);
        }
예제 #10
0
        public ChatUser Join(string username)
        {
            ChatUser user = new ChatUser();

            user.UserId = Guid.NewGuid().ToString();
            user.Name   = username;
            user.Avatar = Avatar.GetNextAvatarSvg();

            ChatUserContext context = new ChatUserContext();

            context.User = user;

            _users.Add(user.UserId, context);

            return(user);
        }
예제 #11
0
 protected abstract Task HandleTurnAsync(ITurnContext turnContext, ChatUserContext userContext, MessageRouter messageRouter, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken));
        protected override async Task HandleTurnAsync(ITurnContext turnContext, ChatUserContext userContext,
                                                      MessageRouter messageRouter, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
        {
            Activity activity = turnContext.Activity;

            if (activity.TryGetChannelData(out Command command) && command.BaseCommand != Commands.Undefined)
            {
                // Check the activity for commands
                ConversationReference selfConversation = activity.GetConversationReference();
                switch (command.BaseCommand)
                {
                case Commands.GetTranscript:
                    if (userContext.Role == ChatUserRole.Admin)
                    {
                        var conversations = await _reportDataManager.GetActiveChatReports();

                        var readUsersStatus = await _routingDataManager.GetUsersReadStatusPerUser(userContext.Id);

                        await messageRouter.SendTranscriptAsync(activity.Conversation.Id, conversations, readUsersStatus);
                    }
                    else
                    {
                        var conversation = await _reportDataManager.GetActiveChatReportFromUser(activity.From.Id);

                        await messageRouter.SendTranscriptAsync(activity.Conversation.Id, new List <ChatReportModel>() { conversation });
                    }
                    break;

                case Commands.ReadUserMessages:
                    //Update a date that shows the last time a message was read by an admin
                    if (userContext.Role == ChatUserRole.Admin)
                    {
                        if (JsonConvert.DeserializeObject <CommandReadUserMessages>(command.Data.ToString()) is CommandReadUserMessages properties)
                        {
                            var result = await _routingDataManager.UpdateUserReadMessageStatus(activity.From.Id, new ChatUserReadStatusModel()
                            {
                                Date   = properties.Date,
                                UserId = properties.UserId
                            });

                            if (!result)
                            {
                                throw new Exception("Error while executing command ReadUserMessages");
                            }
                        }
                    }
                    break;

                case Commands.EndConversation:
                    //End a conversation by adding an EndDate and delete the user conversation session so broadcast messages aren't sent to them anymore.
                    if (userContext.Role == ChatUserRole.Admin)
                    {
                        if (JsonConvert.DeserializeObject <CommandEndConversation>(command.Data.ToString()) is CommandEndConversation properties)
                        {
                            ChatReportModel userReport = await _reportDataManager.GetActiveChatReportFromUser(properties.UserId);

                            var result = await _reportDataManager.CloseReport(new ChatReportLogCloseModel()
                            {
                                EndDate = DateTime.UtcNow, UserId = properties.UserId
                            });

                            if (result)
                            {
                                var userConversationReference = await _routingDataManager.GetConversationsFromUser(properties.UserId);

                                if (userConversationReference != null && userConversationReference.Count() > 0)
                                {
                                    //Warn the user that the conversation is over
                                    await messageRouter.SendMessageAsync(userConversationReference.ToArray()[0],
                                                                         CommandFactoryHelper.CreateCommandSendMessage(selfConversation.Bot.Id, properties.UserId, selfConversation.User)
                                                                         , "The conversation was ended. If you have an issue, please start a new conversation.");

                                    //Call EndOfConversation on the user
                                    await messageRouter.SendEndConversationAsync(messageRouter.CreateEndOfConversationActivity(userConversationReference.ToArray()[0]));

                                    result = await _routingDataManager.DeleteUserConversation(properties.UserId);

                                    //Tell all admins about end of the conversation
                                    var admins = await _routingDataManager.GetAdminConversations();

                                    admins = _routingDataManager.RemoveSelfConversation(admins, selfConversation);
                                    if (admins != null)
                                    {
                                        foreach (var admin in admins)
                                        {
                                            await messageRouter.SendMessageAsync(admin,
                                                                                 CommandFactoryHelper.CreateCommandEndConversation(selfConversation.Bot.Id, properties.UserId));
                                        }
                                    }

                                    //Send event to event processor... if possible
                                    if (userReport != null)
                                    {
                                        //Sanitize user
                                        string      userId = GetDatabaseUserId(userReport.ChannelId, userReport.User.Id);
                                        DeviceModel device = await _deviceRestService.GetMobileDeviceFromUserId(userId);

                                        //Send close message
                                        await PushClosureMessageToEventProcessorSaga(device.DeviceId);
                                    }
                                }
                            }
                            if (!result)
                            {
                                throw new Exception("Error while executing command EndConversation");
                            }
                        }
                    }
                    break;

                case Commands.SendMessage:
                    if (userContext.Role == ChatUserRole.Admin && !string.IsNullOrWhiteSpace(activity.Text))
                    {
                        if (JsonConvert.DeserializeObject <CommandSendMessageProperties>(command.Data.ToString()) is CommandSendMessageProperties properties)
                        {
                            properties.UserId = properties.UserId;
                            properties.From   = userContext;   //Forcing admin, in case it isn't given by user
                            turnContext.TurnState.Add(typeof(CommandSendMessageProperties).FullName, properties);
                            //We forward to the next middleware
                            await next(cancellationToken).ConfigureAwait(false);
                        }
                        else
                        {
                            throw new Exception("Error while executing command SendMessage");
                        }
                    }
                    break;

                default:
                    if (userContext.Role == ChatUserRole.Admin)
                    {
                        throw new Exception($"Command not recognized: '{command.BaseCommand}'.");
                    }
                    break;
                }
            }