Skip to content

Add Reactions Feature (Bot to User)#335

Open
rido-min wants to merge 13 commits intomainfrom
feat/reactions
Open

Add Reactions Feature (Bot to User)#335
rido-min wants to merge 13 commits intomainfrom
feat/reactions

Conversation

@rido-min
Copy link
Member

This pull request introduces a new ReactionClient to the API, adds richer support for message reactions (including new reaction types), and provides a sample project demonstrating usage. It also removes several helper methods related to reactions from the activity model, shifting reaction management responsibilities to the new client. Test code and solution files are updated accordingly.

API Enhancements:

  • Added a new ReactionClient class to encapsulate operations for creating, updating, and deleting message reactions via HTTP requests. This client is now accessible through the ConversationClient as the Reactions property. [1] [2]
  • Exposed the underlying IHttpClient as a property on ApiClient for easier access in advanced scenarios.

Message Reaction Model Changes:

  • Removed AddReaction and RemoveReaction helper methods from MessageReactionActivity, making reaction management the responsibility of the new client rather than the activity model itself.
  • Expanded the ReactionType class to include additional reaction types (e.g., checkmark, hourglass, pushpin, exclamation) with descriptive comments and emoji representations.

Sample and Solution Updates:

  • Added a new sample project, Samples.Reactions, demonstrating how to use the new ReactionClient to add and remove reactions in response to messages. Included relevant configuration and project files. [1] [2] [3] [4] [5] [6] [7]

Test and Serialization Updates:

  • Updated tests and JSON fixtures for MessageReactionActivity to remove reliance on the deleted helper methods and reflect the new approach to reaction handling. [1] [2] [3] [4] [5] [6]

Miscellaneous:

  • Fixed a minor formatting issue in the solution file's Visual Studio version line.

aacebo and others added 5 commits December 2, 2025 13:19
Added a new Samples.Reactions project with a sample bot demonstrating Teams message reactions. Removed AddReaction/RemoveReaction helpers from MessageReactionActivity and updated related tests. Exposed IHttpClient via ApiClient.Client. Registered the new sample in the solution and suppressed CS0618 warnings in test projects. Minor formatting and consistency improvements throughout.
Copilot AI review requested due to automatic review settings February 17, 2026 21:33
@rido-min rido-min mentioned this pull request Feb 17, 2026
@rido-min rido-min requested a review from singhk97 February 17, 2026 21:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new reaction feature that allows bots to add and remove reactions to messages programmatically. The implementation follows a clean separation of concerns by creating a dedicated ReactionClient for reaction operations and removing helper methods from the MessageReactionActivity model. The change represents a shift in design philosophy, moving reaction management from activity models to dedicated client classes.

Changes:

  • Added a new ReactionClient with methods to create/update and delete reactions on messages
  • Integrated ReactionClient into ConversationClient and exposed it through ApiClient.Conversations.Reactions
  • Expanded ReactionType with additional reaction types (checkmark, hourglass, pushpin, exclamation) with emoji documentation
  • Removed AddReaction and RemoveReaction helper methods from MessageReactionActivity
  • Updated tests to reflect the removal of helper methods from the activity model
  • Added a sample project demonstrating the new reaction feature usage
  • Fixed a minor Visual Studio version formatting issue in the solution file
  • Exposed the underlying IHttpClient via the Client property on ApiClient to enable advanced scenarios

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
Libraries/Microsoft.Teams.Api/Clients/ReactionClient.cs New client for managing message reactions with create/update and delete operations
Libraries/Microsoft.Teams.Api/Clients/ConversationClient.cs Integrated ReactionClient as a property in all constructors
Libraries/Microsoft.Teams.Api/Clients/ApiClient.cs Exposed underlying IHttpClient as Client property for advanced scenarios
Libraries/Microsoft.Teams.Api/Messages/Reaction.cs Added new reaction types (checkmark, hourglass, pushpin, exclamation) with emoji documentation
Libraries/Microsoft.Teams.Api/Activities/Message/MessageReactionActivity.cs Removed AddReaction and RemoveReaction helper methods
Tests/Microsoft.Teams.Apps.Tests/Microsoft.Teams.Apps.Tests.csproj Added NoWarn for CS0618 to suppress obsolete warnings in tests
Tests/Microsoft.Teams.Apps.Tests/Activities/Messages/MessageReactionActivityTests.cs Updated test expectations to reflect removal of helper methods
Tests/Microsoft.Teams.Api.Tests/Activities/Message/MessageReactionActivityTests.cs Removed usage of deleted helper methods from tests
Tests/Microsoft.Teams.Api.Tests/Json/Activity/Message/MessageReactionActivity.json Removed reactionsAdded test data to align with simplified model
Samples/Samples.Reactions/* New sample project demonstrating reaction feature usage
Microsoft.Teams.sln Added Samples.Reactions project and fixed Visual Studio version formatting

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@rido-min
Copy link
Member Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copy link
Contributor

Copilot AI commented Feb 17, 2026

@rido-min I've opened a new pull request, #336, to work on those changes. Once the pull request is ready, I'll request review from you.

…336)

Addresses review comments from PR #335 by fixing documentation errors,
code formatting issues, and adding missing test coverage.

**Documentation fixes:**
- Fixed copyright header in `ReactionClient.cs` (added "All rights
reserved.")
- Removed incorrect `userId` parameter references from XML docs in
`CreateOrUpdateAsync` and `DeleteAsync` methods
- Completed incomplete XML comment in `Reaction.cs`: "The type of
reaction given to the message."
- Added comprehensive XML documentation for `ApiClient.Client` property
explaining its purpose and usage caveats

**Code quality:**
- Fixed grammatical error in `Samples.Reactions/Program.cs`: "you
reacted with added" → "you added"
- Removed inconsistent extra blank line in `ApiClient` constructor

**Test coverage:**
- Added `ReactionClientTests.cs` with test methods for
`CreateOrUpdateAsync` and `DeleteAsync` following existing client test
patterns

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rido-min <14916339+rido-min@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Renamed the CreateOrUpdateAsync method to AddAsync in the ReactionClient class for clarity. Updated XML documentation to specify that the method adds a reaction. Refactored all usages in Program.cs and ReactionClientTests.cs to use the new method name. No changes to method behavior or parameters.
The PlusOne static field and IsPlusOne property were deleted
from the ReactionType class, eliminating support for the
"plus-one" reaction.
Copilot AI review requested due to automatic review settings February 17, 2026 22:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 18 to 28

// replace with context.Api.Conversations.Reactions once APX is rolledout to PROD
var api = new ApiClient(context.Activity.ServiceUrl!, context.Api.Client, cancellationToken);

await api.Conversations.Reactions.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f44b_wavinghand-tone4"));

await Task.Delay(2000, cancellationToken);
await api.Conversations.Reactions.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));

await Task.Delay(2000, cancellationToken);
await api.Conversations.Reactions.DeleteAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment mentions "APX" being rolled out to PROD, but this seems like implementation-specific jargon that may not be clear to users of this sample. Consider either explaining what APX is or removing the comment if the workaround is temporary. Additionally, the workaround creates a new ApiClient instance instead of using the existing context.Api, which could be confusing for users trying to understand the intended usage pattern.

Suggested change
// replace with context.Api.Conversations.Reactions once APX is rolledout to PROD
var api = new ApiClient(context.Activity.ServiceUrl!, context.Api.Client, cancellationToken);
await api.Conversations.Reactions.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f44b_wavinghand-tone4"));
await Task.Delay(2000, cancellationToken);
await api.Conversations.Reactions.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));
await Task.Delay(2000, cancellationToken);
await api.Conversations.Reactions.DeleteAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));
await context.Api.Conversations.Reactions.AddAsync(
context.Activity.Conversation.Id,
context.Activity.Id,
new ReactionType("1f44b_wavinghand-tone4"));
await Task.Delay(2000, cancellationToken);
await context.Api.Conversations.Reactions.AddAsync(
context.Activity.Conversation.Id,
context.Activity.Id,
new ReactionType("1f601_beamingfacewithsmilingeyes"));
await Task.Delay(2000, cancellationToken);
await context.Api.Conversations.Reactions.DeleteAsync(
context.Activity.Conversation.Id,
context.Activity.Id,
new ReactionType("1f601_beamingfacewithsmilingeyes"));

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@corinagum corinagum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few nits / question.

rido-min and others added 2 commits February 17, 2026 14:59
Corrected closing brackets to ensure valid JSON formatting. Removed extraneous characters at the end of the file.
Copilot AI review requested due to automatic review settings February 23, 2026 21:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Added obsolete AddReaction/RemoveReaction methods to MessageReactionActivity for direct manipulation of reactions. ReactionClient's AddAsync and DeleteAsync now accept optional CancellationToken. Refactored ReactionType: removed legacy types, added new Unicode-based types (Eyes, CheckMark, Launch, Pushpin). Updated Program.cs comment to reference Reactions client. These changes modernize reaction management and enhance async operation support.
Changed all relevant assertions in MessageReactionActivityTests.cs to verify the "Like" reaction type rather than "Angry". This ensures the tests align with the expected reaction type behavior.
Copilot AI review requested due to automatic review settings February 24, 2026 22:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +101 to 102
var res = await _app.Process<TestPlugin>(_token, new MessageReactionActivity());

Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MessageReactionActivity is created without populating ReactionsAdded, yet the test assertions on lines 86-87 and 95-97 expect it to contain reaction data. The test setup should manually populate the ReactionsAdded property to make these assertions valid.

Suggested change
var res = await _app.Process<TestPlugin>(_token, new MessageReactionActivity());
var activity = new MessageReactionActivity
{
ReactionsAdded = new[] { new MessageReaction() }
};
var res = await _app.Process<TestPlugin>(_token, activity);

Copilot uses AI. Check for mistakes.
});

var res = await _app.Process<TestPlugin>(_token, new MessageReactionActivity().RemoveReaction(Api.Messages.ReactionType.Angry));
var res = await _app.Process<TestPlugin>(_token, new MessageReactionActivity());
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MessageReactionActivity is created without populating ReactionsRemoved, yet the test assertions on lines 125-126 and 136 expect it to contain reaction data. The test setup should manually populate the ReactionsRemoved property (and ReactionsAdded for line 134) to make these assertions valid.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +29
// replace with context.Api.Conversations.Reactions once Reactions client is available in PROD.
var api = new ApiClient(context.Activity.ServiceUrl!, context.Api.Client, cancellationToken);

await api.Conversations.Reactions.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f44b_wavinghand-tone4"));

await Task.Delay(2000, cancellationToken);
await api.Conversations.Reactions.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));

await Task.Delay(2000, cancellationToken);
await api.Conversations.Reactions.DeleteAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));

Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment suggests replacing the manual ApiClient instantiation with context.Api.Conversations.Reactions, but according to the changes in ConversationClient.cs, the Reactions property is already added and should be accessible via context.Api.Conversations.Reactions. If this is genuinely a deployment/availability concern, the comment should clarify what "available in PROD" means (e.g., service-side support, feature flag, etc.). Otherwise, the code should use the simpler context.Api.Conversations.Reactions pattern directly.

Suggested change
// replace with context.Api.Conversations.Reactions once Reactions client is available in PROD.
var api = new ApiClient(context.Activity.ServiceUrl!, context.Api.Client, cancellationToken);
await api.Conversations.Reactions.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f44b_wavinghand-tone4"));
await Task.Delay(2000, cancellationToken);
await api.Conversations.Reactions.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));
await Task.Delay(2000, cancellationToken);
await api.Conversations.Reactions.DeleteAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));
var reactionsClient = context.Api.Conversations.Reactions;
await reactionsClient.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f44b_wavinghand-tone4"));
await Task.Delay(2000, cancellationToken);
await reactionsClient.AddAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));
await Task.Delay(2000, cancellationToken);
await reactionsClient.DeleteAsync(context.Activity.Conversation.Id, context.Activity.Id, new ReactionType("1f601_beamingfacewithsmilingeyes"));

Copilot uses AI. Check for mistakes.
- Changed reaction API route to include reactionType in the URL path.
- Updated XML docs to use "launch" as example reaction type.
- Removed outdated comment in Program.cs and used new Reactions client.
- Renamed test method to match AddAsync method.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants