Edit

Conversation events for agents

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

  • Trigger a welcome message when your agent 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.
  • Trigger a notification when an agent message is liked by a user.
  • Identify the default channel for your agent from user input (selection) during installation.

Conversation update events

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

Important

  • You can add new events anytime and your agent begins to receive them.
  • Design your agent to receive unexpected events.
  • If you are using the Teams SDK, your agent automatically responds with a 200 - OK to any events you choose not to handle.
  • When an Azure Communication Services (ACS) client joins or leaves the Teams meeting, no conversation update events are triggered.

An agent receives a conversationUpdate event in either of the following cases:

  • When the agent is 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 agent 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. All
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 channelCreated event is sent to your agent whenever a new channel is created in a team where your agent is installed.

The following code shows an example of a channel created event:

app.OnChannelCreated(async context =>
{
    var channelName = context.Activity.ChannelData.Channel.Name;
    await context.Send($"{channelName} is the Channel created");
});

Channel renamed

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

The following code shows an example of a channel renamed event:

app.OnChannelRenamed(async context =>
{
    var channelName = context.Activity.ChannelData.Channel.Name;
    await context.Send($"{channelName} is the new Channel name");
});

Channel deleted

The channelDeleted event is sent to your agent, whenever a channel is deleted in a team where your agent is installed.

The following code shows an example of a channel deleted event:

app.OnChannelDeleted(async context =>
{
    var channelName = context.Activity.ChannelData.Channel.Name;
    await context.Send($"{channelName} is the Channel deleted");
});

Channel restored

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

The following code shows an example of a channel restored event:

app.OnChannelRestored(async context =>
{
    var channelName = context.Activity.ChannelData.Channel.Name;
    await context.Send($"{channelName} is the Channel restored.");
});

Members added

A member added event is sent to your agent in the following scenarios:

  1. When the agent, itself, is installed and added to a conversation

    In team context, the activity's conversation.id is set to the id of the channel selected by the user during app installation or the channel where the agent was installed.

  2. When a user is added to a conversation where the agent is installed

    User ids received in the event payload are unique to the agent and can be cached for future use, such as directly messaging a user.

The member added activity eventType is set to teamMemberAdded when the event is sent from a team context. To determine if the new member added was the agent itself or a user, check the Activity object of the Context object. If the MembersAdded list contains an object where id is the same as the id field of the Recipient object, then the member added is the agent, else it's a user. The agent's id is formatted as 28:<MicrosoftAppId>.

Tip

Use the InstallationUpdate event to determine when your agent is added or removed from a conversation.

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

app.OnMembersAdded(async context =>
{
    foreach (var member in context.Activity.MembersAdded)
    {
        if (member.Id == context.Activity.Recipient.Id)
        {
            // Send a message to introduce the bot to the team.
            await context.Send($"The {member.Name} agent has joined {context.Activity.ChannelData.Team.Name}");
        }
        else
        {
            await context.Send($"{member.Name} joined {context.Activity.ChannelData.Team.Name}");
        }
    }
});

Members removed

A member removed event is sent to your agent in the following scenarios:

  1. When the agent, itself, is uninstalled and removed from a conversation.
  2. When a user is removed from a conversation where the agent is installed.

The member removed activity eventType is set to teamMemberRemoved when the event is sent from a team context. To determine if the new member removed was the agent itself or a user, check the Activity object of the Context object. If the MembersRemoved list contains an object where id is the same as the id field of the Recipient object, then the member added is the agent, else it's a user. The agent's id is formatted as 28:<MicrosoftAppId>.

Note

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

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

app.OnMembersRemoved(async context =>
{
    foreach (var member in context.Activity.MembersRemoved)
    {
        if (member.Id == context.Activity.Recipient.Id)
        {
            // The agent was removed.
            // You should clear any cached data you have for this team.
        }
        else
        {
            await context.Send($"{member.Name} was removed from {context.Activity.ChannelData.Team.Name}");
        }
    }
});

Team renamed

Your agent is notified when the team is renamed. It receives a conversationUpdate event with eventType.teamRenamed in the channelData object.

The following code shows an example of a team renamed event:

app.OnTeamRenamed(async context =>
{
    var teamName = context.Activity.ChannelData.Team.Name;
    await context.Send($"{teamName} is the new Team name");
});

Team deleted

The agent receives a notification when the team is deleted. It receives a conversationUpdate event with eventType.teamDeleted in the channelData object.

The following code shows an example of a team deleted event:

app.OnTeamDeleted(async context =>
{
    // Handle delete event.
});

Team restored

The agent 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 a team restored event:

app.OnTeamRestored(async context =>
{
    var teamName = context.Activity.ChannelData.Team.Name;
    await context.Send($"{teamName} is the team name");
});

Team archived

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

The following code shows an example of team archived event:

app.OnTeamArchived(async context =>
{
    var teamName = context.Activity.ChannelData.Team.Name;
    await context.Send($"{teamName} is the team name");
});

Team unarchived

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

The following code shows an example of a team unarchived event:

app.OnTeamUnarchived(async context =>
{
    var teamName = context.Activity.ChannelData.Team.Name;
    await context.Send($"{teamName} is the team name");
});

Now that you've 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 agent. 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 doesn't contain the contents of the original message. If processing reactions to your messages is important for your agent, 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 agent message. All
messageReaction reactionsRemoved Reactions removed from agent message. All

Reactions added to agent message

The following code shows an example of reactions to an agent message:

app.OnReactionsAdded(async context =>
{
    foreach (var reaction in context.Activity.ReactionsAdded)
    {
        var newReaction = $"You reacted with '{reaction.Type}' to the following message: '{context.Activity.ReplyToId}'";
        await context.Send(newReaction);
    }
});

Reactions removed from agent message

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

app.OnReactionsRemoved(async context =>
{
    foreach (var reaction in context.Activity.ReactionsRemoved)
    {
        var newReaction = $"You removed the reaction '{reaction.Type}' from the following message: '{context.Activity.ReplyToId}'";
        await context.Send(newReaction);
    }
});

Installation update event

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

Note

When you upgrade an application, the agent receives the installationUpdate event only to add or remove an agent from the manifest. For all other cases, the installationUpdate event isn't triggered. The action field is set to add-upgrade if you add an agent or remove-upgrade if you remove an agent.

Install update event

Use the installationUpdate event to send an introductory message from your agent 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 agent is uninstalled.

Similar to the conversationUpdate event that's sent when agent is added to a team, the conversation.id of the installationUpdate event is set to the id of the channel selected by a user during app installation or the channel where the installation occurred. The id represents the channel where the user intends for the agent to operate and must be used by the agent when sending a welcome message. For scenarios where the ID of the General channel is explicitly required, you can get it from team.id in channelData.

In this example, the conversation.id of the conversationUpdate and installationUpdate activities is set to the ID of the Response channel in the Daves Demo team.

Create a selected channel.

Note

The selected channel id is only set on installationUpdate add events that are sent when an app is installed into a team.

app.OnInstall(async context =>
{
    var action = context.Activity.Action;
    if (string.Equals(action, "Add", StringComparison.InvariantCultureIgnoreCase))
    {
        await context.Send("Added");
    }
    else
    {
        await context.Send("Uninstalled");
    }
});

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(IContext<IInstallationUpdateActivity> Context object, CancellationToken cancellationToken)
{
    // TO:DO Installation workflow return;
}

Uninstall behavior for personal app with agent

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

Uninstall response code

Event handling for install and uninstall events

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

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

It's important to know that new events can be added anytime in the future and your agent begins to receive them. So you must design for the possibility of receiving unexpected events. If you're using Teams SDK, your agent automatically responds with a 200 - OK to any events you don't choose to handle.

Handling errors in conversation events

When an agent encounters an error while handling different events or activities, don't send messages that have no meaningful context to the conversation as shown in the following screenshot:

Screenshot shows you the error message response in agent conversation.

In the development phase, it's always helpful to send meaningful messages in conversations, which provide additional details about a specific error for better debugging. However, in the production environment, you must log the errors or events to Azure Application Insights. For more information, see add telemetry to your bot.

Code sample

Sample Name Description .NET Node.js Python
Conversation bot This app demonstrates bot conversation events, supporting Adaptive Cards, read receipts, and message update events. It includes immersive reader support for accessibility. View View View

Next step