/// <summary> /// Tries to establish a connection (1:1 chat) between the two given parties. /// /// Note that the conversation owner will have a new separate conversation reference in the created /// conversation, if a new direct conversation is created. /// </summary> /// <param name="conversationReference1">The conversation reference who owns the conversation (e.g. customer service agent).</param> /// <param name="conversationReference2">The other conversation reference in the conversation.</param> /// <param name="createNewDirectConversation"> /// If true, will try to create a new direct conversation between the bot and the /// conversation owner (e.g. agent) where the messages from the other (client) conversation /// reference are routed. /// /// Note that this will result in the conversation owner having a new separate conversation /// reference in the created connection (for the new direct conversation). /// </param> /// <returns> /// The result of the operation: /// - ConnectionResultType.Connected, /// - ConnectionResultType.Error (see the error message for more details). /// </returns> public virtual async Task <ConnectionResult> ConnectAsync( ConversationReference conversationReference1, ConversationReference conversationReference2, bool createNewDirectConversation) { if (conversationReference1 == null || conversationReference2 == null) { throw new ArgumentNullException( $"Neither of the arguments ({nameof(conversationReference1)}, {nameof(conversationReference2)}) can be null"); } ConversationReference botInstance = RoutingDataManager.FindConversationReference( conversationReference1.ChannelId, conversationReference1.Conversation.Id, null, true); if (botInstance == null) { return(new ConnectionResult() { Type = ConnectionResultType.Error, ErrorMessage = "Failed to find the bot instance" }); } ConversationResourceResponse conversationResourceResponse = null; if (createNewDirectConversation) { ChannelAccount conversationReference1ChannelAccount = RoutingDataManager.GetChannelAccount( conversationReference1, out bool conversationReference1IsBot); ConnectorClient connectorClient = new ConnectorClient( new Uri(conversationReference1.ServiceUrl), _microsoftAppCredentials); try { conversationResourceResponse = await connectorClient.Conversations.CreateDirectConversationAsync( botInstance.Bot, conversationReference1ChannelAccount); } catch (Exception e) { Logger.Log($"Failed to create a direct conversation: {e.Message}"); // Do nothing here as we fallback (continue without creating a direct conversation) } if (conversationResourceResponse != null && !string.IsNullOrEmpty(conversationResourceResponse.Id)) { // The conversation account of the conversation owner for this 1:1 chat is different - // thus, we need to re-create the conversation owner instance ConversationAccount directConversationAccount = new ConversationAccount(id: conversationResourceResponse.Id); conversationReference1 = new ConversationReference( null, conversationReference1IsBot ? null : conversationReference1ChannelAccount, conversationReference1IsBot ? conversationReference1ChannelAccount : null, directConversationAccount, conversationReference1.ChannelId, conversationReference1.ServiceUrl); RoutingDataManager.AddConversationReference(conversationReference1); RoutingDataManager.AddConversationReference(new ConversationReference( null, null, botInstance.Bot, directConversationAccount, botInstance.ChannelId, botInstance.ServiceUrl)); } } Connection connection = new Connection(conversationReference1, conversationReference2); ConnectionResult connectResult = RoutingDataManager.ConnectAndRemoveConnectionRequest(connection, conversationReference2); connectResult.ConversationResourceResponse = conversationResourceResponse; return(connectResult); }