Conversation
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.
Libraries/Microsoft.Teams.Api/Activities/Message/MessageReactionActivity.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
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
ReactionClientwith methods to create/update and delete reactions on messages - Integrated
ReactionClientintoConversationClientand exposed it throughApiClient.Conversations.Reactions - Expanded
ReactionTypewith additional reaction types (checkmark, hourglass, pushpin, exclamation) with emoji documentation - Removed
AddReactionandRemoveReactionhelper methods fromMessageReactionActivity - 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
IHttpClientvia theClientproperty onApiClientto 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.
|
@copilot open a new pull request to apply changes based on the comments in this thread |
…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>
There was a problem hiding this comment.
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.
Tests/Microsoft.Teams.Apps.Tests/Activities/Messages/MessageReactionActivityTests.cs
Show resolved
Hide resolved
Tests/Microsoft.Teams.Apps.Tests/Activities/Messages/MessageReactionActivityTests.cs
Show resolved
Hide resolved
Tests/Microsoft.Teams.Apps.Tests/Activities/Messages/MessageReactionActivityTests.cs
Show resolved
Hide resolved
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.
There was a problem hiding this comment.
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.
Samples/Samples.Reactions/Program.cs
Outdated
|
|
||
| // 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")); |
There was a problem hiding this comment.
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.
| // 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")); |
Samples/Samples.Reactions/Properties/launchSettings.TEMPLATE.json
Outdated
Show resolved
Hide resolved
corinagum
left a comment
There was a problem hiding this comment.
I left a few nits / question.
Corrected closing brackets to ensure valid JSON formatting. Removed extraneous characters at the end of the file.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| var res = await _app.Process<TestPlugin>(_token, new MessageReactionActivity()); | ||
|
|
There was a problem hiding this comment.
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.
| 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); |
| }); | ||
|
|
||
| var res = await _app.Process<TestPlugin>(_token, new MessageReactionActivity().RemoveReaction(Api.Messages.ReactionType.Angry)); | ||
| var res = await _app.Process<TestPlugin>(_token, new MessageReactionActivity()); |
There was a problem hiding this comment.
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.
| // 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")); | ||
|
|
There was a problem hiding this comment.
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.
| // 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")); | |
- 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.
This pull request introduces a new
ReactionClientto 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:
ReactionClientclass to encapsulate operations for creating, updating, and deleting message reactions via HTTP requests. This client is now accessible through theConversationClientas theReactionsproperty. [1] [2]IHttpClientas a property onApiClientfor easier access in advanced scenarios.Message Reaction Model Changes:
AddReactionandRemoveReactionhelper methods fromMessageReactionActivity, making reaction management the responsibility of the new client rather than the activity model itself.ReactionTypeclass to include additional reaction types (e.g., checkmark, hourglass, pushpin, exclamation) with descriptive comments and emoji representations.Sample and Solution Updates:
Samples.Reactions, demonstrating how to use the newReactionClientto 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:
MessageReactionActivityto remove reliance on the deleted helper methods and reflect the new approach to reaction handling. [1] [2] [3] [4] [5] [6]Miscellaneous: