Implement global message handlers in the v3 C# SDK

APPLIES TO: SDK v3

Users commonly attempt to access certain functionality within a bot by using keywords like "help", "cancel", or "start over". This often occurs in the middle of a conversation, when the bot is expecting a different response. By implementing global message handlers, you can design your bot to gracefully handle such requests. The handlers will examine user input for the keywords that you specify, such as "help", "cancel", or "start over", and respond appropriately.

how users talk

Note

By defining the logic in global message handlers, you're making it accessible to all dialogs. Individual dialogs and prompts can be configured to safely ignore the keywords.

Listen for keywords in user input

The following walk through shows how to implement global message handlers by using the Bot Framework SDK for .NET.

First, Global.asax.cs registers GlobalMessageHandlersBotModule, which is implemented as shown here. In this example, the module registers two scorables: one for managing a request to change settings (SettingsScorable) and another for managing a request to cancel (CancelScoreable).

public class GlobalMessageHandlersBotModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);

        builder
            .Register(c => new SettingsScorable(c.Resolve<IDialogTask>()))
            .As<IScorable<IActivity, double>>()
            .InstancePerLifetimeScope();

        builder
            .Register(c => new CancelScorable(c.Resolve<IDialogTask>()))
            .As<IScorable<IActivity, double>>()
            .InstancePerLifetimeScope();
    }
}

The CancelScorable contains a PrepareAsync method that defines the trigger: if the message text is "cancel", this scorable will be triggered.

protected override async Task<string> PrepareAsync(IActivity activity, CancellationToken token)
{
    var message = activity as IMessageActivity;
    if (message != null && !string.IsNullOrWhiteSpace(message.Text))
    {
        if (message.Text.Equals("cancel", StringComparison.InvariantCultureIgnoreCase))
        {
            return message.Text;
        }
    }
    return null;
}

When a "cancel" request is received, the PostAsync method within CancelScoreable resets the dialog stack.

protected override async Task PostAsync(IActivity item, string state, CancellationToken token)
{
    this.task.Reset();
}

When a "change settings" request is received, the PostAsync method within SettingsScorable invokes the SettingsDialog (passing the request to that dialog), thereby adding the SettingsDialog to the top of the dialog stack and putting it in control of the conversation.

protected override async Task PostAsync(IActivity item, string state, CancellationToken token)
{
    var message = item as IMessageActivity;
    if (message != null)
    {
        var settingsDialog = new SettingsDialog();
        var interruption = settingsDialog.Void<object, IMessageActivity>();
        this.task.Call(interruption, null);
        await this.task.PollAsync(token);
    }
}

Sample code

For a complete sample that shows how to implement global message handlers using the Bot Framework SDK for .NET, see the Global Message Handlers sample in GitHub.

Additional resources