private async Task <T> InvokeChannelApiAsync <T>(BotAdapter adapter, IBot bot, ClaimsIdentity claimsIdentity, string method, string conversationId, params object[] args) { // make sure there is a channel api middleware if (!adapter.MiddlewareSet.Any(mw => mw is ChannelApiMiddleware)) { adapter.MiddlewareSet.Use(new ChannelApiMiddleware()); } _logger.LogInformation($"InvokeChannelApiAsync(). Invoking method \"{method}\""); var(callerConversationId, callerServiceUrl) = _conversationIdIdFactory.GetConversationInfo(conversationId); var channelApiInvokeActivity = Activity.CreateInvokeActivity(); channelApiInvokeActivity.Name = InvokeActivityName; channelApiInvokeActivity.ChannelId = "unknown"; channelApiInvokeActivity.ServiceUrl = callerServiceUrl; channelApiInvokeActivity.Conversation = new ConversationAccount(id: callerConversationId); channelApiInvokeActivity.From = new ChannelAccount(id: "unknown"); channelApiInvokeActivity.Recipient = new ChannelAccount(id: "unknown", role: RoleTypes.Bot); var activityPayload = args?.Where(arg => arg is Activity).Cast <Activity>().FirstOrDefault(); if (activityPayload != null) { // fix up activityPayload with original conversation.Id and id activityPayload.Conversation.Id = callerConversationId; activityPayload.ServiceUrl = callerServiceUrl; // use the activityPayload for channel accounts, it will be in From=Bot/Skill Recipient=User, // We want to send it to the bot as From=User, Recipient=Bot so we have correct state context. channelApiInvokeActivity.ChannelId = activityPayload.ChannelId; channelApiInvokeActivity.From = activityPayload.Recipient; channelApiInvokeActivity.Recipient = activityPayload.From; // We want ActivityPayload to also be in User->Bot context, if it is outbound it will go through context.SendActivity which will flip outgoing to Bot->User // regardless this gives us same memory context of User->Bot which is useful for things like EndOfConversation processing being in the correct memory context. activityPayload.From = channelApiInvokeActivity.From; activityPayload.Recipient = channelApiInvokeActivity.Recipient; } var channelApiArgs = new ChannelApiArgs { Method = method, Args = args }; channelApiInvokeActivity.Value = channelApiArgs; // send up to the bot to process it... await adapter.ProcessActivityAsync(claimsIdentity, (Activity)channelApiInvokeActivity, bot.OnTurnAsync, CancellationToken.None).ConfigureAwait(false); if (channelApiArgs.Exception != null) { throw channelApiArgs.Exception; } // Return the result that was captured in the middleware handler. return((T)channelApiArgs.Result); }
public TokenExchangeSkillHandler( BotAdapter adapter, IBot bot, IConfiguration configuration, SkillConversationIdFactoryBase conversationIdFactory, SkillsConfiguration skillsConfig, SkillHttpClient skillClient, ICredentialProvider credentialProvider, AuthenticationConfiguration authConfig, IChannelProvider channelProvider = null, ILogger <TokenExchangeSkillHandler> logger = null) : base(adapter, bot, conversationIdFactory, credentialProvider, authConfig, channelProvider, logger) { _adapter = adapter; _tokenExchangeProvider = adapter as IExtendedUserTokenProvider; if (_tokenExchangeProvider == null) { throw new ArgumentException($"{nameof(adapter)} does not support token exchange"); } _configuration = configuration; _skillsConfig = skillsConfig; _skillClient = skillClient; _conversationIdFactory = conversationIdFactory; _logger = logger ?? NullLogger <TokenExchangeSkillHandler> .Instance; _botId = configuration.GetSection(MicrosoftAppCredentials.MicrosoftAppIdKey)?.Value; }
public void SetBotAdapter(BotAdapter adapter, IStorage storage, BotSettings settings, UserState userState, ConversationState conversationState, IServiceProvider s, TelemetryInitializerMiddleware telemetryInitializerMiddleware) { adapter .UseStorage(storage) .UseBotState(userState) .Use(new RegisterClassMiddleware <ConversationState>(conversationState, typeof(ConversationState).FullName)) .Use(new RegisterClassMiddleware <IConfiguration>(Configuration)) .Use(new RegisterClassMiddleware <BotAdapter>(adapter)) .Use(new RegisterClassMiddleware <TaskManager>(new TaskManager())) .Use(new HandleGroupMentionMiddleware()) .Use(new ReferenceMiddleware()) .Use(telemetryInitializerMiddleware); // Configure Middlewares ConfigureTranscriptLoggerMiddleware(adapter, settings); ConfigureInspectionMiddleWare(adapter, settings, storage); ConfigureShowTypingMiddleWare(adapter, settings); adapter.OnTurnError = async(turnContext, exception) => { await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false); await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false); await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false); }; }
private void CreateTimerForConversation(DialogContext dc, string timerId, CancellationToken cancellationToken) { BotAdapter adapter = dc.Context.Adapter; var identity = dc.Context.TurnState.Get <ClaimsIdentity>("BotIdentity"); var appId = identity?.Claims?.FirstOrDefault(c => c.Type == AuthenticationConstants.AudienceClaim)?.Value; ConversationReference conversationReference = dc.Context.Activity.GetConversationReference(); int timeout = TimeOutInMilliseconds.GetValue(dc.State); //Question remaining to be answered: Will this task get garbage collected? If so, we need to maintain a handle for it. Task.Run(async() => { await Task.Delay(timeout).ConfigureAwait(false); string msAppId = appId; // If the channel is the Emulator, and authentication is not in use, // the AppId will be null. We generate a random AppId for this case only. // This is not required for production, since the AppId will have a value. if (string.IsNullOrEmpty(msAppId)) { msAppId = Guid.NewGuid().ToString(); //if no AppId, use a random Guid } //if we aren't already complete, go ahead and timeout await stateMatrix.RunForStatusAsync(timerId, StateStatus.Running, async() => { await adapter.ContinueConversationAsync( msAppId, conversationReference, BotWithLookup.OnTurn, //Leverage dirty hack to achieve Bot lookup from component cancellationToken).ConfigureAwait(false); }).ConfigureAwait(false); }); }
public void ConfigureTranscriptLoggerMiddleware(BotAdapter adapter, BotSettings settings) { if (ConfigSectionValid(settings.BlobStorage.ConnectionString) && ConfigSectionValid(settings.BlobStorage.Container)) { adapter.Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container))); } }
/// <summary> /// Enable Debug Adapter Protocol for the running adapter. /// </summary> /// <param name="botAdapter">The <see cref="BotAdapter"/> to enable.</param> /// <param name="port">port to listen on.</param> /// <param name="sourceMap">ISourceMap to use (default will be SourceMap()).</param> /// <param name="breakpoints">IBreakpoints to use (default will be SourceMap()).</param> /// <param name="terminate">Termination function (Default is Environment.Exit().</param> /// <param name="events">IEvents to use (Default is Events).</param> /// <param name="codeModel">ICodeModel to use (default is internal implementation).</param> /// <param name="dataModel">IDataModel to use (default is internal implementation).</param> /// <param name="logger">ILogger to use (Default is NullLogger).</param> /// <param name="coercion">ICoercion to use (default is internal implementation).</param> /// <returns>The <see cref="BotAdapter"/>.</returns> public static BotAdapter UseDebugger( this BotAdapter botAdapter, int port, ISourceMap sourceMap = null, IBreakpoints breakpoints = null, Action terminate = null, IEvents events = null, ICodeModel codeModel = null, IDataModel dataModel = null, ILogger logger = null, ICoercion coercion = null) { codeModel = codeModel ?? new CodeModel(); DebugSupport.SourceMap = sourceMap ?? new DebuggerSourceMap(codeModel); return(botAdapter.Use( new DialogDebugAdapter( port: port, sourceMap: DebugSupport.SourceMap, breakpoints: breakpoints ?? DebugSupport.SourceMap as IBreakpoints, terminate: terminate, events: events, codeModel: codeModel, dataModel: dataModel, logger: logger))); }
/// <summary> /// Enable Debug Adapter Protocol for the running adapter. /// </summary> /// <param name="botAdapter">The <see cref="BotAdapter"/> to enable.</param> /// <param name="port">port to listen on.</param> /// <param name="sourceMap">ISourceMap to use (default will be SourceMap()).</param> /// <param name="breakpoints">IBreakpoints to use (default will be SourceMap()).</param> /// <param name="terminate">Termination function (Default is Environment.Exit().</param> /// <param name="events">IEvents to use (Default is Events).</param> /// <param name="codeModel">ICodeModel to use (default is internal implementation).</param> /// <param name="dataModel">IDataModel to use (default is internal implementation).</param> /// <param name="logger">ILogger to use (Default is NullLogger).</param> /// <returns>The <see cref="BotAdapter"/>.</returns> public static BotAdapter UseDebugger( this BotAdapter botAdapter, int port, ISourceMap sourceMap = null, IBreakpoints breakpoints = null, Action terminate = null, IEvents events = null, ICodeModel codeModel = null, IDataModel dataModel = null, ILogger logger = null) { codeModel = codeModel ?? new CodeModel(); DebugSupport.SourceMap = sourceMap ?? new DebuggerSourceMap(codeModel); return(botAdapter.Use( #pragma warning disable CA2000 // Dispose objects before losing scope (excluding, the object ownership is transferred to the adapter and the adapter should dispose it) new DialogDebugAdapter( port: port, sourceMap: DebugSupport.SourceMap, breakpoints: breakpoints ?? DebugSupport.SourceMap as IBreakpoints, terminate: terminate, events: events, codeModel: codeModel, dataModel: dataModel, logger: logger))); #pragma warning restore CA2000 // Dispose objects before losing scope }
/// <summary> /// Initializes a new instance of the <see cref="SkillHandler"/> class, /// using a credential provider. /// </summary> /// <param name="adapter">An instance of the <see cref="BotAdapter"/> that will handle the request.</param> /// <param name="bot">The <see cref="IBot"/> instance.</param> /// <param name="conversationIdFactory">A <see cref="SkillConversationIdFactoryBase"/> to unpack the conversation ID and map it to the calling bot.</param> /// <param name="credentialProvider">The credential provider.</param> /// <param name="authConfig">The authentication configuration.</param> /// <param name="channelProvider">The channel provider.</param> /// <param name="logger">The ILogger implementation this adapter should use.</param> /// <exception cref="ArgumentNullException">throw ArgumentNullException.</exception> /// <remarks>Use a <see cref="MiddlewareSet"/> object to add multiple middleware /// components in the constructor. Use the Use(<see cref="IMiddleware"/>) method to /// add additional middleware to the adapter after construction. /// </remarks> public SkillHandler( BotAdapter adapter, IBot bot, SkillConversationIdFactoryBase conversationIdFactory, ICredentialProvider credentialProvider, AuthenticationConfiguration authConfig, IChannelProvider channelProvider = null, ILogger logger = null) : base(credentialProvider, authConfig, channelProvider) { if (adapter == null) { throw new ArgumentNullException(nameof(adapter)); } if (bot == null) { throw new ArgumentNullException(nameof(bot)); } if (conversationIdFactory == null) { throw new ArgumentNullException(nameof(conversationIdFactory)); } _inner = new SkillHandlerImpl( SkillConversationReferenceKey, adapter, bot, conversationIdFactory, () => ChannelProvider != null && ChannelProvider.IsGovernment() ? GovernmentAuthenticationConstants.ToChannelFromBotOAuthScope : AuthenticationConstants.ToChannelFromBotOAuthScope, logger ?? NullLogger.Instance); }
public void ConfigureShowTypingMiddleWare(BotAdapter adapter, BotSettings settings) { if (settings.Feature.UseShowTypingMiddleware) { adapter.Use(new ShowTypingMiddleware()); } }
public void ConfigureInspectionMiddleWare(BotAdapter adapter, BotSettings settings, IStorage storage) { if (settings.Feature.UseInspectionMiddleware) { adapter.Use(new InspectionMiddleware(new InspectionState(storage))); } }
/// <summary> /// Register default LG file as language generation. /// </summary> /// <param name="botAdapter">The <see cref="BotAdapter"/> to add services to.</param> /// <param name="resourceExplorer">resource explorer to use for .lg based resources.</param> /// <param name="defaultLg">Default LG Resource Id (default: main.lg).</param> /// <returns>The BotAdapter.</returns> public static BotAdapter UseLanguageGeneration( this BotAdapter botAdapter, ResourceExplorer resourceExplorer = null, string defaultLg = null) { if (defaultLg == null) { defaultLg = "main.lg"; } if (resourceExplorer == null) { resourceExplorer = new ResourceExplorer(); } if (resourceExplorer.TryGetResource(defaultLg, out var resource)) { botAdapter.UseLanguageGeneration(resourceExplorer, new ResourceMultiLanguageGenerator(defaultLg)); } else { botAdapter.UseLanguageGeneration(resourceExplorer, new TemplateEngineLanguageGenerator()); } return(botAdapter); }
public virtual void Inject(BotAdapter adapter) { foreach (var middleware in Middlewares) { adapter.Use(middleware); } }
/// <summary> /// Register ILanguageGenerator as default langugage generator. /// </summary> /// <param name="botAdapter">botAdapter to add services to.</param> /// <param name="resourceExplorer">resourceExporer to provide to LanguageGenerator.</param> /// <param name="languageGenerator">LanguageGenerator to use.</param> /// <returns>botAdapter.</returns> public static BotAdapter UseLanguageGeneration(this BotAdapter botAdapter, ResourceExplorer resourceExplorer, ILanguageGenerator languageGenerator) { DeclarativeTypeLoader.AddComponent(new LanguageGenerationComponentRegistration()); botAdapter.Use(new RegisterClassMiddleware <LanguageGeneratorManager>(new LanguageGeneratorManager(resourceExplorer ?? throw new ArgumentNullException(nameof(resourceExplorer))))); botAdapter.Use(new RegisterClassMiddleware <ILanguageGenerator>(languageGenerator ?? throw new ArgumentNullException(nameof(languageGenerator)))); return(botAdapter); }
/// <summary> /// Initializes a new instance of the <see cref="CloudSkillHandler"/> class using BotFrameworkAuth. /// </summary> /// <param name="adapter">An instance of the <see cref="BotAdapter"/> that will handle the request.</param> /// <param name="bot">The <see cref="IBot"/> instance.</param> /// <param name="conversationIdFactory">A <see cref="SkillConversationIdFactoryBase"/> to unpack the conversation ID and map it to the calling bot.</param> /// <param name="auth">auth.</param> /// <param name="logger">The ILogger implementation this adapter should use.</param> public CloudSkillHandler( BotAdapter adapter, IBot bot, SkillConversationIdFactoryBase conversationIdFactory, BotFrameworkAuthentication auth, ILogger logger = null) : base(auth) { if (adapter == null) { throw new ArgumentNullException(nameof(adapter)); } if (bot == null) { throw new ArgumentNullException(nameof(bot)); } if (conversationIdFactory == null) { throw new ArgumentNullException(nameof(conversationIdFactory)); } _inner = new SkillHandlerImpl( SkillConversationReferenceKey, adapter, bot, conversationIdFactory, auth.GetOriginatingAudience, logger ?? NullLogger.Instance); }
// Sends a proactive message to the user. private async Task CompleteJobAsync( BotAdapter adapter, string botId, JobLog.JobData jobInfo, CancellationToken cancellationToken = default(CancellationToken)) { await adapter.ContinueConversationAsync(botId, jobInfo.Conversation, CreateCallback(jobInfo), cancellationToken); }
private async Task CompleteNotificationAsync( BotAdapter adapter, string botId, ChannelLog.ChannelData channelInfo, string message, CancellationToken cancellationToken = default(CancellationToken)) { await adapter.ContinueConversationAsync(botId, channelInfo.Conversation, CreateCallback(channelInfo, message), cancellationToken); }
/// <summary> /// Initializes a new instance of the <see cref="MatchingService"/> class. /// </summary> /// <param name="dataProvider">The data provider to use</param> /// <param name="conversationHelper">Conversation helper instance to notify team members</param> /// <param name="telemetryClient">The telemetry client to use</param> /// <param name="botAdapter">Bot adapter.</param> public MatchingService(IBotDataProvider dataProvider, ConversationHelper conversationHelper, TelemetryClient telemetryClient, BotAdapter botAdapter) { this.dataProvider = dataProvider; this.conversationHelper = conversationHelper; this.telemetryClient = telemetryClient; this.botAdapter = botAdapter; this.maxPairUpsPerTeam = Convert.ToInt32(CloudConfigurationManager.GetSetting("MaxPairUpsPerTeam")); this.botDisplayName = CloudConfigurationManager.GetSetting("BotDisplayName"); }
/// <summary> /// Initializes a new instance of the <see cref="BotFrameworkSkillHostAdapter"/> class, /// using a credential provider. /// </summary> /// <param name="adapter">adapter that this skillAdapter is bound to.</param> /// <param name="credentialProvider">The credential provider.</param> /// <param name="channelProvider">The channel provider.</param> /// <param name="connectorClientRetryPolicy">Retry policy for retrying HTTP operations.</param> /// <param name="customHttpClient">The HTTP client.</param> /// <param name="logger">The ILogger implementation this adapter should use.</param> /// <remarks>Use a <see cref="MiddlewareSet"/> object to add multiple middleware /// components in the constructor. Use the Use(<see cref="IMiddleware"/>) method to /// add additional middleware to the adapter after construction. /// </remarks> public BotFrameworkSkillHostAdapter( BotAdapter adapter, ICredentialProvider credentialProvider, IChannelProvider channelProvider = null, RetryPolicy connectorClientRetryPolicy = null, HttpClient customHttpClient = null, ILogger logger = null) : this(adapter, credentialProvider, new AuthenticationConfiguration(), channelProvider, connectorClientRetryPolicy, customHttpClient, logger) { }
private async Task SendNotificationsAsync( BotAdapter adapter, string botId, PasswordNotfications.NotificationData notification, PasswordEventNotification passwordEventNotification, CancellationToken cancellationToken = default(CancellationToken) ) { await adapter.ContinueConversationAsync(botId, notification.Conversation, CreateCallback(notification, passwordEventNotification), cancellationToken); }
/// <summary> /// Get the name of a team. /// </summary> /// <param name="botAdapter">Bot adapter.</param> /// <param name="teamInfo">DB team model info.</param> /// <returns>The name of the team</returns> public virtual async Task <string> GetTeamNameByIdAsync(BotAdapter botAdapter, TeamInstallInfo teamInfo) { TeamDetails teamDetails = null; await this.ExecuteInNewTurnContext(botAdapter, teamInfo, async (newTurnContext, newCancellationToken) => { teamDetails = await this.GetTeamDetailsAsync(newTurnContext, teamInfo.TeamId, newCancellationToken); }); return(teamDetails?.Name); }
public DialogStateData( UserData userProfile, ConversationData conversationData, BotAdapter botAdapter, ConversationReference conversationReference) { this.BotAdapter = botAdapter; this.ConversationData = new ConversationData(conversationData); this.ConversationReference = conversationReference; this.UserProfile = new UserData(userProfile); }
public TurnContextEx(BotAdapter adapter, Activity activity) : base(adapter, activity) { this.OnSendActivities(async(ctx, activities, nextSend) => { var responses = await nextSend().ConfigureAwait(false); SentActivities.AddRange(activities); return(responses); }); }
protected SkillHostAdapter(BotAdapter adapter, ILogger logger = null) { ChannelAdapter = adapter; _logger = logger ?? NullLogger.Instance; // make sure there is a channel api middleware if (!adapter.MiddlewareSet.Any(mw => mw is ChannelApiMiddleware)) { adapter.MiddlewareSet.Use(new ChannelApiMiddleware(this)); } }
/// <summary> /// Send a card to a user in direct conversation /// </summary> /// <param name="botFrameworkAdapter">Bot adapter</param> /// <param name="serviceUrl">Service url</param> /// <param name="teamsChannelId">Team channel id where the bot is installed</param> /// <param name="cardToSend">The actual welcome card (for the team)</param> /// <param name="user">User channel account</param> /// <param name="tenantId">Tenant id</param> /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param> /// <returns>True/False operation status</returns> public async Task <bool> NotifyUserAsync(BotAdapter botFrameworkAdapter, string serviceUrl, string teamsChannelId, IMessageActivity cardToSend, ChannelAccount user, string tenantId, CancellationToken cancellationToken) { this.telemetryClient.TrackTrace($"Sending notification to user {user.Id}"); try { // conversation parameters var conversationParameters = new ConversationParameters { Bot = new ChannelAccount { Id = this.botId }, Members = new[] { user }, ChannelData = new TeamsChannelData { Tenant = new TenantInfo(tenantId), }, }; if (!this.isTesting) { // shoot the activity over await((BotFrameworkAdapter)botFrameworkAdapter).CreateConversationAsync( teamsChannelId, serviceUrl, this.appCredentials, conversationParameters, async(newTurnContext, newCancellationToken) => { // Get the conversationReference var conversationReference = newTurnContext.Activity.GetConversationReference(); await botFrameworkAdapter.ContinueConversationAsync( this.appCredentials.MicrosoftAppId, conversationReference, async(conversationTurnContext, conversationCancellationToken) => { await conversationTurnContext.SendActivityAsync(cardToSend, conversationCancellationToken); }, cancellationToken); }, cancellationToken).ConfigureAwait(false); } return(true); } catch (Exception ex) { this.telemetryClient.TrackTrace($"Error sending notification to user: {ex.Message}", SeverityLevel.Warning); this.telemetryClient.TrackException(ex); return(false); } }
private async Task CompleteJobAsync(BotAdapter adapter, string botId, JobStorage jobStorage, UiPathJobResponse uiPathJobResponse, CancellationToken cancellationToken) { jobStorage.TryGetValue(uiPathJobResponse.JobId, out var jobInfo); if (jobInfo != null) { await adapter.ContinueConversationAsync(botId, jobInfo.ConversationReference, CompleteJobHandler(uiPathJobResponse), cancellationToken); } }
private async Task ProactiveMessageCallbackAsync(BotAdapter adapter, ConversationReference conversationReference, string message, int seconds, CancellationToken cancellationToken) { // Pause on the background thread for the number of seconds specified, then load the conversationi and message the user. // This simulates a long running process. Thread.Sleep(TimeSpan.FromSeconds(seconds)); await adapter.ContinueConversationAsync(_botId, conversationReference, async (innerContext, innerCancellationToken) => { await innerContext.SendActivityAsync(string.IsNullOrWhiteSpace(message) ? $"background notice after {seconds} seconds" : $"background msg {seconds} {message}"); // Could load a dialog stack here, and resume }, cancellationToken); }
private Action <ServiceMessageProcessingEvent> CreateCallback(BotAdapter adapter, ConversationReference conversationReference, string agentId, string connectionId) { return(async message => { var agentContext = await _agentContextProvider.GetContextAsync(agentId); var connection = await _connectionService.GetAsync(agentContext, connectionId); await adapter.ContinueConversationAsync(AppId, conversationReference, async (turnContext, cancellationToken) => { await turnContext.SendActivityAsync($"You are now connected to {connection.Alias?.Name ?? "[unspecified]"}"); }, CancellationToken.None); }); }
private async void CompleteJob(BotAdapter adapter, string appId, ConversationReference conversation, int jobNumber) { await adapter.ContinueConversation(appId, conversation, async context => { // Get the job log from state, and retrieve the job. var jobLog = GetJobLog(context); var job = jobLog[jobNumber]; // Perform bookkeeping. job.Completed = true; // Send the user a proactive confirmation message. await context.SendActivity($"Job {job.JobNumber} is complete."); }); }
/// <summary> /// Initializes a new instance of the <see cref="SkillHandler"/> class, /// using a credential provider. /// </summary> /// <param name="adapter">An instance of the <see cref="BotAdapter"/> that will handle the request.</param> /// <param name="bot">The <see cref="IBot"/> instance.</param> /// <param name="conversationIdFactory">A <see cref="SkillConversationIdFactoryBase"/> to unpack the conversation ID and map it to the calling bot.</param> /// <param name="credentialProvider">The credential provider.</param> /// <param name="authConfig">The authentication configuration.</param> /// <param name="channelProvider">The channel provider.</param> /// <param name="logger">The ILogger implementation this adapter should use.</param> /// <exception cref="ArgumentNullException">throw ArgumentNullException.</exception> /// <remarks>Use a <see cref="MiddlewareSet"/> object to add multiple middleware /// components in the constructor. Use the Use(<see cref="IMiddleware"/>) method to /// add additional middleware to the adapter after construction. /// </remarks> public SkillHandler( BotAdapter adapter, IBot bot, SkillConversationIdFactoryBase conversationIdFactory, ICredentialProvider credentialProvider, AuthenticationConfiguration authConfig, IChannelProvider channelProvider = null, ILogger logger = null) : base(credentialProvider, authConfig, channelProvider) { _adapter = adapter ?? throw new ArgumentNullException(nameof(adapter)); _bot = bot ?? throw new ArgumentNullException(nameof(bot)); _conversationIdFactory = conversationIdFactory ?? throw new ArgumentNullException(nameof(conversationIdFactory)); _logger = logger ?? NullLogger.Instance; }
/// <summary> /// Register ILanguageGenerator as default langugage generator. /// </summary> /// <param name="botAdapter">botAdapter to add services to.</param> /// <param name="resourceExplorer">resourceExporer to provide to LanguageGenerator.</param> /// <param name="languageGenerator">LanguageGenerator to use.</param> /// <returns>botAdapter.</returns> public static BotAdapter UseLanguageGeneration(this BotAdapter botAdapter, ResourceExplorer resourceExplorer, ILanguageGenerator languageGenerator) { DeclarativeTypeLoader.AddComponent(new LanguageGenerationComponentRegistration()); lock (languageGeneratorManagers) { if (!languageGeneratorManagers.TryGetValue(resourceExplorer ?? throw new ArgumentNullException(nameof(resourceExplorer)), out var lgm)) { lgm = new LanguageGeneratorManager(resourceExplorer); languageGeneratorManagers[resourceExplorer] = lgm; } botAdapter.Use(new RegisterClassMiddleware <LanguageGeneratorManager>(lgm)); botAdapter.Use(new RegisterClassMiddleware <ILanguageGenerator>(languageGenerator ?? throw new ArgumentNullException(nameof(languageGenerator)))); return(botAdapter); } }