コード例 #1
0
        public TestBotHttpAdapter(
            ICredentialProvider credentialProvider,
            IConfiguration configuration,
            ILogger <BotFrameworkHttpAdapter> logger,
            IStorage storage,
            UserState userState,
            ConversationState conversationState,
            ResourceExplorer resourceExplorer)
            : base(configuration, credentialProvider)
        {
            this.Use(new RegisterClassMiddleware <IConfiguration>(configuration));
            this.UseStorage(storage);
            this.UseBotState(userState, conversationState);
            this.Use(new SetTestOptionsMiddleware());
            this.UseDebugger(configuration.GetValue("debugport", 4712), logger: logger);

            resourceExplorer.RegisterType <MultiplyDialog>("Testbot.Multiply");
            resourceExplorer.RegisterType <JavascriptAction>("Testbot.JavascriptAction");

            // this.UseDebugger(configuration.GetValue<int>("debugport", 4712), events: new Events<AdaptiveEvents>());

            this.OnTurnError = async(turnContext, exception) =>
            {
                // Log any leaked exception from the application.
                logger.LogError($"Exception caught : {exception.Message}");

                // Send a catch-all apology to the user.
                await turnContext.SendActivityAsync("Sorry, it looks like something went wrong.");

                await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);

                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).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        logger.LogError($"Exception caught on attempting to Delete ConversationState : {e.Message}");
                    }
                }
            };
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: amyngb/HikingClimbingBot
        public static async Task Main(string[] args)
        {
            var root        = ".";
            var region      = "westus";
            var environment = Environment.UserName;

            for (var i = 0; i < args.Length; ++i)
            {
                var arg = args[i];
                switch (arg)
                {
                case "--root": root = NextArg(ref i, args); break;

                case "--region": region = NextArg(ref i, args); break;

                case "--environment": environment = NextArg(ref i, args); break;

                default: Usage(); break;
                }
            }

            ComponentRegistration.Add(new DeclarativeComponentRegistration());
            ComponentRegistration.Add(new AdaptiveComponentRegistration());
            ComponentRegistration.Add(new LanguageGenerationComponentRegistration());
            ComponentRegistration.Add(new AdaptiveTestingComponentRegistration());
            ComponentRegistration.Add(new LuisComponentRegistration());
            ComponentRegistration.Add(new QnAMakerComponentRegistration());

            var config = new ConfigurationBuilder()
                         .AddInMemoryCollection(new Dictionary <string, string> {
                { "root", root }, { "region", region }, { "environment", environment }
            })
                         .UseMockLuisSettings(root, root)
                         .AddUserSecrets("RunBot")
                         .Build();
            var resourceExplorer = new ResourceExplorer().AddFolder(root, monitorChanges: false);

            resourceExplorer.RegisterType(LuisAdaptiveRecognizer.Kind, typeof(MockLuisRecognizer), new MockLuisLoader(config));

            var dialogs = resourceExplorer.GetResources(".dialog").ToList();

            foreach (var test in resourceExplorer.GetResources(".dialog").Where(r => r.Id.EndsWith(".test.dialog")))
            {
                try
                {
                    Console.WriteLine($"Running test {test.Id}");
                    var script = resourceExplorer.LoadType <TestScript>(test.Id);
                    script.Configuration = config;
                    script.Description ??= test.Id;
                    await script.ExecuteAsync(resourceExplorer, test.Id).ConfigureAwait(false);

                    Console.WriteLine("Passed\n");
                }
                catch (Exception e)
                {
                    Console.WriteLine($"*** Failed: {e.Message}\n");
                }
            }
        }
コード例 #3
0
        public static ResourceExplorer BuildMemoryResourceExplorer(IEnumerable <MemoryResource> resources = null)
        {
            var resourceExplorer = new ResourceExplorer();
            var resourceProvider = new MemoryResourceProvider(
                resourceExplorer,
                resources ?? Array.Empty <MemoryResource>());

            resourceExplorer.AddResourceProvider(resourceProvider);
            resourceExplorer.RegisterType <OnQnAMatch>(OnQnAMatch.Kind);

            return(resourceExplorer);
        }
コード例 #4
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            services.AddSingleton <IConfiguration>(this.Configuration);

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton <BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService <IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation for skills.
            services.AddSingleton(sp => new AuthenticationConfiguration {
                ClaimsValidator = new AllowedCallersClaimsValidator(settings.SkillConfiguration)
            });

            // register components.
            ComponentRegistration.Add(new DialogsComponentRegistration());
            ComponentRegistration.Add(new DeclarativeComponentRegistration());
            ComponentRegistration.Add(new AdaptiveComponentRegistration());
            ComponentRegistration.Add(new LanguageGenerationComponentRegistration());
            ComponentRegistration.Add(new QnAMakerComponentRegistration());
            ComponentRegistration.Add(new LuisComponentRegistration());

            // This is for custom action component registration.
            //ComponentRegistration.Add(new CustomActionComponentRegistration());

            // Register the skills client and skills request handler.
            services.AddSingleton <SkillConversationIdFactoryBase, SkillConversationIdFactory>();
            services.AddHttpClient <BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton <ChannelServiceHandler, SkillHandler>();

            // Register telemetry client, initializers and middleware
            services.AddApplicationInsightsTelemetry(settings?.ApplicationInsights?.InstrumentationKey ?? string.Empty);

            services.AddSingleton <ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, TelemetryBotIdInitializer>();
            services.AddSingleton <IBotTelemetryClient, BotTelemetryClient>();
            services.AddSingleton <TelemetryLoggerMiddleware>(sp =>
            {
                var telemetryClient = sp.GetService <IBotTelemetryClient>();
                return(new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: settings?.Telemetry?.LogPersonalInformation ?? false));
            });
            services.AddSingleton <TelemetryInitializerMiddleware>(sp =>
            {
                var httpContextAccessor       = sp.GetService <IHttpContextAccessor>();
                var telemetryLoggerMiddleware = sp.GetService <TelemetryLoggerMiddleware>();
                return(new TelemetryInitializerMiddleware(httpContextAccessor, telemetryLoggerMiddleware, settings?.Telemetry?.LogActivities ?? false));
            });

            var storage = ConfigureStorage(settings);

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            services.AddSingleton(userState);
            services.AddSingleton(conversationState);

            // Configure bot loading path
            var botDir           = settings.Bot;
            var resourceExplorer = new ResourceExplorer().AddFolder(botDir);
            var rootDialog       = GetRootDialog(botDir);

            var defaultLocale = Configuration.GetValue <string>("defaultLanguage") ?? "en-us";

            services.AddSingleton(resourceExplorer);

            resourceExplorer.RegisterType <OnQnAMatch>("Microsoft.OnQnAMatch");

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>(s =>
                                                                                      GetBotAdapter(storage, settings, userState, conversationState, s));

            var removeRecipientMention = settings?.Feature?.RemoveRecipientMention ?? false;

            services.AddSingleton <IBot>(s =>
                                         new ComposerBot(
                                             s.GetService <ConversationState>(),
                                             s.GetService <UserState>(),
                                             s.GetService <ResourceExplorer>(),
                                             s.GetService <BotFrameworkClient>(),
                                             s.GetService <SkillConversationIdFactoryBase>(),
                                             s.GetService <IBotTelemetryClient>(),
                                             rootDialog,
                                             defaultLocale,
                                             removeRecipientMention));
        }
コード例 #5
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            services.AddSingleton <IConfiguration>(this.Configuration);

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            var storage = ConfigureStorage(settings);

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationUserState(storage);

            services.AddSingleton(userState);
            services.AddSingleton <ConversationState>(conversationState);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton <BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService <IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation.
            services.AddSingleton <AuthenticationConfiguration>();

            // register components.
            ComponentRegistration.Add(new DialogsComponentRegistration());
            ComponentRegistration.Add(new DeclarativeComponentRegistration());
            ComponentRegistration.Add(new AdaptiveComponentRegistration());
            ComponentRegistration.Add(new LanguageGenerationComponentRegistration());
            ComponentRegistration.Add(new QnAMakerComponentRegistration());

            // ComponentRegistration.Add(new LuisComponentRegistration());

            // This is for custom action component registration.
            ComponentRegistration.Add(new CustomActionComponentRegistration());

            // Register the skills client and skills request handler.
            var skillConversationIdFactory = new SkillConversationIdFactory(storage);

            services.AddSingleton <SkillConversationIdFactoryBase>(skillConversationIdFactory);
            services.AddHttpClient <BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton <ChannelServiceHandler, SkillHandler>();

            // Register telemetry client, initializers and middleware
            services.AddApplicationInsightsTelemetry(settings.ApplicationInsights.InstrumentationKey);
            services.AddSingleton <ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, TelemetryBotIdInitializer>();
            services.AddSingleton <IBotTelemetryClient, BotTelemetryClient>();
            services.AddSingleton <TelemetryLoggerMiddleware>(sp =>
            {
                var telemetryClient = sp.GetService <IBotTelemetryClient>();
                return(new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: settings.Telemetry.LogPersonalInformation));
            });
            services.AddSingleton <TelemetryInitializerMiddleware>(sp =>
            {
                var httpContextAccessor       = sp.GetService <IHttpContextAccessor>();
                var telemetryLoggerMiddleware = sp.GetService <TelemetryLoggerMiddleware>();
                return(new TelemetryInitializerMiddleware(httpContextAccessor, telemetryLoggerMiddleware, settings.Telemetry.LogActivities));
            });

            var cachedLuisManager = new CachedLuisManager(settings.CachedLuis);

            // Configure bot loading path
            var botDir           = settings.Bot;
            var resourceExplorer = new ResourceExplorer().AddFolder(botDir).RegisterType(LuisAdaptiveRecognizer.Kind, typeof(CachedLuisRecognizer), new CachedLuisLoader(cachedLuisManager));
            var rootDialog       = GetRootDialog(botDir);

            var defaultLocale = Configuration.GetValue <string>("defaultLanguage") ?? "en-us";

            services.AddSingleton(resourceExplorer);

            resourceExplorer.RegisterType <OnQnAMatch>("Microsoft.OnQnAMatch");

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>((s) => GetBotAdapter(storage, settings, userState, conversationState, s, s.GetService <TelemetryInitializerMiddleware>()));

            var removeRecipientMention = settings?.Feature?.RemoveRecipientMention ?? false;

            services.AddSingleton <IBot>((s) => new ComposerBot(
                                             conversationState,
                                             userState,
                                             resourceExplorer,
                                             s.GetService <BotFrameworkClient>(),
                                             skillConversationIdFactory,
                                             s.GetService <IBotTelemetryClient>(),
                                             rootDialog,
                                             defaultLocale,
                                             removeRecipientMention));

            var discordAdapterOptions = new DiscordAdapterOptions
            {
                Token = settings.DiscordToken
            };

            services.AddSingleton((s) =>
            {
                var adapter = new DiscordAdapter(
                    discordAdapterOptions,
                    s.GetService <IBot>());
                SetBotAdapter(adapter, storage, settings, userState, conversationState, s, s.GetService <TelemetryInitializerMiddleware>());
                return(adapter);
            });

            Task.Run(async() =>
            {
                var client = new HttpClient();
                await client.GetAsync(settings.HostUrl + "/discord");
            });
        }
コード例 #6
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            services.AddSingleton(Configuration);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton <BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService <IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation for skills.
            services.AddSingleton(sp => new AuthenticationConfiguration {
                ClaimsValidator = new Authorization.AllowedCallersClaimsValidator(settings.SkillConfiguration)
            });

            // register components.
            ComponentRegistration.Add(new DialogsComponentRegistration());
            ComponentRegistration.Add(new DeclarativeComponentRegistration());

            //to reproduce the below 2 issues uncomment this line & comment the line with AdaptiveComponentRegistrationCustom
            //The 2 issues are:
            //https://github.com/microsoft/botframework-sdk/issues/6248
            //When 2 skills are called back to back the "EndOfConversation" activity returned after the 1st skill completes gets passed to the 2nd skill & prevents the 2nd skill from completing
            //https://stackoverflow.com/questions/67541109/bot-framework-how-do-i-stop-a-waterfall-dialog-which-is-waiting-for-a-prompt-re/67576904#67576904
            //There is no way to prevent a skill which has a waterfall prompt from reprompting if it is interrupted
            //ComponentRegistration.Add(new AdaptiveComponentRegistration());
            ComponentRegistration.Add(new AdaptiveComponentRegistrationCustom());

            ComponentRegistration.Add(new LanguageGenerationComponentRegistration());
            ComponentRegistration.Add(new QnAMakerComponentRegistration());
            ComponentRegistration.Add(new LuisComponentRegistration());

            // This is for custom action component registration.
            //ComponentRegistration.Add(new CustomActionComponentRegistration());

            // Register the skills client and skills request handler.
            services.AddSingleton <SkillConversationIdFactoryBase, Bot.Builder.Skills.SkillConversationIdFactory>();
            services.AddHttpClient <BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton <ChannelServiceHandler, SkillHandler>();

            // Register telemetry client, initializers and middleware
            services.AddApplicationInsightsTelemetry(settings?.ApplicationInsights?.InstrumentationKey ?? string.Empty);

            services.AddSingleton <ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, TelemetryBotIdInitializer>();
            services.AddSingleton <IBotTelemetryClient, BotTelemetryClient>();
            services.AddSingleton <TelemetryLoggerMiddleware>(sp =>
            {
                var telemetryClient = sp.GetService <IBotTelemetryClient>();
                return(new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: settings?.Telemetry?.LogPersonalInformation ?? false));
            });
            services.AddSingleton <TelemetryInitializerMiddleware>(sp =>
            {
                var httpContextAccessor       = sp.GetService <IHttpContextAccessor>();
                var telemetryLoggerMiddleware = sp.GetService <TelemetryLoggerMiddleware>();
                return(new TelemetryInitializerMiddleware(httpContextAccessor, telemetryLoggerMiddleware, settings?.Telemetry?.LogActivities ?? false));
            });

            var storage = ConfigureStorage(settings);

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            services.AddSingleton(userState);
            services.AddSingleton(conversationState);

            // Configure bot loading path
            var botDir           = settings.Bot;
            var resourceExplorer = new ResourceExplorer().AddFolder(botDir);
            var rootDialog       = GetRootDialog(botDir);

            var defaultLocale = Configuration.GetValue <string>("defaultLanguage") ?? "en-us";

            services.AddSingleton(resourceExplorer);

            resourceExplorer.RegisterType <OnQnAMatch>("Microsoft.OnQnAMatch");

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>(s =>
                                                                                      GetBotAdapter(storage, settings, userState, conversationState, s));

            var removeRecipientMention = settings?.Feature?.RemoveRecipientMention ?? false;

            services.AddSingleton <IBot>(s =>
                                         new ComposerBot(
                                             s.GetService <ConversationState>(),
                                             s.GetService <UserState>(),
                                             s.GetService <ResourceExplorer>(),
                                             s.GetService <BotFrameworkClient>(),
                                             s.GetService <SkillConversationIdFactoryBase>(),
                                             s.GetService <IBotTelemetryClient>(),
                                             rootDialog,
                                             defaultLocale,
                                             removeRecipientMention));
        }
コード例 #7
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options => options.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddSingleton <IConfiguration>(this.Configuration);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            IStorage storage = null;

            // Configure storage for deployment
            if (!string.IsNullOrEmpty(settings.CosmosDb.AuthKey))
            {
                storage = new CosmosDbStorage(settings.CosmosDb);
            }
            else
            {
                Console.WriteLine("The settings of CosmosDbStorage is incomplete, please check following settings: settings.CosmosDb");
                storage = new MemoryStorage();
            }

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            var botFile = Configuration.GetSection("bot").Get <string>();

            // manage all bot resources
            var resourceExplorer = new ResourceExplorer().AddFolder(botFile);

            resourceExplorer.RegisterType <HttpRecognizer>(HttpRecognizer.DeclarativeType);

            var credentials = new MicrosoftAppCredentials(this.Configuration["MicrosoftAppId"], this.Configuration["MicrosoftAppPassword"]);

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>((s) =>
            {
                HostContext.Current.Set <IConfiguration>(Configuration);

                var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));
                adapter
                .UseStorage(storage)
                .UseState(userState, conversationState);

                if (!string.IsNullOrEmpty(settings.BlobStorage.ConnectionString) && !string.IsNullOrEmpty(settings.BlobStorage.Container))
                {
                    adapter.Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container)));
                }
                else
                {
                    Console.WriteLine("The settings of TranscriptLoggerMiddleware is incomplete, please check following settings: settings.BlobStorage.ConnectionString, settings.BlobStorage.Container");
                }

                adapter.OnTurnError = async(turnContext, exception) =>
                {
                    await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                    await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                    await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
                };
                return(adapter);
            });

            services.AddSingleton <IBot, ComposerBot>((sp) => new ComposerBot("Main.dialog", conversationState, userState, resourceExplorer, DebugSupport.SourceMap));
        }
コード例 #8
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            services.AddSingleton <IConfiguration>(this.Configuration);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton <BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService <IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation.
            services.AddSingleton <AuthenticationConfiguration>();

            // Register the skills client and skills request handler.
            services.AddSingleton <SkillConversationIdFactoryBase, SkillConversationIdFactory>();
            services.AddHttpClient <BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton <ChannelServiceHandler, SkillHandler>();

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            IStorage storage = null;

            // Configure storage for deployment
            if (!string.IsNullOrEmpty(settings?.CosmosDb?.AuthKey))
            {
                storage = new CosmosDbStorage(settings.CosmosDb);
            }
            else
            {
                Console.WriteLine("The settings of CosmosDbStorage is incomplete, please check following settings: settings.CosmosDb");
                storage = new MemoryStorage();
            }

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            var botFile = Configuration.GetSection("bot").Get <string>();

            // manage all bot resources
            var resourceExplorer = new ResourceExplorer().AddFolder(botFile);

            resourceExplorer.RegisterType <HttpRecognizer>(HttpRecognizer.DeclarativeType);
            resourceExplorer.RegisterType <SpacyRecognizer>(SpacyRecognizer.DeclarativeType);

            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(resourceExplorer);

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>((s) =>
            {
                HostContext.Current.Set <IConfiguration>(Configuration);

                var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));
                adapter
                .UseStorage(storage)
                .UseState(userState, conversationState);

                if (!string.IsNullOrEmpty(settings?.BlobStorage?.ConnectionString) && !string.IsNullOrEmpty(settings?.BlobStorage?.Container))
                {
                    adapter.Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container)));
                }
                else
                {
                    Console.WriteLine("The settings of TranscriptLoggerMiddleware is incomplete, please check following settings: settings.BlobStorage.ConnectionString, settings.BlobStorage.Container");
                }

                adapter.OnTurnError = async(turnContext, exception) =>
                {
                    await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                    await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                    await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
                };
                return(adapter);
            });

            services.AddSingleton <IBot, ComposerBot>();
        }