internal bool AssignBot(ChatInteraction interaction) { using (Trace.BotManager.scope()) { try { // Assign first pass if (AssignBot(interaction, false)) { return(true); } /* Beg someone to take the interaction -- * The idea behind this is that a bot can choose not to take the chat on the first pass * if the chat doesn't meet its criteria for selection. On the second pass, we're asking * each bot to reconsider and take the chat unless it can't possibly service that * chat. If the second pass fails, the chat will remain in queue. */ if (AssignBot(interaction, true)) { return(true); } Trace.BotManager.error("Failed to assign interaction {} to any bot", interaction.InteractionId.Id); } catch (Exception ex) { Trace.BotManager.exception(ex); } return(false); } }
private void UnassignChat(ChatInteraction chat, UnassignmentReason reason) { using (Trace.Main.scope()) { try { // Unassign _botManager.UnassignBot(chat.InteractionId.Id, reason); // Stop watches if (chat.ChatIsWatching()) { chat.ChatStopWatching(); } if (chat.IsWatching()) { chat.StopWatching(); } // Remove event handlers chat.TextAdded -= ChatOnTextAdded; chat.UrlAdded -= ChatOnUrlAdded; } catch (Exception ex) { Trace.Main.exception(ex); } } }
private void DoAssignBot(ChatInteraction chat, IChatBot bot, IDictionary <string, string> attributes) { Trace.BotManager.status("Assigning interaction {} to bot {}", chat.InteractionId.Id, bot.BotName); Console.WriteLine("Assigning interaction {0} to bot {1}", chat.InteractionId.Id, bot.BotName); _interactionAssignments[chat.InteractionId.Id] = bot; try { bot.InteractionAssigned(chat.InteractionId.Id, attributes); } catch (Exception ex) { Trace.BotManager.exception(ex); } }
internal void ReassignChat(ChatInteraction chat, string suggestedBotName, IChatBot bot) { using (Trace.BotManager.scope()) { try { if (chat == null) { throw new Exception("Unable to reassign null chat"); } ValidateBotAssignmentAndThrow(chat.InteractionId.Id, bot); Console.WriteLine("ReassignChat ({0})"); var targetBot = Bots.FirstOrDefault( b => b.BotName.Equals(suggestedBotName.Trim(), StringComparison.InvariantCultureIgnoreCase)); if (targetBot != null) { var attributes = chat.GetStringAttributes(targetBot.RequestedAttributes.ToArray()); // Found selected bot, see if it will claim the chat if (targetBot.ClaimInteraction(chat.InteractionId.Id, attributes, true)) { UnassignBot(chat.InteractionId.Id, UnassignmentReason.Reassigned); DoAssignBot(chat, targetBot, attributes); } } // Try to assign the bot if it's not assigned to the suggested bot if (targetBot == null || !ValidateBotAssignment(chat.InteractionId.Id, targetBot)) { AssignBot(chat); } } catch (Exception ex) { Trace.BotManager.exception(ex); } } }
private bool AssignBot(ChatInteraction interaction, bool prettyPlease) { foreach (var bot in Bots) { try { var attributes = interaction.GetStringAttributes(bot.RequestedAttributes.ToArray()); if (!bot.ClaimInteraction(interaction.InteractionId.Id, attributes, prettyPlease)) { continue; } DoAssignBot(interaction, bot, attributes); return(true); } catch (Exception ex) { Trace.BotManager.exception(ex, "Exception from ClaimInteraction from bot {}", bot.BotName); } } return(false); }
private void SendToChat(ChatInteraction chat, IChatMessage message) { using (Trace.Main.scope()) { try { // Send the message to the chat switch (message.MessageType) { case ChatMessageType.Text: var text = message as TextChatMessage; chat.SendText(text.Text); break; case ChatMessageType.Url: var url = message as UrlChatMessage; chat.SendUrl(url.Uri); break; case ChatMessageType.FilePath: var filePath = message as FilePathChatMessage; chat.SendFile(filePath.Path); break; case ChatMessageType.FileStream: var fileStream = message as FileStreamChatMessage; chat.SendFile(fileStream.Stream, fileStream.Filename); break; default: return; } } catch (Exception ex) { Trace.Main.exception(ex); } } }
private void AssignChat(ChatInteraction chat) { using (Trace.Main.scope()) { try { if (!_botManager.AssignBot(chat)) { Trace.Main.warning("Chat {} was not assigned to any bot!", chat.InteractionId.Id); return; } // Set up watches chat.TextAdded += ChatOnTextAdded; chat.UrlAdded += ChatOnUrlAdded; chat.ChatStartWatching(); } catch (Exception ex) { Trace.Main.exception(ex); } } }
public async Task SendMessage(string receiverId, SendingMessageDTO message) { string senderName = Context.User.FindFirst(ClaimTypes.Name).Value; ObjectId senderId = ObjectId.Parse(Context.User.FindFirst(ClaimTypes.NameIdentifier).Value); ObjectId receiver = ObjectId.Parse(receiverId); ObjectId?chatInteractionId = null; if (message.ChatInteractionId != null) { chatInteractionId = ObjectId.Parse(message.ChatInteractionId); } var data = _context.GetDb; Message newMessage = new Message { Id = ObjectId.GenerateNewId(), Content = message.Message, Seen = false, DateSent = DateTime.Now, Sender = senderName }; var chatCollection = data.GetCollection <ChatInteraction>("ChatInteractions"); var userCollection = data.GetCollection <User>("Users"); var filterForSenderUser = Builders <User> .Filter.Eq("_id", senderId); var filterForReceiverUser = Builders <User> .Filter.Eq("_id", receiver); bool setSeen = true; if (chatInteractionId == null) { var receiverUser = (await userCollection.FindAsync(filterForReceiverUser)).FirstOrDefault(); // check receiver contacts if they contain sender var chatInteractionWithSender = receiverUser.Contacts?.Where(contact => contact.Name == senderName).FirstOrDefault(); if (chatInteractionWithSender != null) { chatInteractionId = chatInteractionWithSender.ChatInteractionReference; } } if (chatInteractionId == null) { // New chat interaction: List <Message> messages = new List <Message> { newMessage }; ChatInteraction newChatInteraction = new ChatInteraction { Id = ObjectId.GenerateNewId(), Messages = messages }; await chatCollection.InsertOneAsync(newChatInteraction); var senderUser = (await userCollection.FindAsync <User>(filterForSenderUser)).First(); var receiverUser = (await userCollection.FindAsync(filterForReceiverUser)).FirstOrDefault(); Contact contact; // New friend request for receiver: contact = new Contact { ChatInteractionReference = newChatInteraction.Id, Id = ObjectId.GenerateNewId(), Name = senderName, Status = "Request", OtherUserId = senderId, Seen = false }; setSeen = false; UpdateDefinition <User> updateDefinition; if (receiverUser.Contacts == null) { updateDefinition = Builders <User> .Update.Set("Contacts", new List <Contact> { contact }); } else { updateDefinition = Builders <User> .Update.Push <Contact>("Contacts", contact); } await userCollection.UpdateOneAsync(filterForReceiverUser, updateDefinition); // New friend contact for sender: contact = new Contact { ChatInteractionReference = newChatInteraction.Id, Id = ObjectId.GenerateNewId(), Name = receiverUser.Username, Status = "Friend", OtherUserId = receiver, Seen = true }; if (senderUser.Contacts == null) { updateDefinition = Builders <User> .Update.Set("Contacts", new List <Contact> { contact }); } else { updateDefinition = Builders <User> .Update.Push <Contact>("Contacts", contact); } await userCollection.UpdateOneAsync(filterForSenderUser, updateDefinition); } else { // Just add message: var filter = Builders <ChatInteraction> .Filter.Eq("_id", chatInteractionId); await chatCollection.UpdateOneAsync(filter, Builders <ChatInteraction> .Update.Push <Message>("Messages", newMessage)); } // Notify Users about new message: var userConnections = _connections.GetConnections(receiver); if (userConnections != null) { foreach (var connectionId in userConnections) { await Clients.Client(connectionId).SendAsync("receivedMessage", new { SenderId = senderId.ToString(), Message = new MessageReturnDTO(newMessage), ReceiverId = receiver.ToString(), ChatInteractionId = chatInteractionId.ToString() }); } } else { // Nobody notified, set Seen to false: if (setSeen) { var filterUser = Builders <User> .Filter.Eq("_id", senderId); var filterContact = Builders <Contact> .Filter.Eq(u => u.OtherUserId, receiver); var filterContactList = Builders <User> .Filter.ElemMatch(user => user.Contacts, filterContact); var filter = Builders <User> .Filter.And(filterUser, filterContactList); var update = Builders <User> .Update.Set(userOrigin => userOrigin.Contacts[-1].Seen, false); await userCollection.UpdateOneAsync(filter, update); } } var senderConnections = _connections.GetConnections(senderId); foreach (var connectionId in senderConnections) { await Clients.Client(connectionId).SendAsync("receivedMessage", new { SenderId = senderId.ToString(), Message = new MessageReturnDTO(newMessage), ReceiverId = receiver.ToString(), ChatInteractionId = chatInteractionId.ToString() }); } }