| title | Channel/Group Conversation Chat Bot |
|---|---|
| description | Learn how to create new conversation threads, user and tag mentions, and send message on installation. Explore Teams file upload sample (.NET, JavaScript, Python). |
| ms.topic | conceptual |
| ms.localizationpriority | medium |
| ms.author | anclear |
| ms.owner | angovil |
| ms.date | 01/23/2025 |
[!INCLUDE pre-release-label]
To install the Microsoft Teams bot in a team or group chat, add the teams or groupchat scope to your bot. This allows all members of the conversation to interact with your bot. After the bot is installed, it has access to metadata about the conversation, such as the list of conversation members. Also, when it's installed in a team, the bot has access to details about that team and the full list of channels.
Bots in a group or channel only receive messages when they're mentioned @botname. They don't receive any other messages sent to the conversation. The bot must be @mentioned directly. Your bot doesn't receive a message when the team or channel is mentioned, or when someone replies to a message from your bot without @mentioning it.
Note
- Using resource-specific consent (RSC), a bot can receive all channel messages in teams that it's installed in without being @mentioned. For more information, see receive all channel messages with RSC.
- Posting a message or Adaptive Card to a private channel isn't supported.
See the following video to learn about channel and group chat conversations with a bot:
[!VIDEO a22d3980-2cf0-45fe-89a2-02a13cf8640e]
Unlike personal chats, in group chats and channels, your bot must provide a quick introduction. You must follow these and more bot design guidelines. For more information on how to design bots in Teams, see how to design bot conversations in channels and chats.
Now, you can create new conversation threads and easily manage different conversations in channels.
When your bot is installed in a team, you must create a new conversation thread rather than reply to an existing one. At times, it's difficult to differentiate between two conversations. If the conversation is threaded, it's easier to organize and manage different conversations in channels. This is a form of proactive messaging.
Next, you can retrieve mentions using the entities object and add mentions to your messages using the Mention object.
Every message to your bot from a group or channel contains an @mention with its name in the message text. Your bot can also retrieve other users mentioned in a message and add mentions to any messages it sends. Bots in group chats enable user mentions using @mention; however, they don’t support @everyone for mentions.
You must also strip out the @mentions from the content of the message your bot receives.
Mentions are returned in the entities object in payload and contain both the unique ID of the user and the name of the user mentioned. The text of the message also includes the mention, such as <at>@John Smith<at>. However, don't rely on the text in the message to retrieve any information about the user. It's possible for the person sending the message to alter it. Therefore, use the entities object.
You can retrieve all mentions in the message by calling the GetMentions function in the Bot Builder SDK, which returns an array of Mention objects.
The following code shows an example of retrieving mentions:
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// Resolves the mentions from the entities activity.
Mention[] mentions = turnContext.Activity.GetMentions();
if(mentions != null)
{
ChannelAccount firstMention = mentions[0].Mentioned;
// Sends a message activity to the sender of the incoming activity.
await turnContext.SendActivityAsync($"Hello {firstMention.Name}");
}
else
{
// Sends a message activity to the sender of the incoming activity.
await turnContext.SendActivityAsync("Aw, no one was mentioned.");
}
}this.onMessage(async (turnContext, next) => {
// Resolves the mentions from the entities activity.
const mentions = TurnContext.getMentions(turnContext.activity);
if (mentions){
const firstMention = mentions[0].mentioned;
// Sends a message activity to the sender of the incoming activity.
await turnContext.sendActivity(`Hello ${firstMention.name}.`);
} else {
// Sends a message activity to the sender of the incoming activity.
await turnContext.sendActivity(`Aw, no one was mentioned.`);
}
await next();
});{
"type": "message",
"text": "Hey <at>Pranav Smith</at> check out this message",
"timestamp": "2017-10-29T00:51:05.9908157Z",
"localTimestamp": "2017-10-28T17:51:05.9908157-07:00",
"serviceUrl": "https://skype.botframework.com",
"channelId": "msteams",
"from": {
"id": "29:9e52142b-5e5e-4d7b-bb3e-e82dcf620000",
"name": "Jane Smith"
},
"conversation": {
"id": "19:[email protected];messageid=1481567603816"
},
"recipient": {
"id": "8:orgid:6aebbad0-e5a5-424a-834a-20fb051f3c1a",
"name": "stlrgload100"
},
"attachments": [
{
"contentType": "image/png",
"contentUrl": "https://upload.wikimedia.org/wikipedia/en/a/a6/Bender_Rodriguez.png",
"name": "Bender_Rodriguez.png"
}
],
"entities": [
{
"type":"mention",
"mentioned":{
"id":"29:08q2j2o3jc09au90eucae",
"name":"Pranav Smith"
},
"text": "<at>@Pranav Smith</at>"
}
],
"replyToId": "3UP4UTkzUk1zzeyW"
}@staticmethod
// Resolves the mentions from the entities of this activity.
def get_mentions(activity: Activity) -> List[Mention]:
result: List[Mention] = []
if activity.entities is not None:
for entity in activity.entities:
if entity.type.lower() == "mention":
result.append(entity)
return resultThere are two types of mentions:
Note
User mention and tag mention is supported for both text message and Adaptive Card.
Your bot can mention other users in messages posted in channels.
The Mention object has two properties that you must set using the following:
- Include @username in the message text.
- Include the mention object inside the entities collection.
The Bot Framework SDK provides helper methods and objects to create mentions.
The following code shows an example of adding mentions to your messages:
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var mention = new Mention
{
Mentioned = turnContext.Activity.From,
Text = $"<at>{XmlConvert.EncodeName(turnContext.Activity.From.Name)}</at>",
Type = "mention",
};
// Returns a simple text message.
var replyActivity = MessageFactory.Text($"Hello {mention.Text}.");
replyActivity.Entities = new List<Entity> { mention };
// Sends an activity to the sender of the incoming activity.
await turnContext.SendActivityAsync(replyActivity, cancellationToken);
}this.onMessage(async (turnContext, next) => {
const mention = {
mentioned: turnContext.activity.from,
text: `<at>${ new TextEncoder().encode(turnContext.activity.from.name) }</at>`,
type: "mention",
} as Mention;
// Returns a simple text message.
const replyActivity = MessageFactory.text(`Hello ${mention.text}`);
replyActivity.entities = [mention];
// Sends a message activity to the sender of the incoming activity.
await turnContext.sendActivity(replyActivity);
// By calling next() you ensure that the next BotHandler is run.
await next();
});The text field in the object in the entities array must match a portion of the message text field. If it doesn't, the mention is ignored.
{
"type": "message",
"text": "Hey <at>Pranav Smith</at> check out this message",
"timestamp": "2017-10-29T00:51:05.9908157Z",
"localTimestamp": "2017-10-28T17:51:05.9908157-07:00",
"serviceUrl": "https://skype.botframework.com",
"channelId": "msteams",
"from": {
"id": "29:9e52142b-5e5e-4d7b-bb3e-e82dcf620000",
"name": "Jane Smith"
},
"conversation": {
"id": "19:[email protected];messageid=1481567603816"
},
"recipient": {
"id": "8:orgid:6aebbad0-e5a5-424a-834a-20fb051f3c1a",
"name": "stlrgload100"
},
"attachments": [
{
"contentType": "image/png",
"contentUrl": "https://upload.wikimedia.org/wikipedia/en/a/a6/Bender_Rodriguez.png",
"name": "Bender_Rodriguez.png"
}
],
"entities": [
{
"type":"mention",
"mentioned":{
"id":"29:08q2j2o3jc09au90eucae",
"name":"Pranav Smith"
},
"text": "<at>@Pranav Smith</at>"
}
],
"replyToId": "3UP4UTkzUk1zzeyW"
}async def _mention_activity(self, turn_context: TurnContext):
mention = Mention(
mentioned=turn_context.activity.from_property,
text=f"<at>{turn_context.activity.from_property.name}</at>",
type="mention"
)
// Returns a simple text message.
reply_activity = MessageFactory.text(f"Hello {mention.text}")
# Sends a message activity to the sender of the incoming activity.
reply_activity.entities = [Mention().deserialize(mention.serialize())]
await turn_context.send_activity(reply_activity)Now you can send an introduction message when your bot is first installed or added to a group or team.
The following code snippet shows an example of mentioning users with Entra Object Id and UPN in a text message:
var userId = "[email protected]"; //User Principle Name
var mention = new ChannelAccount(userId, "Adele");
var mentionObj = new Mention
{
Mentioned = mention,
Text = $"<at>{mention.Name}</at>" ,
Type = "mention"
};
// Returns a simple text message.var replyActivity = MessageFactory.Text($"Hello {mentionObj.Text}.");replyActivity.Entities = new List<Entity> { mentionObj };
// Sends an activity to the sender of the incoming activity.await turnContext.SendActivityAsync(replyActivity, cancellationToken); The following code snippet shows an example of mentioning users with Entra Object Id and UPN in an Adaptive Card:
{
"type": "mention",
"text": "<at>Adele</at>",
"mentioned": {
"id": "[email protected]" ,// User Principle Name
"name": "Adele"
}
} Your bot can mention tags in text messages and Adaptive Cards posted in channels. When the bot @mentions the tag in a channel, the tag is highlighted and the people associated with the tag get notified. When a user hovers over the tag, a pop-up appears with the tag details.
Note
Tag mentions aren't supported in Teams operated by 21Vianet.
In the mention.properties object, add the property 'type': 'tag'. If the property 'type': 'tag' isn't added, the bot treats the mention as a user mention.
Example:
The type:tag is added as a Properties in ChannelAccount.
var mention = new ChannelAccount(tagId, "Test Tag");
mention.Properties = JObject.Parse("{'type': 'tag'}");
var mentionObj = new Mention
{
Mentioned = mention,
Text = "<at>Test Tag</at>"
};
var replyActivity = MessageFactory.Text("Hello " + mentionObj.Text);
replyActivity.Entities = new List<Microsoft.Bot.Schema.Entity> { mentionObj };
await turnContext.SendActivityAsync(replyActivity, cancellationToken); In the Adaptive Card schema, under the mentioned object, add the "type": "tag" property. If the "type": "tag" property isn't added, the bot treats the mention as a user mention.
You can get the list of the tags available in the channel using the List teamworkTags API.
Example:
{
"type": "mention",
"text": "<at>Test Tag</at>",
"mentioned": {
"id": "base64 encoded id" ,// tag graph 64 base ID
"name": "Test Tag",
"type": "tag"
}
} | Name | Description |
|---|---|
type |
The type of mention. The supported type is tag. |
id |
The unique identifier for the tag. For more information, see teamworkTag. |
| Status code | Error code | Message values | Retry request | Developer action |
|---|---|---|---|---|
| 400 | Code: Bad Request |
Mentioned tag with ID {id string} doesn't exist in current team Tag can only be mentioned in channel Invalid mentioned tag because no tag exists in the team |
No | Reevaluate request payload for errors. Check returned error message for details. |
| 502 | Code: Bad Gateway |
Invalid team group ID Malformed tenant ID for the tag Mention ID can't be resolved |
No | Retry manually. |
Any request can be evaluated against multiple limits, depending on the scope, the window type (short and long), number of tags per message, and other factors. The first limit to be reached triggers throttling behavior.
Ensure that you don't exceed the throttling limits to avoid failed message delivery. For example, a bot can send only two messages with tag mention in a five-second window and each message can have only up to 10 tags.
The following table lists the throttling limits for tag mentions in a bot:
| Scope | Window Type | Number of tags per message | Time windows (sec) | Maximum number of messages per time window |
|---|---|---|---|---|
| Per bot per thread | Short | 10 | 5 | 2 |
| Long | 10 | 60 | 5 | |
| All bots per thread | Short | 10 | 5 | 4 |
| Long | 10 | 60 | 5 |
- Tag mentions are supported only in bot to client message flow with text and Adaptive Card.
- Tag mentions aren't supported in shared and private channels.
- Tag mentions aren't supported in connectors.
- Tag mentions don't support the invoke flow in a bot.
When your bot is first added to the group or team, an introduction message must be sent. The message must provide a brief description of the bot's features and how to use them. You must subscribe to the conversationUpdate event with the teamMemberAdded eventType. The event is sent when any new team member is added. Check if the new member added is the bot. For more information, see sending a welcome message to a new team member.
You can send a personal message to each member of the team when the bot is added. To do this, fetch the team roster and send each user a direct message.
Note
Ensure that the message sent by the bot is relevant and adds value to the initial message and doesn't spam the users.
Don't send a message in the following cases:
- When the team is large, for example, larger than 100 members. Your bot can be seen as spam and the person who added it can get complaints. You must clearly communicate your bot's value proposition to everyone who sees the welcome message.
- Your bot is first mentioned in a group or channel instead of being first added to a team.
- A group or channel is renamed.
- A team member is added to a group or channel.
[!INCLUDE sample]
[!div class="nextstepaction"] Subscribe to conversation events