-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1314 from Microsoft/kaiqb-welcomebot
Welcome User Bot
- Loading branch information
Showing
10 changed files
with
200 additions
and
330 deletions.
There are no files selected for viewing
42 changes: 42 additions & 0 deletions
42
samples/csharp_dotnetcore/03.welcome-user/AdapterWithErrorHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using Microsoft.Bot.Builder; | ||
using Microsoft.Bot.Builder.Integration.AspNet.Core; | ||
using Microsoft.Bot.Connector.Authentication; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Microsoft.BotBuilderSamples | ||
{ | ||
public class AdapterWithErrorHandler : BotFrameworkHttpAdapter | ||
{ | ||
public AdapterWithErrorHandler(ICredentialProvider credentialProvider, ILogger<BotFrameworkHttpAdapter> logger, ConversationState conversationState = null) | ||
: base(credentialProvider) | ||
{ | ||
OnTurnError = async (turnContext, exception) => | ||
{ | ||
// Log any leaked exception from the application. | ||
logger.LogError($"Exception caught : {exception.Message}"); | ||
|
||
// Send a catch-all appology to the user. | ||
await turnContext.SendActivityAsync("Sorry, it looks like something went wrong."); | ||
|
||
if (conversationState != null) | ||
{ | ||
try | ||
{ | ||
// Delete the conversationState for the current conversation to prevent the | ||
// bot from getting stuck in a error-loop caused by being in a bad state. | ||
// ConversationState should be thought of as similar to "cookie-state" in a Web pages. | ||
await conversationState.DeleteAsync(turnContext); | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.LogError($"Exception caught on attempting to Delete ConversationState : {e.Message}"); | ||
} | ||
} | ||
}; | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
samples/csharp_dotnetcore/03.welcome-user/ConfigurationCredentialProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using Microsoft.Bot.Connector.Authentication; | ||
using Microsoft.Extensions.Configuration; | ||
|
||
namespace Microsoft.BotBuilderSamples | ||
{ | ||
public class ConfigurationCredentialProvider : SimpleCredentialProvider | ||
{ | ||
public ConfigurationCredentialProvider(IConfiguration configuration) | ||
: base(configuration["MicrosoftAppId"], configuration["MicrosoftAppPassword"]) | ||
{ | ||
} | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
samples/csharp_dotnetcore/03.welcome-user/Controllers/BotController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.Bot.Builder; | ||
using Microsoft.Bot.Builder.Integration.AspNet.Core; | ||
|
||
namespace Microsoft.BotBuilderSamples | ||
{ | ||
// This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot | ||
// implementation at runtime. Multiple different IBot implementations running at different endpoints can be | ||
// achieved by specifying a more specific type for the bot constructor argument. | ||
[Route("api/messages")] | ||
[ApiController] | ||
public class BotController : ControllerBase | ||
{ | ||
private readonly IBotFrameworkHttpAdapter _adapter; | ||
private readonly IBot _bot; | ||
|
||
public BotController(IBotFrameworkHttpAdapter adapter, IBot bot) | ||
{ | ||
_adapter = adapter; | ||
_bot = bot; | ||
} | ||
|
||
[HttpPost] | ||
public async Task PostAsync() | ||
{ | ||
// Delegate the processing of the HTTP POST to the adapter. | ||
// The adapter will invoke the bot. | ||
await _adapter.ProcessAsync(Request, Response, _bot); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,154 +1,58 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Collections.Concurrent; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.Bot.Builder; | ||
using Microsoft.Bot.Builder.Integration; | ||
using Microsoft.Bot.Builder.Integration.AspNet.Core; | ||
using Microsoft.Bot.Configuration; | ||
using Microsoft.Bot.Connector.Authentication; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Bot.Schema; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace Microsoft.BotBuilderSamples | ||
{ | ||
/// <summary> | ||
/// The Startup class configures services and the app's request pipeline. | ||
/// </summary> | ||
public class Startup | ||
{ | ||
private ILoggerFactory _loggerFactory; | ||
private bool _isProduction = false; | ||
|
||
public Startup(IHostingEnvironment env) | ||
{ | ||
_isProduction = env.IsProduction(); | ||
|
||
var builder = new ConfigurationBuilder() | ||
.SetBasePath(env.ContentRootPath) | ||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) | ||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) | ||
.AddEnvironmentVariables(); | ||
|
||
Configuration = builder.Build(); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the configuration that represents a set of key/value application configuration properties. | ||
/// </summary> | ||
/// <value> | ||
/// The <see cref="IConfiguration"/> that represents a set of key/value application configuration properties. | ||
/// </value> | ||
public IConfiguration Configuration { get; } | ||
|
||
/// <summary> | ||
/// This method gets called by the runtime. Use this method to add services to the container. | ||
/// </summary> | ||
/// <param name="services">Specifies the contract for a <see cref="IServiceCollection"/> of service descriptors.</param> | ||
/// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/> | ||
/// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/> | ||
// This method gets called by the runtime. Use this method to add services to the container. | ||
public void ConfigureServices(IServiceCollection services) | ||
{ | ||
services.AddBot<WelcomeUserBot>(options => | ||
{ | ||
var secretKey = Configuration.GetSection("botFileSecret")?.Value; | ||
var botFilePath = Configuration.GetSection("botFilePath")?.Value; | ||
if (!File.Exists(botFilePath)) | ||
{ | ||
throw new FileNotFoundException($"The .bot configuration file was not found. botFilePath: {botFilePath}"); | ||
} | ||
// Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. | ||
var botConfig = BotConfiguration.Load(botFilePath ?? @".\welcome-user.bot", secretKey); | ||
services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. botFilePath: {botFilePath}")); | ||
|
||
// Retrieve current endpoint. | ||
var environment = _isProduction ? "production" : "development"; | ||
var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment); | ||
if (!(service is EndpointService endpointService)) | ||
{ | ||
throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); | ||
} | ||
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); | ||
|
||
options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); | ||
// Create the credential provider to be used with the Bot Framework Adapter. | ||
services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>(); | ||
|
||
// Creates a logger for the application to use. | ||
ILogger logger = _loggerFactory.CreateLogger<WelcomeUserBot>(); | ||
// Create the Bot Framework Adapter with error handling enabled. | ||
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>(); | ||
|
||
// Catches any errors that occur during a conversation turn and logs them. | ||
options.OnTurnError = async (context, exception) => | ||
{ | ||
logger.LogError($"Exception caught : {exception}"); | ||
await context.SendActivityAsync("Sorry, it looks like something went wrong."); | ||
}; | ||
// Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.) | ||
services.AddSingleton<IStorage, MemoryStorage>(); | ||
|
||
// The Memory Storage used here is for local bot debugging only. When the bot | ||
// is restarted, anything stored in memory will be gone. | ||
IStorage dataStore = new MemoryStorage(); | ||
// Create the User state. | ||
services.AddSingleton<UserState>(); | ||
|
||
// For production bots use the Azure Blob or | ||
// Azure CosmosDB storage providers. For the Azure | ||
// based storage providers, add the Microsoft.Bot.Builder.Azure | ||
// Nuget package to your solution. That package is found at: | ||
// https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/ | ||
// Uncomment the following lines to use Azure Blob Storage | ||
// //Storage configuration name or ID from the .bot file. | ||
// const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>"; | ||
// var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId); | ||
// if (!(blobConfig is BlobStorageService blobStorageConfig)) | ||
// { | ||
// throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'."); | ||
// } | ||
// // Default container name. | ||
// const string DefaultBotContainer = "<DEFAULT-CONTAINER>"; | ||
// var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container; | ||
// IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer); | ||
|
||
// Create Conversation State object. | ||
// The Conversation State object is where we persist anything at the conversation-scope. | ||
var userState = new UserState(dataStore); | ||
options.State.Add(userState); | ||
}); | ||
|
||
// Create and register state accessors. | ||
// Accessors created here are passed into the IBot-derived class on every turn. | ||
services.AddSingleton<WelcomeUserStateAccessors>(sp => | ||
{ | ||
var options = sp.GetRequiredService<IOptions<BotFrameworkOptions>>().Value; | ||
if (options == null) | ||
{ | ||
throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the State Accessors"); | ||
} | ||
|
||
var userState = options.State.OfType<UserState>().FirstOrDefault(); | ||
if (userState == null) | ||
{ | ||
throw new InvalidOperationException("UserState must be defined and added before adding user-scoped state accessors."); | ||
} | ||
|
||
// Create the custom state accessor. | ||
// State accessors enable other components to read and write individual properties of state. | ||
var accessors = new WelcomeUserStateAccessors(userState) | ||
{ | ||
WelcomeUserState = userState.CreateProperty<WelcomeUserState>(WelcomeUserStateAccessors.WelcomeUserName), | ||
}; | ||
|
||
return accessors; | ||
}); | ||
// Create the bot as a transient. In this case the ASP Controller is expecting an IBot. | ||
services.AddTransient<IBot, WelcomeUserBot>(); | ||
} | ||
|
||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) | ||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | ||
public void Configure(IApplicationBuilder app, IHostingEnvironment env) | ||
{ | ||
_loggerFactory = loggerFactory; | ||
if (env.IsDevelopment()) | ||
{ | ||
app.UseDeveloperExceptionPage(); | ||
} | ||
else | ||
{ | ||
app.UseHsts(); | ||
} | ||
|
||
app.UseDefaultFiles(); | ||
app.UseStaticFiles(); | ||
|
||
app.UseDefaultFiles() | ||
.UseStaticFiles() | ||
.UseBotFramework(); | ||
//app.UseHttpsRedirection(); | ||
app.UseMvc(); | ||
} | ||
} | ||
} |
24 changes: 5 additions & 19 deletions
24
samples/csharp_dotnetcore/03.welcome-user/WelcomeUser.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp2.0</TargetFramework> | ||
<TargetFramework>netcoreapp2.1</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup> | ||
<CodeAnalysisRuleSet></CodeAnalysisRuleSet> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" /> | ||
<PackageReference Include="Microsoft.Bot.Builder" Version="4.2.2" /> | ||
<PackageReference Include="Microsoft.Bot.Builder.Dialogs" Version="4.2.2" /> | ||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Version="4.2.2" /> | ||
<PackageReference Include="AsyncUsageAnalyzers" Version="1.0.0-alpha003" PrivateAssets="all" /> | ||
<PackageReference Include="Microsoft.Bot.Configuration" Version="4.2.2" /> | ||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta008" PrivateAssets="all" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="*.bot"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</None> | ||
<PackageReference Include="Microsoft.AspNetCore.App" /> | ||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" /> | ||
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Version="4.3.1" /> | ||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Oops, something went wrong.