How to delete dialog stack of Botframework from console.application

0

Question : How is dialog stack of Botframework deleted from console application (or web job)

I would like to delete user's dialog stack so that user can back to root dialog if they stop talking to Bot and few hours passed. As a test, I created following console app and tried to delete user's dialog stack.

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

However, an exception occurs when following method is called.

await botData.LoadAsync(default(CancellationToken));

The exception is as follows (401 Not authorized).

System.AggregateException occurred HResult=0x80131500 Message=1 つ以上のエラーが発生しました。 Source=mscorlib StackTrace: at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at System.Threading.Tasks.Task.Wait() at ConsoleApp6.Program.Main(String[] args) in C:\Users\sheda\documents\visual studio 2017\Projects\ConsoleApp6\ConsoleApp6\Program.cs:line 22

Inner Exception 1: OAuthException: Unauthorized

Inner Exception 2: HttpRequestException: 応答の状態コードは成功を示していません: 401 (Unauthorized)。

Could you tell me how to delete dialog stack?

FYI: I know if I create instance of StateCient and call DeleteStateForUserAsync() method, I confirmed the method can delete dialog stack. But the method deletes not only dialog stack but also properties set at state service. I would like to delete only dialog stack. Therefore I am looking for another way.

c#
botframework
microsoft-teams
direct-line-botframework
asked on Stack Overflow Sep 18, 2017 by user3395471 • edited Sep 18, 2017 by JasonSowers

1 Answer

0

When you make the call in your code:

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

Internally, the Bot Framework SDK registers its own MicrosoftAppCredentials instance; that instance is what requests the token used by your bot. However, the token only lasts for 60 minutes or so. As long as the user keeps talking to the bot, that token is transparently refreshed behind the scenes, but when a user hasn't been talking to the bot in a while, that doesn't happen, which is what leads to the exception. If you watch your bot using Fiddler, you'll see it trying to get a token with a blank appid and password, followed by the HTTP 401 exception.

If you add the following to your app.config or web.config file, then the MicrosoftAppCredentials instance in the SDK will pick up the app ID and password using ConfigurationManager.AppSettings and refresh the token for you:

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

Once you do that, you can clean up your own code to retrieve MicrosoftAppId and MicrosoftAppPassword from the ConfigurationManager.AppSettings API too instead of setting them as variables in your Test() function.

answered on Stack Overflow Sep 27, 2017 by Bill Bliss - MSFT

User contributions licensed under CC BY-SA 3.0