From 3a7dc158aa43bdb373ccf0ee2b101d3f0b03de92 Mon Sep 17 00:00:00 2001 From: Kavin Singh Date: Fri, 24 Apr 2026 12:40:30 -0700 Subject: [PATCH 1/2] add comments --- core/samples/CompatBot/EchoBot.cs | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/core/samples/CompatBot/EchoBot.cs b/core/samples/CompatBot/EchoBot.cs index 5ce32902..050527b6 100644 --- a/core/samples/CompatBot/EchoBot.cs +++ b/core/samples/CompatBot/EchoBot.cs @@ -34,15 +34,21 @@ protected override async Task OnMessageActivityAsync(ITurnContext conversationStateAccessors = conversationState.CreateProperty(nameof(ConversationData)); ConversationData conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationData(), cancellationToken); + // --- CompatTeamsInfo: Retrieve member details for the sender --- var mm = await CompatTeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id); string replyText = $"Echo {mm.Name} from BF Compat [{conversationData.MessageCount++}]: {turnContext.Activity.Text}"; + // --- Targeted Messaging via BF compat layer --- + // Setting isTargeted on the Recipient makes the message visible only to that user. + // Note: This sets the property on the BF ChannelAccount; the compat layer converts it + // to CoreActivity.Recipient.IsTargeted which appends ?isTargetedActivity=true to the URL. var act = MessageFactory.Text(replyText, replyText); act.Recipient = new ChannelAccount(); act.Recipient.Properties.Add("isTargeted", true); await turnContext.SendActivityAsync(act, cancellationToken); + // --- CompatTeamsInfo: Team details and paged member listing (group context only) --- if (turnContext.Activity.Conversation.IsGroup == true) { var teamDetails = await CompatTeamsInfo.GetTeamDetailsAsync(turnContext, null, cancellationToken); @@ -60,7 +66,6 @@ protected override async Task OnMessageActivityAsync(ITurnContext m.Name).ToList(), Formatting.Indented)); } - - - - // await turnContext.SendActivityAsync(MessageFactory.Text($"Send a proactive message `/api/notify/{turnContext.Activity.Conversation.Id}`"), cancellationToken); - + // --- Targeted Messaging via Core SDK (preferred approach) --- + // Uses CoreActivity builder with WithRecipient(from, isTargeted: true) and sends + // directly through ConversationClient, bypassing the BF compat layer's + // ApplyConversationReference which would overwrite the Recipient. var incomingCoreActivity = ((Activity)turnContext.Activity).FromCompatActivity(); CoreActivity tm = CoreActivity.CreateBuilder() .WithConversation(new Conversation { Id = incomingCoreActivity.Conversation?.Id! }) @@ -85,11 +89,13 @@ protected override async Task OnMessageActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) { await turnContext.SendActivityAsync(MessageFactory.Text("Installation update received."), cancellationToken); @@ -150,6 +163,8 @@ protected override async Task OnInstallationUpdateAddAsync(ITurnContext OnInvokeActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) { logger.LogInformation("Invoke Activity received: {Name}", turnContext.Activity.Name); @@ -179,6 +194,7 @@ protected override async Task OnInstallationUpdateAddAsync(ITurnContext membersAdded, ITurnContext turnContext, CancellationToken cancellationToken) { await turnContext.SendActivityAsync(MessageFactory.Text("Welcome."), cancellationToken); @@ -196,6 +212,7 @@ protected override async Task OnTeamsMeetingStartAsync(MeetingStartEventDetails await turnContext.SendActivityAsync(MessageFactory.Text($"{meeting.Title} {meeting.MeetingType}"), cancellationToken); } + // --- Activity Lifecycle: Send, update, then delete an activity --- private static async Task SendUpdateDeleteActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) { ConversationReference cr = turnContext.Activity.GetConversationReference(); From bae05c1b3956fcc79b63ece35ddf477c0836a22f Mon Sep 17 00:00:00 2001 From: Kavin Singh Date: Fri, 24 Apr 2026 16:15:26 -0700 Subject: [PATCH 2/2] Remove obvious, redundant, and duplicate comments Keep only comments that explain non-obvious behavior (isTargeted compat layer conversion, Core SDK bypassing ApplyConversationReference, and cross-reference to OnInvokeActivityAsync). Co-Authored-By: Claude Opus 4.6 (1M context) --- core/samples/CompatBot/EchoBot.cs | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/core/samples/CompatBot/EchoBot.cs b/core/samples/CompatBot/EchoBot.cs index 050527b6..a1131d65 100644 --- a/core/samples/CompatBot/EchoBot.cs +++ b/core/samples/CompatBot/EchoBot.cs @@ -34,21 +34,18 @@ protected override async Task OnMessageActivityAsync(ITurnContext conversationStateAccessors = conversationState.CreateProperty(nameof(ConversationData)); ConversationData conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationData(), cancellationToken); - // --- CompatTeamsInfo: Retrieve member details for the sender --- var mm = await CompatTeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id); string replyText = $"Echo {mm.Name} from BF Compat [{conversationData.MessageCount++}]: {turnContext.Activity.Text}"; - // --- Targeted Messaging via BF compat layer --- - // Setting isTargeted on the Recipient makes the message visible only to that user. - // Note: This sets the property on the BF ChannelAccount; the compat layer converts it - // to CoreActivity.Recipient.IsTargeted which appends ?isTargetedActivity=true to the URL. + // Targeted Messaging via BF compat layer: setting isTargeted on the BF ChannelAccount + // causes the compat layer to set CoreActivity.Recipient.IsTargeted, which appends + // ?isTargetedActivity=true to the URL making the message visible only to that user. var act = MessageFactory.Text(replyText, replyText); act.Recipient = new ChannelAccount(); act.Recipient.Properties.Add("isTargeted", true); await turnContext.SendActivityAsync(act, cancellationToken); - // --- CompatTeamsInfo: Team details and paged member listing (group context only) --- if (turnContext.Activity.Conversation.IsGroup == true) { var teamDetails = await CompatTeamsInfo.GetTeamDetailsAsync(turnContext, null, cancellationToken); @@ -73,10 +70,8 @@ protected override async Task OnMessageActivityAsync(ITurnContext m.Name).ToList(), Formatting.Indented)); } - // --- Targeted Messaging via Core SDK (preferred approach) --- - // Uses CoreActivity builder with WithRecipient(from, isTargeted: true) and sends - // directly through ConversationClient, bypassing the BF compat layer's - // ApplyConversationReference which would overwrite the Recipient. + // Targeted Messaging via Core SDK (preferred): sends directly through ConversationClient + // to bypass the BF compat layer's ApplyConversationReference which would overwrite the Recipient. var incomingCoreActivity = ((Activity)turnContext.Activity).FromCompatActivity(); CoreActivity tm = CoreActivity.CreateBuilder() .WithConversation(new Conversation { Id = incomingCoreActivity.Conversation?.Id! }) @@ -89,13 +84,11 @@ protected override async Task OnMessageActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) { await turnContext.SendActivityAsync(MessageFactory.Text("Installation update received."), cancellationToken); @@ -163,8 +151,6 @@ protected override async Task OnInstallationUpdateAddAsync(ITurnContext OnInvokeActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) { logger.LogInformation("Invoke Activity received: {Name}", turnContext.Activity.Name); @@ -194,7 +180,6 @@ protected override async Task OnInstallationUpdateAddAsync(ITurnContext membersAdded, ITurnContext turnContext, CancellationToken cancellationToken) { await turnContext.SendActivityAsync(MessageFactory.Text("Welcome."), cancellationToken); @@ -212,7 +197,6 @@ protected override async Task OnTeamsMeetingStartAsync(MeetingStartEventDetails await turnContext.SendActivityAsync(MessageFactory.Text($"{meeting.Title} {meeting.MeetingType}"), cancellationToken); } - // --- Activity Lifecycle: Send, update, then delete an activity --- private static async Task SendUpdateDeleteActivityAsync(ITurnContext turnContext, CancellationToken cancellationToken) { ConversationReference cr = turnContext.Activity.GetConversationReference();