/// <summary> /// Tries to initiate a connection (1:1 conversation) by creating a request on behalf of /// the given requestor. This method does nothing, if a request for the same user already exists. /// </summary> /// <param name="requestor">The requestor conversation reference.</param> /// <param name="rejectConnectionRequestIfNoAggregationChannel"> /// If true, will reject all requests, if there is no aggregation channel.</param> /// <returns>The result of the operation: /// - ConnectionRequestResultType.Created, /// - ConnectionRequestResultType.AlreadyExists, /// - ConnectionRequestResultType.NotSetup or /// - ConnectionRequestResultType.Error (see the error message for more details). /// </returns> public virtual ConnectionRequestResult CreateConnectionRequest( ConversationReference requestor, bool rejectConnectionRequestIfNoAggregationChannel = false) { if (requestor == null) { throw new ArgumentNullException("Requestor missing"); } ConnectionRequestResult createConnectionRequestResult = null; RoutingDataManager.AddConversationReference(requestor); ConnectionRequest connectionRequest = new ConnectionRequest(requestor); if (RoutingDataManager.IsAssociatedWithAggregation(requestor)) { createConnectionRequestResult = new ConnectionRequestResult() { Type = ConnectionRequestResultType.Error, ErrorMessage = $"The given ConversationReference ({RoutingDataManager.GetChannelAccount(requestor)?.Name}) is associated with aggregation and hence invalid to request a connection" }; } else { createConnectionRequestResult = RoutingDataManager.AddConnectionRequest( connectionRequest, rejectConnectionRequestIfNoAggregationChannel); } return(createConnectionRequestResult); }
/// <summary> /// Stores the conversation reference instances (sender and recipient) in the given activity. /// </summary> /// <param name="activity">The activity.</param> /// <returns>The list of two results, where the first element is for the sender and the last for the recipient.</returns> public IList <ModifyRoutingDataResult> StoreConversationReferences(IActivity activity) { return(new List <ModifyRoutingDataResult>() { RoutingDataManager.AddConversationReference(CreateSenderConversationReference(activity)), RoutingDataManager.AddConversationReference(CreateRecipientConversationReference(activity)) }); }
/// <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); }