Send welcome message to users

APPLIES TO: SDK v4

The primary goal when creating any bot is to engage your user in a meaningful conversation. One of the best ways to achieve this goal is to ensure that from the moment a user first connects, they understand your bot's main purpose and capabilities, the reason your bot was created. This article provides code examples to help you welcome users to your bot.

Note

The Bot Framework JavaScript, C#, and Python SDKs will continue to be supported, however, the Java SDK is being retired with final long-term support ending in November 2023.

Existing bots built with the Java SDK will continue to function.

For new bot building, consider using Microsoft Copilot Studio and read about choosing the right copilot solution.

For more information, see The future of bot building.

Prerequisites

About this sample code

This sample code shows how to detect and welcome new users when they're initially connected to your bot. The following diagram shows the logic flow for this bot.

The two main events encountered by the bot are:

  • OnMembersAddedAsync, called when a new user connects to your bot.
  • OnMessageActivityAsync, called when your bot receives new user input.

Logic flow diagram for C# sample.

Whenever a new user is connected, they're provided with a WelcomeMessage, InfoMessage, and PatternMessage by the bot. When a new user input is received, WelcomeUserState is checked to see if DidBotWelcomeUser is set to true. If not, an initial welcome user message is returned to the user.

Create user state

The user state object is created at startup and dependency injected into the bot constructor.

Startup.cs


// Create the Bot Framework Authentication to be used with the Bot Adapter.
services.AddSingleton<BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>();

// Create the Bot Adapter with error handling enabled.

Bots\WelcomeUserBot.cs


// Initializes a new instance of the "WelcomeUserBot" class.
public WelcomeUserBot(UserState userState)
{
    _userState = userState;
}

Create property accessors

We now create a property accessor that provides us a handle to WelcomeUserState inside the OnMessageActivityAsync method. Then call the GetAsync method to get the properly scoped key. We then save user state data after each user input iteration using the SaveChangesAsync method.

Bots\WelcomeUserState.cs

// Gets or sets whether the user has been welcomed in the conversation.
public bool DidBotWelcomeUser { get; set; } = false;

Bots\WelcomeUserBot.cs

var didBotWelcomeUser = await welcomeUserStateAccessor.GetAsync(turnContext, () => new WelcomeUserState(), cancellationToken);

await _userState.SaveChangesAsync(turnContext, cancellationToken: cancellationToken);
}

Detect and greet newly connected users

In WelcomeUserBot, we check for an activity update using OnMembersAddedAsync() to see if a new user has been added to the conversation and then send them a set of three initial welcome messages WelcomeMessage, InfoMessage and PatternMessage. Complete code for this interaction is shown below.

Bots\WelcomeUserBot.cs

public class WelcomeUserBot : ActivityHandler
{
    // Messages sent to the user.
    private const string WelcomeMessage = "This is a simple Welcome Bot sample. This bot will introduce you " +
                                            "to welcoming and greeting users. You can say 'intro' to see the " +
                                            "introduction card. If you are running this bot in the Bot Framework " +
                                            "Emulator, press the 'Start Over' button to simulate user joining " +
                                            "a bot or a channel";

    private const string InfoMessage = "You are seeing this message because the bot received at least one " +
                                        "'ConversationUpdate' event, indicating you (and possibly others) " +
                                        "joined the conversation. If you are using the emulator, pressing " +
                                        "the 'Start Over' button to trigger this event again. The specifics " +
                                        "of the 'ConversationUpdate' event depends on the channel. You can " +
                                        "read more information at: " +
                                        "https://aka.ms/about-botframework-welcome-user";

    private const string LocaleMessage = "You can use the activity's 'GetLocale()' method to welcome the user " +
                                         "using the locale received from the channel. " + 
                                         "If you are using the Emulator, you can set this value in Settings.";
{
    foreach (var member in membersAdded)
    {
        if (member.Id != turnContext.Activity.Recipient.Id)
        {
            await turnContext.SendActivityAsync($"Hi there - {member.Name}. {WelcomeMessage}", cancellationToken: cancellationToken);
            await turnContext.SendActivityAsync(InfoMessage, cancellationToken: cancellationToken);
            await turnContext.SendActivityAsync($"{LocaleMessage} Current locale is '{turnContext.Activity.GetLocale()}'.", cancellationToken: cancellationToken);
            await turnContext.SendActivityAsync(PatternMessage, cancellationToken: cancellationToken);
        }
    }
}

Welcome new user and discard initial input

It's also important to consider when your user's input might actually contain useful information, and this may vary for each channel. To ensure your user has a good experience on all possible channels, we check the status flag didBotWelcomeUser and if this is "false", we don't process the initial user input. We instead provide the user with an initial welcome message. The bool welcomedUserProperty is then set to "true", stored in UserState and our code will now process this user's input from all additional message activities.

Bots\WelcomeUserBot.cs

{
    var welcomeUserStateAccessor = _userState.CreateProperty<WelcomeUserState>(nameof(WelcomeUserState));
    var didBotWelcomeUser = await welcomeUserStateAccessor.GetAsync(turnContext, () => new WelcomeUserState(), cancellationToken);

    if (didBotWelcomeUser.DidBotWelcomeUser == false)
    {
        didBotWelcomeUser.DidBotWelcomeUser = true;

        // the channel should sends the user name in the 'From' object
        var userName = turnContext.Activity.From.Name;

        await turnContext.SendActivityAsync("You are seeing this message because this was your first message ever to this bot.", cancellationToken: cancellationToken);
        await turnContext.SendActivityAsync($"It is a good practice to welcome the user and provide personal greeting. For example, welcome {userName}.", cancellationToken: cancellationToken);
    }
    else
await _userState.SaveChangesAsync(turnContext, cancellationToken: cancellationToken);
}

Process additional input

Once a new user has been welcomed, user input information is evaluated for each message turn, and the bot provides a response based on the context of that user input. The following code shows the decision logic used to generate that response.

An input of 'intro' or 'help' calls the function SendIntroCardAsync to present the user with an informational hero card. That code is examined in the next section of this article.

Bots\WelcomeUserBot.cs

    switch (text)
    {
        case "hello":
        case "hi":
            await turnContext.SendActivityAsync($"You said {text}.", cancellationToken: cancellationToken);
            break;
        case "intro":
        case "help":
            await SendIntroCardAsync(turnContext, cancellationToken);
            break;
        default:
            await turnContext.SendActivityAsync(WelcomeMessage, cancellationToken: cancellationToken);
            break;
    }
}

Using hero card greeting

As mentioned above, some user inputs generate a Hero Card in response to their request. You can learn more about hero card greetings here Send an Intro Card. Below is the code required to create this bot's hero card response.

Bots\WelcomeUserBot.cs

    {
        var card = new HeroCard
        {
            Title = "Welcome to Bot Framework!",
            Text = @"Welcome to Welcome Users bot sample! This Introduction card
                     is a great way to introduce your Bot to the user and suggest
                     some things to get them started. We use this opportunity to
                     recommend a few next steps for learning more creating and deploying bots.",
            Images = new List<CardImage>() { new CardImage("https://aka.ms/bf-welcome-card-image") },
            Buttons = new List<CardAction>()
            {
                new CardAction(ActionTypes.OpenUrl, "Get an overview", null, "Get an overview", "Get an overview", "https://docs.microsoft.com/en-us/azure/bot-service/?view=azure-bot-service-4.0"),
                new CardAction(ActionTypes.OpenUrl, "Ask a question", null, "Ask a question", "Ask a question", "https://stackoverflow.com/questions/tagged/botframework"),
                new CardAction(ActionTypes.OpenUrl, "Learn how to deploy", null, "Learn how to deploy", "Learn how to deploy", "https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-deploy-azure?view=azure-bot-service-4.0"),
            }
        };

        var response = MessageFactory.Attachment(card.ToAttachment());
        await turnContext.SendActivityAsync(response, cancellationToken);
    }
}

Test the bot

Download and install the latest Bot Framework Emulator

  1. Run the sample locally on your machine. If you need instructions, refer to the README file for the C# sample or JavaScript sample.
  2. Open the Emulator to test your bot.
    1. When you start a conversation with your bot, it will send you a series of welcome messages.

    2. When you send a "hello" message the first time, your bot replies with some advice.

    3. When you send subsequent "hello" messages, your bot replies with, "You said hello."

      Screenshot of initial interactions with your bot in the Emulator.

    4. Send a "help" message to your bot. It responds by sending a hero card.

      Screenshot of the help message and the bot response in the Emulator.

Additional Resources

Learn more about various media responses in Add media to messages.

Next steps