Skip to content

Use TM in SSO Flows#478

Open
rido-min wants to merge 10 commits into
mainfrom
core/sso-in-channels
Open

Use TM in SSO Flows#478
rido-min wants to merge 10 commits into
mainfrom
core/sso-in-channels

Conversation

@rido-min
Copy link
Copy Markdown
Member

@rido-min rido-min commented May 5, 2026

This pull request enhances the SsoBot sample to provide a more personalized and user-friendly experience, especially in group chat scenarios. The main focus is on improving message formatting, adding suggested actions, and ensuring that responses are correctly targeted to individual users in group conversations.

Personalization and Targeting in Messages:

  • Updated all user-facing messages (sign-in, sign-out, status, Graph API responses, errors) to include the user's name and set the Recipient and IsTargeted properties based on whether the chat is a group conversation, ensuring privacy and clarity in group contexts. [1] [2] [3] [4]

User Experience Improvements:

  • Added suggested actions (buttons) to key bot responses such as sign-in completion and help messages, making it easier for users to interact with the bot by clicking instead of typing commands. [1] [2]

OAuth Flow and Schema Adjustments:

  • Modified the OAuth flow to correctly set the recipient and targeting flag based on the conversation type when sending sign-in failure messages.
  • Improved XML documentation for the ConversationType property in TeamsConversation to clarify its reference.

rido-min and others added 6 commits May 4, 2026 12:49
Enhanced messages with user names for sign-in, sign-out, status, profile, and calendar commands. Added suggested action buttons for common commands in sign-in and help responses. Updated OAuthFlow recipient logic for conversation type and clarified ConversationType XML docs.
Refactor bot responses to use MessageActivity with Markdown formatting, explicitly setting Recipient and IsTargeted properties. This ensures correct message delivery and formatting in both 1:1 and group chat contexts. Update OAuthFlow to set recipient for OAuth cards based on conversation type.
@rido-min rido-min added the CORE label May 26, 2026
rido-min and others added 3 commits May 27, 2026 09:17
Added the ExperimentalTeamsTargeted warning to the <NoWarn> property in SsoBot.csproj to prevent build warnings related to experimental Teams features. No other changes were made.
@rido-min rido-min marked this pull request as ready for review May 27, 2026 21:22
Copilot AI review requested due to automatic review settings May 27, 2026 21:22
Copy link
Copy Markdown
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 updates the SsoBot sample and related core OAuth/schema code to better support targeted (private) responses in group chat SSO scenarios, plus adds some UX improvements (suggested actions) and a small XML doc clarification.

Changes:

  • Add targeted-recipient behavior in the OAuth sign-in flow when the conversation is a group chat.
  • Improve SsoBot sample message formatting/personalization and add suggested-action buttons.
  • Adjust XML documentation for TeamsConversation.ConversationType and suppress experimental targeted-messaging warnings in the SsoBot sample project.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 12 comments.

File Description
core/src/Microsoft.Teams.Apps/Schema/TeamsConversation.cs Updates XML doc reference for known conversation type values.
core/src/Microsoft.Teams.Apps/OAuth/OAuthFlow.cs Sends OAuth card with recipient targeting in group chat contexts.
core/samples/SsoBot/SsoBot.csproj Suppresses ExperimentalTeamsTargeted warnings for the sample.
core/samples/SsoBot/Program.cs Adds suggested actions and attempts to target/personalize user-facing messages.

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

Comment on lines 181 to 185
TeamsActivity oauthActivity = TeamsActivity.CreateBuilder()
.WithConversationReference(context.Activity)
.WithRecipient(context.Activity.From, false)
.WithRecipient(context.Activity.From, context.Activity?.Conversation?.ConversationType == ConversationType.GroupChat)
.WithAttachment(attachment)
.Build();
Comment on lines +41 to +50
await context.SendActivityAsync(new MessageActivity("You're now signed in! Try `profile` or `calendar`.")
.WithSuggestedActions(
new SuggestedActions()
{
Actions = new List<SuggestedAction>()
{
new SuggestedAction() { Title = "Profile", Type = "imBack", Value = "profile" },
new SuggestedAction() { Title = "Calendar", Type = "imBack", Value = "calendar" }
}
}), ct);
Comment on lines +62 to +64
signInFailureMessage.Recipient = context.Activity.From;
signInFailureMessage.Recipient?.IsTargeted = context.Activity?.Conversation?.ConversationType == ConversationType.GroupChat; // only set IsTargeted for 1:1 chats to avoid issues in group contexts
await context.SendActivityAsync(signInFailureMessage, ct);
Comment on lines +79 to +81
alreadySignedInMessage.Recipient = context.Activity.From;
alreadySignedInMessage.Recipient?.IsTargeted = context.Activity?.Conversation?.ConversationType == ConversationType.GroupChat; // only set IsTargeted for 1:1 chats to avoid issues in group contexts
await context.SendActivityAsync(alreadySignedInMessage, ct);
Comment on lines +102 to +104
msgResponse.Recipient = context.Activity.From;
msgResponse.Recipient?.IsTargeted = context.Activity?.Conversation?.ConversationType == ConversationType.GroupChat; // only set IsTargeted for 1:1 chats to avoid issues in group contexts
await context.SendActivityAsync(msgResponse, ct);
Comment on lines 127 to 130
catch (HttpRequestException ex)
{
await context.SendActivityAsync($"Graph call failed: {ex.Message}", ct);
await context.SendActivityAsync($"[{context.Activity.From?.Name}] Graph call failed: {ex.Message}", ct);
}
Comment on lines +140 to +142
signOutMessage.Recipient = context.Activity.From;
signOutMessage.Recipient?.IsTargeted = context.Activity?.Conversation?.ConversationType == ConversationType.GroupChat; // only set IsTargeted for 1:1 chats to avoid issues in group contexts
await context.SendActivityAsync(signOutMessage, ct);
Comment on lines +154 to +156
signInStatusMessage.Recipient = context.Activity.From;
signInStatusMessage.Recipient?.IsTargeted = context.Activity?.Conversation?.ConversationType == ConversationType.GroupChat; // only set IsTargeted for 1:1 chats to avoid issues in group contexts
await context.SendActivityAsync(signInStatusMessage, ct);
Comment on lines +177 to +181
Actions = new List<SuggestedAction>()
{
new SuggestedAction() { Title = "Login", Type = "imBack", Value = "login" },
new SuggestedAction() { Title = "Logout", Type = "imBack", Value = "logout" },
new SuggestedAction() { Title = "Status", Type = "imBack", Value = "status" },
Comment on lines 74 to 77
/// <summary>
/// Conversation Type. See <see cref="ConversationType"/> for known values.
/// Conversation Type. See <see cref="Schema.ConversationType"/> for known values.
/// </summary>
[JsonPropertyName("conversationType")] public string? ConversationType { get; set; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants