Botframework-solutions: Bot.Builder.Community.Adapters.Alexa 不与 VA 一起工作

创建于 2019-09-19  ·  3评论  ·  资料来源: microsoft/botframework-solutions

什么项目受到影响?

虚拟助手。

这是什么语言?

C#

发生什么了?

BotBuilder.Community.Adapters.Alexa 似乎不适用于 VA。

重现此问题的步骤是什么?

按照此处的说明进行操作https://github.com/BotBuilderCommunity/botbuilder-community-dotnet/tree/develop/libraries/Bot.Builder.Community.Adapters.Alexa

1) 在 Startup.cs 中,我添加了以下 NuGet 包:

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

这段代码之前

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

我补充说:

            // 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)创建一个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) 使用以下 JSON 创建一个 Alexa 技能:

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

你期待发生什么?

当通过 Alexa 的开发人员控制台或通过 Alexa 设备测试 Alexa 技能时,它会做出响应,但不幸的是,即使活动类型是消息类型,它最终也会调用 OnEventSync()。

你能分享任何日志、错误输出等吗?

从 MainDialog.cs 文件抛出的 System.NullReferenceException:

image

任何屏幕截图或其他上下文?

image

VA 对 Alexa 的响应(从 Startup.cs context.SendActi vityAsync生成的响应

{
    "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": {}
    }
}

最有用的评论

@samaea我已经重现了这个问题。 @lauren-mills 是对的,这是因为 RouterDialog 寻找活动的值并将其视为事件,而不是正常的消息活动。

您可以将以下覆盖添加到 MainDialog 作为解决方法。 唯一的变化是我们正在检查频道 ID 是否为 Alexa。

添加此更改后,我可以通过 Alexa 成功获得 VA 的响应。 希望能解决您的问题。

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

所有3条评论

这可能是由默认的 RouterDialog 实现引起的。 尝试的一种选择是使用您想要的行为覆盖 MainDialog 中的 ContinueDialogAsync 方法。

@samaea我已经重现了这个问题。 @lauren-mills 是对的,这是因为 RouterDialog 寻找活动的值并将其视为事件,而不是正常的消息活动。

您可以将以下覆盖添加到 MainDialog 作为解决方法。 唯一的变化是我们正在检查频道 ID 是否为 Alexa。

添加此更改后,我可以通过 Alexa 成功获得 VA 的响应。 希望能解决您的问题。

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

谢谢@garypretty! 我有一个开放的工作项供下一个版本使用,以重构 RouterDialog 以使其与 SDK 更加一致,因此我也可以将这些反馈用于该工作。

此页面是否有帮助?
0 / 5 - 0 等级