Initial config support of proactive for WebAPI
This commit is contained in:
Родитель
87ceda1c5c
Коммит
69d849cff7
|
@ -2,10 +2,12 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Bot.Builder.Adapters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Integration.AspNet.Core
|
||||
{
|
||||
|
@ -47,7 +49,7 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.Core
|
|||
}
|
||||
|
||||
applicationBuilder.Map(
|
||||
paths.BasePath + paths.ActivitiesPath,,
|
||||
paths.BasePath + paths.ActivitiesPath,
|
||||
botActivitiesAppBuilder => botActivitiesAppBuilder.Run(new BotActivitiesHandler(botFrameworkAdapter).HandleAsync));
|
||||
|
||||
return applicationBuilder;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Middleware;
|
||||
using System;
|
||||
using Microsoft.Bot.Connector.Authentication;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
||||
|
@ -10,9 +11,9 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
{
|
||||
private BotFrameworkOptions _options;
|
||||
|
||||
public BotFrameworkConfigurationBuilder()
|
||||
public BotFrameworkConfigurationBuilder(BotFrameworkOptions botFrameworkOptions)
|
||||
{
|
||||
_options = new BotFrameworkOptions();
|
||||
_options = botFrameworkOptions;
|
||||
}
|
||||
|
||||
public BotFrameworkOptions BotFrameworkOptions { get => _options; }
|
||||
|
@ -33,5 +34,25 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
|
||||
return this;
|
||||
}
|
||||
|
||||
public BotFrameworkConfigurationBuilder EnableProactiveMessages(string proactiveMessagesPath = default(string))
|
||||
{
|
||||
_options.EnableProactiveMessages = true;
|
||||
|
||||
if (proactiveMessagesPath != null)
|
||||
|
||||
{
|
||||
_options.Paths.ProactiveMessagesPath = proactiveMessagesPath;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public BotFrameworkConfigurationBuilder UsePaths(Action<BotFrameworkPaths> configurePaths)
|
||||
{
|
||||
configurePaths(_options.Paths);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,15 +10,17 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
public class BotFrameworkOptions
|
||||
{
|
||||
private readonly List<IMiddleware> _middleware;
|
||||
private readonly BotFrameworkPaths _paths;
|
||||
|
||||
public BotFrameworkOptions()
|
||||
{
|
||||
RouteBaseUrl = "api/";
|
||||
_middleware = new List<IMiddleware>();
|
||||
_paths = new BotFrameworkPaths();
|
||||
}
|
||||
|
||||
public string RouteBaseUrl { get; set; }
|
||||
public ICredentialProvider CredentialProvider { get; set; }
|
||||
public List<IMiddleware> Middleware { get => _middleware; }
|
||||
public bool EnableProactiveMessages { get; set; }
|
||||
public BotFrameworkPaths Paths { get => _paths; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
||||
{
|
||||
public class BotFrameworkPaths
|
||||
{
|
||||
public BotFrameworkPaths()
|
||||
{
|
||||
this.BasePath = "api/";
|
||||
this.MessagesPath = "messages";
|
||||
this.ProactiveMessagesPath = "messages/proactive";
|
||||
}
|
||||
|
||||
public string BasePath { get; set; }
|
||||
public string MessagesPath { get; set; }
|
||||
public string ProactiveMessagesPath { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Adapters;
|
||||
using Microsoft.Bot.Schema;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi.Handlers
|
||||
{
|
||||
internal sealed class BotMessageHandler : BotMessageHandlerBase
|
||||
{
|
||||
public BotMessageHandler(BotFrameworkAdapter botFrameworkAdapter) : base(botFrameworkAdapter)
|
||||
{
|
||||
}
|
||||
|
||||
protected override async Task ProcessMessageRequestAsync(HttpRequestMessage request, BotFrameworkAdapter botFrameworkAdapter, Func<IBotContext, Task> botCallbackHandler, CancellationToken cancellationToken)
|
||||
{
|
||||
var activity = await request.Content.ReadAsAsync<Activity>(BotMessageHandlerBase.BotMessageMediaTypeFormatters, cancellationToken);
|
||||
|
||||
await botFrameworkAdapter.ProcessActivity(
|
||||
request.Headers.Authorization?.Parameter,
|
||||
activity,
|
||||
botCallbackHandler);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Adapters;
|
||||
using Microsoft.Bot.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
|
@ -12,11 +11,11 @@ using System.Net.Http.Formatting;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
||||
namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi.Handlers
|
||||
{
|
||||
internal sealed class BotActivitiesHandler : HttpMessageHandler
|
||||
public abstract class BotMessageHandlerBase : HttpMessageHandler
|
||||
{
|
||||
private static readonly MediaTypeFormatter[] BotActivityMediaTypeFormatters = new [] {
|
||||
public static readonly MediaTypeFormatter[] BotMessageMediaTypeFormatters = new [] {
|
||||
new JsonMediaTypeFormatter
|
||||
{
|
||||
SerializerSettings =
|
||||
|
@ -30,7 +29,7 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
|
||||
private readonly BotFrameworkAdapter _botFrameworkAdapter;
|
||||
|
||||
public BotActivitiesHandler(BotFrameworkAdapter botFrameworkAdapter)
|
||||
public BotMessageHandlerBase(BotFrameworkAdapter botFrameworkAdapter)
|
||||
{
|
||||
_botFrameworkAdapter = botFrameworkAdapter;
|
||||
}
|
||||
|
@ -42,26 +41,23 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
return request.CreateResponse(HttpStatusCode.MethodNotAllowed);
|
||||
}
|
||||
|
||||
var requestContent = request.Content;
|
||||
var requestContentHeaders = requestContent.Headers;
|
||||
var requestContentHeaders = request.Content.Headers;
|
||||
|
||||
if (requestContentHeaders.ContentLength == 0)
|
||||
{
|
||||
return request.CreateErrorResponse(HttpStatusCode.BadRequest, "Request body should not be empty.");
|
||||
}
|
||||
|
||||
if (!BotActivityMediaTypeFormatters[0].SupportedMediaTypes.Contains(requestContentHeaders.ContentType))
|
||||
if (!BotMessageMediaTypeFormatters[0].SupportedMediaTypes.Contains(requestContentHeaders.ContentType))
|
||||
{
|
||||
return request.CreateErrorResponse(HttpStatusCode.NotAcceptable, $"Expecting Content-Type of \"{BotActivityMediaTypeFormatters[0].SupportedMediaTypes[0].MediaType}\".");
|
||||
return request.CreateErrorResponse(HttpStatusCode.NotAcceptable, $"Expecting Content-Type of \"{BotMessageMediaTypeFormatters[0].SupportedMediaTypes[0].MediaType}\".");
|
||||
}
|
||||
|
||||
var activity = await requestContent.ReadAsAsync<Activity>(BotActivitiesHandler.BotActivityMediaTypeFormatters, cancellationToken);
|
||||
|
||||
try
|
||||
{
|
||||
await _botFrameworkAdapter.ProcessActivity(
|
||||
request.Headers.Authorization?.Parameter,
|
||||
activity,
|
||||
await ProcessMessageRequestAsync(
|
||||
request,
|
||||
_botFrameworkAdapter,
|
||||
botContext =>
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
@ -77,13 +73,14 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
bot = null;
|
||||
}
|
||||
|
||||
if(bot == null)
|
||||
if (bot == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Did not find an {typeof(IBot).Name} service via the dependency resolver. Please make sure you have registered your bot with your dependency injection container.");
|
||||
}
|
||||
|
||||
return bot.OnReceiveActivity(botContext);
|
||||
});
|
||||
},
|
||||
cancellationToken);
|
||||
|
||||
return request.CreateResponse(HttpStatusCode.OK);
|
||||
}
|
||||
|
@ -96,5 +93,7 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
return request.CreateErrorResponse(HttpStatusCode.NotFound, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Task ProcessMessageRequestAsync(HttpRequestMessage request, BotFrameworkAdapter botFrameworkAdapter, Func<IBotContext, Task> botCallbackHandler, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Adapters;
|
||||
using Microsoft.Bot.Schema;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi.Handlers
|
||||
{
|
||||
public sealed class BotProactiveMessageHandler : BotMessageHandlerBase
|
||||
{
|
||||
public BotProactiveMessageHandler(BotFrameworkAdapter botFrameworkAdapter) : base(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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.Bot.Builder.Adapters;
|
||||
using Microsoft.Bot.Builder.Integration.AspNet.WebApi.Handlers;
|
||||
using System;
|
||||
using System.Web.Http;
|
||||
|
||||
|
@ -11,13 +12,12 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
{
|
||||
public static HttpConfiguration MapBotFramework(this HttpConfiguration httpConfiguration, Action<BotFrameworkConfigurationBuilder> configurer)
|
||||
{
|
||||
var optionsBuilder = new BotFrameworkConfigurationBuilder();
|
||||
var options = new BotFrameworkOptions();
|
||||
var optionsBuilder = new BotFrameworkConfigurationBuilder(options);
|
||||
|
||||
configurer(optionsBuilder);
|
||||
|
||||
var options = optionsBuilder.BotFrameworkOptions;
|
||||
|
||||
ConfigureBotRoute(BuildAdapter());
|
||||
ConfigureBotRoutes(BuildAdapter());
|
||||
|
||||
return httpConfiguration;
|
||||
|
||||
|
@ -33,23 +33,32 @@ namespace Microsoft.Bot.Builder.Integration.AspNet.WebApi
|
|||
return adapter;
|
||||
}
|
||||
|
||||
void ConfigureBotRoute(BotFrameworkAdapter adapter)
|
||||
void ConfigureBotRoutes(BotFrameworkAdapter adapter)
|
||||
{
|
||||
var botActivitiesRouteUrl = options.RouteBaseUrl;
|
||||
var routes = httpConfiguration.Routes;
|
||||
var baseUrl = options.Paths.BasePath;
|
||||
|
||||
if (!botActivitiesRouteUrl.EndsWith("/"))
|
||||
if (!baseUrl.EndsWith("/"))
|
||||
{
|
||||
botActivitiesRouteUrl += "/";
|
||||
baseUrl += "/";
|
||||
}
|
||||
|
||||
botActivitiesRouteUrl += "messages";
|
||||
|
||||
httpConfiguration.Routes.MapHttpRoute(
|
||||
"BotFrameworkV4 Activities Controller",
|
||||
botActivitiesRouteUrl,
|
||||
if (options.EnableProactiveMessages)
|
||||
{
|
||||
routes.MapHttpRoute(
|
||||
"BotFramework - Proactive Message Handler",
|
||||
baseUrl + options.Paths.ProactiveMessagesPath,
|
||||
defaults: null,
|
||||
constraints: null,
|
||||
handler: new BotActivitiesHandler(adapter));
|
||||
handler: new BotProactiveMessageHandler(adapter));
|
||||
}
|
||||
|
||||
routes.MapHttpRoute(
|
||||
"BotFramework - Message Handler",
|
||||
baseUrl + options.Paths.MessagesPath,
|
||||
defaults: null,
|
||||
constraints: null,
|
||||
handler: new BotMessageHandler(adapter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Microsoft.Bot.Samples.EchoBot_AspNet461
|
|||
{
|
||||
botConfig
|
||||
.UseMicrosoftApplicationIdentity(ConfigurationManager.AppSettings["BotFramework.MicrosoftApplicationId"], ConfigurationManager.AppSettings["BotFramework.MicrosoftApplicationPassword"])
|
||||
.EnableProactiveMessages()
|
||||
.UseMiddleware(new ConversationState<EchoState>(new MemoryStorage()));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ namespace Microsoft.Bot.Samples.EchoBot_AspNet461
|
|||
{
|
||||
GlobalConfiguration.Configure(config =>
|
||||
{
|
||||
WebApiConfig.Register(config);
|
||||
BotConfig.Register(config);
|
||||
WebApiConfig.Register(config);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче