protected abstract Task <InvokeResponse> ProcessMessageRequestAsync(HttpRequestMessage request, BotFrameworkAdapter botFrameworkAdapter, Func <ITurnContext, Task> botCallbackHandler, CancellationToken cancellationToken);
 public BotMessageHandlerBase(BotFrameworkAdapter botFrameworkAdapter)
 {
     _botFrameworkAdapter = botFrameworkAdapter;
 }
        protected override async Task ProcessMessageRequestAsync(HttpRequestMessage request, BotFrameworkAdapter botFrameworkAdapter, Func <IBotContext, Task> botCallbackHandler, CancellationToken cancellationToken)
        {
            var conversationReference = await request.Content.ReadAsAsync <ConversationReference>(BotMessageHandlerBase.BotMessageMediaTypeFormatters, cancellationToken);

            await botFrameworkAdapter.ContinueConversation(conversationReference, botCallbackHandler);
        }
 public BotMessageHandlerBase(BotFrameworkAdapter botFrameworkAdapter)
 {
     _botFrameworkAdapter = botFrameworkAdapter ?? throw new ArgumentNullException(nameof(botFrameworkAdapter));
 }
Example #5
0
        protected override async Task <InvokeResponse> ProcessMessageRequestAsync(HttpRequestMessage request, BotFrameworkAdapter botFrameworkAdapter, Func <ITurnContext, Task> botCallbackHandler, CancellationToken cancellationToken)
        {
            var activity = await request.Content.ReadAsAsync <Activity>(BotMessageHandlerBase.BotMessageMediaTypeFormatters, cancellationToken);

            var invokeResponse = await botFrameworkAdapter.ProcessActivityAsync(
                request.Headers.Authorization?.ToString(),
                activity,
                botCallbackHandler,
                cancellationToken);

            return(invokeResponse);
        }
 public BotProactiveMessageHandler(BotFrameworkAdapter botFrameworkAdapter) : base(botFrameworkAdapter)
 {
 }
Example #7
0
        public async Task CreateConversationOverloadProperlySetsTenantId()
        {
            // Arrange
            const string activityIdName      = "ActivityId";
            const string activityIdValue     = "SendActivityId";
            const string conversationIdName  = "Id";
            const string conversationIdValue = "NewConversationId";
            const string tenantIdValue       = "theTenantId";
            const string eventActivityName   = ActivityEventNames.CreateConversation;

            Task <HttpResponseMessage> CreateResponseMessage()
            {
                var response = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(new JObject
                    {
                        { activityIdName, activityIdValue },
                        { conversationIdName, conversationIdValue }
                    }.ToString())
                };

                return(Task.FromResult(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.Equal(tenantIdValue, JObject.FromObject(newActivity.ChannelData)["tenant"]["tenantId"]);
            Assert.Equal(activityIdValue, newActivity.Id);
            Assert.Equal(conversationIdValue, newActivity.Conversation.Id);
            Assert.Equal(tenantIdValue, newActivity.Conversation.TenantId);
            Assert.Equal(eventActivityName, newActivity.Name);
        }
        protected override async Task ProcessMessageRequestAsync(HttpRequest request, BotFrameworkAdapter botFrameworkAdapter, Func <ITurnContext, Task> botCallbackHandler)
        {
            var activity = default(Activity);

            using (var bodyReader = new JsonTextReader(new StreamReader(request.Body, Encoding.UTF8)))
            {
                activity = BotMessageHandlerBase.BotMessageSerializer.Deserialize <Activity>(bodyReader);
            }

            await botFrameworkAdapter.ProcessActivity(
                request.Headers["Authorization"],
                activity,
                botCallbackHandler);
        }
Example #9
0
        public async Task ContinueConversationAsyncWithAudience()
        {
            // Arrange
            var mockCredentialProvider = new Mock <ICredentialProvider>();
            var mockHttpMessageHandler = new Mock <HttpMessageHandler>();
            var httpClient             = new HttpClient(mockHttpMessageHandler.Object);
            var adapter = new BotFrameworkAdapter(mockCredentialProvider.Object, customHttpClient: httpClient);

            // Create ClaimsIdentity that represents Skill2-to-Skill1 communication
            var skill2AppId = "00000000-0000-0000-0000-000000skill2";
            var skill1AppId = "00000000-0000-0000-0000-000000skill1";

            var skillClaims = new List <Claim>
            {
                new Claim(AuthenticationConstants.AudienceClaim, skill1AppId),
                new Claim(AuthenticationConstants.AppIdClaim, skill2AppId),
                new Claim(AuthenticationConstants.VersionClaim, "1.0")
            };
            var skillsIdentity   = new ClaimsIdentity(skillClaims);
            var skill2ServiceUrl = "https://continuetest.skill2.com/api/skills/";

            // Skill1 is calling ContinueSkillConversationAsync() to proactively send an Activity to Skill 2
            var callback = new BotCallbackHandler((turnContext, ct) =>
            {
                GetAppCredentialsAndAssertValues(turnContext, skill1AppId, skill2AppId, 1);
                GetConnectorClientsAndAssertValues(
                    turnContext,
                    skill1AppId,
                    skill2AppId,
                    new Uri(skill2ServiceUrl),
                    1);

                // Get "skill1-to-skill2" ConnectorClient off of TurnState
                var contextAdapter = turnContext.Adapter as BotFrameworkAdapter;
                var clientCache    = GetCache <ConcurrentDictionary <string, ConnectorClient> >(contextAdapter, ConnectorClientsCacheName);
                clientCache.TryGetValue($"{skill2ServiceUrl}{skill1AppId}:{skill2AppId}", out var client);

                var turnStateClient = turnContext.TurnState.Get <IConnectorClient>();
                var clientCreds     = turnStateClient.Credentials as AppCredentials;

                Assert.Equal(skill1AppId, clientCreds.MicrosoftAppId);
                Assert.Equal(skill2AppId, clientCreds.OAuthScope);
                Assert.Equal(client.BaseUri, turnStateClient.BaseUri);

                var scope = turnContext.TurnState.Get <string>(BotAdapter.OAuthScopeKey);
                Assert.Equal(skill2AppId, scope);

                // Ensure the serviceUrl was added to the trusted hosts
                Assert.True(AppCredentials.TrustedHostNames.ContainsKey(new Uri(skill2ServiceUrl).Host));

                return(Task.CompletedTask);
            });

            // Create ConversationReference to send a proactive message from Skill1 to Skill2
            var refs = new ConversationReference(serviceUrl: skill2ServiceUrl);

            // Ensure the serviceUrl is NOT in the trusted hosts
            Assert.False(AppCredentials.TrustedHostNames.ContainsKey(new Uri(skill2ServiceUrl).Host));

            await adapter.ContinueConversationAsync(skillsIdentity, refs, skill2AppId, callback, default);
        }
Example #10
0
        public async Task ProcessContinueConversationEvent()
        {
            var mockCredentialProvider = new Mock <ICredentialProvider>();
            var mockHttpMessageHandler = new Mock <HttpMessageHandler>();
            var httpClient             = new HttpClient(mockHttpMessageHandler.Object);
            var adapter = new BotFrameworkAdapter(mockCredentialProvider.Object, customHttpClient: httpClient);

            var cr = new ConversationReference
            {
                ActivityId = "activityId",
                Bot        = new ChannelAccount
                {
                    Id   = "channelId",
                    Name = "testChannelAccount",
                    Role = "bot",
                },
                ChannelId    = "testChannel",
                ServiceUrl   = "https://fake.service.url",
                Conversation = new ConversationAccount
                {
                    ConversationType = string.Empty,
                    Id      = "testConversationId",
                    IsGroup = false,
                    Name    = "testConversationName",
                    Role    = "user",
                },
                User = new ChannelAccount
                {
                    Id   = "channelId",
                    Name = "testChannelAccount",
                    Role = "bot",
                },
            };

            var activity = cr.GetContinuationActivity();

            activity.Value = "test";

            // Create ClaimsIdentity that represents Skill1-to-Skill1 communication
            var appId = "00000000-0000-0000-0000-000000skill1";

            var claims = new List <Claim>
            {
                new Claim(AuthenticationConstants.AudienceClaim, appId),
                new Claim(AuthenticationConstants.AppIdClaim, appId),
                new Claim(AuthenticationConstants.VersionClaim, "1.0")
            };
            var identity = new ClaimsIdentity(claims);

            var callback = new BotCallbackHandler((turnContext, ct) =>
            {
                var cr2        = turnContext.Activity.GetConversationReference();
                cr.ActivityId  = null; // activityIds will be different...
                cr2.ActivityId = null;
                Assert.Equal(JsonConvert.SerializeObject(cr), JsonConvert.SerializeObject(cr2));
                Assert.Equal("test", (string)turnContext.Activity.Value);

                return(Task.CompletedTask);
            });

            await adapter.ProcessActivityAsync(identity, (Activity)activity, callback, default);
 public BotController(Builder.Bot bot)
 {
     _adapter = (BotFrameworkAdapter)bot.Adapter;
     bot.OnReceive(BotReceiveHandler);
 }
        protected override async Task <InvokeResponse> ProcessMessageRequestAsync(HttpRequest request, BotFrameworkAdapter botFrameworkAdapter, Func <ITurnContext, Task> botCallbackHandler)
        {
            const string BotAppIdHttpHeaderName        = "MS-BotFramework-BotAppId";
            const string BotIdQueryStringParameterName = "BotAppId";

            if (!request.Headers.TryGetValue(BotAppIdHttpHeaderName, out var botAppIdHeaders))
            {
                if (!request.Query.TryGetValue(BotIdQueryStringParameterName, out botAppIdHeaders))
                {
                    throw new InvalidOperationException($"Expected a Bot App ID in a header named \"{BotAppIdHttpHeaderName}\" or in a querystring parameter named \"{BotIdQueryStringParameterName}\".");
                }
            }

            var botAppId = botAppIdHeaders.First();
            var conversationReference = default(ConversationReference);

            using (var bodyReader = new JsonTextReader(new StreamReader(request.Body, Encoding.UTF8)))
            {
                conversationReference = BotMessageHandlerBase.BotMessageSerializer.Deserialize <ConversationReference>(bodyReader);
            }

            await botFrameworkAdapter.ContinueConversation(botAppId, conversationReference, botCallbackHandler);

            return(null);
        }
        protected override async Task <InvokeResponse> ProcessMessageRequestAsync(HttpRequestMessage request, BotFrameworkAdapter botFrameworkAdapter, Func <ITurnContext, Task> botCallbackHandler, CancellationToken cancellationToken)
        {
            const string BotAppIdHttpHeaderName           = "MS-BotFramework-BotAppId";
            const string BotAppIdQueryStringParameterName = "BotAppId";

            var botAppId = default(string);

            if (request.Headers.TryGetValues(BotAppIdHttpHeaderName, out var botIdHeaders))
            {
                botAppId = botIdHeaders.FirstOrDefault();
            }
            else
            {
                botAppId = request.GetQueryNameValuePairs()
                           .Where(kvp => kvp.Key == BotAppIdQueryStringParameterName)
                           .Select(kvp => kvp.Value)
                           .FirstOrDefault();
            }

            if (string.IsNullOrEmpty(botAppId))
            {
                throw new InvalidOperationException($"Expected a Bot App ID in a header named \"{BotAppIdHttpHeaderName}\" or in a querystring parameter named \"{BotAppIdQueryStringParameterName}\".");
            }

            var conversationReference = await request.Content.ReadAsAsync <ConversationReference>(BotMessageHandlerBase.BotMessageMediaTypeFormatters, cancellationToken);

            await botFrameworkAdapter.ContinueConversation(botAppId, conversationReference, botCallbackHandler);

            return(null);
        }
 public MessagesController(BotFrameworkAdapter adapter) : base(adapter)
 {
 }
 public BotActivitiesHandler(BotFrameworkAdapter botFrameworkAdapter)
 {
     _botFrameworkAdapter = botFrameworkAdapter;
 }
        private static void ConfigureBotRoutes(HttpConfiguration httpConfiguration, BotFrameworkOptions options, BotFrameworkAdapter adapter)
        {
            var routes  = httpConfiguration.Routes;
            var baseUrl = options.Paths.BasePath;

            routes.MapHttpRoute(
                BotMessageHandler.RouteName,
                baseUrl.Trim('/') + "/" + options.Paths.MessagesPath.Trim('/'),
                defaults: null,
                constraints: null,
                handler: new BotMessageHandler(adapter));
        }
        public static IApplicationBuilder UseBotFramework(this IApplicationBuilder applicationBuilder)
        {
            var options = applicationBuilder.ApplicationServices.GetRequiredService <IOptions <BotFrameworkOptions> >().Value;

            var botFrameworkAdapter = new BotFrameworkAdapter(options.ApplicationId, options.ApplicationPassword);

            foreach (var middleware in options.Middleware)
            {
                botFrameworkAdapter.Use(middleware);
            }

            var botActivitiesPath = new PathString(options.RouteBaseUrl);

            botActivitiesPath.Add("/activities");

            applicationBuilder.Map(
                botActivitiesPath,
                botActivitiesAppBuilder => botActivitiesAppBuilder.Run(BotRequestHandler));

            return(applicationBuilder);

            async Task BotRequestHandler(HttpContext httpContext)
            {
                var request  = httpContext.Request;
                var response = httpContext.Response;

                if (request.Method != HttpMethods.Post)
                {
                    response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;

                    return;
                }

                if (request.ContentType != "application/json")
                {
                    response.StatusCode = (int)HttpStatusCode.NotAcceptable;

                    return;
                }

                if (request.ContentLength == 0)
                {
                    response.StatusCode = (int)HttpStatusCode.BadRequest;

                    return;
                }

                var activity = default(Activity);

                using (var bodyReader = new JsonTextReader(new StreamReader(request.Body, Encoding.UTF8)))
                {
                    activity = ActivitySerializer.Deserialize <Activity>(bodyReader);
                }

                try
                {
                    await botFrameworkAdapter.ProcessActivity(
                        request.Headers["Authorization"],
                        activity,
                        botContext =>
                    {
                        var bot = httpContext.RequestServices.GetRequiredService <IBot>();

                        return(bot.OnReceiveActivity(botContext));
                    });

                    response.StatusCode = (int)HttpStatusCode.OK;
                }
                catch (UnauthorizedAccessException)
                {
                    response.StatusCode = (int)HttpStatusCode.Forbidden;
                }
            }
        }