0
votes

i'd like to start a proactive dialog. I try to modify this proactive message example https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/16.proactive-messages

I have changed this sample the next way:

private async Task BotCallback(ITurnContext turnContext, CancellationToken)  
{  
    _dialog.RunAsync(turnContext, _conversationState<DialogState>("DialogState"), cancellationToken);  
     try  
     {  
        await _conversationState.SaveChangesAsync(turnContext, true, cancellationToken);  
     }  
     catch(Exception ex)  
     {  
        _logger.LogError($"{nameof(_conversationState)}, {ex.Message}");  
     }  
}  

and the dialog starts but when bot gets the next message from a user it can not continue this dialog and throws the below exception:

Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter:Error: >Exception caught : DialogContext.ContinueDialogAsync(): Can't continue >dialog. A dialog with an id of 'LearnDialog' wasn't found.".

i inject the dialog via constructor using DI
Constructor:

public NotifiController(IBotFrameworkHttpAdapter adapter, IStorage storage, LearnDialog dialog, ConversationState conversationState)  
        {  
            _adapter = (BotFrameworkHttpAdapter)adapter ?? throw new ArgumentNullException(nameof(adapter));  
            _storage = storage ?? throw new ArgumentNullException(nameof(storage));  
            _dialog = dialog ?? throw new ArgumentNullException(nameof(dialog));  
        }  

Startup.cs:

public void ConfigureServices(IServiceCollection services)  
        {        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);  
            // Create the Bot Framework Adapter with error handling enabled.  
            services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();  
            services.AddSingleton<IStorage, MemoryStorage>();  
            services.AddSingleton < UserState>();  
            services.AddSingleton<ConversationState>();  
            services.AddSingleton<MainDialog>();  
            services.AddSingleton<LearnDialog>();  
            services.AddTransient<IBot, DialogBot<MainDialog>();  
        }  
1
Can you show how you added _dialog there? And also how changed (if changed?) OnMessageActivityAsync of your bot? - JleruOHeP
i did not change OnMessageActivityAsync protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken) { await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken); } - Konstantin Galiakhmetov

1 Answers

0
votes

the reason of my problem was that i tried to run LearnDialog directly although it usually is run from MainDialog. The solution is as follows: In the MainDialog class define the special methoth that allows an external code to change a starting dialog:

public void SetLearnDialogAsInitial(bool state) =>
    InitialDialogId = state ? nameof(LearnDialog) : nameof(WaterfallDialog);

Pas the MainDialog to Class that calls proactive dialog, in my case it is NotifyController like in the source example of sending proactive-messages

public class NotifiController : ControllerBase
    {

        public NotifiController(IBotFrameworkHttpAdapter adapter, IStorage storage, MainDialog dialog, ConversationState conversationState, ILogger<NotifiController> logger)
        {
            _adapter = (BotFrameworkHttpAdapter)adapter ?? throw new ArgumentNullException(nameof(adapter));
            _storage = storage ?? throw new ArgumentNullException(nameof(storage));
            _mainDialog = dialog ?? throw new ArgumentNullException(nameof(dialog));
            _conversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
            _appId = Guid.NewGuid().ToString();
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }
    }

in BotCalback methoth set LearnDialog as Initial dialog in MainDialog and then Run MainDialog:

private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)   
        {
            _mainDialog.SetLearnDialogAsInitial(true);
            var dialog = (Dialog)_mainDialog;
            await dialog.RunAsync(turnContext, _conversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
//              _mainDialog.SetLearnDialogAsInitial(false);
            try
            {
                await _conversationState.SaveChangesAsync(turnContext, true, cancellationToken);
            }
            catch(Exception ex)
            {
                _logger.LogError($"{nameof(_conversationState)}, {ex.Message}");
            }
        }

it works for me.