Skip to content
This repository has been archived by the owner on Jun 30, 2022. It is now read-only.

Bot.Builder.Community.Adapters.Alexa not working with the VA #2403

Closed
samaea opened this issue Sep 19, 2019 · 3 comments
Closed

Bot.Builder.Community.Adapters.Alexa not working with the VA #2403

samaea opened this issue Sep 19, 2019 · 3 comments
Assignees
Labels
Type: Bug Something isn't working

Comments

@samaea
Copy link

samaea commented Sep 19, 2019

What project is affected?

Virtual Assistant.

What language is this in?

C#

What happens?

BotBuilder.Community.Adapters.Alexa doesn't seem to work with the VA.

What are the steps to reproduce this issue?

Followed the instructions here:- https://github.com/BotBuilderCommunity/botbuilder-community-dotnet/tree/develop/libraries/Bot.Builder.Community.Adapters.Alexa

  1. In the Startup.cs I added the following NuGet packages:

Bot.Builder.Community.Adapters.Alexa;
Bot.Builder.Community.Adapters.Alexa.Integration.AspNet.Core;
Bot.Builder.Community.Adapters.Alexa.Middleware;

Before this code

            // Configure bot
            services.AddTransient<IBot, DialogBot<MainDialog>>();

I added:

            // Registering the AlexaHttpAdapter
            services.AddSingleton<IAlexaHttpAdapter>((sp) =>
            {
                var alexaHttpAdapter = new AlexaHttpAdapter(validateRequests: true)
                {
                    OnTurnError = async (context, exception) =>
                    {
                        await context.SendActivityAsync("Sorry, something went wrong. Please try again later." + context + " Exception:" + exception);
                    },
                    ShouldEndSessionByDefault = true,
                    ConvertBotBuilderCardsToAlexaCards = false,
                };
                alexaHttpAdapter.Use(new AlexaIntentRequestToMessageActivityMiddleware());
                return alexaHttpAdapter;
            });

            services.AddSingleton<AlexaIntentRequestToMessageActivityMiddleware>();
  1. Created an Alexa controller:
using Bot.Builder.Community.Adapters.Alexa.Integration.AspNet.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GuideDogs_VA.Controllers
{
    [Route("api/skillrequests")]
    [ApiController]
    public class AlexaBotController : ControllerBase
    {
        private readonly IAlexaHttpAdapter _adapter;
        private readonly IBot _bot;

        public AlexaBotController(IAlexaHttpAdapter adapter, IBot bot)
        {
            _adapter = adapter;
            _bot = bot;
        }

        [HttpPost]
        public async Task PostAsync()
        {
            await _adapter.ProcessAsync(Request, Response, _bot);
        }
    }
}
  1. Created an Alexa Skill using the following JSON:
{
    "interactionModel": {
        "languageModel": {
            "invocationName": "guide dogs",
            "intents": [
                {
                    "name": "GetUserIntent",
                    "slots": [
                        {
                            "name": "phrase",
                            "type": "phrase"
                        }
                    ],
                    "samples": [
                        "{phrase}"
                    ]
                },
                {
                    "name": "AMAZON.FallbackIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.NavigateHomeIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                }
            ],
            "types": [
                {
                    "name": "phrase",
                    "values": [
                        {
                            "name": {
                                "value": "hi there Alexa"
                            }
                        },
                        {
                            "name": {
                                "value": "you are just going to repeat what I said aren't you"
                            }
                        },
                        {
                            "name": {
                                "value": "what colour is the sky?"
                            }
                        }
                    ]
                }
            ]
        }
    }
}

What were you expecting to happen?

When testing the Alexa Skill through Alexa's developer console or via an Alexa device, for it to respond, but unfortunately it ends up calling OnEventSync() even though the activity type is of type message.

Can you share any logs, error output, etc.?

System.NullReferenceException thrown from the MainDialog.cs file:

image

Any screenshots or additional context?

image

Response from the VA to Alexa (response generated from the Startup.cs context.SendActivityAsync:- await context.SendActivityAsync("Sorry, something went wrong. Please try again later." + context + " Exception:" + exception):

{
	"body": {
		"version": "1.0",
		"response": {
			"outputSpeech": {
				"type": "PlainText",
				"text": "Sorry, something went wrong. Please try again later.Microsoft.Bot.Builder.TurnContext Exception:System.NullReferenceException: Object reference not set to an instance of an object.\r\n   at GuideDogs_VA.Dialogs.MainDialog.OnEventAsync(DialogContext dc, CancellationToken cancellationToken) in C:\\Users\\hussel\\source\\repos\\GuideDogs-VA\\GuideDogs_VA\\Dialogs\\MainDialog.cs:line 204\r\n   at Microsoft.Bot.Builder.Solutions.Dialogs.RouterDialog.OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken)\r\n   at Microsoft.Bot.Builder.Dialogs.ComponentDialog.BeginDialogAsync(DialogContext outerDc, Object options, CancellationToken cancellationToken)\r\n   at Microsoft.Bot.Builder.Dialogs.DialogContext.BeginDialogAsync(String dialogId, Object options, CancellationToken cancellationToken)\r\n   at Microsoft.Bot.Builder.Dialogs.DialogExtensions.RunAsync(Dialog dialog, ITurnContext turnContext, IStatePropertyAccessor`1 accessor, CancellationToken cancellationToken)\r\n   at GuideDogs_VA.Bots.DialogBot`1.OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) in C:\\Users\\hussel\\source\\repos\\GuideDogs-VA\\GuideDogs_VA\\Bots\\DialogBot.cs:line 39\r\n   at Bot.Builder.Community.Adapters.Alexa.Middleware.AlexaIntentRequestToMessageActivityMiddleware.OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken)\r\n   at Microsoft.Bot.Builder.MiddlewareSet.ReceiveActivityWithStatusAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken)\r\n   at Microsoft.Bot.Builder.BotAdapter.RunPipelineAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken)"
			},
			"directives": [],
			"shouldEndSession": true,
			"type": "_DEFAULT_RESPONSE"
		},
		"sessionAttributes": {}
	}
}
@lauren-mills
Copy link
Contributor

This is probably caused by the default RouterDialog implementation. One option to try is overriding the ContinueDialogAsync method in MainDialog with the behavior you want.

@lauren-mills lauren-mills self-assigned this Sep 20, 2019
@lauren-mills lauren-mills added Bot Services Required for internal Azure reporting. Do not delete. Do not change color. customer-replied-to Indicates that the team has replied to the issue reported by the customer. Do not delete. customer-reported Issue is created by anyone that is not a collaborator in the repository. and removed Needs Triage Needs to be triaged for assignment labels Sep 20, 2019
@garypretty
Copy link
Contributor

@samaea I have reproduced the issue. @lauren-mills was right, it is due to the RouterDialog looking for a value on the activity and treating it as an event, rather than a normal message activity.

You can add the following override to your MainDialog as a workaround. With the only change being that we are checking if the channel ID is Alexa.

After adding this change I can successfully get a response from the VA via Alexa. Hope that resolves your issue.

protected override async Task<DialogTurnResult> OnContinueDialogAsync(DialogContext innerDc, CancellationToken cancellationToken = default)
        {
            var activity = innerDc.Context.Activity;

            if (activity.IsStartActivity())
            {
                await OnStartAsync(innerDc);
            }

            switch (activity.Type)
            {
                case ActivityTypes.Message:
                    {
                        if (activity.Value != null && activity.ChannelId != "alexa")
                        {
                            await OnEventAsync(innerDc);
                        }
                        else if (!string.IsNullOrEmpty(activity.Text))
                        {
                            var result = await innerDc.ContinueDialogAsync();

                            switch (result.Status)
                            {
                                case DialogTurnStatus.Empty:
                                    {
                                        await RouteAsync(innerDc);
                                        break;
                                    }

                                case DialogTurnStatus.Complete:
                                    {
                                        await CompleteAsync(innerDc);

                                        // End active dialog
                                        await innerDc.EndDialogAsync();
                                        break;
                                    }

                                default:
                                    {
                                        break;
                                    }
                            }
                        }

                        break;
                    }

                case ActivityTypes.Event:
                    {
                        await OnEventAsync(innerDc);
                        break;
                    }

                default:
                    {
                        await OnSystemMessageAsync(innerDc);
                        break;
                    }
            }

            return EndOfTurn;
        }

@lauren-mills
Copy link
Contributor

Thanks @garypretty! I have an open work item for the next release to refactor RouterDialog to align more with the SDK, so I can take this feedback in for that work as well.

@darrenj darrenj removed Bot Services Required for internal Azure reporting. Do not delete. Do not change color. customer-replied-to Indicates that the team has replied to the issue reported by the customer. Do not delete. customer-reported Issue is created by anyone that is not a collaborator in the repository. labels Sep 24, 2019
@darrenj darrenj closed this as completed Sep 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants