Hello Sharavan !
Thank you for posting on Microsoft Q&A.
In Microsoft Teams the replyToId field is optional in the Bot Framework schema and Teams often doesn’t set it on incoming activities even for thread replies. In channel conversations, Teams encodes the thread (root message) id inside activity.conversation.id, and that’s the reliable way to tell if it is a new top-level post or a reply.
You can use the thread id embedded in conversation.id. If the current activity id equals the embedded root id so it’s the root post, otherwise it’s a reply.
using System.Text.RegularExpressions;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
static string GetRootMessageId(Activity a)
{
var convId = a.Conversation?.Id ?? "";
var m = Regex.Match(convId, @";messageid=([^;]+)", RegexOptions.IgnoreCase);
return m.Success ? m.Groups[1].Value : null;
}
var activity = turnContext.Activity;
bool isChannel = activity.Conversation?.ConversationType == "channel";
var rootId = GetRootMessageId(activity);
bool isThread = isChannel && rootId != null;
bool isRootPost = isThread && activity.Id == rootId;
bool isReply = isThread && activity.Id != rootId;
bool botMentioned = activity.GetMentions()?
.Any(m => m.Mentioned?.Id == activity.Recipient?.Id) == true;
if (isRootPost) {
// respond
} else if (isReply && !botMentioned) {
// ignore
}
using System.Text.RegularExpressions;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
static string GetRootMessageId(Activity a)
{
var convId = a.Conversation?.Id ?? "";
var m = Regex.Match(convId, @";messageid=([^;]+)", RegexOptions.IgnoreCase);
return m.Success ? m.Groups[1].Value : null;
}
var activity = turnContext.Activity;
bool isChannel = activity.Conversation?.ConversationType == "channel";
var rootId = GetRootMessageId(activity);
bool isThread = isChannel && rootId != null;
bool isRootPost = isThread && activity.Id == rootId;
bool isReply = isThread && activity.Id != rootId;
bool botMentioned = activity.GetMentions()?
.Any(m => m.Mentioned?.Id == activity.Recipient?.Id) == true;
if (isRootPost) {
// respond
} else if (isReply && !botMentioned) {
// ignore
}
== activity.Recipient?.Id) == true;
if (isRootPost) {
// respond
} else if (isReply && !botMentioned) {
// ignore
}
So what you are seeing is a normal behavior because replyToId is not guaranteed by channels sinceTeams commonly omits it.
It is always omitted for new posts frequently for replies in Teams channel threads also for 1:1/group chats (no threading).
To distinguish replies if replyToId isn’t present, you can parse the root message id from conversation.id and compare to activity.id as shown above.