Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        /// <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));
        }
        /// <summary>
        /// Primary adapter method for processing activities sent from streaming channel.
        /// Creates a turn context and runs the middleware pipeline for an incoming activity.
        /// Throws <see cref="ArgumentNullException"/> on null arguments.
        /// </summary>
        /// <param name="activity">The <see cref="Activity"/> to process.</param>
        /// <param name="callbackHandler">The <see cref="BotCallbackHandler"/> that will handle the activity.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents the work queued to execute. If the activity type
        /// was 'Invoke' and the corresponding key (channelId + activityId) was found
        /// then an InvokeResponse is returned, otherwise null is returned.</returns>
        /// <remarks>Call this method to reactively send a message to a conversation.
        /// If the task completes successfully, then if the activity's <see cref="Activity.Type"/>
        /// is <see cref="ActivityTypes.Invoke"/> and the corresponding key
        /// (<see cref="Activity.ChannelId"/> + <see cref="Activity.Id"/>) is found
        /// then an <see cref="InvokeResponse"/> is returned, otherwise null is returned.
        /// <para>This method registers the following services for the turn.<list type="bullet"/></para>
        /// </remarks>
        public async Task <InvokeResponse> ProcessStreamingActivityAsync(Activity activity, BotCallbackHandler callbackHandler, CancellationToken cancellationToken = default)
        {
            BotAssert.ActivityNotNull(activity);

            Logger.LogInformation($"Received an incoming streaming activity. ActivityId: {activity.Id}");

            // If a conversation has moved from one connection to another for the same Channel or Skill and
            // hasn't been forgotten by the previous StreamingRequestHandler. The last requestHandler
            // the conversation has been associated with should always be the active connection.
            var requestHandler = RequestHandlers.Where(x => x.ServiceUrl == activity.ServiceUrl).Where(y => y.HasConversation(activity.Conversation.Id)).LastOrDefault();

            using (var context = new TurnContext(this, activity))
            {
                // Pipes are unauthenticated. Pending to check that we are in pipes right now. Do not merge to master without that.
                if (ClaimsIdentity != null)
                {
                    context.TurnState.Add <IIdentity>(BotIdentityKey, ClaimsIdentity);
                }

                var connectorClient = CreateStreamingConnectorClient(activity, requestHandler);
                context.TurnState.Add(connectorClient);

                await RunPipelineAsync(context, callbackHandler, cancellationToken).ConfigureAwait(false);

                if (activity.Type == ActivityTypes.Invoke)
                {
                    var activityInvokeResponse = context.TurnState.Get <Activity>(InvokeResponseKey);
                    if (activityInvokeResponse == null)
                    {
                        return(new InvokeResponse {
                            Status = (int)HttpStatusCode.NotImplemented
                        });
                    }
                    else
                    {
                        return((InvokeResponse)activityInvokeResponse.Value);
                    }
                }

                return(null);
            }
        }
        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);
        }
        /// <summary>
        /// Log an activity to the transcript.
        /// </summary>
        /// <param name="activity">Activity being logged.</param>
        /// <returns></returns>
        public async Task LogActivity(IActivity activity)
        {
            BotAssert.ActivityNotNull(activity);

            var blobName      = GetBlobName(activity);
            var blobReference = this.Container.Value.GetBlockBlobReference(blobName);

            blobReference.Properties.ContentType  = "application/json";
            blobReference.Metadata["FromId"]      = activity.From.Id;
            blobReference.Metadata["RecipientId"] = activity.Recipient.Id;
            blobReference.Metadata["Timestamp"]   = activity.Timestamp.Value.ToString("O");
            using (var blobStream = await blobReference.OpenWriteAsync())
            {
                using (var jsonWriter = new JsonTextWriter(new StreamWriter(blobStream)))
                {
                    jsonSerializer.Serialize(jsonWriter, activity);
                }
            }
            await blobReference.SetMetadataAsync();
        }
Ejemplo n.º 7
0
        public async override Task Send(IList <IActivity> activities)
        {
            BotAssert.ActivityListNotNull(activities);

            foreach (Activity activity in activities)
            {
                if (activity.Type == "delay")
                {
                    // The Activity Schema doesn't have a delay type build in, so it's simulated
                    // here in the Bot. This matches the behavior in the Node connector.
                    int delayMs = (int)activity.Value;
                    await Task.Delay(delayMs).ConfigureAwait(false);
                }
                else
                {
                    var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl), _credentials);
                    await connectorClient.Conversations.SendToConversationAsync(activity).ConfigureAwait(false);
                }
            }
        }
Ejemplo n.º 8
0
        private async Task ContextCreatedInternal(IBotContext context, IContextCreated[] middleware)
        {
            BotAssert.MiddlewareNotNull(middleware);

            if (middleware.Length == 0) // No middleware to run.
            {
                return;
            }

            async Task next()
            {
                // Remove the first item from the list of middleware to call,
                // so that the next call just has the remaining items to worry about.
                IContextCreated[] remainingMiddleware = middleware.Skip(1).ToArray();
                await ContextCreatedInternal(context, remainingMiddleware).ConfigureAwait(false);
            }

            // Grab the current middleware, which is the 1st element in the array, and execute it
            await middleware[0].ContextCreated(context, 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);
        }
Ejemplo n.º 10
0
        public void TrackIntent(IActivity activity, RecognizerResult result)
        {
            BotAssert.ActivityNotNull(activity);

            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            var topScoringIntent = result.GetTopScoringIntent();

            var properties = new Dictionary <string, string>
            {
                { IntentConstants.Intent, topScoringIntent.intent },
                { IntentConstants.Score, topScoringIntent.score.ToString(CultureInfo.InvariantCulture) },
                { IntentConstants.Entities, result.Entities.ToString(Formatting.None) }
            };

            this.TrackIntent(activity, properties);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Recognizes and validates the user input.
        /// </summary>
        /// <param name="context">Context for the current turn of the conversation with the user.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public override async Task <AttachmentResult> RecognizeAsync(ITurnContext context)
        {
            BotAssert.ContextNotNull(context);
            BotAssert.ActivityNotNull(context.Activity);

            var attachmentResult = new AttachmentResult();

            if (context.Activity.Type == ActivityTypes.Message)
            {
                var message = context.Activity.AsMessageActivity();
                if (message.Attachments != null)
                {
                    attachmentResult.Status = PromptStatus.Recognized;
                    attachmentResult.Attachments.AddRange(message.Attachments);
                    await ValidateAsync(context, attachmentResult);
                }
            }

            return(attachmentResult);
        }
        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 ProcessActivity(DirectMessageEvent obj, BotCallbackHandler callback)
        {
            TurnContext context = null;

            try
            {
                var activity = RequestToActivity(obj);
                BotAssert.ActivityNotNull(activity);

                context = new TurnContext(this, activity);

                await RunPipelineAsync(context, callback, default).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                await OnTurnError(context, ex);

                throw;
            }
        }
Ejemplo n.º 14
0
        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
                });
            }
        }
        public async Task <GoogleResponseBody> ProcessActivity(Payload actionPayload, GoogleOptions googleOptions, BotCallbackHandler callback)
        {
            TurnContext context = null;

            try
            {
                Options = googleOptions;

                var activity = RequestToActivity(actionPayload, googleOptions);
                BotAssert.ActivityNotNull(activity);

                context = new TurnContext(this, activity);

                Responses = new Dictionary <string, List <Activity> >();

                await base.RunPipelineAsync(context, callback, default(CancellationToken)).ConfigureAwait(false);

                var key = $"{activity.Conversation.Id}:{activity.Id}";

                try
                {
                    GoogleResponseBody response = null;
                    var activities = Responses.ContainsKey(key) ? Responses[key] : new List <Activity>();
                    response = CreateResponseFromLastActivity(activities, context);
                    return(response);
                }
                finally
                {
                    if (Responses.ContainsKey(key))
                    {
                        Responses.Remove(key);
                    }
                }
            }
            catch (Exception ex)
            {
                await googleOptions.OnTurnError(context, ex);

                throw;
            }
        }
Ejemplo n.º 17
0
        /// <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);
        }
        /// <summary>
        /// Primary adapter method for processing activities sent from calling bot.
        /// </summary>
        /// <param name="activity">The activity to process.</param>
        /// <param name="callback">The BotCallBackHandler to call on completion.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>The response to the activity.</returns>
        public async Task <InvokeResponse> ProcessActivityAsync(Activity activity, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            BotAssert.ActivityNotNull(activity);

            _botTelemetryClient.TrackTrace($"Received an incoming activity. ActivityId: {activity.Id}", Severity.Information, null);

            using (var context = new TurnContext(this, activity))
            {
                await RunPipelineAsync(context, callback, cancellationToken).ConfigureAwait(false);

                // We do not support Invoke in websocket transport
                if (activity.Type == ActivityTypes.Invoke)
                {
                    return(new InvokeResponse {
                        Status = (int)HttpStatusCode.NotImplemented
                    });
                }

                return(null);
            }
        }
Ejemplo n.º 19
0
        /// <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);
        }
Ejemplo n.º 20
0
        /// <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 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>
        /// 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 void TrackEvent(IMessageActivity activity, QueryResult queryResult)
        {
            BotAssert.ActivityNotNull(activity);
            if (queryResult == null)
            {
                throw new ArgumentNullException(nameof(queryResult));
            }

            var properties = new Dictionary <string, string>
            {
                { QnAConstants.UserQuery, activity.Text },
                { QnAConstants.KnowledgeBaseQuestion, string.Join(QuestionsSeparator, queryResult.Questions) },
                { QnAConstants.KnowledgeBaseAnswer, queryResult.Answer },
                { QnAConstants.Score, queryResult.Score.ToString(CultureInfo.InvariantCulture) }
            };

            var builder        = new EventTelemetryBuilder(activity, this.settings, properties);
            var eventTelemetry = builder.Build();

            eventTelemetry.Name = EventTypes.QnaEvent;
            this.telemetryClient.TrackEvent(eventTelemetry);
        }
        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);
        }
Ejemplo n.º 25
0
        /// <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
                });
            }
        }
Ejemplo n.º 26
0
            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());
            }
        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);
        }
Ejemplo n.º 28
0
        /// <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);
        }
        // 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);
                    }
                }
            }
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Primary adapter method for processing activities sent from calling bot.
        /// </summary>
        /// <param name="activity">The activity to process.</param>
        /// <param name="callback">The BotCallBackHandler to call on completion.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>The response to the activity.</returns>
        public async Task <InvokeResponse> ProcessActivityAsync(Activity activity, BotCallbackHandler callback, CancellationToken cancellationToken)
        {
            // Ensure the Activity has been retrieved from the HTTP POST
            BotAssert.ActivityNotNull(activity);

            _botTelemetryClient.TrackTrace($"SkillHttpBotAdapter: Received an incoming activity. Activity id: {activity.Id}", Severity.Information, null);

            // Process the Activity through the Middleware and the Bot, this will generate Activities which we need to send back.
            using (var context = new TurnContext(this, activity))
            {
                await RunPipelineAsync(context, callback, default(CancellationToken));
            }

            _botTelemetryClient.TrackTrace($"SkillHttpBotAdapter: Batching activities in the response. ReplyToId: {activity.ReplyToId}", Severity.Information, null);

            // Any Activity responses are now available (via SendActivitiesAsync) so we need to pass back for the response
            var response = new InvokeResponse
            {
                Status = (int)HttpStatusCode.OK,
                Body   = GetReplies(),
            };

            return(response);
        }