Exemple #1
0
        public async Task <IActionResult> SendMessage(SendMessageAddressModel model)
        {
            var user = await GetKahlaUser();

            var target = await _dbContext.Conversations.FindAsync(model.Id);

            if (!await _dbContext.VerifyJoined(user.Id, target))
            {
                return(this.Protocal(ErrorType.Unauthorized, "You don't have any relationship with that conversation."));
            }
            if (model.Content.Trim().Length == 0)
            {
                return(this.Protocal(ErrorType.InvalidInput, "Can not send empty message."));
            }
            //Create message.
            var message = new Message
            {
                Content        = model.Content,
                SenderId       = user.Id,
                ConversationId = target.Id
            };

            _dbContext.Messages.Add(message);
            await _dbContext.SaveChangesAsync();

            //Push the message to reciever
            if (target.Discriminator == nameof(PrivateConversation))
            {
                var privateConversation = target as PrivateConversation;
                await _pusher.NewMessageEvent(privateConversation.RequesterId, target.Id, model.Content, user);

                await _pusher.NewMessageEvent(privateConversation.TargetId, target.Id, model.Content, user);
            }
            else if (target.Discriminator == nameof(GroupConversation))
            {
                var usersJoined = _dbContext.UserGroupRelations.Where(t => t.GroupId == target.Id);
                await usersJoined.ForEachAsync(async t => await _pusher.NewMessageEvent(t.UserId, target.Id, model.Content, user));
            }
            //Return success message.
            return(this.Protocal(ErrorType.Success, "Your message has been sent."));
        }
Exemple #2
0
        public async Task <IActionResult> SendMessage(SendMessageAddressModel model)
        {
            var user = await GetKahlaUser();

            var target = await _dbContext
                         .Conversations
                         .Include(t => (t as PrivateConversation).RequestUser)
                         .ThenInclude(t => t.HisDevices)
                         .Include(t => (t as PrivateConversation).TargetUser)
                         .ThenInclude(t => t.HisDevices)
                         .Include(t => (t as GroupConversation).Users)
                         .ThenInclude(t => t.User)
                         .ThenInclude(t => t.HisDevices)
                         .SingleOrDefaultAsync(t => t.Id == model.Id);

            if (target == null)
            {
                return(this.Protocol(ErrorType.NotFound, $"Can not find conversation with id: {model.Id}."));
            }
            if (!target.HasUser(user.Id))
            {
                return(this.Protocol(ErrorType.Unauthorized, "You don't have any relationship with that conversation."));
            }
            if (model.Content.Trim().Length == 0)
            {
                return(this.Protocol(ErrorType.InvalidInput, "Can not send empty message."));
            }
            // Get last message Id.
            string lastMessageId;

            try
            {
                lastMessageId = _lastSaidJudger.LastMessageId(target.Id);
            }
            catch (InvalidOperationException)
            {
                Guid?nullableLastMessageId = await _dbContext
                                             .Messages
                                             .Where(t => t.ConversationId == target.Id)
                                             .OrderByDescending(t => t.SendTime)
                                             .Select(t => t.Id)
                                             .FirstOrDefaultAsync();

                lastMessageId = nullableLastMessageId.Value.ToString();
            }
            // Create message.
            var message = new Message
            {
                Id                = Guid.Parse(model.MessageId),
                Content           = model.Content,
                SenderId          = user.Id,
                Sender            = user.Build(_onlineJudger),
                ConversationId    = target.Id,
                SendTime          = DateTime.UtcNow,
                GroupWithPrevious = _lastSaidJudger.ShallBeGroupped(user.Id, target.Id)
            };
            await _dbContext.Messages.AddAsync(message);

            await _dbContext.SaveChangesAsync();

            _lastSaidJudger.MarkSend(user.Id, target.Id, message.Id);
            // Create at info for this message.
            foreach (var atTargetId in model.At)
            {
                if (target.HasUser(atTargetId))
                {
                    var at = new At
                    {
                        MessageId    = message.Id,
                        TargetUserId = atTargetId
                    };
                    message.Ats.Add(at);
                    await _dbContext.Ats.AddAsync(at);
                }
                else
                {
                    _dbContext.Messages.Remove(message);
                    await _dbContext.SaveChangesAsync();

                    return(this.Protocol(ErrorType.InvalidInput, $"Can not at person with Id: '{atTargetId}' because he is not in this conversation."));
                }
            }
            // Save the ats.
            await _dbContext.SaveChangesAsync();

            // Set last read time.
            await _dbContext.SetLastRead(target, user.Id);

            await _dbContext.SaveChangesAsync();

            target.ForEachUser((eachUser, relation) =>
            {
                var mentioned  = model.At.Contains(eachUser.Id);
                var muted      = relation?.Muted ?? false;
                var isSentByMe = eachUser.Id == user.Id;
                _kahlaPushService.NewMessageEvent(
                    stargateChannel: eachUser.CurrentChannel,
                    devices: eachUser.HisDevices,
                    conversation: target,
                    message: message,
                    lastMessageId: lastMessageId,
                    pushAlert: !isSentByMe && (mentioned || !muted),
                    mentioned: mentioned).Wait();
            });
            return(this.Protocol(new AiurValue <Message>(message)
            {
                Code = ErrorType.Success,
                Message = "Your message has been sent."
            }));
        }
        public async Task <IActionResult> SendMessage(SendMessageAddressModel model)
        {
            var user = await _userManager.GetUserAsync(User);

            var target = await _dbContext.Conversations.FindAsync(model.Id);

            if (!await _dbContext.VerifyJoined(user.Id, target))
            {
                return(this.Protocol(ErrorType.Unauthorized, "您没有权限访问这个会话."));
            }
            if (model.Content.Trim().Length == 0)
            {
                return(this.Protocol(ErrorType.InvalidInput, "不要发送空白消息哦."));
            }

            var message = new Message
            {
                Content        = model.Content,
                SenderId       = user.Id,
                ConversationId = target.Id
            };

            _dbContext.Messages.Add(message);
            await _dbContext.SaveChangesAsync();

            if (target is PrivateConversation privateConversation)
            {
                var requester = await _userManager.FindByIdAsync(privateConversation.RequesterId);

                var targetUser = await _userManager.FindByIdAsync(privateConversation.TargetId);

                await _pusher.NewMessageEvent(requester, target, model.Content, user, true);

                if (requester.Id != targetUser.Id)
                {
                    await _pusher.NewMessageEvent(targetUser, target, model.Content, user, true);
                }
            }
            else if (target is GroupConversation)
            {
                var usersJoined = await _dbContext
                                  .UserGroupRelations
                                  .Include(t => t.User)
                                  .Where(t => t.GroupId == target.Id)
                                  .ToListAsync();

                var taskList = new List <Task>();
                foreach (var relation in usersJoined)
                {
                    async Task SendNotification()
                    {
                        await _pusher.NewMessageEvent(
                            reciever : relation.User,
                            conversation : target,
                            content : model.Content,
                            sender : user,
                            alert : !relation.Muted);
                    }

                    taskList.Add(SendNotification());
                }
                await Task.WhenAll(taskList);
            }

            return(this.Protocol(ErrorType.Success, "您的消息成功发送."));
        }
Exemple #4
0
        public async Task <IActionResult> SendMessage(SendMessageAddressModel model)
        {
            model.At = model.At ?? new string[0];
            var user = await GetKahlaUser();

            var target = await _dbContext.Conversations.FindAsync(model.Id);

            if (!await _dbContext.VerifyJoined(user.Id, target))
            {
                return(this.Protocol(ErrorType.Unauthorized, "You don't have any relationship with that conversation."));
            }

            if (model.Content.Trim().Length == 0)
            {
                return(this.Protocol(ErrorType.InvalidInput, "Can not send empty message."));
            }
            // Create message.
            var message = new Message
            {
                Content        = model.Content,
                SenderId       = user.Id,
                ConversationId = target.Id
            };

            _dbContext.Messages.Add(message);
            await _dbContext.SaveChangesAsync();

            // Create at info for this message.
            foreach (var atTargetId in model.At)
            {
                if (await _dbContext.VerifyJoined(atTargetId, target))
                {
                    var at = new At
                    {
                        MessageId    = message.Id,
                        TargetUserId = atTargetId
                    };
                    _dbContext.Ats.Add(at);
                }
                else
                {
                    _dbContext.Messages.Remove(message);
                    await _dbContext.SaveChangesAsync();

                    return(this.Protocol(ErrorType.InvalidInput, $"Can not at person with Id: '{atTargetId}' because he is not in this conversation."));
                }
            }
            await _dbContext.SaveChangesAsync();

            await target.ForEachUserAsync(async (eachUser, relation) =>
            {
                var mentioned = model.At.Contains(eachUser.Id);
                await _pusher.NewMessageEvent(
                    receiver: eachUser,
                    conversation: target,
                    content: model.Content,
                    sender: user,
                    muted: !mentioned && (relation?.Muted ?? false),
                    mentioned: mentioned
                    );
            }, _userManager);

            try
            {
                await _dbContext.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                return(this.Protocol(ErrorType.RequireAttention, "Your message has been sent. But an error occured while sending web push notification."));
            }
            //Return success message.
            return(this.Protocol(ErrorType.Success, "Your message has been sent."));
        }
        public async Task <IActionResult> SendMessage(SendMessageAddressModel model)
        {
            if (model.RecordTime > DateTime.UtcNow || model.RecordTime + TimeSpan.FromSeconds(100) < DateTime.UtcNow)
            {
                model.RecordTime = DateTime.UtcNow;
            }
            model.At = model.At ?? new string[0];
            var user = await GetKahlaUser();

            var target = await _dbContext
                         .Conversations
                         .Include(t => (t as PrivateConversation).RequestUser)
                         .ThenInclude(t => t.HisDevices)
                         .Include(t => (t as PrivateConversation).TargetUser)
                         .ThenInclude(t => t.HisDevices)
                         .Include(t => (t as GroupConversation).Users)
                         .ThenInclude(t => t.User)
                         .ThenInclude(t => t.HisDevices)
                         .SingleOrDefaultAsync(t => t.Id == model.Id);

            if (target == null)
            {
                return(this.Protocol(ErrorType.NotFound, $"Can not find conversation with id: {model.Id}."));
            }
            if (!target.HasUser(user.Id))
            {
                return(this.Protocol(ErrorType.Unauthorized, "You don't have any relationship with that conversation."));
            }
            if (model.Content.Trim().Length == 0)
            {
                return(this.Protocol(ErrorType.InvalidInput, "Can not send empty message."));
            }
            // Create message.
            var message = new Message
            {
                Id             = Guid.Parse(model.MessageId),
                Content        = model.Content,
                SenderId       = user.Id,
                Sender         = user,
                ConversationId = target.Id,
                SendTime       = model.RecordTime
            };

            _dbContext.Messages.Add(message);
            await _dbContext.SaveChangesAsync();

            // Create at info for this message.
            foreach (var atTargetId in model.At)
            {
                if (target.HasUser(atTargetId))
                {
                    var at = new At
                    {
                        MessageId    = message.Id,
                        TargetUserId = atTargetId
                    };
                    message.Ats.Add(at);
                    _dbContext.Ats.Add(at);
                }
                else
                {
                    _dbContext.Messages.Remove(message);
                    await _dbContext.SaveChangesAsync();

                    return(this.Protocol(ErrorType.InvalidInput, $"Can not at person with Id: '{atTargetId}' because he is not in this conversation."));
                }
            }
            // Save the ats.
            await _dbContext.SaveChangesAsync();

            // Set last read time.
            var lastReadTime = await target.SetLastRead(_dbContext, user.Id);

            await _dbContext.SaveChangesAsync();

            await target.ForEachUserAsync((eachUser, relation) =>
            {
                var mentioned = model.At.Contains(eachUser.Id);
                return(_pusher.NewMessageEvent(
                           stargateChannel: eachUser.CurrentChannel,
                           devices: eachUser.HisDevices,
                           conversation: target,
                           message: message,
                           pushAlert: eachUser.Id != user.Id && (mentioned || !(relation?.Muted ?? false)),
                           mentioned: mentioned
                           ));
            });

            return(Json(new AiurValue <Message>(message)
            {
                Code = ErrorType.Success,
                Message = "Your message has been sent."
            }));
        }
        public async Task <IActionResult> SendMessage(SendMessageAddressModel model)
        {
            var user = await GetKahlaUser();

            var target = await _dbContext.Conversations.FindAsync(model.Id);

            if (!await _dbContext.VerifyJoined(user.Id, target))
            {
                return(this.Protocol(ErrorType.Unauthorized, "You don't have any relationship with that conversation."));
            }

            if (model.Content.Trim().Length == 0)
            {
                return(this.Protocol(ErrorType.InvalidInput, "Can not send empty message."));
            }
            //Create message.
            var message = new Message
            {
                Content        = model.Content,
                SenderId       = user.Id,
                ConversationId = target.Id
            };

            _dbContext.Messages.Add(message);
            await _dbContext.SaveChangesAsync();

            switch (target)
            {
            //Push the message to receiver
            case PrivateConversation privateConversation:
            {
                var requester = await _userManager.FindByIdAsync(privateConversation.RequesterId);

                var targetUser = await _userManager.FindByIdAsync(privateConversation.TargetId);

                await _pusher.NewMessageEvent(requester, target, model.Content, user, true);

                // In cause you are talking to yourself.
                if (requester.Id != targetUser.Id)
                {
                    await _pusher.NewMessageEvent(targetUser, target, model.Content, user, true);
                }
                break;
            }

            case GroupConversation groupConversation:
            {
                var usersJoined = await _dbContext
                                  .UserGroupRelations
                                  .Include(t => t.User)
                                  .Where(t => t.GroupId == groupConversation.Id)
                                  .ToListAsync();

                var taskList = new List <Task>();
                foreach (var relation in usersJoined)
                {
                    var pushTask = _pusher.NewMessageEvent(
                        receiver: relation.User,
                        conversation: target,
                        content: model.Content,
                        sender: user,
                        alert: !relation.Muted);
                    taskList.Add(pushTask);
                }
                await Task.WhenAll(taskList);

                break;
            }
            }
            try
            {
                await _dbContext.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                return(this.Protocol(ErrorType.RequireAttention, "Your message has been sent. But an error occured while sending web push notification."));
            }
            //Return success message.
            return(this.Protocol(ErrorType.Success, "Your message has been sent."));
        }