Conversation events in your Teams bot

Important

The code samples in this section are based on version 4.6 and later versions of the Bot Framework SDK. If you are looking for documentation for earlier versions, see the bots - v3 SDK section in the Resources folder of the documentation.

When building your conversational bots for Microsoft Teams, you can work with conversation events. Teams sends notifications to your bot for conversation events that happen in scopes where your bot is active. You can capture these events in your code and take the following actions:

  • Trigger a welcome message when your bot is added to a team.
  • Trigger a welcome message when a new team member is added or removed.
  • Trigger a notification when a channel is created, renamed, or deleted.
  • When a bot message is liked by a user.

Conversation update events

You can use conversation update events to provide better notifications and more effective bot actions.

Important

  • You can add new events any time and your bot begins to receive them.
  • You must design your bot to receive unexpected events.
  • If you are using the Bot Framework SDK, your bot automatically responds with a 200 - OK to any events you choose not to handle.

A bot receives a conversationUpdate event in either of the following cases:

  • When bot has been added to a conversation.
  • Other members are added to or removed from a conversation.
  • Conversation metadata has changed.

The conversationUpdate event is sent to your bot when it receives information on membership updates for teams where it has been added. It also receives an update when it has been added for the first time for personal conversations.

The following table shows a list of Teams conversation update events with more details:

Action taken EventType Method called Description Scope
Channel created channelCreated OnTeamsChannelCreatedAsync A channel is created. Team
Channel renamed channelRenamed OnTeamsChannelRenamedAsync A channel is renamed. Team
Channel deleted channelDeleted OnTeamsChannelDeletedAsync A channel is deleted. Team
Channel restored channelRestored OnTeamsChannelRestoredAsync A channel is restored. Team
Members added membersAdded OnTeamsMembersAddedAsync A member is added. All
Members removed membersRemoved OnTeamsMembersRemovedAsync A member is removed. groupChat and team
Team renamed teamRenamed OnTeamsTeamRenamedAsync A team is renamed. Team
Team deleted teamDeleted OnTeamsTeamDeletedAsync A team is deleted. Team
Team archived teamArchived OnTeamsTeamArchivedAsync A team is archived. Team
Team unarchived teamUnarchived OnTeamsTeamUnarchivedAsync A team is unarchived. Team
Team restored teamRestored OnTeamsTeamRestoredAsync A team is restored Team

Channel created

The channel created event is sent to your bot whenever a new channel is created in a team where your bot is installed.

The following code shows an example of channel created event:

protected override async Task OnTeamsChannelCreatedAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    var heroCard = new HeroCard(text: $"{channelInfo.Name} is the Channel created");
    await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
}

Channel renamed

The channel renamed event is sent to your bot whenever a channel is renamed in a team where your bot is installed.

The following code shows an example of channel renamed event:

protected override async Task OnTeamsChannelRenamedAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    var heroCard = new HeroCard(text: $"{channelInfo.Name} is the new Channel name");
    await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
}

Channel deleted

The channel deleted event is sent to your bot whenever a channel is deleted in a team where your bot is installed.

The following code shows an example of channel deleted event:

protected override async Task OnTeamsChannelDeletedAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    var heroCard = new HeroCard(text: $"{channelInfo.Name} is the Channel deleted");
    await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
}

Channel restored

The channel restored event is sent to your bot whenever a channel that was previously deleted is restored in a team where your bot is already installed.

The following code shows an example of channel restored event:

protected override async Task OnTeamsChannelRestoredAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    var heroCard = new HeroCard(text: $"{channelInfo.Name} is the Channel restored.");
    await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
}

Team members added

The teamMemberAdded event is sent to your bot the first time it is added to a conversation. The event is sent to your bot every time a new user is added to a team or group chat where your bot is installed. The user information that is ID is unique for your bot and can be cached for future use by your service, such as sending a message to a specific user.

The following code shows an example of team members added event:

protected override async Task OnTeamsMembersAddedAsync(IList<TeamsChannelAccount> teamsMembersAdded , TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    foreach (TeamsChannelAccount member in teamsMembersAdded)
    {
        if (member.Id == turnContext.Activity.Recipient.Id)
        {
            // Send a message to introduce the bot to the team
            var heroCard = new HeroCard(text: $"The {member.Name} bot has joined {teamInfo.Name}");
            await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
        }
        else
        {
            var heroCard = new HeroCard(text: $"{member.Name} joined {teamInfo.Name}");
            await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
        }
    }
}

Team members removed

The teamMemberRemoved event is sent to your bot if it is removed from a team. The event is sent to your bot every time any user is removed from a team where your bot is a member. To determine if the new member removed was the bot itself or a user, check the Activity object of the turnContext. If the Id field of the MembersRemoved object is the same as the Id field of the Recipient object, then the member removed is the bot, else it is a user. The bot's Id generally is 28:<MicrosoftAppId>.

Note

When a user is permanently deleted from a tenant, membersRemoved conversationUpdate event is triggered.

The following code shows an example of team members removed event:

protected override async Task OnTeamsMembersRemovedAsync(IList<ChannelAccount> membersRemoved, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    foreach (TeamsChannelAccount member in membersRemoved)
    {
        if (member.Id == turnContext.Activity.Recipient.Id)
        {
            // The bot was removed
            // You should clear any cached data you have for this team
        }
        else
        {
            var heroCard = new HeroCard(text: $"{member.Name} was removed from {teamInfo.Name}");
            await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
        }
    }
}

Team renamed

Your bot is notified when the team it is in has been renamed. It receives a conversationUpdate event with eventType.teamRenamed in the channelData object.

The following code shows an example of team renamed event:

protected override async Task OnTeamsTeamRenamedAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    var heroCard = new HeroCard(text: $"{teamInfo.Name} is the new Team name");
    await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
}

Team deleted

Your bot is notified when the team it is in has been deleted. It receives a conversationUpdate event with eventType.teamDeleted in the channelData object.

The following code shows an example of team deleted event:

protected override async Task OnTeamsTeamDeletedAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    //handle delete event
}

Team restored

The bot receives a notification when a team is restored after being deleted. It receives a conversationUpdate event with eventType.teamrestored in the channelData object.

The following code shows an example of team restored event:

protected override async Task OnTeamsTeamrestoredAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    var heroCard = new HeroCard(text: $"{teamInfo.Name} is the team name");
    await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
}

Team archived

The bot receives a notification when the team it is installed in is archived. It receives a conversationUpdate event with eventType.teamarchived in the channelData object.

The following code shows an example of team archived event:

protected override async Task OnTeamsTeamArchivedAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    var heroCard = new HeroCard(text: $"{teamInfo.Name} is the team name");
    await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
}

Team unarchived

The bot receives a notification when the team it is installed in is unarchived. It receives a conversationUpdate event with eventType.teamUnarchived in the channelData object.

The following code shows an example of team unarchived event:

protected override async Task OnTeamsTeamUnarchivedAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    var heroCard = new HeroCard(text: $"{teamInfo.Name} is the team name");
    await turnContext.SendActivityAsync(MessageFactory.Attachment(heroCard.ToAttachment()), cancellationToken);
}

Now that you have worked with the conversation update events, you can understand the message reaction events that occur for different reactions to a message.

Message reaction events

The messageReaction event is sent when a user adds or removes reactions to a message which was sent by your bot. The replyToId contains the ID of the message, and the Type is the type of reaction in text format. The types of reactions include angry, heart, laugh, like, sad, and surprised. This event does not contain the contents of the original message. If processing reactions to your messages is important for your bot, you must store the messages when you send them. The following table provides more information about the event type and payload objects:

EventType Payload object Description Scope
messageReaction reactionsAdded Reactions added to bot message. All
messageReaction reactionsRemoved Reactions removed from bot message. All

Reactions added to bot message

The following code shows an example of reactions to a bot message:

protected override async Task OnReactionsAddedAsync(IList<MessageReaction> messageReactions, ITurnContext<IMessageReactionActivity> turnContext, CancellationToken cancellationToken)
{
    foreach (var reaction in messageReactions)
    {
      var newReaction = $"You reacted with '{reaction.Type}' to the following message: '{turnContext.Activity.ReplyToId}'";
      var replyActivity = MessageFactory.Text(newReaction);
      var resourceResponse = await turnContext.SendActivityAsync(replyActivity, cancellationToken);
    }
}

Reactions removed from bot message

The following code shows an example of reactions removed from bot message:

protected override async Task OnReactionsRemovedAsync(IList<MessageReaction> messageReactions, ITurnContext<IMessageReactionActivity> turnContext, CancellationToken cancellationToken)
{
    foreach (var reaction in messageReactions)
    {
      var newReaction = $"You removed the reaction '{reaction.Type}' from the following message: '{turnContext.Activity.ReplyToId}'";
      var replyActivity = MessageFactory.Text(newReaction);
      var resourceResponse = await turnContext.SendActivityAsync(replyActivity, cancellationToken);
    }
}

Installation update event

The bot receives an installationUpdate event when you install a bot to a conversation thread. Uninstallation of the bot from the thread also triggers the event. On installing a bot, the action field in the event is set to add, and when the bot is uninstalled the action field is set to remove.

Note

When you upgrade an application, and then add or remove a bot, the action also triggers the installationUpdate event. The action field is set to add-upgrade if you add a bot or remove-upgrade if you remove a bot.

Install update event

Use the installationUpdate event to send an introductory message from your bot on installation. This event helps you to meet your privacy and data retention requirements. You can also clean up and delete user or thread data when the bot is uninstalled.

protected override async Task
OnInstallationUpdateActivityAsync(ITurnContext<IInstallationUpdateActivity> turnContext, CancellationToken cancellationToken) {
var activity = turnContext.Activity; if
(string.Equals(activity.Action, "Add",
StringComparison.InvariantCultureIgnoreCase)) {
// TO:DO Installation workflow }
else
{ // TO:DO Uninstallation workflow
} return; }

You can also use a dedicated handler for add or remove scenarios as an alternative method to capture an event.

protected override async Task
OnInstallationUpdateAddAsync(ITurnContext<IInstallationUpdateActivity>
turnContext, CancellationToken cancellationToken) {
// TO:DO Installation workflow return;
}

Uninstall behavior for personal app with bot

Note

Uninstall behavior for personal app with bot is currently available only in public developer preview.

When you uninstall an app, the bot is also uninstalled. When a user sends a message to your app, they receive a 403 response code. Your bot receives a 403 response code for new messages posted by your bot. The post uninstall behavior for bots in the personal scope with the Teams and groupChat scopes are now aligned. You cannot send or receive messages after an app has been uninstalled.

Uninstall event

Event handling for install and uninstall events

When you use these install and uninstall events, there are some instances where bots give exceptions on receiving unexpected events from Teams. This occurs in the following cases:

  • You build your bot without the Microsoft Bot Framework SDK, and as a result the bot gives an exception on receiving an unexpected event.
  • You build your bot with the Microsoft Bot Framework SDK, and you select to alter the default event behavior by overriding the base event handle.

It is important to know that new events can be added anytime in the future and your bot begins to receive them. So you must design for the possibility of receiving unexpected events. If you are using the Bot Framework SDK, your bot automatically responds with a 200 – OK to any events you do not choose to handle.

Code sample

Sample name Description .NET Node.js Python
Conversation bot Sample code for bots conversation events. View View View

Next step