Agents Can Now Send Reactions to Messages in Microsoft Teams
Public Preview | May 2026
Your Teams agents can now react to messages with emojis. You can acknowledge, confirm, celebrate, and listen without sending an extra message reply. Agent message reactions are available today in public preview across .NET, TypeScript, and Python.

The Problem: Messages Can Be Too Noisyโ
Every interaction your agent has today requires a new message to be sent, yet another reply cluttering an already busy thread.
Meanwhile, humans communicate volumes with a single ๐.
Agent reactions bridge that gap. Your agent can now participate in the lightweight, non-verbal layer of conversation that makes Teams collaboration feel natural.
What You Can Doโ
| Capability | Description |
|---|---|
| Add reactions | React to any message your agent can see - 1:1, group chat, or channel |
| Remove reactions | Programmatically remove reactions as context changes |
| Receive reaction events | Get notified when users react to your agent's messages |
| Teams Reaction Reference | Discover all available emojis and their skin tone variants |
Real-World Scenariosโ
1. Instant Acknowledgmentโ
Agents can react to a request with a simple ๐ (like). No additionl messages, and users know their request has been heard
2. Progress Signalingโ
Agents can react to acknowledge a request, then swap their reaction to a different one signaling their work has been completed. Agent tasks run in the background without additional thread noise.
Below is an example of an agent reacting to a message with โ holdon, then swapping that for a โ
2705_whiteheavycheckmark when the task is complete.
You can find the complete list of emojis for use on Teams and their associated EmojiID on the Teams Reactions Reference page
// Acknowledge user request and notify them work has commenced with an hourglass "holdon" emoji
// Add reaction to message
await context.Api.Conversations.Reactions.AddAsync(
context.Activity.Conversation.Id,
context.Activity.Id,
new ReactionType("holdon"),
cancellationToken
);
// ... task completes ...
// Swap to checkmark emoji to indicate task completion
// Remove previously added hourglass "holdon" emoji
await context.Api.Conversations.Reactions.DeleteAsync(
context.Activity.Conversation.Id,
context.Activity.Id,
new ReactionType("holdon"),
cancellationToken
);
// Add new checkmark '2705_whiteheavycheckmark" reaction to signal work is complete
await context.Api.Conversations.Reactions.AddAsync(
context.Activity.Conversation.Id,
context.Activity.Id,
new ReactionType("2705_whiteheavycheckmark"),
cancellationToken
);
3. Silent Celebrationsโ
Agent monitors a channel for deployments, launches, or other celebratory events and joins in by reacting with ๐ฅณ party.
Adding a Reactionโ
You can utilize lightweight communication with reactions to acknowledge a message with a simple ๐ like, below are examples of doing so in each language:
TypeScriptโ
// Add a reaction
app.on('message', async ({ activity, api, send }) => {
await send("Hello! I'll react to your message.");
// Add a reaction to the incoming message
await api.reactions.add(activity.conversation.id, activity.id, 'like');
});
.NETโ
// Add a reaction
app.OnMessage(async (context, cancellationToken) =>
{
await context.Send("Hello! I'll react to your message.", cancellationToken);
// Add a reaction to the incoming message
await context.Api.Conversations.Reactions.AddAsync(
context.Activity.Conversation.Id,
context.Activity.Id,
ReactionType.Like,
cancellationToken: cancellationToken
);
});
Pythonโ
# Add a reaction
@app.on_message
async def handle_message(ctx: ActivityContext[MessageActivity]):
await ctx.send("Hello! I'll react to your message.")
# Add a reaction to the incoming message
await ctx.api.reactions.add(
ctx.activity.conversation.id,
ctx.activity.id,
'like'
)
Removing a Reactionโ
The pattern for reaction removal is standardized across languages. Below are examples of removing the ๐ like reaction from a message in each language:
TypeScriptโ
// Remove a reaction
app.on('message', async ({ activity, api, send }) => {
await send("Hello! I'll react to this message.");
await api.conversations.reactions.delete(activity.conversation.id, activity.id, 'like');
});
.NETโ
// Remove a reaction
app.OnMessage(async context =>
{
await context.Api.Conversations.Reactions.DeleteAsync(
context.Activity.Conversation.Id,
context.Activity.Id,
new ReactionType("like")
);
})
Pythonโ
# Remove a reaction
@app.on_message
async def handle_message(ctx: ActivityContext[MessageActivity]):
await ctx.api.conversations.reactions.delete(
ctx.activity.conversation.id,
ctx.activity.id,
'like'
)
Listening to Reactionsโ
Listening to reactions in conjunction with sending reactions can help you create complete end-to-end scenarios. In the following examples, agents listen for a ๐ like reaction and take action when that reaction has been added to an agent's message:
TypeScriptโ
app.on('messageReaction', async ({ activity }) => {
// Listen for a reaction added to agent message
for (const reaction of activity.reactionsAdded ?? []) {
if (reaction.type === 'like') {
// Complete some task here
}
}
// Listen for a reaction removed from agent message
for (const reaction of activity.reactionsRemoved ?? []) {
if (reaction.type === 'like') {
// Complete some task here
}
}
});
.NETโ
// Listen for a reaction added to agent message
app.OnMessageReactionAdded(async (context, cancellationToken) => {
foreach (var reaction in context.Activity.ReactionsAdded ?? []) {
if (reaction.Type == "like") {
// Complete some task here
}
}
});
// Listen for a reaction removed from agent message
app.OnMessageReactionRemoved(async (context, cancellationToken) => {
foreach (var reaction in context.Activity.ReactionsRemoved ?? []) {
if (reaction.Type == "like") {
// Complete some task here
}
}
});
Pythonโ
# Listen for a reaction added to agent message
@app.on_message_reaction
async def handle_reaction_added(ctx: ActivityContext[MessageReactionActivity]):
for reaction in ctx.activity.reactions_added or []:
if reaction.type == "like":
# Complete some task here
pass
# Listen for a reaction removed from agent message
@app.on_message_reaction
async def handle_reaction_removed(ctx: ActivityContext[MessageReactionActivity]):
for reaction in ctx.activity.reactions_removed or []:
if reaction.type == "like":
# Complete some task here
pass
Reaction IDs (EmojiIDs)โ
When using emojis as reactions in Teams you must use the Teams specific EmojiID to identify the correct emoji you'd like to send. Below are some examples of EmojiIDs:
| EmojiID | Emoji | Diverse (skin tones) |
|---|---|---|
like | ๐ | No |
heart | โค๏ธ | No |
happyface | ๐ | No |
grinningfacewithsmilingeyes | ๐ | No |
1f603_grinningfacewithbigeyes | ๐ | No |
1f44b_wavinghand | ๐ | Yes |
1f590_handwithfingerssplayed | ๐๏ธ | Yes |
1f91a_raisedbackofhand | ๐ค | Yes |
Skin-tone variants are supported via suffix modifiers:
1f44b_wavinghand-tone11f44b_wavinghand-tone21f44b_wavinghand-tone31f44b_wavinghand-tone41f44b_wavinghand-tone5
Teams Reactions Referenceโ
Alongside this preview, we're publishing the Teams Reactions Reference. This page was created as a developer resource for discovering all thevalid EmojiIDs supported by Teams.
The reference includes:
- Complete catalog of supported EmojiIDs organized by category (Smileys, Hand gestures, etc.)
- Skin-tone variations for diverse emojis
We're continuously adding new capabilites and features based on your feedback. We're excited to release this capability to you and can't wait to see what you build!๐