public async Task ReplyWithTokens( ITurnContext turnContext, string templateId, IDictionary <string, string> tokens, object data = null) { BotAssert.ContextNotNull(turnContext); // apply template var manager = new TellTimeResponses(); var activity = await manager.RenderTemplate(turnContext, turnContext.Activity?.AsMessageActivity()?.Locale, templateId, data). ConfigureAwait(false); activity.Text = ResponseTokens.ReplaceToken(activity.Text, tokens); activity.Speak = ResponseTokens.ReplaceToken(activity.Speak, tokens); await turnContext.SendActivityAsync(activity); }
public async Task <DialogContext> CreateContextAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { BotAssert.ContextNotNull(turnContext); // ToDo: Component Dialog doesn't call this code path. This needs to be cleaned up in 4.1. if (_dialogState == null) { // Note: This shouldn't ever trigger, as the _dialogState is set in the constructor and validated there. throw new InvalidOperationException($"DialogSet.CreateContextAsync(): DialogSet created with a null IStatePropertyAccessor."); } // Load/initialize dialog state var state = await _dialogState.GetAsync(turnContext, () => { return(new DialogState()); }, cancellationToken).ConfigureAwait(false); // Create and return context return(new DialogContext(this, turnContext, state)); }
public async Task <IList <Intent> > Recognize(ITurnContext context) { BotAssert.ContextNotNull(context); bool isEnabled = await IsRecognizerEnabled(context).ConfigureAwait(false); if (isEnabled) { var allRecognizedIntents = await RunRecognizer(context).ConfigureAwait(false); await RunFilters(context, allRecognizedIntents); return(allRecognizedIntents); } else { return(new List <Intent>()); } }
public async Task ForgetIdAsync(ITurnContext turnContext, DataId dataId, CancellationToken cancellationToken = default) { BotAssert.ContextNotNull(turnContext); if (dataId is null) { throw new ArgumentNullException(nameof(dataId)); } var state = await GetStateAsync(turnContext, cancellationToken).ConfigureAwait(false); if (state.DataIdsByScope.TryGetValue(dataId.Key, out var ids)) { ids?.Remove(dataId.Value); } await StateAccessor.SetAsync(turnContext, state, cancellationToken).ConfigureAwait(false); }
private async Task <TokenStatus[]> GetTokenStatusAsync(ITurnContext context, string userId, string includeFilter = null, CancellationToken cancellationToken = default(CancellationToken)) { BotAssert.ContextNotNull(context); if (string.IsNullOrWhiteSpace(userId)) { throw new ArgumentNullException(nameof(userId)); } if (_appCredentials == null) { throw new ArgumentNullException("AppCredentials were not passed which are required for speech enabled authentication scenarios."); } var client = new OAuthClient(new Uri(OAuthClientConfig.OAuthEndpoint), _appCredentials); var result = await client.UserToken.GetTokenStatusAsync(userId, context.Activity?.ChannelId, includeFilter, cancellationToken).ConfigureAwait(false); return(result?.ToArray()); }
public DialogContext CreateContext(ITurnContext context, object state) { BotAssert.ContextNotNull(context); if (state == null) { throw new ArgumentNullException(nameof(state)); } var d = (IDictionary <string, object>)state; object value; if (!d.TryGetValue("dialogStack", out value)) { value = new List <DialogInstance>(); d["dialogStack"] = value; } return(new DialogContext(this, context, (List <DialogInstance>)value)); }
public async Task UnsaveActivityAsync(ITurnContext turnContext, string activityId, CancellationToken cancellationToken = default) { BotAssert.ContextNotNull(turnContext); if (activityId is null) { throw new ArgumentNullException(nameof(activityId)); } var state = await GetStateAsync(turnContext, cancellationToken).ConfigureAwait(false); var activitiesWithMatchingId = state.SavedActivities.Where(activity => activity.Id == activityId).ToArray(); // We used ToArray because the WhereEnumerableIterator must be copied // or else it would throw an exception here state.SavedActivities.ExceptWith(activitiesWithMatchingId); await StateAccessor.SetAsync(turnContext, state, cancellationToken).ConfigureAwait(false); }
public async Task <DialogResult> Continue(TurnContext context, object state) { BotAssert.ContextNotNull(context); if (state == null) { throw new ArgumentNullException(nameof(state)); } // Create empty dialog set and ourselves to it var dialogs = new DialogSet(); dialogs.Add("control", (IDialog)this); // Start the control var cdc = dialogs.CreateContext(context, state); await cdc.Continue(); return(cdc.DialogResult); }
private async Task <TokenStatus[]> GetTokenStatusAsync(ITurnContext context, string userId, string includeFilter = null, CancellationToken cancellationToken = default(CancellationToken)) { BotAssert.ContextNotNull(context); if (string.IsNullOrWhiteSpace(userId)) { throw new ArgumentNullException(nameof(userId)); } var tokenProvider = context.Adapter as IExtendedUserTokenProvider; if (tokenProvider != null) { return(await tokenProvider.GetTokenStatusAsync(context, _oauthCredentials, userId, includeFilter, cancellationToken).ConfigureAwait(false)); } else { throw new Exception("Adapter does not support IExtendedUserTokenProvider"); } }
/// <summary> /// Recognizes and validates the user input. /// </summary> public override async Task <AttachmentResult> Recognize(ITurnContext context) { BotAssert.ContextNotNull(context); BotAssert.ActivityNotNull(context.Activity); var attachmentResult = new AttachmentResult(); if (context.Activity.Type == ActivityTypes.Message) { IMessageActivity message = context.Activity.AsMessageActivity(); if (message.Attachments != null) { attachmentResult.Status = PromptStatus.Recognized; attachmentResult.Attachments.AddRange(message.Attachments); await Validate(context, attachmentResult); } } return(attachmentResult); }
/// <summary> /// Records incoming and outgoing text messages to the debug console. /// </summary> /// <param name="context">The <see cref="ITurnContext"/> object for this turn.</param> /// <param name="next">The delegate to call to continue the bot middleware pipeline.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> public async Task OnTurnAsync( ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { BotAssert.ContextNotNull(turnContext); if (turnContext.Activity.Text is string text) { Debug.WriteLine(text); } turnContext.OnSendActivities(OnSendActivitiesAsync); if (next != null) { await next(cancellationToken).ConfigureAwait(false); } }
internal override async Task <RecognizerResult> RecognizeInternalAsync(ITurnContext turnContext, HttpClient httpClient, CancellationToken cancellationToken) { BotAssert.ContextNotNull(turnContext); if (turnContext.Activity == null || turnContext.Activity.Type != ActivityTypes.Message) { return(null); } var utterance = turnContext.Activity.AsMessageActivity()?.Text; RecognizerResult recognizerResult; LuisResult luisResult = null; if (string.IsNullOrWhiteSpace(utterance)) { recognizerResult = new RecognizerResult { Text = utterance }; } else { luisResult = await GetLuisResultAsync(utterance, httpClient, cancellationToken).ConfigureAwait(false); recognizerResult = BuildRecognizerResultFromLuisResult(luisResult, utterance); } var traceInfo = JObject.FromObject( new { recognizerResult, luisModel = new { ModelID = Application.ApplicationId, }, luisOptions = PredictionOptions, luisResult, }); await turnContext.TraceActivityAsync("LuisRecognizer", traceInfo, LuisTraceType, LuisTraceLabel, cancellationToken).ConfigureAwait(false); return(recognizerResult); }
/// <summary> /// identifies intent /// </summary> /// <param name="innerDc"></param> /// <returns></returns> private async Task <DialogTurnResult> StartAsync(DialogContext innerDc) { BotAssert.ContextNotNull(innerDc.Context); string response = string.Empty; var message = innerDc.Context.Activity; string intent = await Utilities.PredictSalutationIntent(lstIntentUtterance, message.Text); if (!string.IsNullOrEmpty(intent)) { switch (intent) { case Constants.Greetings: GreetingHandler(out response, message); break; case Constants.IntentWelcome: case Constants.IntentClosurePositive: case Constants.IntentClosureNegative: GetWelcomeClosureResponse(out response, intent); break; } await innerDc.Context.SendActivityAsync(response.Replace("<FirstName>", innerDc.Context.Activity.From.Name)); // sql logging //TaskResult taskResult = new TaskResult() //{ // Category = CategoryType.Salutation, // ModelName = "SalutationQnA.csv", // Intent = intent, // Entity = string.Empty, // Response = response, // ResponseType = BotResponseType.ValidResponse, // Score = 1, // Source = string.IsNullOrEmpty(response) ? CategoryType.Salutation : CategoryType.BotResponse //}; //await _loggerRepository.InsertBotLogAsync(innerDc.Context.Activity, taskResult); return(await innerDc.EndDialogAsync(result : true)); } return(await innerDc.EndDialogAsync(result : false)); }
public async Task OnTurn(ITurnContext context, MiddlewareSet.NextDelegate next) { BotAssert.ContextNotNull(context); var logCategoryStates = new List <LogCategoryState>(); logCategoryStates.Add(new LogCategoryState { Name = "Working out" }); logCategoryStates.Add(new LogCategoryState { Name = "Biking" }); logCategoryStates.Add(new LogCategoryState { Name = "Reading" }); context.Services.Add <IList <LogCategoryState> >(logCategoryStates); await next().ConfigureAwait(false); }
public async Task OnProcessRequest(ITurnContext context, MiddlewareSet.NextDelegate next) { BotAssert.ContextNotNull(context); var intents = await this.Recognize(context); var result = new IntentRecognition(); if (intents.Count != 0) { result.Intents = intents; var topIntent = FindTopIntent(intents); if (topIntent.Score > 0.0) { result.TopIntent = topIntent; } } context.Services.Add((IRecognizedIntents)result); await next().ConfigureAwait(false); }
public async Task ReceiveActivity(IBotContext context, MiddlewareSet.NextDelegate next) { BotAssert.ContextNotNull(context); var intents = await this.Recognize(context); var result = new IntentRecognition(); if (intents.Count != 0) { result.Intents = intents; var topIntent = FindTopIntent(intents); if (topIntent.Score > 0.0) { result.TopIntent = topIntent; } } context.Set((IRecognizedIntents)result); await next().ConfigureAwait(false); }
public async Task OnTurnAsync(ITurnContext context, NextDelegate nextTurn, CancellationToken cancellationToken) { BotAssert.ContextNotNull(context); var intents = await this.Recognize(context); var result = new IntentRecognition(); if (intents.Count != 0) { result.Intents = intents; var topIntent = FindTopIntent(intents); if (topIntent.Score > 0.0) { result.TopIntent = topIntent; } } context.TurnState.Add((IRecognizedIntents)result); await nextTurn(cancellationToken).ConfigureAwait(false); }
public async Task <ChoiceResult> RecognizeAsync(ITurnContext context, List <Choice> choices) { BotAssert.ContextNotNull(context); BotAssert.ActivityNotNull(context.Activity); if (context.Activity.Type != ActivityTypes.Message) { throw new InvalidOperationException("No Message to Recognize"); } if (choices == null) { throw new ArgumentNullException(nameof(choices)); } var request = context.Activity; var utterance = request.Text; var options = RecognizerOptions ?? new FindChoicesOptions(); options.Locale = request.Locale ?? options.Locale ?? Culture ?? Recognizers.Text.Culture.English; var results = ChoiceRecognizers.RecognizeChoices(utterance, choices, options); if (results != null && results.Count > 0) { var value = results[0].Resolution; var result = new ChoiceResult { Status = PromptStatus.Recognized, Value = value }; if (Validator != null) { await Validator(context, result).ConfigureAwait(false); } return(result); } else { return(new ChoiceResult { Status = PromptStatus.NotRecognized }); } }
/// <summary> /// Recognizes and validates the user input. /// </summary> /// <param name="context">The context for the current turn.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <remarks>Call this when you expect that the incoming activity for this /// turn contains the user input to recognize. /// If recognition succeeds, the <see cref="TextResult.Value"/> property of the /// result contains the value recognized. /// <para>If recognition fails, returns a <see cref="TextResult"/> with /// its <see cref="PromptStatus"/> set to <see cref="PromptStatus.NotRecognized"/> and /// its <see cref="TextResult.Value"/> set to <c>null</c>.</para> /// </remarks> public override async Task <TextResult> Recognize(ITurnContext context) { BotAssert.ContextNotNull(context); BotAssert.ActivityNotNull(context.Activity); if (context.Activity.Type != ActivityTypes.Message) { throw new InvalidOperationException("No Message to Recognize"); } IMessageActivity message = context.Activity.AsMessageActivity(); TextResult textResult = new TextResult(); if (message.Text != null) { textResult.Status = PromptStatus.Recognized; textResult.Value = message.Text; textResult.Text = message.Text; await Validate(context, textResult); } return(textResult); }
/// <summary> /// Processess an incoming activity. /// </summary> /// <param name="context">The context object for this turn.</param> /// <param name="next">The delegate to call to continue the bot middleware pipeline.</param> /// /// <param name="cancellationToken">Cancellation token.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</placeholder></returns> public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { BotAssert.ContextNotNull(context); if (context.Activity.Type == ActivityTypes.Message) { var utterance = context.Activity.AsMessageActivity().Text; if (!string.IsNullOrWhiteSpace(utterance)) { var result = await _luisRecognizer.RecognizeAsync(context, CancellationToken.None).ConfigureAwait(false); context.TurnState.Add(LuisRecognizerResultKey, result); var traceActivity = Activity.CreateTraceActivity("LuisRecognizerMiddleware", LuisTraceType); await context.SendActivityAsync(traceActivity).ConfigureAwait(false); } } await next(cancellationToken).ConfigureAwait(false); }
public async Task OnTurnAsync( ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { BotAssert.ContextNotNull(turnContext); #pragma warning disable CA1062 // Validate arguments of public methods if (turnContext.Activity != null) #pragma warning restore CA1062 // Validate arguments of public methods { var et = this.BuildEventTelemetry(turnContext.Activity); this.telemetryClient.TrackEvent(et); } // hook up onSend pipeline turnContext.OnSendActivities(async(ctx, activities, nextSend) => { activities.ForEach(a => this.telemetryClient.TrackEvent(this.BuildEventTelemetry(a))); return(await nextSend() .ConfigureAwait(false)); }); // hook up update activity pipeline turnContext.OnUpdateActivity(async(ctx, activity, nextUpdate) => { var et = this.BuildEventTelemetry(activity); this.telemetryClient.TrackEvent(et); return(await nextUpdate() .ConfigureAwait(false)); }); if (next != null) { await next(cancellationToken) .ConfigureAwait(false); } }
/// <summary> /// Used to validate the incoming text, expected on context.Request, is /// valid according to the rules defined in the validation steps. /// </summary> public override async Task <NumberResult <T> > Recognize(IBotContext context) { BotAssert.ContextNotNull(context); BotAssert.ActivityNotNull(context.Request); if (context.Request.Type != ActivityTypes.Message) { throw new InvalidOperationException("No Message to Recognize"); } NumberResult <T> numberResult = new NumberResult <T>(); IMessageActivity message = context.Request.AsMessageActivity(); var results = _model.Parse(message.Text); if (results.Any()) { var result = results.First(); if (typeof(T) == typeof(float)) { if (float.TryParse(result.Resolution["value"].ToString(), out float value)) { numberResult.Status = RecognitionStatus.Recognized; numberResult.Value = (T)(object)value; numberResult.Text = result.Text; await Validate(context, numberResult); } } else if (typeof(T) == typeof(int)) { if (int.TryParse(result.Resolution["value"].ToString(), out int value)) { numberResult.Status = RecognitionStatus.Recognized; numberResult.Value = (T)(object)value; numberResult.Text = result.Text; await Validate(context, numberResult); } } } return(numberResult); }
public async Task Prompt(ITurnContext context, List <Choice> choices, string prompt = null, string speak = null) { BotAssert.ContextNotNull(context); if (choices == null) { throw new ArgumentNullException(nameof(choices)); } IMessageActivity msg; switch (Style) { case ListStyle.Inline: msg = ChoiceFactory.Inline(choices, prompt, speak, ChoiceOptions); break; case ListStyle.List: msg = ChoiceFactory.List(choices, prompt, speak, ChoiceOptions); break; case ListStyle.SuggestedAction: msg = ChoiceFactory.SuggestedAction(choices, prompt, speak); break; case ListStyle.None: msg = Activity.CreateMessageActivity(); msg.Text = prompt; msg.Speak = speak; break; case ListStyle.Auto: default: msg = ChoiceFactory.ForChannel(context, choices, prompt, speak, ChoiceOptions); break; } msg.InputHint = InputHints.ExpectingInput; await context.SendActivity(msg); }
/// <summary> /// Processess an incoming activity and if it is for MsTeams attaches <see cref="ITeamsContext"/> instances along with the context. /// </summary> /// <param name="context">The context object for this turn.</param> /// <param name="nextDelegate">The delegate to call to continue the bot middleware pipeline.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// Task tracking operation. /// </returns> /// <remarks> /// Middleware calls the <paramref name="nextDelegate" /> delegate to pass control to /// the next middleware in the pipeline. If middleware doesn’t call the next delegate, /// the adapter does not call any of the subsequent middleware’s request handlers or the /// bot’s receive handler, and the pipeline short circuits. /// <para>The <paramref name="context" /> provides information about the /// incoming activity, and other data needed to process the activity.</para> /// </remarks> /// <seealso cref="ITurnContext" /> /// <seealso cref="Schema.IActivity" /> public async Task OnTurnAsync(ITurnContext context, NextDelegate nextDelegate, CancellationToken cancellationToken = default(CancellationToken)) { BotAssert.ContextNotNull(context); if (context.Activity.ChannelId.Equals(Channels.Msteams, StringComparison.OrdinalIgnoreCase)) { // BotFrameworkAdapter when processing activity, post Auth adds BotIdentity into the context. ClaimsIdentity claimsIdentity = context.TurnState.Get <ClaimsIdentity>("BotIdentity"); // If we failed to find ClaimsIdentity, create a new AnonymousIdentity. This tells us that Auth is off. if (claimsIdentity == null) { claimsIdentity = new ClaimsIdentity(new List <Claim>(), "anonymous"); } ITeamsConnectorClient teamsConnectorClient = await this.CreateTeamsConnectorClientAsync(context.Activity.ServiceUrl, claimsIdentity).ConfigureAwait(false); context.TurnState.Add((ITeamsContext) new TeamsContext(context, teamsConnectorClient)); } await nextDelegate(cancellationToken).ConfigureAwait(false); }
public override async Task <TimexResult> Recognize(ITurnContext context) { BotAssert.ContextNotNull(context); BotAssert.ActivityNotNull(context.Activity); if (context.Activity.Type == ActivityTypes.Message) { var message = context.Activity.AsMessageActivity(); var results = _model.Parse(message.Text); if (results.Any()) { var result = results.First(); if (result.Resolution.Any()) { var timexResult = new TimexResult { Status = PromptStatus.Recognized }; var distinctTimex = new HashSet <string>(); foreach (var resolution in result.Resolution) { var values = (List <Dictionary <string, string> >)resolution.Value; foreach (var timex in values.Select(r => r["timex"])) { distinctTimex.Add(timex); } } timexResult.Resolutions = distinctTimex.ToArray(); await Validate(context, timexResult); return(timexResult); } } } return(new TimexResult()); }
/// <summary> /// Passes a users reply to the dialog for further processing.The bot should keep calling /// 'continue()' for future turns until the dialog returns a completion object with /// 'isCompleted == true'. To cancel or interrupt the prompt simply delete the `state` object /// being persisted. /// </summary> /// <param name="context">Context for the current turn of the conversation with the user.</param> /// <param name="state">A state object that was previously initialized by a call to [begin()](#begin).</param> /// <returns>DialogCompletion result</returns> public async Task <DialogCompletion> Continue(ITurnContext context, IDictionary <string, object> state) { BotAssert.ContextNotNull(context); if (state == null) { throw new ArgumentNullException(nameof(state)); } // Create empty dialog set and ourselves to it var dialogs = new DialogSet(); dialogs.Add("dialog", (IDialog)this); // Continue the dialog IDictionary <string, object> result = null; var dc = new DialogContext(dialogs, context, state, (r) => { result = r; }); if (dc.ActiveDialog != null) { await dc.Continue(); return(dc.ActiveDialog != null ? new DialogCompletion { IsActive = true, IsCompleted = false } : new DialogCompletion { IsActive = false, IsCompleted = true, Result = result }); } else { return(new DialogCompletion { IsActive = false, IsCompleted = false }); } }
/// <summary> /// Used to validate the incoming text, expected on context.Request, is /// valid according to the rules defined in the validation steps. /// </summary> public override async Task <TextResult> Recognize(IBotContext context) { BotAssert.ContextNotNull(context); BotAssert.ActivityNotNull(context.Request); if (context.Request.Type != ActivityTypes.Message) { throw new InvalidOperationException("No Message to Recognize"); } TextResult textResult = new TextResult(); IMessageActivity message = context.Request.AsMessageActivity(); var results = _model.Parse(message.Text); if (results.Any()) { var result = results.First(); textResult.Status = RecognitionStatus.Recognized; textResult.Text = result.Text; textResult.Value = (string)result.Resolution["value"]; await Validate(context, textResult); } return(textResult); }
public async Task OnTurn(ITurnContext context, MiddlewareSet.NextDelegate next) { BotAssert.ContextNotNull(context); if (context.Activity.Type == ActivityTypes.Message) { var utterance = context.Activity.AsMessageActivity().Text; var result = await _luisRecognizer.CallAndRecognize(utterance, CancellationToken.None).ConfigureAwait(false); context.Services.Add(LuisRecognizerResultKey, result.recognizerResult); var traceInfo = new LuisTraceInfo { RecognizerResult = result.recognizerResult, LuisModel = RemoveSensitiveData(_luisModel), LuisOptions = _luisOptions, LuisResult = result.luisResult }; var traceActivity = Activity.CreateTraceActivity("LuisRecognizerMiddleware", LuisTraceType, traceInfo, LuisTraceLabel); await context.SendActivity(traceActivity).ConfigureAwait(false); } await next().ConfigureAwait(false); }
// TODO: Incorporate value preservation into other updates made to Adaptive Cards public async Task PreserveValuesAsync(ITurnContext turnContext, CancellationToken cancellationToken = default) { BotAssert.ContextNotNull(turnContext); if (turnContext.GetIncomingActionData() is JObject data) { var matchResult = await GetDataMatchAsync(turnContext, cancellationToken).ConfigureAwait(false); if (matchResult.SavedActivity != null && matchResult.SavedAttachment?.ContentType.EqualsCI(ContentTypes.AdaptiveCard) == true) { var changed = false; // The content must be non-null or else the attachment couldn't have been a match matchResult.SavedAttachment.Content = matchResult.SavedAttachment.Content.ToJObjectAndBack( card => { // Iterate through all inputs in the card foreach (var input in AdaptiveCardUtil.GetAdaptiveInputs(card)) { var id = AdaptiveCardUtil.GetAdaptiveInputId(input); var inputValue = data.GetValue(id); input.SetValue(AdaptiveProperties.Value, inputValue); changed = true; } }); if (changed) { // The changes to the attachment will already be reflected in the activity await UpdateActivityAsync(turnContext, matchResult.SavedActivity, cancellationToken).ConfigureAwait(false); } } } }
public async Task OnTurnAsync( ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) { if (this.disposed) { throw new ObjectDisposedException(this.GetType().FullName); } BotAssert.ContextNotNull(turnContext); if (turnContext.Activity.IsIncomingMessage()) { await this.sentimentInstrumentation.TrackMessageSentiment(turnContext.Activity) .ConfigureAwait(false); } if (next != null) { await next(cancellationToken) .ConfigureAwait(false); } }