Botframework-solutions: Bot.Builder.Community.Adapters.Alexa ne fonctionne pas avec le VA

Créé le 19 sept. 2019  ·  3Commentaires  ·  Source: microsoft/botframework-solutions

Quel projet est concerné ?

Assistant virtuel.

C'est dans quelle langue ?

C#

Ce qui se produit?

BotBuilder.Community.Adapters.Alexa ne semble pas fonctionner avec le VA.

Quelles sont les étapes pour reproduire ce problème ?

J'ai suivi les instructions ici :- https://github.com/BotBuilderCommunity/botbuilder-community-dotnet/tree/develop/libraries/Bot.Builder.Community.Adapters.Alexa

1) Dans Startup.cs, j'ai ajouté les packages NuGet suivants :

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

Avant ce code

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

J'ai ajouté:

            // 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>();

2) Création d'une manette Alexa :

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);
        }
    }
}

3) Création d'une compétence Alexa à l'aide du JSON suivant :

{
    "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?"
                            }
                        }
                    ]
                }
            ]
        }
    }
}

Que vous attendiez-vous à ce qu'il se passe ?

Lors du test de la compétence Alexa via la console développeur d'Alexa ou via un appareil Alexa, pour qu'elle réponde, mais malheureusement, elle finit par appeler OnEventSync() même si le type d'activité est de type message.

Pouvez-vous partager des journaux, des sorties d'erreur, etc. ?

System.NullReferenceException levée à partir du fichier MainDialog.cs :

image

Des captures d'écran ou un contexte supplémentaire ?

image

Réponse du VA à Alexa (réponse générée à partir du contexte Startup.cs.SendActi vityAsync :- wait context.SendActivityAsync ("Désolé, quelque chose s'est mal passé. Veuillez réessayer plus tard." + contexte + " 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": {}
    }
}
Bug

Commentaire le plus utile

@samaea J'ai reproduit le problème. @lauren-mills avait raison, cela est dû au fait que RouterDialog recherche une valeur sur l'activité et la traite comme un événement, plutôt que comme une activité de message normale.

Vous pouvez ajouter le remplacement suivant à votre MainDialog comme solution de contournement. Le seul changement étant que nous vérifions si l'ID de la chaîne est Alexa.

Après avoir ajouté ce changement, je peux obtenir avec succès une réponse du VA via Alexa. J'espère que cela résoudra votre problème.

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;
        }

Tous les 3 commentaires

Cela est probablement dû à l'implémentation par défaut de RouterDialog. Une option à essayer consiste à remplacer la méthode ContinueDialogAsync dans MainDialog avec le comportement souhaité.

@samaea J'ai reproduit le problème. @lauren-mills avait raison, cela est dû au fait que RouterDialog recherche une valeur sur l'activité et la traite comme un événement, plutôt que comme une activité de message normale.

Vous pouvez ajouter le remplacement suivant à votre MainDialog comme solution de contournement. Le seul changement étant que nous vérifions si l'ID de la chaîne est Alexa.

Après avoir ajouté ce changement, je peux obtenir avec succès une réponse du VA via Alexa. J'espère que cela résoudra votre problème.

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;
        }

Merci @garypretty ! J'ai un élément de travail ouvert pour la prochaine version afin de refactoriser RouterDialog afin de l'aligner davantage sur le SDK, afin que je puisse également prendre en compte ces commentaires pour ce travail.

Cette page vous a été utile?
0 / 5 - 0 notes