public async Task CreateConversastionOverloadProperlySetsTenantId() { // Arrange const string ActivityIdName = "ActivityId"; const string ActivityIdValue = "SendActivityId"; const string ConversationIdName = "Id"; const string ConversationIdValue = "NewConversationId"; const string TenantIdValue = "theTenantId"; const string EventActivityName = "CreateConversation"; Func <Task <HttpResponseMessage> > createResponseMessage = async() => { var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); response.Content = new StringContent(new JObject { { ActivityIdName, ActivityIdValue }, { ConversationIdName, ConversationIdValue } }.ToString()); return(response); }; var mockCredentialProvider = new Mock <ICredentialProvider>(); var mockHttpMessageHandler = new Mock <HttpMessageHandler>(); mockHttpMessageHandler.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Returns((HttpRequestMessage request, CancellationToken cancellationToken) => createResponseMessage()); var httpClient = new HttpClient(mockHttpMessageHandler.Object); var adapter = new BotFrameworkAdapter(mockCredentialProvider.Object, customHttpClient: httpClient); var activity = new Activity("test") { ChannelId = Channels.Msteams, ServiceUrl = "https://fake.service.url", ChannelData = new JObject { ["tenant"] = new JObject { ["id"] = TenantIdValue }, }, Conversation = new ConversationAccount { TenantId = TenantIdValue }, }; var parameters = new ConversationParameters() { Activity = new Activity() { ChannelData = activity.ChannelData, }, }; var reference = activity.GetConversationReference(); var credentials = new MicrosoftAppCredentials(string.Empty, string.Empty, httpClient); Activity newActivity = null; Task UpdateParameters(ITurnContext turnContext, CancellationToken cancellationToken) { newActivity = turnContext.Activity; return(Task.CompletedTask); } // Act await adapter.CreateConversationAsync(activity.ChannelId, activity.ServiceUrl, credentials, parameters, UpdateParameters, reference, new CancellationToken()); // Assert - all values set correctly Assert.AreEqual(TenantIdValue, JObject.FromObject(newActivity.ChannelData)["tenant"]["tenantId"]); Assert.AreEqual(ActivityIdValue, newActivity.Id); Assert.AreEqual(ConversationIdValue, newActivity.Conversation.Id); Assert.AreEqual(TenantIdValue, newActivity.Conversation.TenantId); Assert.AreEqual(EventActivityName, newActivity.Name); }
/// <summary> /// Process incoming Service Bus messages, and create a new conversation with the user. /// This will call <see cref="MessageCallback(T, UserInfoEntity)"/> when teh new conversation was successfuly created. /// </summary> /// <param name="message">Service Bus message object.</param> /// <param name="cancellationToken" >(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>Task.</returns> private async Task ProcessMessagesAsync(Message message, CancellationToken cancellationToken) { var json = Encoding.UTF8.GetString(message.Body); var parsedMessage = JsonConvert.DeserializeObject <T>(json); var logProperties = JsonConvert.DeserializeObject <Dictionary <string, string> >(json); logProperties.Add("ProactiveMessageType", GetType().Name); logProperties.Add("ServiceBusSequenceNumber", message.SystemProperties.SequenceNumber.ToString()); var userInfos = await _table.RetrieveUserInfoAsync(parsedMessage.UserId); if (userInfos == null || userInfos.Count == 0) { await _queueClient.CompleteAsync(message.SystemProperties.LockToken); _telemetryClient.TrackEvent( "Failed to send bot proactive message: User was not found in the bot's database.", logProperties); } if (!_env.IsProduction()) { userInfos = userInfos.Where(i => i.ChannelId == ChannelIds.Emulator).ToList(); } foreach (var userInfo in userInfos) { try { await _botFrameworkAdapter.CreateConversationAsync( userInfo.ChannelId, userInfo.ServiceUrl, new MicrosoftAppCredentials(_endpoint.AppId, _endpoint.AppPassword), new ConversationParameters(bot : userInfo.Bot, members : new List <ChannelAccount> { userInfo.User }, channelData : userInfo.ChannelData), MessageCallback(parsedMessage, userInfo), cancellationToken); // Same with an existing conversation // var conversation = new ConversationReference( // null, // userInfo.User, // userInfo.Bot, // new ConversationAccount(null, null, userInfo.CurrentConversation.Conversation.Id, null, null, null), // userInfo.ChannelId, // userInfo.ServiceUrl); // await _botFrameworkAdapter.ContinueConversationAsync(_endpoint.AppId, conversation, MessageCallback(), cancellationToken); } catch (ErrorResponseException e) { _telemetryClient.TrackException( e, new Dictionary <string, string> { { "Error message", e.Message }, { "Response body", e.Response.Content }, { "Request body", e.Request.Content }, { "Request uri", $"{e.Request.Method.ToString()} {e.Request.RequestUri.AbsoluteUri}" }, { "Request headers", e.Request.Headers.ToJson() }, }); } catch (Exception e) { _telemetryClient.TrackException(e); } } // Note: Use the cancellationToken passed as necessary to determine if the queueClient has already been closed. // If queueClient has already been Closed, you may chose to not call CompleteAsync() or AbandonAsync() etc. calls // to avoid unnecessary exceptions. // // Complete the message so that it is not received again. // This can be done only if the queueClient is created in ReceiveMode.PeekLock mode (which is default). await _queueClient.CompleteAsync(message.SystemProperties.LockToken); _telemetryClient.TrackEvent( "Proactive message sent by bot.", logProperties, new Dictionary <string, double> { { "Proactive message", 1 }, { $"Proactive{GetType().Name}", 1 }, }); }