/// <summary> /// Tries to establish 1:1 chat between the two given parties. /// Note that the conversation owner will have a new separate party in the created engagement. /// </summary> /// <param name="conversationOwnerParty">The party who owns the conversation (e.g. customer service agent).</param> /// <param name="conversationClientParty">The other party in the conversation.</param> /// <returns>The result of the operation.</returns> public async Task <MessageRouterResult> AddEngagementAsync( Party conversationOwnerParty, Party conversationClientParty) { if (conversationOwnerParty == null || conversationClientParty == null) { throw new ArgumentNullException( $"Neither of the arguments ({nameof(conversationOwnerParty)}, {nameof(conversationClientParty)}) can be null"); } MessageRouterResult result = new MessageRouterResult() { ConversationOwnerParty = conversationOwnerParty, ConversationClientParty = conversationClientParty }; Party botParty = RoutingDataManager.FindBotPartyByChannelAndConversation( conversationOwnerParty.ChannelId, conversationOwnerParty.ConversationAccount); if (botParty != null) { ConnectorClient connectorClient = new ConnectorClient(new Uri(conversationOwnerParty.ServiceUrl)); ConversationResourceResponse response = await connectorClient.Conversations.CreateDirectConversationAsync( botParty.ChannelAccount, conversationOwnerParty.ChannelAccount); if (response != null && !string.IsNullOrEmpty(response.Id)) { // The conversation account of the conversation owner for this 1:1 chat is different - // thus, we need to create a new party instance ConversationAccount directConversationAccount = new ConversationAccount(id: response.Id); Party acceptorPartyEngaged = new Party( conversationOwnerParty.ServiceUrl, conversationOwnerParty.ChannelId, conversationOwnerParty.ChannelAccount, directConversationAccount); RoutingDataManager.AddParty(acceptorPartyEngaged); RoutingDataManager.AddParty( new Party(botParty.ServiceUrl, botParty.ChannelId, botParty.ChannelAccount, directConversationAccount), false); result = RoutingDataManager.AddEngagementAndClearPendingRequest(acceptorPartyEngaged, conversationClientParty); result.ConversationResourceResponse = response; } else { result.Type = MessageRouterResultType.Error; result.ErrorMessage = "Failed to create a direct conversation"; } } else { result.Type = MessageRouterResultType.Error; result.ErrorMessage = "Failed to find the bot instance"; } await HandleAndLogMessageRouterResultAsync(result); return(result); }
/// <summary> /// Checks the given parties and adds them to the collection, if not already there. /// /// Note that this method expects that the recipient is the bot. The sender could also be /// the bot, but that case is checked before adding the sender to the container. /// </summary> /// <param name="senderParty">The sender party (from).</param> /// <param name="recipientParty">The recipient party.</param> public void MakeSurePartiesAreTracked(Party senderParty, Party recipientParty) { // Store the bot identity, if not already stored RoutingDataManager.AddParty(recipientParty, false); // Check that the party who sent the message is not the bot if (!RoutingDataManager.GetBotParties().Contains(senderParty)) { // Store the user party, if not already stored RoutingDataManager.AddParty(senderParty); } }
/// <summary> /// Tries to establish 1:1 chat between the two given parties. /// Note that the conversation owner will have a new separate party in the created engagement. /// </summary> /// <param name="conversationOwnerParty">The party who owns the conversation (e.g. customer service agent).</param> /// <param name="conversationClientParty">The other party in the conversation.</param> /// <returns>The result of the operation.</returns> public async Task <MessageRouterResult> AddEngagementAsync( Party conversationOwnerParty, Party conversationClientParty) { if (conversationOwnerParty == null || conversationClientParty == null) { throw new ArgumentNullException( $"Neither of the arguments ({nameof(conversationOwnerParty)}, {nameof(conversationClientParty)}) can be null"); } MessageRouterResult result = new MessageRouterResult() { ConversationOwnerParty = conversationOwnerParty, ConversationClientParty = conversationClientParty }; Party botParty = RoutingDataManager.FindBotPartyByChannelAndConversation( conversationOwnerParty.ChannelId, conversationOwnerParty.ConversationAccount); if (botParty != null) { ConnectorClient connectorClient = new ConnectorClient(new Uri(conversationOwnerParty.ServiceUrl)); try { ConversationResourceResponse response = await connectorClient.Conversations.CreateDirectConversationAsync( botParty.ChannelAccount, conversationOwnerParty.ChannelAccount); // ResponseId and conversationOwnerParty.ConversationAccount.Id are not consistent // with each other across channels. Here we need the ConversationAccountId to route // messages correctly across channels, e.g.: // * In Slack they are the same: // * response.Id: B6JJQ7939: T6HKNHCP7: D6H04L58R // * conversationOwnerParty.ConversationAccount.Id: B6JJQ7939: T6HKNHCP7: D6H04L58R // * In Skype they are not: // * response.Id: 8:daltskin // * conversationOwnerParty.ConversationAccount.Id: 29:11MZyI5R2Eak3t7bFjDwXmjQYnSl7aTBEB8zaSMDIEpA if (response != null && !string.IsNullOrEmpty(conversationOwnerParty.ConversationAccount.Id)) { // The conversation account of the conversation owner for this 1:1 chat is different - // thus, we need to create a new party instance ConversationAccount directConversationAccount = new ConversationAccount(id: conversationOwnerParty.ConversationAccount.Id); Party acceptorPartyEngaged = new EngageableParty( conversationOwnerParty.ServiceUrl, conversationOwnerParty.ChannelId, conversationOwnerParty.ChannelAccount, directConversationAccount); RoutingDataManager.AddParty(acceptorPartyEngaged); RoutingDataManager.AddParty( new EngageableParty(botParty.ServiceUrl, botParty.ChannelId, botParty.ChannelAccount, directConversationAccount), false); result = RoutingDataManager.AddEngagementAndClearPendingRequest(acceptorPartyEngaged, conversationClientParty); result.ConversationResourceResponse = response; } else { result.Type = MessageRouterResultType.Error; result.ErrorMessage = "Failed to create a direct conversation"; } } catch (Exception e) { result.Type = MessageRouterResultType.Error; result.ErrorMessage = $"Failed to create a direct conversation: {e.Message}"; } } else { result.Type = MessageRouterResultType.Error; result.ErrorMessage = "Failed to find the bot instance"; } return(result); }