How to receive the location from Messenger Locatio

2019-07-29 07:42发布

问题:

Hi i have this code that prompt the user for their location. I am using Botframework v4 and C#. I put the messenger quick reply in an attachment prompt.

  if (response == "test location")
        {
            Activity reply = stepContext.Context.Activity.CreateReply();

            reply.ChannelData = JObject.FromObject(
            new
            {
                text = "loc",
                quick_replies = new object[]
                {
                    new
                    {
                        content_type = "location",
                    },
                },
            });

            return await stepContext.PromptAsync(
               ATTACHPROMPT,
               new PromptOptions
               {
                   Prompt = reply,
               });
        }

But after the user send its location. The bot crashes. How can i handle the return of the location so the bot won't crash? Here is the exeption

System.ArgumentNullException: Value cannot be null. Parameter name: utterance at Microsoft.Bot.Builder.AI.Luis.LuisRecognizer.d*23.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.AI.Luis.LuisRecognizer.d*10.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.BotBuilderSamples.BasicBot.d*24.MoveNext() in C:\Users\bguevarra\Desktop\finko\FinkoBot\Bots\BasicBot.cs:line 104 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.MiddlewareSet.d*3.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Bot.Builder.BotAdapter.d__13.MoveNext() == Oops Sorry, it looks like something went wrong.

OnTurnAsync()

    public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken)
    {
        var dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
        var activity = turnContext.Activity;

        var userstate = await _basicAccessors.BasicUserStateAccessor.GetAsync(turnContext, () => new BasicUserState(), cancellationToken);
        var state = await _basicAccessors.BasicStateAccessor.GetAsync(turnContext, () => new BasicState(), cancellationToken);

        if (turnContext.Activity.Type == ActivityTypes.Message)
        {
            turnContext.TurnState.Add("BasicAccessors", _basicAccessors);

            string text = string.IsNullOrEmpty(turnContext.Activity.Text) ? string.Empty : turnContext.Activity.Text.ToLower();

            var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken);
            var topScoringIntent = luisResults?.GetTopScoringIntent();
            var topIntent = topScoringIntent.Value.intent;
            turnContext.TurnState.Add("topIntent", topIntent);

            turnContext.TurnState.Add("text", text);

            var interrupted = await IsTurnInterruptedAsync(turnContext);
            if (interrupted)
            {
                await _basicAccessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
                await _basicAccessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
                return;
            }

            // Continue the current dialog
            var dialogResult = await dc.ContinueDialogAsync();

            // if no one has responded,
            if (!dc.Context.Responded)
            {
                // examine results from active dialog
                switch (dialogResult.Status)
                {
                    case DialogTurnStatus.Empty:

                        switch (topIntent) 
                        {
                            case MainDialogIntent:
                                await dc.BeginDialogAsync(MainDialogId);
                                break;

                            case LoanCalculatorIntent:
                                await dc.BeginDialogAsync(LoanCalculatorId);
                                break;

                            case RealEstateIntent:
                                await dc.BeginDialogAsync(RealEstateDialogId);
                                break;

                            case GreetingIntent:
                                Random rnd = new Random();
                                int x = rnd.Next(1, 5);
                                switch (x)
                                {
                                    case 1:
                                        await dc.Context.SendActivityAsync("Hi!");
                                        break;

                                    case 2:
                                        await dc.Context.SendActivityAsync("Hello!");
                                        break;

                                    case 3:
                                        await dc.Context.SendActivityAsync("Good day!");
                                        break;

                                    default:
                                        break;
                                }

                                break;

                            case NoneIntent: // NoneIntent:
                            default:
                                await dc.Context.SendActivityAsync("I didn't understand what you just said to me.");
                                break;
                        }

                        break;

                    case DialogTurnStatus.Waiting:
                        // The active dialog is waiting for a response from the user, so do nothing.
                        break;

                    case DialogTurnStatus.Complete:
                        await dc.EndDialogAsync();
                        break;

                    default:
                        await dc.CancelAllDialogsAsync();
                        break;
                }
            }

            await _basicAccessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
            await _basicAccessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
        }
        else if (activity.Type == ActivityTypes.ConversationUpdate)
        {
            if (activity.MembersAdded != null)
            {
                // Iterate over all new members added to the conversation.
                foreach (var member in activity.MembersAdded)
                {
                    // Greet anyone that was not the target (recipient) of this message.
                    // To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
                    if (member.Id != activity.Recipient.Id)
                    {
                        await SendWelcomeMessageAsync(turnContext, cancellationToken);
                    }
                }
            }
        }

        await _basicAccessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
        await _basicAccessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
    }

回答1:

When the user clicks on the location quick reply in Facebook Messenger, the incoming activity does not have a text property which would cause a 'Value cannot be null' error when calling LUIS. This is currently a known issue in the BotFramework, and the development team is currently working to resolve this problem. In the meantime, check to make sure the incoming activity's text attribute is not null or empty before calling the LUIS recognizer.

if(!string.IsNullOrEmpty(turnContext.Activity.Text)) {
  var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken);
} 

Hope this helps!