0

问题:如何从控制台应用程序(或 Web 作业)中删除 Botframework 的对话框堆栈

我想删除用户的对话框堆栈,以便用户在停止与 Bot 交谈并且几个小时过去后可以返回到根对话框。作为测试,我创建了以下控制台应用程序并尝试删除用户的对话框堆栈。

using Autofac;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Internals;
using Microsoft.Bot.Connector;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp6
{
    class Program
    {
        const string MicrosoftTeamsUserId = "29:xxxxxxxxxxx-Q";
        const string BotId = "28:xxxx-xxxx-xxx-xxxx-xxx";
        const string channelId = "msteams";
        const string appId = "xxxx-xxxx-xxxx-xxxx-xxxxx";
        const string password = "xxxxxxxxxxxxxxx";
        const string serviceUrl = "https://smba.trafficmanager.net/";

        static void Main(string[] args)
        {
            Test().Wait();
            Console.WriteLine("Done");
            Console.Read();
        }

        public static async Task Test()
        {
            MicrosoftAppCredentials.TrustServiceUrl(serviceUrl, DateTime.MaxValue);
            var connector = new ConnectorClient(new Uri(serviceUrl), appId, password);
            var botAccount = new ChannelAccount(BotId);
            var userAccount = new ChannelAccount(MicrosoftTeamsUserId);
            var res = connector.Conversations.CreateDirectConversation(botAccount, userAccount);

            var activity = Activity.CreateMessageActivity();
            activity.ChannelId = channelId;
            activity.Recipient = userAccount;
            activity.From = botAccount;
            activity.ServiceUrl = serviceUrl;
            activity.Conversation = new ConversationAccount(id: res.Id);
            activity.Locale = "ja-JP";
            activity.Text = "TEST";

            using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
            {
                var botData = scope.Resolve<IBotData>();
                await botData.LoadAsync(default(CancellationToken));
                var stack = scope.Resolve<IDialogStack>();
                stack.Reset();
                await botData.FlushAsync(default(CancellationToken));
                //await Conversation.SendAsync(activity, () => new RootDialog());
            }
        }
    }
}

但是,调用以下方法时会发生异常。

等待 botData.LoadAsync(default(CancellationToken));

例外情况如下(401 未授权)。

System.AggregateException 发生 HResult=0x80131500 Message=1 つ以上のエラーが発生しました。 Source=mscorlib StackTrace: at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task.Wait(Int32在 C:\Users\sheda\documents\visual studio 2017\Projects\ConsoleApp6\ConsoleApp6\Program 中 ConsoleApp6.Program.Main(String[] args) 的 System.Threading.Tasks.Task.Wait() 的毫秒超时,CancellationToken cancelToken) .cs:第 22 行

内部异常 1:OAuthException:未经授权

内部异常2:HttpRequestException: 応の状态コードは成功を示していません: 401 (Unauthorized)。</p>

你能告诉我如何删除对话框堆栈吗?

仅供参考:我知道如果我创建 StateCient 实例并调用 DeleteStateForUserAsync() 方法,我确认该方法可以删除对话框堆栈。但是该方法不仅删除了对话框堆栈,还删除了在状态服务中设置的属性。我想只删除对话框堆栈。因此,我正在寻找另一种方式。

4

1 回答 1

0

当您在代码中进行调用时:

var connector = new ConnectorClient(new Uri(serviceUrl), appId, password)

在内部,Bot Framework SDK 注册了自己的 MicrosoftAppCredentials 实例;该实例是请求您的机器人使用的令牌的原因。但是,令牌仅持续 60 分钟左右。只要用户继续与机器人交谈,该令牌就会在幕后透明地刷新,但是当用户有一段时间没有与机器人交谈时,这种情况就不会发生,这就是导致异常的原因。如果你使用 Fiddler 观察你的机器人,你会看到它试图获取一个带有空白 appid 和密码的令牌,然后是 HTTP 401 异常。

如果您将以下内容添加到 app.config 或 web.config 文件,则 SDK 中的 MicrosoftAppCredentials 实例将使用 ConfigurationManager.AppSettings 获取应用 ID 和密码并为您刷新令牌:

<appSettings>
  <add key="MicrosoftAppId" value="[id]"/>
  <add key="MicrosoftAppPassword" value="[password]"/>
</appSettings>

完成此操作后,您可以清理自己的代码以从ConfigurationManager.AppSettings API检索 MicrosoftAppId 和 MicrosoftAppPassword,而不是将它们设置为 Test() 函数中的变量。

于 2017-09-27T21:34:39.087 回答