using Microsoft.Teams.Api.Activities;
using Microsoft.Teams.Api.Entities;
using Microsoft.Teams.Apps.Activities;
using Microsoft.Teams.Apps.Extensions;
using Microsoft.Teams.Plugins.AspNetCore.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.AddTeams();
var app = builder.Build();
var teams = app.UseTeams();
teams.OnActivity(async (context, cancellationToken) =>
{
context.Log.Info($"[ACTIVITY] Type: {context.Activity.Type}, From: {context.Activity.From?.Name ?? "unknown"}");
await context.Next();
});
teams.OnMessage(async (context, cancellationToken) =>
{
var activity = context.Activity;
var text = activity.Text?.ToLowerInvariant() ?? "";
context.Log.Info($"[MESSAGE] Received: {text}");
// ============================================
// Read inbound quoted replies
// ============================================
var quotes = activity.GetQuotedMessages();
if (quotes.Count > 0)
{
var quote = quotes[0].QuotedReply!;
var info = $"Quoted message ID: {quote.MessageId}";
if (quote.SenderName != null) info += $"\nFrom: {quote.SenderName}";
if (quote.Preview != null) info += $"\nPreview: \"{quote.Preview}\"";
if (quote.IsReplyDeleted == true) info += "\n(deleted)";
if (quote.ValidatedMessageReference == true) info += "\n(validated)";
await context.Send($"You sent a message with a quoted reply:\n\n{info}", cancellationToken);
}
// ============================================
// Reply() — auto-quotes the inbound message
// ============================================
if (text.Contains("test reply"))
{
await context.Reply("Thanks for your message! This reply auto-quotes it using Reply().", cancellationToken);
return;
}
// ============================================
// Quote() — quote a previously sent message by ID
// ============================================
if (text.Contains("test quote"))
{
var sent = await context.Send("The meeting has been moved to 3 PM tomorrow.", cancellationToken);
await context.Quote(sent.Id, "Just to confirm — does the new time work for everyone?", cancellationToken);
return;
}
// ============================================
// AddQuote() — builder with response
// ============================================
if (text.Contains("test add"))
{
var sent = await context.Send("Please review the latest PR before end of day.", cancellationToken);
var msg = new MessageActivity()
.AddQuote(sent.Id, "Done! Left my comments on the PR.");
await context.Send(msg, cancellationToken);
return;
}
// ============================================
// Multi-quote with mixed responses
// ============================================
if (text.Contains("test multi"))
{
var sentA = await context.Send("We need to update the API docs before launch.", cancellationToken);
var sentB = await context.Send("The design mockups are ready for review.", cancellationToken);
var sentC = await context.Send("CI pipeline is green on main.", cancellationToken);
var msg = new MessageActivity()
.AddQuote(sentA.Id, "I can take the docs — will have a draft by Thursday.")
.AddQuote(sentB.Id, "Looks great, approved!")
.AddQuote(sentC.Id);
await context.Send(msg, cancellationToken);
return;
}
// ============================================
// AddQuote() + AddText() — manual control
// ============================================
if (text.Contains("test manual"))
{
var sent = await context.Send("Deployment to staging is complete.", cancellationToken);
var msg = new MessageActivity()
.AddQuote(sent.Id)
.AddText(" Verified — all smoke tests passing.");
await context.Send(msg, cancellationToken);
return;
}
// ============================================
// ToQuoteReply() — obsolete method (temporary)
// ============================================
if (text.Contains("test obsolete"))
{
#pragma warning disable CS0618 // Obsolete
var placeholder = activity.ToQuoteReply();
#pragma warning restore CS0618
await context.Send($"ToQuoteReply() returned: {placeholder}", cancellationToken);
return;
}
// ============================================
// Help / Default
// ============================================
if (text.Contains("help"))
{
await context.Send(
"**Quoting Test Bot**\n\n" +
"**Commands:**\n" +
"- `test reply` - Reply() auto-quotes your message\n" +
"- `test quote` - Quote() quotes a previously sent message\n" +
"- `test add` - AddQuote() builder with response\n" +
"- `test multi` - Multi-quote with mixed responses (one bare quote with no response)\n" +
"- `test manual` - AddQuote() + AddText() manual control\n" +
"- `test obsolete` - ToQuoteReply() obsolete method\n\n" +
"Quote any message to me to see the parsed metadata!", cancellationToken);
return;
}
await context.Send($"You said: '{activity.Text}'\n\nType `help` to see available commands.", cancellationToken);
});
app.Run();microsoft/teams.net
Publicmirrored fromhttps://github.com/microsoft/teams.netAvailable
Samples/Samples.Quoting/Program.cs
134lines · modepreview