Updates from: 04/13/2021 03:11:50
Service Microsoft Docs article Related commit history on GitHub Change details
platform Bot Basics https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/bot-basics.md
Title: Bot basics
+ Title: Bot activity handlers
-description: Understand the basics of bots in Teams.
+description: Understand the bot activity handlers in Teams.
-# Bot basics
-This document provides an introduction to bots in Microsoft Teams that builds on the article [How bots work](https://aka.ms/how-bots-work) in the core [Bot Framework documentation](https://aka.ms/azure-bot-service-docs). The primary difference between bots developed for Microsoft Teams and the core Bot Framework is in the features provided in Teams.
+# Bot activity handlers
+
+This document builds on the article on [how bots work](https://aka.ms/how-bots-work) in the core [Bot Framework documentation](https://aka.ms/azure-bot-service-docs). The primary difference between bots developed for Microsoft Teams and the core Bot Framework is in the features provided in Teams.
+
+To organize the conversational logic for your bot, an activity handler is used. Activities are handled in two ways using Teams activity handlers and bot logic. The Teams activity handler adds support for Microsoft Teams-specific events and interactions. The bot object contains the conversational reasoning or logic for a turn and exposes a turn handler, which is the method that can accept incoming activities from the bot adapter.
## Teams activity handlers Teams activity handler is derived from Microsoft Bot Framework's activity handler. It routes all Teams activities before allowing any non-Teams specific activities to be handled.
-When a bot for Teams receives an activity, it is directed to the *activity handlers*. All activities are routed through one base handler called the *turn handler*. The *turn handler* calls the required activity handler to manage any activity received. The Teams bot is derived from `TeamsActivityHandler` class, which is derived from the Bot Framework's `ActivityHandler` class.
+When a bot for Teams receives an activity, it is routed to the activity handlers. All activities are routed through one base handler called the turn handler. The turn handler calls the required activity handler to manage any activity received. The Teams bot is derived from `TeamsActivityHandler` class, which is derived from the Bot Framework's `ActivityHandler` class.
# [C#](#tab/csharp)
Bots are created using the Bot Framework. If the bots receive a message activity
In the Teams activity handler class, there are two primary Teams activity handlers, `OnConversationUpdateActivityAsync` and `OnInvokeActivityAsync`. `OnConversationUpdateActivityAsync` routes all conversation update activities and `OnInvokeActivityAsync` routes all Teams invoke activities.
-To implement your logic for Teams specific activity handlers, you must override the methods in your bot as shown in the [Bot logic](#bot-logic) section. There is no base implementation for these handlers, therefore, you must add the logic that you want in your override.
+To implement your logic for Teams specific activity handlers, you must override the methods in your bot as shown in the [bot logic](#bot-logic) section. There is no base implementation for these handlers, therefore, you must add the logic that you want in your override.
# [JavaScript](#tab/javascript)
Bots are created using the Bot Framework. If the bots receive a message activity
In the Teams activity handler class, there are two primary Teams activity handlers, `dispatchConversationUpdateActivity` and `onInvokeActivity`. `dispatchConversationUpdateActivity` routes all conversation update activities and `onInvokeActivity` routes all Teams invoke activities.
-To implement your logic for Teams specific activity handlers, you must override the methods in your bot as shown in the [Bot logic](#bot-logic) section. Define your bot logic for these handlers, then **be sure to call `next()` at the end**. By calling `next()` you ensure that the next handler runs.
+To implement your logic for Teams specific activity handlers, you must override the methods in your bot as shown in the [bot logic](#bot-logic) section. Define your bot logic for these handlers, then be sure to call `next()` at the end. By calling `next()` you ensure that the next handler runs.
# [Python](#tab/python)
Bots are created using the Bot Framework. If the bots receive a message activity
In the Teams activity handler class, there are two primary Teams activity handlers, `on_conversation_update_activity` and `on_invoke_activity`. `on_conversation_update_activity` routes all conversation update activities and `on_invoke_activity` routes all Teams invoke activities.
-To implement your logic for Teams specific activity handlers, you must override the methods in your bot as shown in the [Bot logic](#bot-logic) section. There is no base implementation for these handlers, therefore, you must add the logic that you want in your override.
+To implement your logic for Teams specific activity handlers, you must override the methods in your bot as shown in the [bot logic](#bot-logic) section. There is no base implementation for these handlers, therefore, you must add the logic that you want in your override.
The bot logic processes incoming activities from one or more of your bot channel
#### Core Bot Framework handlers >[!NOTE]
-> Except for the *added* and *removed* members' activities, all the activity handlers described in this section continue to work as they do with a non-Teams bot.
+> Except for the **added** and **removed** members' activities, all the activity handlers described in this section continue to work as they do with a non-Teams bot.
Activity handlers are different in context of a team, where a new member is added to the team instead of a message thread.
The list of handlers defined in `ActivityHandler` include the following:
#### Teams specific activity handlers
-The `TeamsActivityHandler` extends the list of handlers in the Core Bot Framework handlers section to include the following:
+The `TeamsActivityHandler` extends the list of handlers in the core Bot Framework handlers section to include the following:
| Event | Handler | Description | | :-- | :-- | :-- |
-| channelCreated | `OnTeamsChannelCreatedAsync` | This method can be overridden to handle a Teams channel being created. For more information, see [Channel created](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-created) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
-| channelDeleted | `OnTeamsChannelDeletedAsync` | This method can be overridden to handle a Teams channel being deleted. For more information, see [Channel deleted](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-deleted) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| channelRenamed | `OnTeamsChannelRenamedAsync` | This method can be overridden to handle a Teams channel being renamed. For more information, see [Channel renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-renamed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| teamRenamed | `OnTeamsTeamRenamedAsync` | `return Task.CompletedTask;` This method can be overridden to handle a Teams team being renamed. For more information, see [Team renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-renamed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| MembersAdded | `OnTeamsMembersAddedAsync` | This method calls the `OnMembersAddedAsync` method in `ActivityHandler`. The method can be overridden to handle members joining a team. For more information, see [Team members added](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-added) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| MembersRemoved | `OnTeamsMembersRemovedAsync` | This method calls the `OnMembersRemovedAsync` method in `ActivityHandler`. The method can be overridden to handle members leaving a team. For more information, see [Team members removed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-removed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| channelCreated | `OnTeamsChannelCreatedAsync` | This method can be overridden to handle a Teams channel being created. For more information, see [channel created](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-created) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
+| channelDeleted | `OnTeamsChannelDeletedAsync` | This method can be overridden to handle a Teams channel being deleted. For more information, see [channel deleted](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-deleted) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| channelRenamed | `OnTeamsChannelRenamedAsync` | This method can be overridden to handle a Teams channel being renamed. For more information, see [channel renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-renamed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| teamRenamed | `OnTeamsTeamRenamedAsync` | `return Task.CompletedTask;` This method can be overridden to handle a Teams team being renamed. For more information, see [team renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-renamed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| MembersAdded | `OnTeamsMembersAddedAsync` | This method calls the `OnMembersAddedAsync` method in `ActivityHandler`. The method can be overridden to handle members joining a team. For more information, see [team members added](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-added) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| MembersRemoved | `OnTeamsMembersRemovedAsync` | This method calls the `OnMembersRemovedAsync` method in `ActivityHandler`. The method can be overridden to handle members leaving a team. For more information, see [team members removed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-removed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
#### Teams invoke activities
The list of Teams activity handlers called from the `OnInvokeActivityAsync` Team
| task/fetch | `OnTeamsTaskModuleFetchAsync` | This method can be overridden in a derived class to provide logic when a task module is fetched. | | task/submit | `OnTeamsTaskModuleSubmitAsync` | This method can be overridden in a derived class to provide logic when a task module is submitted. |
-The invoke activities listed in this section are for conversational bots in Teams. The Bot Framework SDK also supports invoke activities specific to messaging extensions. For more information, see [What are messaging extensions](https://aka.ms/azure-bot-what-are-messaging-extensions).
+The invoke activities listed in this section are for conversational bots in Teams. The Bot Framework SDK also supports invoke activities specific to messaging extensions. For more information, see [what are messaging extensions](https://aka.ms/azure-bot-what-are-messaging-extensions).
# [JavaScript](#tab/javascript) #### Core Bot Framework handlers >[!NOTE]
-> Except for the *added* and *removed* members' activities, all the activity handlers described in this section continue to work as they do with a non-Teams bot.
+> Except for the **added** and **removed** members' activities, all the activity handlers described in this section continue to work as they do with a non-Teams bot.
Activity handlers are different in context of a team, where the new member is added to the team instead of a message thread.
The list of handlers defined in `ActivityHandler` include the following:
#### Teams specific activity handlers
-The `TeamsActivityHandler` extends the list of handlers in the Core Bot Framework handlers section to include the following:
+The `TeamsActivityHandler` extends the list of handlers in the core Bot Framework handlers section to include the following:
| Event | Handler | Description | | :-- | :-- | :-- |
-| channelCreated | `OnTeamsChannelCreatedAsync` | This method can be overridden to handle a Teams channel being created. For more information, see [Channel created](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-created) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
-| channelDeleted | `OnTeamsChannelDeletedAsync` | This method can be overridden to handle a Teams channel being deleted. For more information, see [Channel deleted](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-deleted) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| channelRenamed | `OnTeamsChannelRenamedAsync` | This method can be overridden to handle a Teams channel being renamed. For more information, see [Channel renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-renamed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
-| teamRenamed | `OnTeamsTeamRenamedAsync` | `return Task.CompletedTask;` This method can be overridden to handle a Teams team being renamed. For more information, see [Team renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-renamed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
-| MembersAdded | `OnTeamsMembersAddedAsync` | This method calls the `OnMembersAddedAsync` method in `ActivityHandler`. The method can be overridden to handle members joining a team. For more information, see [Team members added](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-added) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
-| MembersRemoved | `OnTeamsMembersRemovedAsync` | This method calls the `OnMembersRemovedAsync` method in `ActivityHandler`. The method can be overridden to handle members leaving a team. For more information, see [Team members removed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-removed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
+| channelCreated | `OnTeamsChannelCreatedAsync` | This method can be overridden to handle a Teams channel being created. For more information, see [channel created](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-created) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
+| channelDeleted | `OnTeamsChannelDeletedAsync` | This method can be overridden to handle a Teams channel being deleted. For more information, see [channel deleted](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-deleted) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| channelRenamed | `OnTeamsChannelRenamedAsync` | This method can be overridden to handle a Teams channel being renamed. For more information, see [channel renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-renamed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
+| teamRenamed | `OnTeamsTeamRenamedAsync` | `return Task.CompletedTask;` This method can be overridden to handle a Teams team being renamed. For more information, see [team renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-renamed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
+| MembersAdded | `OnTeamsMembersAddedAsync` | This method calls the `OnMembersAddedAsync` method in `ActivityHandler`. The method can be overridden to handle members joining a team. For more information, see [team members added](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-added) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
+| MembersRemoved | `OnTeamsMembersRemovedAsync` | This method calls the `OnMembersRemovedAsync` method in `ActivityHandler`. The method can be overridden to handle members leaving a team. For more information, see [team members removed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-removed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
#### Teams invoke activities
The list of Teams activity handlers called from the `onInvokeActivity` Teams act
| task/fetch | `handleTeamsTaskModuleFetch` | This method can be overridden in a derived class to provide logic when a task module is fetched. | | task/submit | `handleTeamsTaskModuleSubmit` | This method can be overridden in a derived class to provide logic when a task module is submitted. |
-The invoke activities listed in this section are for conversational bots in Teams. The Bot Framework SDK also supports invoke activities specific to messaging extensions. For more information, see [What are messaging extensions](https://aka.ms/azure-bot-what-are-messaging-extensions).
+The invoke activities listed in this section are for conversational bots in Teams. The Bot Framework SDK also supports invoke activities specific to messaging extensions. For more information, see [what are messaging extensions](https://aka.ms/azure-bot-what-are-messaging-extensions).
# [Python](#tab/python) #### Core Bot Framework handlers >[!NOTE]
-> Except for the *added* and *removed* members' activities, all the activity handlers described in this section continue to work as they do with a non-Teams bot.
+> Except for the **added** and **removed** members' activities, all the activity handlers described in this section continue to work as they do with a non-Teams bot.
Activity handlers are different in context of a team, where the new member is added to the team instead of a message thread.
The list of handlers defined in `ActivityHandler` include the following:
#### Teams specific activity handlers
-The `TeamsActivityHandler` extends the list of handlers from the Core Bot Framework handlers section to include the following:
+The `TeamsActivityHandler` extends the list of handlers from the core Bot Framework handlers section to include the following:
| Event | Handler | Description | | :-- | :-- | :-- |
-| channelCreated | `on_teams_channel_created` | This method can be overridden to handle a Teams channel being created. For more information, see [Channel created](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-created) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
-| channelDeleted | `on_teams_channel_deleted` | This method can be overridden to handle a Teams channel being deleted. For more information, see [Channel deleted](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-deleted) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| channelRenamed | `on_teams_channel_renamed` | This method can be overridden to handle a Teams channel being renamed. For more information, see [Channel renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-renamed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| teamRenamed | `on_teams_team_renamed` | `return Task.CompletedTask;` This method can be overridden to handle a Teams team being renamed. For more information, see [Team renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-renamed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| MembersAdded | `on_teams_members_added` | This method calls the `OnMembersAddedAsync` method in `ActivityHandler`. The method can be overridden to handle members joining a team. For more information, see [Team members added](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-added) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
-| MembersRemoved | `on_teams_members_removed` | This method calls the `OnMembersRemovedAsync` method in `ActivityHandler`. The method can be overridden to handle members leaving a team. For more information, see [Team members removed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-removed) in [Conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| channelCreated | `on_teams_channel_created` | This method can be overridden to handle a Teams channel being created. For more information, see [channel created](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-created) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events). |
+| channelDeleted | `on_teams_channel_deleted` | This method can be overridden to handle a Teams channel being deleted. For more information, see [channel deleted](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-deleted) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| channelRenamed | `on_teams_channel_renamed` | This method can be overridden to handle a Teams channel being renamed. For more information, see [channel renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#channel-renamed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| teamRenamed | `on_teams_team_renamed` | `return Task.CompletedTask;` This method can be overridden to handle a Teams team being renamed. For more information, see [team renamed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-renamed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| MembersAdded | `on_teams_members_added` | This method calls the `OnMembersAddedAsync` method in `ActivityHandler`. The method can be overridden to handle members joining a team. For more information, see [team members added](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-added) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
+| MembersRemoved | `on_teams_members_removed` | This method calls the `OnMembersRemovedAsync` method in `ActivityHandler`. The method can be overridden to handle members leaving a team. For more information, see [team members removed](https://aka.ms/azure-bot-subscribe-to-conversation-events#team-members-removed) in [conversation update events](https://aka.ms/azure-bot-subscribe-to-conversation-events).|
#### Teams invoke activities
The list of Teams activity handlers called from the `on_invoke_activity` Teams a
| task/fetch | `on_teams_task_module_fetch` | This method can be overridden in a derived class to provide logic when a task module is fetched. | | task/submit | `on_teams_task_module_submit` | This method can be overridden in a derived class to provide logic when a task module is submitted. |
-The invoke activities listed in this section are for conversational bots in Teams. The Bot Framework SDK also supports invoke activities specific to messaging extensions. For more information, see [What are messaging extensions](https://aka.ms/azure-bot-what-are-messaging-extensions).
+The invoke activities listed in this section are for conversational bots in Teams. The Bot Framework SDK also supports invoke activities specific to messaging extensions. For more information, see [what are messaging extensions](https://aka.ms/azure-bot-what-are-messaging-extensions).
+
+* * *
+
+Now that you have familiarized yourself with bot activity handlers, let us see how bots behave differently depending on the conversation and the messages it receives or sends.
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Conversation basics](~/bots/how-to/conversations/conversation-basics.md)
platform Bot Features https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/bot-features.md
+
+ Title: Bots and SDKs
+
+description: Bots and SDKs in Microsoft Teams.
++++
+# Bots and SDKs
+
+To create a bot that works in Microsoft Teams, you can use one of the following:
+* An existing bot built on the Microsoft Bot Framework SDK
+* Power Virtual Agents chatbot service
+* Webhooks and connectors
+
+## Bots and the Microsoft Bot Framework
+
+Your Teams bot consists of the following three elements:
+
+* A publicly accessible web service that you host.
+* Your bot registration with the Bot Framework.
+* Your Teams app package with your app manifest. This is what your users install and connect the Teams client to your web service, routed through the bot service.
+
+The [Bot Framework](https://dev.botframework.com/) is a rich SDK used to create bots using C#, Java, Python, and JavaScript. If you already have a bot that is based on the Bot Framework, you can easily modify it to work in Microsoft Teams. Use either C# or Node.js to take advantage of our [SDKs](/microsoftteams/platform/#pivot=sdk-tools). These packages extend the basic Bot Builder SDK classes and methods as follows:
+
+* Use specialized card types like the Office 365 connector card.
+* Set Teams-specific channel data on activities.
+* Process messaging extension requests.
+
+> [!IMPORTANT]
+> You can develop Teams apps in any web programming technology and call the [Bot Framework REST APIs](/bot-framework/rest-api/bot-framework-rest-overview) directly. But you must perform token handling in all cases.
+
+> [!TIP]
+> Teams App Studio helps you create and configure your app manifest, and register your web service as a bot on the Bot Framework. It also contains a React control library and an interactive card builder. For more information, see [getting started with Teams App Studio](~/concepts/build-and-test/app-studio-overview.md).
+
+## Bots and the Microsoft Power Virtual Agents
+
+[Power Virtual Agents](/power-virtual-agents/fundamentals-what-is-power-virtual-agents) is a chatbot service built on the Microsoft Power platform and Bot Framework. The Power Virtual Agent development process uses a guided, no-code, and graphical interface approach that empowers your team members to easily create and maintain an intelligent virtual agent. After creating your chatbot in the [Power Virtual Agents portal](https://powervirtualagents.microsoft.com), you can easily [integrate it with Teams](how-to/add-power-virtual-agents-bot-to-teams.md). For more information on getting started, see [Power Virtual Agents documentation](https://docs.microsoft.com/power-virtual-agents/).
+
+## Bots and webhooks and connectors
+
+Webhooks and connectors connect your bot to your web services. Using webhooks and connectors, you can create a simple bot for basic interaction, such as creating a workflow or other simple commands. They are available only in the team where you create them and are intended for simple processes specific to your company's workflow. For more information, see [what are webhooks and connectors](~/webhooks-and-connectors/what-are-webhooks-and-connectors.md).
+
+## Advantages of bots
+
+Bots in Microsoft Teams can be part of a one-to-one conversation, a group chat, or a channel in a team. Each scope provides unique opportunities and challenges for your conversational bot.
+
+| In a channel | In a group chat | In a one-to-one chat |
+| :-- | :-- | :-- |
+| Massive reach | Fewer members | Traditional way |
+| Concise individual interactions | @mention to bot | Q&A bots |
+| @mention to bot | Similar to channel | Bots that tell jokes and take notes |
+
+### In a channel
+
+Channels contain threaded conversations between multiple people even up to two thousand. This potentially gives your bot massive reach, but individual interactions must be concise. Traditional multi-turn interactions do not work. Instead, you must look to use interactive cards or task modules, or move the conversation to a one-to-one conversation to collect lots of information. Your bot only has access to messages where it is `@mentioned`. You can retrieve additional messages from the conversation using Microsoft Graph and organization-level permissions.
+
+Bots work better in a channel in the following cases:
+
+* Notifications, where you provide an interactive card for users to take additional information.
+* Feedback scenarios, such as polls and surveys.
+* Single request or response cycle resolves interactions and the results are useful for multiple members of the conversation.
+* Social or fun bots, where you get an awesome cat image, randomly pick a winner, and so on.
+
+### In a group chat
+
+Group chats are non-threaded conversations between three or more people. They tend to have fewer members than a channel and are more transient. Similar to a channel, your bot only has access to messages where it is `@mentioned` directly.
+
+In the cases where bots work better in a channel also work better in a group chat.
+
+### In a one-to-one chat
+
+One-to-one chat is a traditional way for a conversational bot to interact with a user. A few examples of one-to-one conversational bots are Q&A bots, bots that initiate workflows in other systems, bots that tell jokes, and bots that take notes. Before creating one-to-one chatbots, consider whether a conversation-based interface is the best way to present your functionality.
+
+## Disadvantages of bots
+
+An extensive dialog between your bot and the user is a slow and complex way to get a task completed. A bot that supports excessive commands, especially a broad range of commands, is not successful or viewed positively by users.
+
+### Have multi-turn experiences in chat
+
+An extensive dialog requires the developer to maintain state. To exit this state a user must either time-out or select **Cancel**. Also, the process is tedious. For example, see the following conversation scenario:
+
+USER: Schedule a meeting with Megan.
+
+BOT: IΓÇÖve found 200 results, please include a first and last name.
+
+USER: Schedule a meeting with Megan Bowen.
+
+BOT: OK, what time would you like to meet with Megan Bowen?
+
+USER: 1:00 pm.
+
+BOT: On which day?
+
+### Support too many commands
+
+As there are only six visible commands in the current bot menu, anything more is unlikely to be used with any frequency. Bots that go deep into a specific area rather than trying to be a broad assistant work and fare better.
+
+### Maintain a large knowledge base
+
+One of the disadvantages of bots is that it is difficult to maintain a large retrieval knowledge base with unranked responses. Bots are best suited for short, quick interactions, and not sifting through long lists looking for an answer.
+
+## Code sample
+
+|Sample name | Description | .NETCore | Node.js |
+|-|--|--|-|
+| Teams conversation bot | Messaging and conversation event handling. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/57.teams-conversation-bot)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/57.teams-conversation-bot)|
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Bot activity handlers](~/bots/bot-basics.md)
platform Call Notifications https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/calls-and-meetings/call-notifications.md
Title: Technical details on handling incoming call notifications
+ Title: Incoming call notifications
description: Detailed technical information on handling notifications from incoming calls+ keywords: calling calls notifications callback region affinity Last updated 04/02/2019
-# Incoming call notifications: technical details
+# Incoming call notifications
-In [Registering a calling and meeting bot for Microsoft Teams](./registering-calling-bot.md#creating-a-new-bot-or-adding-calling-capabilities-to-an-existing-bot), we mentioned the **Webhook (for calling)** URL ΓÇö the webhook endpoint for all incoming calls to your bot. This topic discusses the technical details you'll need to respond to these notifications.
+In [registering a calls and meetings bot for Microsoft Teams](./registering-calling-bot.md#create-new-bot-or-add-calling-capabilities), the Webhook for calling URL is mentioned. This URL is the webhook endpoint for all incoming calls to your bot.
## Protocol determination
-The incoming notification is provided in legacy format for compatibility with the previous [Skype protocol](/azure/bot-service/dotnet/bot-builder-dotnet-real-time-media-concepts?view=azure-bot-service-3.0). In order to convert the call to the Microsoft Graph protocol, your bot must determine whether the notification is in legacy format and reply with:
+The incoming notification is provided in a legacy format for compatibility with the previous [Skype protocol](/azure/bot-service/dotnet/bot-builder-dotnet-real-time-media-concepts?view=azure-bot-service-3.0&preserve-view=true). In order to convert the call to the Microsoft Graph protocol, your bot must determine whether the notification is in a legacy format and provide the following response:
```http HTTP/1.1 204 No Content ```
-Your bot will receive the notification again, but this time in the Microsoft Graph protocol.
+Your bot receives the notification again, but this time in the Microsoft Graph protocol.
-In a future release of the Real-time Media Platform, we'll allow you to configure the protocol your application supports to avoid receiving the initial callback in the legacy format.
+In a future release of the Real-time Media Platform, you can configure the protocol your application supports to avoid receiving the initial callback in the legacy format.
+
+The next section provides details on incoming call notifications redirected for region affinity to your deployment.
## Redirects for region affinity
-You'll call your webhook from the data-center hosting the call. The call may start in any data center and doesn't take into account region affinities. The notification will be sent to your deployment depending on the GeoDNS resolution. If your application determines, by inspecting the initial notification payload or otherwise, that it needs to run in a different deployment, the application may reply with:
+You call your webhook from the data-center hosting the call. The call starts in any data center and does not take into account region affinities. The notification is sent to your deployment depending on the GeoDNS resolution. If your application determines, by inspecting the initial notification payload or otherwise, that it needs to run in a different deployment, the application provides the following response:
```http HTTP/1.1 302 Found Location: your-new-location ```
-Enable your bot to answer an incoming call using the [answer](https://developer.microsoft.com/graph/docs/api-reference/beta/api/call_answer) API. You can specify the `callbackUri` to handle this particular call. This is useful for _stateful_ instances where your call is handled by a particular partition and you want to embed this information in the `callbackUri` for routing to the right instance.
+Enable your bot to answer an incoming call using the [answer](https://developer.microsoft.com/graph/docs/api-reference/beta/api/call_answer) API. You can specify the `callbackUri` to handle this particular call. This is useful for stateful instances where your call is handled by a particular partition, and you want to embed this information in the `callbackUri` for routing to the right instance.
+
+The next section provides details on authenticating the callback by inspecting the token posted to your webhook.
+
+## Authenticate the callback
-## Authenticating the callback
+Your bot must inspect the token posted to your webhook to validate the request. Every time the API posts to the webhook, the HTTP POST message contains an OAuth token in the Authorization header as a bearer token, with the audience as your application's App ID.
-Your bot should inspect the token posted to your webhook to validate the request. Whenever the API posts to the webhook, the HTTP POST message contains an OAuth token in the Authorization header as a Bearer token, with audience as your application's App ID.
+Your application must validate this token before accepting the callback request.
-Your application should validate this token before accepting the callback request.
+The following sample code is used to authenticate the callback:
```http POST https://bot.contoso.com/api/calls
Authentication: Bearer <TOKEN>
] ```
-The OAuth token will have values like the following, and will be signed by Skype. The OpenID configuration published at <https://api.aps.skype.com/v1/.well-known/OpenIdConfiguration> can be used to verify the token.
+The OAuth token has the following values, and is signed by Skype:
```json {
The OAuth token will have values like the following, and will be signed by Skype
} ```
-* **aud** audience is the App ID URI specified for the application.
-* **tid** is the tenant id for Contoso.com.
-* **iss** is the token issuer, `https://api.botframework.com`.
+The OpenID configuration published at <https://api.aps.skype.com/v1/.well-known/OpenIdConfiguration> can be used to verify the token. Each OAuth token value is used as follows:
+
+* `aud` where audience is the App ID URI specified for the application.
+* `tid` is the tenant id for Contoso.com.
+* `iss` is the token issuer, `https://api.botframework.com`.
+
+For your code handling, the webhook must validate the token, ensure it has not expired, and check whether it has been signed by the published OpenID configuration. You must also check whether aud matches your App ID before accepting the callback request.
+
+For more information, see [validate inbound requests](https://github.com/microsoftgraph/microsoft-graph-comms-samples/blob/master/Samples/Common/Sample.Common/Authentication/AuthenticationProvider.cs).
-Your code handling the webhook should validate the token, ensure it hasn't expired, and check whether it has been signed by our published OpenID configuration. You should also check whether **aud** matches your App ID before accepting the callback request.
+## Next step
-[Sample](https://github.com/microsoftgraph/microsoft-graph-comms-samples/blob/master/Samples/Common/Sample.Common/Authentication/AuthenticationProvider.cs) shows how to validate inbound requests.
+> [!div class="nextstepaction"]
+> [Requirements and considerations for application-hosted media bots](~/bots/calls-and-meetings/requirements-considerations-application-hosted-media-bots.md)
platform Calls Meetings Bots Overview https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/calls-and-meetings/calls-meetings-bots-overview.md
Title: Calls and Online Meetings Bots
+ Title: Calls and online meetings bots
description: Learn how your Microsoft Teams apps can interact with users using voice and video using Microsoft Graph APIs for calls and online meetings.+ keywords: calling calls audio video IVR voice online meetings # Calls and online meetings bots
-With the addition of [Microsoft Graph APIs for calls and online meetings](/graph/api/resources/communications-api-overview?view=graph-rest-beta&preserve-view=true), Microsoft Teams apps can now interact with users in rich ways using voice and video. These APIs allow you to add new features such as interactive voice response (IVR), call control, and access to real-time audio and/or video streams for calls and meetings, including desktop and app sharing.
-
-To use these Microsoft Graph APIs in a Microsoft Teams app, you create a bot and specify some additional information and permissions which we'll describe elsewhere, but first, it's important to understand some core concepts, terminology, and conventions:
-
-* **Audio/video calls.** Calls in Teams can be purely audio or audio+video. For brevity's sake, we don't say "audio/video call" everywhere; we just say "call."
-* **Call types.** Calls are either peer-to-peer (between a person and your bot) or multiparty (your bot and two or more people in a group call).
- ![CallingTypes](~/assets/images/calls-and-meetings/call-types.png):
- * A user may initiate a peer-to-peer call with your bot or invite your bot into an existing multiparty call (although the latter is not yet enabled in the Microsoft Teams UI).
-
- > [!NOTE]
- > User initiated calls to a bot are currently not supported on Microsoft Teams mobile platform.
-
- * Microsoft Graph permissions aren't necessary for a user to initiate a peer-to-peer call with your bot, but additional permissions are needed for your bot to participate in a multiparty call, or for your bot to initiate a peer-to-peer call with a user.
- * A call may start as peer-to-peer and escalate to multiparty. Your bot can initiate this escalation by inviting others, provided your bot has the proper permissions. If your bot doesn't have permissions to participate in group calls and one participant adds another party, your bot is dropped from the call.
-* **Signaling.** There are two types of signals ΓÇö incoming call and in-call:
- * To receive an incoming call, you specify an endpoint in your bot settings; this endpoint receives a notification when an incoming call arrives. You can answer the call, reject it, or redirect it to somewhere or someone else.
- ![Call Types](~/assets/images/calls-and-meetings/call-handling.png)
- * When a bot is in a call, there are APIs for muting and unmuting itself and to start/stop sharing video/desktop content with the other participants.
- * The bot can also access the list of participants, invite new participants, and mute them.
-* **Calls and online meetings.** From a Teams user's perspective, there are two kinds of online meetings ΓÇö ad hoc and scheduled. However, from a bot's perspective, both are the same. To a bot, an online meeting is just a multiparty call (the set of participants) plus "meeting coordinates," which you can think of as the metadata for the meeting: `botId`, `chatId` associated with the meeting, `joinUrl`, `startTime`/`endTime`, and more.
-* **Real-time media.** When a bot is participating in a call or online meeting, it must deal with audio and video streams. When users talk on a call, show themselves on a webcam, or present their screens in a meeting, a bot "sees" this as audio and/or video streams. If a bot wants to say something or present screen content, that requires an audio or video stream. Even something as simple as the bot saying, "press 0 to reach the operator" in an IVR (interactive voice response) scenario means playing a .WAV file. Collectively, we refer to this as _media_ or _real-time media_ (when referring to scenarios where media must be processed in real time, as opposed to playback of previously-recorded audio/video). Historically, dealing with media streams, particularly real-time media streams, has been extremely complex for developers. Microsoft has created the _Real-time Media Platform_ to handle these use cases and to offload as much of the traditional "heavy lifting" of real-time media processing as possible. When the bot answers an incoming call, or joins a new or existing call, it needs to tell the Real-time Media Platform how media will be handled. If you're building an IVR application, you can offload the expensive audio processing to Microsoft. Alternatively, if your bot requires direct access to media streams, we support that scenario too. There are the two types of media processing:
- * **Service-hosted media.** Bots focus on managing application workflow (e.g., routing calls) and offload audio processing to the Microsoft Real-time Media Platform. With service-hosted media, you have several options to implement and host your bot. A service-hosted media bot can be implemented as a stateless service since it doesn't process media locally. Service-hosted media bots can use APIs such as `PlayPrompt` for playing an audio clip, `Record` for recording audio clips, or `SubscribeToTone` for subscribing to DTMF tones (e.g., knowing when a user has pressed 0 to reach the operator).
- * **Application-hosted media.** For a bot to get direct access to the media, it needs a specific Graph permission, but once your bot has it, the [Real-time Media Library](https://www.nuget.org/packages/Microsoft.Graph.Communications.Calls.Medi).
-
-## Further reading
-
-Here's more information on how to create and test calls and online meetings bots:
-
-* [Graph API reference](/graph/api/resources/communications-api-overview?view=graph-rest-beta&preserve-view=true)
-* [Sample apps](https://github.com/microsoftgraph/microsoft-graph-comms-samples)
-* [Registering a bot that supports calls and online meetings](./registering-calling-bot.md) and [Microsoft Graph permissions for calls and online meetings bots](./registering-calling-bot.md#add-microsoft-graph-permissions)
-* [How to develop calling and online meeting bots on your local PC](./debugging-local-testing-calling-meeting-bots.md)
-* [More information on real-time media processing](./real-time-media-concepts.md), and [what's needed to support application-hosted media](./requirements-considerations-application-hosted-media-bots.md)
-* [Technical information on handling incoming call notifications](./call-notifications.md)
+> [!NOTE]
+> Support for calls and online meeting bots is currently not supported on the Microsoft Teams mobile platform.
+
+Bots can interact with Teams calls and meetings using real-time voice, video, and screen sharing. With [Microsoft Graph APIs for calls and online meetings](/graph/api/resources/communications-api-overview?view=graph-rest-beta&preserve-view=true), Teams apps can now interact with users using voice and video to enhance the experience. These APIs allow you to add the following new features:
+
+* Interactive voice response (IVR).
+* Call control.
+* Access to real-time audio and video streams, including desktop and app sharing.
+
+To use these Graph APIs in a Teams app, you create a bot and specify some additional information and permissions.
+
+In addition, the Real-time Media Platform enables bots to interact with Teams calls and meetings using real-time voice, video, and screen sharing. A bot that participates in audio or video calls and online meetings is a regular Microsoft Teams bot with few extra features used to register the bot.
+
+The Teams app manifest with two additional settings `supportsCalling` and `supportsVideo`, Graph permissions for your bot's Microsoft App ID, and tenant admin consent enable you to register the bot. In registering a calls and meetings bot for Teams, the Webhook URL is mentioned, which is the webhook endpoint for all incoming calls to your bot. An application-hosted media bot requires the Microsoft.Graph.Communications.Calls.Media .NET library to access the audio and video media streams, and the bot must be deployed on a Windows Server machine or Windows Server guest Operating System (OS) in Azure. Bots on Teams supports only a specific set of media formats for audio and video content.
+
+Now, you must understand some core concepts, terminology, and conventions.
+
+## Terminologies
+
+The following core concepts, terminology, and conventions guide you through the use of calls and online meetings bots:
+
+* Audio or video calls
+* Call types
+* Signals
+* Calls and online meetings
+* Real-time media
+
+### Audio or video calls
+
+Calls in Teams can be purely audio or audio and video. Instead of audio or video call, the term call is used.
+
+### Call types
+
+Calls are either peer-to-peer between a person and your bot, or multiparty between your bot and two or more people in a group call.
+
+![Calling types](~/assets/images/calls-and-meetings/call-types.png)
+
+Following are the different call types and permissions required for the call:
+
+* A user can initiate a peer-to-peer call with your bot or invite your bot into an existing multiparty call. The multiparty call is not enabled yet in the Teams user interface.
+* Graph permissions are not necessary for a user to initiate a peer-to-peer call with your bot. Additional permissions are needed for your bot to participate in a multiparty call, or for your bot to initiate a peer-to-peer call with a user.
+* A call can start as peer-to-peer and eventually become a multiparty call. Your bot can initiate multiparty calls by inviting others, provided your bot has the proper permissions. If your bot does not have permissions to participate in group calls and if a participant adds another participant to the call, your bot is dropped from the call.
+
+### Signals
+
+There are two types of signals, incoming call and in-call. Following are the different features of signals:
+
+* To receive an incoming call, you enter an endpoint in your bot settings. This endpoint receives a notification when an incoming call is initiated. You can answer the call, reject it, or redirect it to someone else.
+
+ ![Call handling](~/assets/images/calls-and-meetings/call-handling.png)
+
+* When a bot is in a call, there are APIs for muting and unmuting the bot and to start or stop sharing video or desktop content with other participants.
+* The bot can also access the list of participants, invite new participants, and mute them.
+
+### Calls and online meetings
+
+From a Teams user's perspective, there are two kinds of online meetings, ad hoc and scheduled. From a bot's perspective, both online meetings are the same. To a bot, an online meeting is a multiparty call between a set of participants and includes meeting coordinates. Meeting coordinates are the metadata for the meeting including `botId`, `chatId` associated with the meeting, `joinUrl`, `startTime` or `endTime`, and so on.
+
+### Real-time media
+
+When a bot is participating in a call or online meeting, it must deal with audio and video streams. When users talk on a call, show themselves on a webcam, or present their screens in a meeting, to a bot it is shown as audio and video streams. If a bot wants to say something as simple as, **press 0 to reach the operator** in an interactive voice response (IVR) scenario, it requires playing a .WAV file. Collectively, this is referred to as media or real-time media.
+
+Real-time media refers to scenarios where media must be processed in real-time, as opposed to playback of previously recorded audio or video. Dealing with media streams, particularly real-time media streams, is extremely complex. Microsoft has created the Real-time Media Platform to handle these scenarios and to offload as much of the traditional heavy lifting of real-time media processing as possible. When the bot answers an incoming call or joins a new or existing call, it needs to tell the Real-time Media Platform how media is handled. If you are building an IVR application, you can offload the expensive audio processing to Microsoft. Alternately, if your bot requires direct access to media streams, that scenario is also supported. There are two types of media processing:
+
+* **Service-hosted media**: Bots focus on managing application workflow, such as routing calls and offload audio processing to the Microsoft Real-time Media Platform. With service-hosted media, you have several options to implement and host your bot. A service-hosted media bot can be implemented as a stateless service as it does not process media locally. Service-hosted media bots can use the following APIs:
+
+ * `PlayPrompt` for playing an audio clip.
+ * `Record` for recording audio clips.
+ * `SubscribeToTone` for subscribing to dual tone multiple frequency (DTMF) tones.
+
+ For example, knowing when a user has pressed **0** to reach the operator.
+
+* **Application-hosted media**: For a bot to get direct access to the media, it needs a specific Graph permission. After your bot has the permission, the [Real-time Media Library](https://www.nuget.org/packages/Microsoft.Graph.Communications.Calls.Medi).
+
+## See also
+
+> [!div class="nextstepaction"]
+> [Graph API reference](/graph/api/resources/communications-api-overview?view=graph-rest-beta&preserve-view=true)
+> [!div class="nextstepaction"]
+> [Sample apps](https://github.com/microsoftgraph/microsoft-graph-comms-samples)
+> [!div class="nextstepaction"]
+> [Registering a bot that supports calls and online meetings](./registering-calling-bot.md)
+> [!div class="nextstepaction"]
+> [Graph permissions for calls and online meetings bots](./registering-calling-bot.md#add-graph-permissions)
+> [!div class="nextstepaction"]
+> [How to develop calling and online meeting bots on your computer](./debugging-local-testing-calling-meeting-bots.md)
+> [!div class="nextstepaction"]
+> [Requirements and considerations for application-hosted media bots](./requirements-considerations-application-hosted-media-bots.md)
+> [!div class="nextstepaction"]
+> [Technical information on handling incoming call notifications](./call-notifications.md)
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Real-time media calls and meetings](~/bots/calls-and-meetings/real-time-media-concepts.md)
platform Real Time Media Concepts https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/calls-and-meetings/real-time-media-concepts.md
Title: Real-time media calls and online meetings with Microsoft Teams description: Understand key concepts in building bot that can conduct real-time audio and video calls and online meetings.+ keywords: audio stream video stream audio/video calling meeting real-time media application-hosted media service-hosted media # Real-time media calls and meetings with Microsoft Teams
-The Real-time Media Platform enables bots to interact with Microsoft Teams calls and meetings using real-time voice, video, and screen sharing. This is an advanced capability which allows the bot to send and receive voice and video content *frame by frame*. The bot has "raw" access to the voice, video, and screen sharing media streams. (Bots which process media themselves are called _application-hosted media_ bots, as opposed to simpler _service-hosted media_ bots that rely on the Real-time Media platform for all media processing.)
+The Real-time Media Platform enables bots to interact with Microsoft Teams calls and meetings using real-time voice, video, and screen sharing. This is an advanced capability that allows the bot to send and receive voice and video content frame by frame. The bot has raw access to the voice, video, and screen sharing media streams. There are simpler service-hosted media bots that rely on the Real-time Media Platform for all media processing. Bots that process media themselves are called application-hosted media bots.
-For example, in a 1:1 call with a bot, as the user speaks, the bot will receive 50 audio frames per second, with each frame containing 20 milliseconds (ms) of audio. An application-hosted media bot can perform real-time speech recognition as the audio frames are received, rather than having to wait for a recording after the user has stopped speaking. The bot can also send and receive high-definition-resolution video, including video-based screen sharing content.
+For example, in a 1:1 call with a bot, as the user speaks, the bot receives 50 audio frames per second, with each frame containing 20 milliseconds (ms) of audio. An application-hosted media bot can perform real-time speech recognition as the audio frames are received, rather than having to wait for a recording after the user has stopped speaking. The bot can also send and receive high-definition-resolution video, including video-based screen sharing content.
-The platform provides a simple socket-like API for the bot to send and receive media, and handles the real-time encoding and decoding of audio/video packets using codecs such as SILK and G.722 for audio and H.264 for video. The platform also handles all media packet encryption/decryption and packet network transmission automatically, so the bot just needs to concern itself with the actual audio/video content. A real-time media bot may participate in 1:1 calls as well as meetings with multiple participants.
-
-This article introduces key concepts related to building a bot that can conduct real-time audio/video calls with Microsoft Teams.
+The platform provides a simple socket-like API for the bot to send and receive media. It handles the real-time encoding and decoding of audio or video packets using codecs such as SILK and G.722 for audio and H.264 for video. The platform also handles all media packet encryption or decryption and packet network transmission automatically. The bot is only concerned with the actual audio or video content. A real-time media bot participates in 1:1 calls as well as meetings with multiple participants.
## Media session
-When a real-time media bot answers an incoming call or joins a Microsoft Teams meeting, it must declare what modalities it intends to support. For each supported modality, the bot declares whether it can send and receive media, receive only, or send only. For example, a bot designed to handle 1:1 Teams calls may wish to both send and receive audio, but only *send* video (as it does not need to receive the video of the caller). The set of audio and video modalities established between the bot and the Teams caller or meeting is called the **media session**.
+When a real-time media bot answers an incoming call or joins a Teams meeting, it must declare what modalities it must support. For each supported modality, the bot declares whether it can send and receive media, receive only, or send only. For example, a bot designed to handle 1:1 Teams calls, requires to both send and receive audio, but only send video as it does not require to receive the video of the caller. The set of audio and video modalities established between the bot and the Teams caller or meeting is called the media session.
+
+Two types of video modalities are supported, main video and video-based screen sharing. The main video is used to transport the video from a user's webcam. The video-based screen sharing allows a user to share his or her screen as a video stream. The platform allows a bot to send and receive both video types.
-Two types of video modalities are supported: **main video** and **video-based screen sharing**. Main video is used to transport the video from a user's webcam. Video-based screen sharing allows a user to share his or her screen as a video stream. The platform allows a bot to send and/or receive *both* video types.
+When joined to a Teams meeting, a bot can receive multiple main video streams simultaneously up to ten per media session. This allows the bot to see more than one participant in the meeting.
-When joined to a Teams meeting, a bot can receive multiple main video streams simultaneously ΓÇö up to 10 per media session. This allows the bot to "see" more than one participant in the meeting.
+The next section provides details about the bot sending and receiving media as a sequence of frames.
## Frames and frame rate
-A real-time media bot interacts directly with the audio and video modalities of a media session. This means the bot is sending and/or receiving media as a sequence of **frames**, where each frame represents a unit of content. One second of audio may be transmitted as a sequence of 50 frames, with each frame containing 20 milliseconds (ms) ΓÇö1/50th of a second ΓÇö of speech content. One second worth of video may be sliced as a sequence of 30 still images, each intended to be viewed for just 33.3ms ΓÇö 1/30th of a second ΓÇö before the next video frame is displayed. The number of frames transmitted or rendered per second is called the **frame rate**. "30fps" indicates 30 frames per second.
+A real-time media bot interacts directly with the audio and video modalities of a media session. This means the bot is sending and receiving media as a sequence of frames, where each frame represents a unit of content. One second of audio is transmitted as a sequence of 50 frames, with each frame containing 20 ms that is 1/50th of a second of speech content. One second of video is transmitted as a sequence of 30 still images, each intended to be viewed for just 33.3 ms that is 1/30th of a second before the next video frame is displayed. The number of frames transmitted or rendered per second is called the frame rate.
+
+The next section provides details about the audio and video format used in real-time media calls and meetings.
-## Audio format
+## Audio and video format
-Each second of audio is represented as 16,000 **samples**, with each sample containing 16-bits of data. A 20ms audio frame contains 320 samples (640 bytes of data).
+In audio format, each second of audio is represented as 16,000 samples, with each sample containing 16-bits of data. A 20 ms audio frame contains 320 samples that is 640 bytes of data.
-## Video format
+In video format, several formats are supported. Two key properties of a video format are its frame size and color format. Supported frame sizes include 640x360 that is 360 pixels, 1280x720 that is 720 pixels, and 1920x1080 that is 1080 pixels. Supported color formats include NV12 that is 12 bits per pixel and RGB24 that is 24 bits per pixel.
-There are several formats supported for video. Two key properties of a video format are its **frame size** and **color format**. Supported frame sizes include 640x360 ("360p"), 1280x720 ("720p"), and 1920x1080 ("1080p"). Supported color formats include NV12 (12 bits per pixel) and RGB24 (24 bits per pixel).
+A 720p video frame contains 921,600 pixels that is 1280 times 720. In the RGB24 color format, each pixel is represented as 3 bytes that is 24-bits comprised of one byte each of red, green, and blue color components. Therefore, a single 720p RGB24 video frame requires 2,764,800 bytes of data that is 921,600 pixels times 3 bytes per pixel. At a frame rate of 30 fps, sending 720p RGB24 video frames means processing approximately 80 megabytes per second of content, which is substantially compressed by the H.264 video codec before network transmission.
-A "720p" video frame contains 921,600 pixels (1280 times 720). In the RGB24 color format, each pixel is represented as 3 bytes (24-bits) comprised of one byte each of red, green, and blue color components. Therefore, a single 720p RGB24 video frame requires 2,764,800 bytes of data (921,600 pixels times 3 bytes/pixel). At a frame rate of 30fps, sending 720p RGB24 video frames means processing approximately 80 MB/s of content (which is substantially compressed by the H.264 video codec before network transmission).
+An advanced capability of the platform allows a bot to send or receive video as encoded H.264 frames. This supports bots which provide their own H.264 encoder or decoder, or do not require the video stream decoded into raw RGB24 or NV12 bitmaps.
-An advanced capability of the platform allows a bot to send/receive video as **encoded** H.264 frames. This supports bots which provide their own H.264 encoder/decoder, or do not need the video stream decoded into raw RGB24 or NV12 bitmaps.
+The next section provides details about which meeting participants are speaking that is which are active and dominant speakers.
## Active and dominant speakers
-When joined to a Teams meeting consisting of multiple participants, a bot can identify which meeting participants are currently speaking. **Active speakers** identify which participants are being heard in each received audio frame. **Dominant speakers** identify which participants are currently most active (or "dominant") in the group conversation, even though their voice may not be heard in every audio frame. The set of dominant speakers can change as different participants take turns speaking.
+When joined to a Teams meeting consisting of multiple participants, a bot can identify which meeting participants are currently speaking. Active speakers identify which participants are being heard in each received audio frame. Dominant speakers identify which participants are currently most active or dominant in the group conversation, even though their voice is not heard in every audio frame. The set of dominant speakers can change as different participants take turns speaking.
+
+The next section provides details about video subscription requests made by a bot.
## Video subscription
-In a 1:1 call, the bot will automatically receive the video of the caller if the bot is enabled to receive video. In a Teams meeting, the bot must indicate to the platform which participants it wants to see. A **video subscription** is a request by the bot to receive a participantΓÇÖs main video or screen-sharing content. As the participants in the meeting conduct their conversation, the bot may modify its desired video subscriptions based on updates of the dominant speaker set or notifications indicating which participant is currently screen sharing.
+In a 1:1 call, the bot automatically receives the video of the caller if the bot is enabled to receive the video. In a Teams meeting, the bot must indicate to the platform which participants it wants to see. A video subscription is a request by the bot to receive a participantΓÇÖs main video or screen-sharing content. As the participants in the meeting conduct their conversation, the bot modifies its desired video subscriptions based on updates of the dominant speaker set or notifications indicating which participant is currently screen sharing.
+
+The next section provides details about what you must install and the requirements to develop an application-hosted media bot.
## Developer resources
-To develop an application-hosted media bot, you must install the following NuGet package within your Visual Studio project:
+To develop an application-hosted media bot, you must install the [Microsoft.Graph.Calls.Media .NET library](https://www.nuget.org/packages/Microsoft.Graph.Communications.Calls.Media/) NuGet package within your Visual Studio project.
+
+Application-hosted media bots require .NET or C# and Windows Server. For more information, see [requirements and considerations for application-hosted media bots](requirements-considerations-application-hosted-media-bots.md#c-or-net-and-windows-server-for-development).
-- [Microsoft.Graph.Calls.Media .NET library](https://www.nuget.org/packages/Microsoft.Graph.Communications.Calls.Media/)
+## Next step
-Application-hosted media bots require .NET/C# and Windows Server, as described in detail in [Requirements and considerations for application-hosted media bots](requirements-considerations-application-hosted-media-bots.md#application-hosted-media-bot-development-requires-cnet-and-windows-server).
+> [!div class="nextstepaction"]
+> [Register a calling bot](~/bots/calls-and-meetings/registering-calling-bot.md)
platform Registering Calling Bot https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/calls-and-meetings/registering-calling-bot.md
Title: Registering a calling and meeting bot for Microsoft Teams
+ Title: Register a calls and meetings bot for Microsoft Teams
description: Learn how to register a new audio/video calling bot for Microsoft Teams+ keywords: calling bot audio/video audio video media
-# Register a calling bot for Microsoft Teams
+# Register a calls and meetings bot for Microsoft Teams
-A bot that participates in audio/video calls and online meetings is an ordinary Microsoft Teams bot with a few extra features:
+A bot that participates in audio or video calls and online meetings is a regular Microsoft Teams bot with the following extra features used to register the bot:
-* There's a new version of the Teams app manifest with two additional settings, `supportsCalling` and `supportsVideo`. These settings are included in the [Developer Preview](../../resources/dev-preview/developer-preview-intro.md) version of the Microsoft Teams app manifest.
-* [Microsoft Graph permissions](./registering-calling-bot.md#add-microsoft-graph-permissions) must be configured for your bot's Microsoft App ID.
-* The Microsoft Graph calls and online meetings APIs permissions require tenant admin consent.
-
-Let's discuss the above in more detail.
+* There is a new version of the Teams app manifest with two additional settings, `supportsCalling` and `supportsVideo`. These settings are included in the [developer preview](../../resources/dev-preview/developer-preview-intro.md) version of the Teams app manifest.
+* [Microsoft Graph permissions](./registering-calling-bot.md#add-graph-permissions) must be configured for your bot's Microsoft App ID.
+* The Graph calls and online meetings APIs permissions require tenant admin consent.
## New manifest settings
-Calling and online meetings bots have two additional settings in the manifest.json that enable audio/video for your bot in Teams.
+Calls and online meetings bots have the following two additional settings in the manifest.json that enable audio or video for your bot in Teams.
-* `bots[0].supportsCalling`. If present and set to `true`, Teams will allow your bot to participate in calls and online meetings.
+* `bots[0].supportsCalling`. If present and set to `true`, Teams allows your bot to participate in calls and online meetings.
* `bots[0].supportsVideo`. If present and set to `true`, Teams knows that your bot supports video.
-If you want your IDE to properly validate the manifest.json schema for your calling and meeting bot for these values, you can change the `$schema` attribute as follows:
+If you want your IDE to properly validate the manifest.json schema for your calls and meetings bot for these values, you can change the `$schema` attribute as follows:
```json "$schema": "https://raw.githubusercontent.com/OfficeDev/microsoft-teams-app-schema/preview/DevPreview/MicrosoftTeams.schema.json", ```
-## Creating a new bot or adding calling capabilities to an existing bot
+The next section enables you to create a new bot or add calling capabilities to your existing bot.
+
+## Create new bot or add calling capabilities
+
+For information on creating bots, see [create a bot for Teams](../how-to/create-a-bot-for-teams.md).
+
+**To create a new bot for Teams**
+
+1. Use this link to create a new bot, `https://dev.botframework.com/bots/new`. Alternately, if you select the **Create a bot** button in the Bot Framework portal, you create your bot in Microsoft Azure, for which you must have an Azure account.
+1. Add the Teams channel.
+1. Select the **Calling** tab on the Teams channel page. Select **Enable calling**, and then update **Webhook (for calling)** with your HTTPS URL where you receive incoming notifications, for example `https://contoso.com/teamsapp/api/calling`. For more information, see [configuring channels](/bot-framework/portal-configure-channels).
-Creating a new bot is covered in more detail in the [Create a bot for Microsoft Teams](../how-to/create-a-bot-for-teams.md) topic, but we'll repeat some of it here:
+ ![Configure Teams channel information](~/assets/images/calls-and-meetings/configure-msteams-channel.png)
-1. Use this link to create a new bot: `https://dev.botframework.com/bots/new`. If, instead, you select the *Create a bot* button in the Bot Framework portal, you will create your bot in Microsoft Azure, for which you'll need an Azure account.
-1. Add the Microsoft Teams channel. Click on the "Calling" tab on the Microsoft Teams channel page and select **Enable calling**, and then update **Webhook (for calling)** with your HTTPS URL where you will receive incoming notifications, e.g.`https://contoso.com/teamsapp/api/calling`. Refer to [Configuring Channels](/bot-framework/portal-configure-channels) for more information on how to configure channels.
- ![Configure Microsoft Teams channel information](~/assets/images/calls-and-meetings/configure-msteams-channel.png)
+The next section provides a list of application permissions supported for calls and online meetings.
-## Add Microsoft Graph permissions
+## Add Graph permissions
-Microsoft Graph exposes granular permissions controlling the access that apps have to resources. As a developer, you decide which permissions for Microsoft Graph your app requests. The Microsoft Graph Calling APIs support _Application permissions_, which are used by apps that run without a signed-in user present. A tenant administrator must grant consent to application permissions. Below is a list of those permissions:
+The Graph provides granular permissions to control the access that apps have to resources. You decide which permissions for Graph your app requests. The Graph calling APIs support application permissions, which are used by apps that run without a signed-in user present. A tenant administrator must grant consent to application permissions.
-### Application permissions: calls
+### Application permissions for calls
-|Permission |Display String |Description |Admin Consent Required |
+The following table provides a list of application permissions for calls:
+
+|Permission |Display string |Description |Admin consent required |
|:--|:--|:--|:--|
-|_Calls.Initiate.All_|Initiate outgoing 1:1 calls from the app (preview)|Allows the app to place outbound calls to a single user and transfer calls to users in your organizationΓÇÖs directory, without a signed-in user.|Yes|
-|_Calls.InitiateGroupCall.All_|Initiate outgoing group calls from the app (preview)|Allows the app to place outbound calls to multiple users and add participants to meetings in your organization, without a signed-in user.|Yes|
-|_Calls.JoinGroupCall.All_|Join Group Calls and Meetings as an app (preview)|Allows the app to join group calls and scheduled meetings in your organization, without a signed-in user. The app will be joined with the privileges of a directory user to meetings in your tenant.|Yes|
-|_Calls.JoinGroupCallasGuest.All_|Join Group Calls and Meetings as a guest (preview)|Allows the app to anonymously join group calls and scheduled meetings in your organization, without a signed-in user. The app will be joined as a guest to meetings in your tenant.|Yes|
-|_Calls.AccessMedia.All_ <sup>_see below_</sup>|Access media streams in a call as an app (preview)|Allows the app to get direct access to media streams in a call, without a signed-in user.|Yes|
+| Calls.Initiate.All |Initiate outgoing 1:1 calls from the app preview. |Allows the app to place outbound calls to a single user and transfer calls to users in your organizationΓÇÖs directory, without a signed-in user.|Yes|
+| Calls.InitiateGroupCall.All |Initiate outgoing group calls from the app preview. |Allows the app to place outbound calls to multiple users and add participants to meetings in your organization, without a signed-in user.|Yes|
+| Calls.JoinGroupCall.All |Join group calls and meetings as an app preview. |Allows the app to join group calls and scheduled meetings in your organization, without a signed-in user. The app is joined with the privileges of a directory user to meetings in your tenant.|Yes|
+| Calls.JoinGroupCallasGuest.All |Join group calls and meetings as a guest preview. |Allows the app to anonymously join group calls and scheduled meetings in your organization, without a signed-in user. The app is joined as a guest to meetings in your tenant.|Yes|
+| Calls.AccessMedia.All |Access media streams in a call as an app preview. |Allows the app to get direct access to media streams in a call, without a signed-in user.|Yes|
> [!IMPORTANT]
-> You **cannot** use the Media Access API to record or otherwise persist media content from calls or meetings that your application accesses, or data derived from that media content ("record" or "recording"), without first calling the [`updateRecordingStatus` API](/graph/api/call-updaterecordingstatus) to indicate that recording has begun, and receiving a success reply from that API. If your application begins recording any meeting/call, it must end the recording prior to calling the `updateRecordingStatus` API to indicate that the recording has ended.
+> You cannot use the Media Access API to record or otherwise persist media content from calls or meetings that your application accesses or derive data from that media content record or recording. You must first call the [`updateRecordingStatus` API](/graph/api/call-updaterecordingstatus) to indicate that recording has begun, and receive a success reply from that API. If your application begins recording any meeting or call, it must end the recording before calling the `updateRecordingStatus` API to indicate that the recording has ended.
+
+### Application permissions for online meetings
-### Application permissions: online meetings
+The following table provides a list of application permissions for online meetings:
-|Permission |Display String |Description |Admin Consent Required |
+|Permission |Display string |Description |Admin consent required |
|:--|:--|:--|:--|
-|_OnlineMeetings.Read.All_|Read Online Meeting details from the app (preview)|Allows the app to read Online Meeting details in your organization, without a signed-in user.|Yes|
-|_OnlineMeetings.ReadWrite.All_|Read and Create Online Meetings from the app (preview) on behalf of a user|Allows the app to create Online Meetings in your organization on behalf of a user, without a signed-in user.|Yes|
+| OnlineMeetings.Read.All |Read online meeting details from the app preview|Allows the app to read online meeting details in your organization, without a signed-in user.|Yes|
+| OnlineMeetings.ReadWrite.All |Read and create online meetings from the app preview on behalf of a user|Allows the app to create online meetings in your organization on behalf of a user, without a signed-in user.|Yes|
-### Assigning permissions
+### Assign permissions
-You must configure the application permissions for your bot in advance by using the [Azure portal](https://aka.ms/aadapplist) if you prefer to use the [Azure AD V1 endpoint](/azure/active-directory/develop/azure-ad-endpoint-comparison).
+You must configure the application permissions for your bot in advance by using the [Azure portal](https://aka.ms/aadapplist) if you prefer to use the [Azure Active Directory (AAD) V1 endpoint](/azure/active-directory/develop/azure-ad-endpoint-comparison).
-### Getting tenant administrator consent
+### Get tenant administrator consent
-For apps using the Azure AD V1 endpoint, a tenant administrator can consent to the application permissions using the [Azure portal](https://portal.azure.com) when your app is installed in their organization, or you can provide a sign-up experience in your app through which administrators can consent to the permissions you configured. Once administrator consent is recorded by Azure AD, your app can request tokens without having to request consent again.
+For apps using the AAD V1 endpoint, a tenant administrator can consent to the application permissions using the [Azure portal](https://portal.azure.com) when your app is installed in their organization. Alternately, you can provide a sign-up experience in your app through which administrators can consent to the permissions you configured. Once administrator consent is recorded by AAD, your app can request tokens without having to request consent again.
-You can rely on an administrator to grant the permissions your app needs at the [Azure portal](https://portal.azure.com); though, often a better option is to provide a sign-up experience for administrators by using the Azure AD V2 `/adminconsent` endpoint. Please refer to the [instructions on constructing an Admin Consent URL](https://developer.microsoft.com/graph/docs/concepts/auth_v2_service#3-get-administrator-consent) for more information.
+You can rely on an administrator to grant the permissions your app needs at the [Azure portal](https://portal.azure.com). A better option is to provide a sign-up experience for administrators by using the AAD V2 `/adminconsent` endpoint. For more information, see [instructions on constructing an Admin consent URL](https://developer.microsoft.com/graph/docs/concepts/auth_v2_service#3-get-administrator-consent).
> [!NOTE]
-> Constructing the Tenant Admin Consent URL requires a configured Redirect URI/Reply URL in the [App Registration Portal](https://apps.dev.microsoft.com/). To add reply URLs for your bot, access your bot registration, choose Advanced Options -> Edit Application Manifest. Add your Redirect URL to the `replyUrls` collection.
+> To construct the tenant Admin consent URL, a configured redirect URI or reply URL in the [app registration portal](https://apps.dev.microsoft.com/) is required. To add reply URLs for your bot, access your bot registration, choose **Advanced Options** > **Edit Application Manifest**. Add your redirect URL to the `replyUrls` collection.
> [!IMPORTANT]
-> Anytime you make a change to your application's permissions, you must also repeat the Admin Consent process. Changes made in the app registration portal will not be reflected until consent has been reapplied by the tenant's administrator.
+> Anytime you make a change to your application's permissions, you must also repeat the Admin consent process. Changes made in the app registration portal are not reflected until the consent has been reapplied by the tenant's administrator.
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Incoming call notifications](~/bots/calls-and-meetings/call-notifications.md)
platform Requirements Considerations Application Hosted Media Bots https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/calls-and-meetings/requirements-considerations-application-hosted-media-bots.md
Last updated 11/16/2018
# Requirements and considerations for application-hosted media bots
-Not all guidance for developing messaging and Interactive Voice Response (IVR) bots applies equally to building application-hosted media bots. This article describes some of the important requirements and considerations for developing and running an application-hosted media bot.
+An application-hosted media bot requires the [`Microsoft.Graph.Communications.Calls.Media` .NET library](https://www.nuget.org/packages/Microsoft.Graph.Communications.Calls.Media/) to access the audio and video media streams. The bot must be deployed on a Windows Server machine or Windows Server guest Operating System (OS) in Azure.
> [!NOTE]
-> Because the Microsoft Real-time Media Platform for Bots is in developer preview, the guidance in this article is subject to change.
+> * The guidance for developing messaging and Interactive Voice Response (IVR) bots does not completely apply to building application-hosted media bots.
+> * As the Microsoft Real-time Media Platform for bots is in developer preview, the guidance in this document is subject to change.
-## Application-hosted media bot development requires C#/.NET and Windows Server
+## C# or .NET and Windows Server for development
-- An application-hosted media bot requires the `Microsoft.Graph.Communications.Calls.Media` .NET library ([available here](https://www.nuget.org/packages/Microsoft.Graph.Communications.Calls.Media/) to access the audio and video media streams, and the bot must be deployed on a Windows Server machine (or Windows Server guest OS in Azure). Therefore, the bot must be developed in C# and the standard .NET Framework and deployed in Microsoft Azure. You can't use C++ or Node.js APIs to access real-time media and .NET Core is not supported for an application-hosted media bot.
+An application-hosted media bot requires the following:
-- An application-hosted media bot can be hosted within one of the following Azure service environments:
- - Cloud Service.
- - Service Fabric with Virtual Machine Scale Sets (VMSS).
- - Infrastructure as a Service (IaaS) Virtual Machine (VM).
+- The bot must be developed in C# and the standard .NET Framework and deployed in Microsoft Azure. You cannot use C++ or Node.js APIs to access real-time media and .NET Core is not supported for an application-hosted media bot.
+
+- The bot can be hosted within one of the following Azure service environments:
+ - Cloud Service.
+ - Service Fabric with Virtual Machine Scale Sets (VMSS).
+ - Infrastructure as a Service (IaaS) Virtual Machine (VM).
-- An application-hosted media bot can't be deployed as an Azure Web App.
+- The bot cannot be deployed as an Azure web app.
+
+- The bot must be running on a recent version of the `Microsoft.Graph.Communications.Calls.Media` .NET library. The bot must use either the newest available version of the [NuGet package](https://www.nuget.org/packages/Microsoft.Graph.Communications.Calls.Media/), or a version that is not more than three months old. Older versions of the library are deprecated and do not work after a few months. Keeping the `Microsoft.Graph.Communications.Calls.Media` library up-to-date ensures the best interoperability between the bot and Microsoft Teams.
+
+The next section provides details on where real-time media calls are located.
-- An application-hosted media bot must be running on a recent version of the `Microsoft.Graph.Communications.Calls.Media` .NET library. The bot should use either the newest available version of the [NuGet package](https://www.nuget.org/packages/Microsoft.Graph.Communications.Calls.Media/), or a version that is not more than three months old. Older versions of the library will be deprecated and may not work after a few months. Keeping the `Microsoft.Graph.Communications.Calls.Media` library up-to-date will ensure the best interoperability between the bot and Microsoft Teams.
+## Real-time media calls stay where they are created
-## Real-time media calls stay on the machine where they were created
+Real-time media calls stay on the computer where they were created. A real-time media call is pinned to the virtual machine (VM) instance that accepted or started the call. Media from a Microsoft Teams call or meeting flows to that VM instance, and media the bot sends back to Microsoft Teams must also originate from that VM. If there are any real-time media calls in progress when the VM is stopped, those calls are abruptly terminated. If the bot has prior knowledge of the pending VM shutdown, it can end the calls.
-- A real-time media call is pinned to the virtual machine (VM) instance that accepted or started the call. Media from a Microsoft Teams call or meeting will flow to that VM instance, and media the bot sends back to Microsoft Teams must also originate from that VM.-- If there are any real-time media calls in progress when the VM is stopped, those calls will be abruptly terminated. If the bot has prior knowledge of the pending VM shutdown, it can try to "gracefully" end the calls.
+The next section provides details on accessibility of application-hosted media bots.
-## Application-hosted media bots must be directly accessible on the internet
+## Application-hosted media bots accessible on the internet
+
+Application-hosted media bots must be directly accessible on the internet. These bots must include the following features:
- Each VM instance hosting an application-hosted media bot in Azure must be directly accessible from the internet using an instance-level public IP address (ILPIP).
- - For obtaining and configuring an ILPIP for an Azure Cloud Service, see [Instance level public IP (Classic) overview](/azure/virtual-network/virtual-networks-instance-level-public-ip).
- - For configuring an ILPIP for a VM Scale Set, see [Public IPv4 per virtual machine](/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-networking#public-ipv4-per-virtual-machine).
+ - For obtaining and configuring an ILPIP for an Azure Cloud Service, see [instance level public IP classic overview](/azure/virtual-network/virtual-networks-instance-level-public-ip).
+ - For configuring an ILPIP for a VM Scale Set, see [public IPv4 per virtual machine](/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-networking#public-ipv4-per-virtual-machine).
- The service hosting an application-hosted media bot must also configure each VM instance with a public-facing port which maps to the specific instance.
- - For an Azure Cloud Service, this requires an instance input endpoint; see [Enable communication for role instances in Azure](/azure/cloud-services/cloud-services-enable-communication-role-instances).
- - For a VM Scale Set, a NAT rule on the load balancer must be configured; see [Virtual networks and virtual machines in Azure](/azure/virtual-machines/windows/network-overview).
-- Application-hosted media bots aren't supported by the Bot Framework Emulator.
+ - For an Azure Cloud Service, this requires an instance input endpoint. For more information, see [enable communication for role instances in Azure](/azure/cloud-services/cloud-services-enable-communication-role-instances).
+ - For a VM Scale Set, a NAT rule on the load balancer must be configured. For more information, see [virtual networks and virtual machines in Azure](/azure/virtual-machines/windows/network-overview).
+- Application-hosted media bots are not supported by the Bot Framework Emulator.
+
+The next section provides details on scalability and performance considerations of application-hosted media bots.
## Scalability and performance considerations -- Application-hosted media bots require more compute and network (bandwidth) capacity than messaging bots and may incur significantly higher operational costs. A real-time media bot developer must carefully measure the bot's scalability, and ensure the bot doesn't accept more simultaneous calls than it can manage. A video-enabled bot may be able to sustain only one or two concurrent media sessions per CPU core (if using the "raw" RGB24 or NV12 video formats).-- The Real-time Media Platform doesn't currently take advantage of any Graphics Processing Units (GPU) available on the VM to off-load H.264 video encoding/decoding. Instead, video encode and decode are done in software on the CPU. If a GPU is available, the bot may take advantage of it for its own graphics rendering (e.g. if the bot is using a 3D graphics engine).-- The VM instance hosting the real-time media bot must have at least 2 CPU cores. For Azure, a Dv2-series virtual machine is recommended. For other Azure VM types, a system with 4 virtual CPUs (vCPU) is the minimum size required. Detailed information about Azure VM types is available in the [Azure documentation](/azure/virtual-machines/windows/sizes-general).
+Application-hosted media bots require the following scalability and performance considerations:
-## Samples and Additional Resources
+- The bots require more compute and network bandwidth capacity than messaging bots and incur significantly higher operational costs. A real-time media bot developer must carefully measure the bot's scalability, and ensure the bot does not accept more simultaneous calls than it can manage. A video-enabled bot can sustain only one or two concurrent media sessions per CPU core if using the raw RGB24 or NV12 video formats.
+- The Real-time Media Platform does not currently take advantage of any Graphics Processing Units (GPU) available on the VM to off-load H.264 video encoding or decoding. Instead, video encode and decode are done in software on the CPU. If a GPU is available, the bot takes advantage of it for its own graphics rendering, for example, if the bot is using a 3D graphics engine.
+- The VM instance hosting the real-time media bot must have at least 2 CPU cores. For Azure, a Dv2-series virtual machine is recommended. For other Azure VM types, a system with 4 virtual CPUs (vCPU) is the minimum size required. For more information about Azure VM types, see [Azure documentation](/azure/virtual-machines/windows/sizes-general).
+
+The next section provides samples that illustrate different local media scenarios.
+
+## Samples and additional resources
- [Sample applications](https://github.com/microsoftgraph/microsoft-graph-comms-samples/tree/master/Samples/V1.0Samples/LocalMediaSamples)-- [Graph Calling SDK Documentation](https://microsoftgraph.github.io/microsoft-graph-comms-samples/docs/)
+- [Graph calling SDK documentation](https://microsoftgraph.github.io/microsoft-graph-comms-samples/docs/)
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Supported media formats](~/resources/media-formats.md)
platform Add Power Virtual Agents Bot To Teams https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/add-power-virtual-agents-bot-to-teams.md
# Integrate a Power Virtual Agents chatbot with Microsoft Teams
-[Power Virtual Agents](/power-virtual-agents/fundamentals-what-is-power-virtual-agents) is a no-code, guided graphical interface solution that empowers every member of your team to create rich, conversational chatbots that easily integrate with the Teams platform. All content authored in Power Virtual Agents renders naturally in Teams and Power Virtual Agents bots engage with users in the Teams native chat canvas. Your IT administrators, business analysts, domain specialists, and skilled app developers can design, develop and publish intelligent virtual agents for Teams without having to setup a development environment, create a web service, or directly register with the Bot Framework. *See* [Create a chatbot for Teams with Microsoft Power Virtual Agents](../what-are-bots.md#create-a-chatbot-for-teams-with-microsoft-power-virtual-agents).
+[Power Virtual Agents](/power-virtual-agents/fundamentals-what-is-power-virtual-agents) is a no-code, guided graphical interface solution that empowers every member of your team to create rich, conversational chatbots that easily integrate with the Teams platform. All content authored in Power Virtual Agents renders naturally in Teams and Power Virtual Agents bots engage with users in the Teams native chat canvas. Your IT administrators, business analysts, domain specialists, and skilled app developers can design, develop and publish intelligent virtual agents for Teams without having to setup a development environment, create a web service, or directly register with the Bot Framework. *See* [Create a chatbot for Teams with Microsoft Power Virtual Agents](../bot-features.md#bots-and-the-microsoft-power-virtual-agents).
> [!NOTE] > By adding your chatbot to Microsoft Teams, some of data, such as bot content and end-user chat content, will be shared with Microsoft Teams (meaning that your data will flow outside of your [organizationΓÇÖs compliance and geographic or regional boundaries](/power-virtual-agents/data-location)). <br/>
platform Bots Filesv4 https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/bots-filesv4.md
There are two ways to send files to and receive files from a bot:
-* **Using the Microsoft Graph APIs:** This method works for bots in all Microsoft Teams scopes:
+* [**Use the Microsoft Graph APIs:**](#use-the-graph-apis) This method works for bots in all Microsoft Teams scopes:
* `personal` * `channel` * `groupchat`
-* **Using the Teams bot APIs:** These only support files in `personal` context.
+* [**Use the Teams bot APIs:**](#use-the-teams-bot-apis) These only support files in `personal` context.
-## Using the Graph APIs
+## Use the Graph APIs
Post messages with card attachments that refer to existing SharePoint files, using the Graph APIs for [OneDrive and SharePoint](/onedrive/developer/rest-api/). To use the Graph APIs, obtain access to either of the following through the standard OAuth 2.0 authorization flow:+ * A user's OneDrive folder for `personal` and `groupchat` files. * The files in a team's channel for `channel` files.
-Graph APIs work in all Teams scopes.
+Graph APIs work in all Teams scopes. For more information, see [send chat message file attachments](/graph/api/chatmessage-post?view=graph-rest-beta&tabs=http#example-4-file-attachments&preserve-view=true).
+
+Alternately, you can send files to and receive files from a bot using the Teams bot APIs.
-## Using the Teams bot APIs
+## Use the Teams bot APIs
> [!NOTE] > Teams bot APIs work only in the `personal` context. They do not work in the `channel` or `groupchat` context. Using Teams APIs, the bot can directly send and receive files with users in the `personal` context, also known as personal chats. Implement features, such as expense reporting, image recognition, file archival, and e-signatures involving the editing of file content. Files shared in Teams typically appear as cards and allow rich in-app viewing.
-The following sections describe how to send file content as a direct user interaction, like sending a message. This API is provided as part of the Teams bot platform.
+The next sections describe how to send file content as direct user interaction, like sending a message. This API is provided as part of the Teams bot platform.
-### Configuring the bot to support files
+### Configure the bot to support files
To send and receive files in the bot, set the `supportsFiles` property in the manifest to `true`. This property is described in the [bots](~/resources/schem#bots) section of the Manifest reference. The definition looks like this, `"supportsFiles": true`. If the bot does not enable `supportsFiles`, the features listed in this section do not work.
-### Receiving files in personal chat
+### Receive files in personal chat
-When a user sends a file to the bot, the file is first uploaded to the user's OneDrive for Business storage. The bot then receives a message activity notifying the user about the user upload. The activity contains file metadata, such as its name and the content URL. The user can directly read from this URL to fetch its binary content.
+When a user sends a file to the bot, the file is first uploaded to the user's OneDrive for business storage. The bot then receives a message activity notifying the user about the user upload. The activity contains file metadata, such as its name and the content URL. The user can directly read from this URL to fetch its binary content.
#### Message activity with file attachment example
+The following code shows an example of message activity with file attachment:
+ ```json { "attachments": [{
The following table describes the content properties of the attachment:
As a best practice, acknowledge the file upload by sending a message back to the user.
-### Uploading files to personal chat
+### Upload files to personal chat
-The following steps are required to upload a file to a user:
+**To upload a file to a user**
1. Send a message to the user requesting permission to write the file. This message must contain a `FileConsentCard` attachment with the name of the file to be uploaded. 2. If the user accepts the file download, the bot receives an invoke activity with a location URL.
The following desktop message contains a simple attachment object requesting use
The following mobile message contains an attachment object requesting user permission to upload the file:
-![Consent card requesting user permission to upload file on mobile](../../assets/images/bots/mobile-bot-file-consent-card.png)
+<img src="../../assets/images/bots/mobile-bot-file-consent-card.png" alt="Consent card requesting user permission to upload file on mobile" width="350"/>
```json {
The following table describes the content properties of the attachment:
An invoke activity is sent to the bot if and when the user accepts the file. It contains the OneDrive for Business placeholder URL that the bot can then issue a `PUT` to transfer the file contents. For information on uploading to the OneDrive URL, see [upload bytes to the upload session](/onedrive/developer/rest-api/api/driveitem_createuploadsession#upload-bytes-to-the-upload-session).
-The following example shows a concise version of the invoke activity that the bot receives:
+The following code shows an example of a concise version of the invoke activity that the bot receives:
```json {
The following table describes the content properties of the attachment:
| `uniqueId` | OneDrive or SharePoint drive item ID. | | `fileType` | Type of file, such as .pdf or .docx. |
-### Fetching inline images from message
+### Fetch inline images from message
Fetch inline images that are part of the message using the Bot's access token. ![Inline image](../../assets/images/bots/inline-image.png)
+The following code shows an example of fetching inline images from message:
+ ```csharp private async Task ProcessInlineImage(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken) {ΓÇïΓÇïΓÇïΓÇïΓÇï
private static Attachment GetInlineAttachment()
### Basic example in C#
-The following sample shows how to handle file uploads and send file consent requests in the bot's dialog:
+The following code shows an example of how to handle file uploads and send file consent requests in the bot's dialog:
```csharp
private async Task SendFileCardAsync(ITurnContext turnContext, string filename,
} ```
-### Code sample
+## Code sample
-|**Sample name** | **Description** | **.NETCore** | **Javascript** | **Python**|
+|Sample name | Description | .NETCore | Javascript | Python |
|-|--|--|-|--| | File upload | Demonstrates how to obtain file consent and upload files to Teams from a bot. Also, how to receive a file sent to a bot. | [View](https://github.com/microsoft/BotBuilder-Samples/blob/main/samples/csharp_dotnetcore/56.teams-file-upload) | [View](https://github.com/microsoft/BotBuilder-Samples/blob/main/samples/javascript_nodejs/56.teams-file-upload) | [View](https://github.com/microsoft/BotBuilder-Samples/blob/main/samples/python/56.teams-file-upload) |+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Optimize your bot with rate limiting in Teams](~/bots/how-to/rate-limit.md)
platform Channel And Group Conversations https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/conversations/channel-and-group-conversations.md
Title: Channel and group conversations with a bot description: How to send, receive, and handle messages for a bot in a channel or group chat.-+
-# Channel and group chat conversations with a Microsoft Teams bot
+# Channel and group chat conversations with a bot
[!INCLUDE [pre-release-label](~/includes/v4-to-v3-pointer-bots.md)]
-By adding the `teams` or `groupchat` scope to your bot, it can be available to be installed in a team or group chat. This allows all members of the conversation to interact with your bot. Once installed, it will also have access to metadata about the conversation like the list of conversation members, and when installed in a team details about that team and the full list of channels.
+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 is 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 are mentioned (@botname), they do not receive any other messages sent to the conversation.
+Bots in a group or channel only receive messages when they are mentioned `@botname`. They do not receive any other messages sent to the conversation.
> [!NOTE]
-> The bot must be @mentioned directly. Your bot will not receive a message when the team or channel is mentioned, or when someone replies to a message from your bot without @mentioning it.
+> The bot must be `@mentioned` directly. Your bot does not receive a message when the team or channel is mentioned, or when someone replies to a message from your bot without @mentioning it.
## Design guidelines
-See how to [design bot conversations in channels and chats](~/bots/design/bots.md).
+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](~/bots/design/bots.md).
-## Creating new conversation threads
+Now, you can create new conversation threads and easily manage different conversations in channels.
-When your bot is installed in a team, it can sometimes be necessary to create a new conversation thread rather than replying to an existing one. This is a form of [proactive messaging](~/bots/how-to/conversations/send-proactive-messages.md).
+## Create new conversation threads
-## Working with mentions
+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 is difficult to differentiate between two conversations. If the conversation is threaded, it is easier to organize and manage different conversations in channels. This is a form of [proactive messaging](~/bots/how-to/conversations/send-proactive-messages.md).
-Every message to your bot from a group or channel will contain an @mention with its own name in the message text, so you'll need to ensure your message parsing handles that. Your bot can also retrieve other users mentioned in a message, and add mentions to any messages it sends.
+Next, you can retrieve mentions using the `entities` object and add mentions to your messages using the `Mention` object.
-### Stripping mentions from message text
+## Work with mentions
-You may find it necessary to strip out the @mentions from the text of the message your bot receives.
+Every message to your bot from a group or channel contains an @mention with its name in the message text. Ensure that your message parsing handles @mention. Your bot can also retrieve other users mentioned in a message and add mentions to any messages it sends.
-### Retrieving 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, in most cases, the name of user mentioned. The text of the message will also include the mention like `<at>@John Smith<at>`. However, you should not rely on the text in the message to retrieve any information about the user; it is possible for the person sending the message to alter it. Instead, use the `entities` object.
+### Retrieve mentions
-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.
+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, do not rely on the text in the message to retrieve any information about the user. It is possible for the person sending the message to alter it. Therefore, use the `entities` object.
-# [C#/.NET](#tab/dotnet)
+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:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivi
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript this.onMessage(async (turnContext, next) => {
def get_mentions(activity: Activity) -> List[Mention]:
* * *
-### Adding mentions to your messages
+### Add mentions to your messages
-Your bot can mention other users in messages posted into channels. To do this, your message must do the following:
+Your bot can mention other users in messages posted into channels.
-The `Mention` object has two properties that you will need to set:
+The `Mention` object has two properties that you must set using the following:
-* Include <at>@username</at> in the message text
-* Include the mention object inside the entities collection
+* Include <at>@username</at> in the message text.
+* Include the mention object inside the entities collection.
-The Bot Framework SDK provides helper methods and objects to make constructing the mention easier.
+The Bot Framework SDK provides helper methods and objects to create mentions.
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of adding mentions to your messages:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivi
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript this.onMessage(async (turnContext, next) => {
this.onMessage(async (turnContext, next) => {
# [JSON](#tab/json)
-The `text` field in the object in the `entities` array must *exactly* match a portion of the message `text` field. If it does not, the mention will be ignored.
+The `text` field in the object in the `entities` array must match a portion of the message `text` field. If it does not, the mention is ignored.
```json {
async def _mention_activity(self, turn_context: TurnContext):
* * *
-## Sending a message on installation
+Now you can send an introduction message when your bot is first installed or added to a group or team.
-When your bot is first added to the group or team, it may be useful to send a message introducing it. The message should provide a brief description of the bot's features, and how to use them. You'll want to subscribe to the `conversationUpdate` event, with the `teamMemberAdded` eventType. Since the event is sent when any new team member is added, you need to check to determine if the new member added is the bot. See [Sending a welcome message to a new team member](~/bots/how-to/conversations/send-proactive-messages.md) for more details.
+## Send a message on installation
-You might also want to send a personal message to each member of the team when the bot is added. To do this, you could get the team roster and send each user a direct message.
+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](~/bots/how-to/conversations/send-proactive-messages.md).
-It is not recommended to send a message in the following situations:
+Send a personal message to each team member when the bot is added. To do this, get the team roster and send each user a direct message.
-* The team is large (obviously subjective, but for example larger than 100 members). Your bot may be seen as 'spammy' and the person who added it may get complaints unless you clearly communicate your bot's value proposition to everyone who sees the welcome message.
-* Your bot is first mentioned in a group or channel (versus being first added to a team)
-* A group or channel is renamed
-* A team member is added to a group or channel
+Do not send a message in the following cases:
-## Learn more
+* 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.
-Your bot has access to additional information about the group chat or team it is installed in. See [get teams context](~/bots/how-to/get-teams-context.md) for additional APIs available for your bot.
-There are also additional events that your bot can subscribe and respond to. See [subscribe to conversation events](~/bots/how-to/conversations/subscribe-to-conversation-events.md) to learn how.
+## See also
+> [!div class="nextstepaction"]
+> [Get teams context](~/bots/how-to/get-teams-context.md).
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Subscribe to conversation events](~/bots/how-to/conversations/subscribe-to-conversation-events.md)
platform Conversation Basics https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/conversations/conversation-basics.md
Title: Conversation basics
-description: describes ways to have a conversation with a Microsoft Teams bot
+description: Introduction to conversations
-keyword: conversations basics receive message send message picture message channel data adaptive cards
+keyword: conversations basics messages
# Conversation basics [!INCLUDE [pre-release-label](~/includes/v4-to-v3-pointer-bots.md)]
-A conversation is a series of messages sent between your Microsoft Teams bot and one or more users. There are three types of conversations, also called scopes in Teams:
+A conversation is a series of messages sent between your Microsoft Teams bot and one or more users. The following table provides the three types of conversations, also called scopes in Teams:
| Conversation type | Description | | - | -- |
A bot behaves differently depending on the conversation it is involved in:
For the bot to work in a particular conversation or scope, add support to that scope in the [app manifest](~/resources/schem).
-## Messages in bot conversations
+Each message in a bot conversation is an `Activity` object of type `messageType: message`. When a user sends a message, Teams posts the message to your bot and the bot handles the message. In addition, to define core commands that your bot responds to, you can add a command menu with a drop-down list of commands for your bot. Bots in a group or channel only receive messages when they are mentioned @botname. Teams sends notifications to your bot for conversation events that happen in scopes where your bot is active. You can capture these events in your code and take action on them.
-Each message in a conversation is an `Activity` object of type `messageType: message`. When a user sends a message, Teams posts the message to your bot. Teams sends a JSON object to your bot's messaging endpoint. Your bot examines the message to determine its type and responds accordingly.
-
-Basic conversations are handled through the Bot Framework connector, a single REST API. This API enables your bot to communicate with Teams and other channels. The Bot Builder SDK provides the following:
-
-* Easy access to the Bot Framework connector.
-* Additional functionality to manage conversation flow and state.
-* Simple ways to incorporate cognitive services such as Natural Language Processing (NLP).
-
-Your bot receives messages from Teams using the `Text` property and it sends single or multiple message responses to the users.
-
-## Receive a message
-
-To receive a text message, use the `Text` property of the `Activity` object. In the bot's activity handler, use the turn context object's `Activity` to read a single message request.
-
-The following code shows an example of receiving a message:
-
-# [C#](#tab/dotnet)
-
-```csharp
-protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
-{
- await turnContext.SendActivityAsync(MessageFactory.Text($"Echo: {turnContext.Activity.Text}"), cancellationToken);
-}
-
-```
-
-# [TypeScript](#tab/typescript)
-
-```typescript
-
-export class MyBot extends TeamsActivityHandler {
- constructor() {
- super();
- this.onMessage(async (context, next) => {
- await context.sendActivity(`Echo: '${context.activity.text}'`);
- await next();
- });
- }
-}
-
-```
-
-# [Python](#tab/python)
-
-<!-- Verify -->
-```python
-
-async def on_message_activity(self, turn_context: TurnContext):
- return await turn_context.send_activity(MessageFactory.text(f"Echo: {turn_context.activity.text}"))
-
-```
-
-# [JSON](#tab/json)
-
-```json
-{
- "type": "message",
- "id": "1485983408511",
- "timestamp": "2017-02-01T21:10:07.437Z",
- "localTimestamp": "2017-02-01T14:10:07.437-07:00",
- "serviceUrl": "https://smba.trafficmanager.net/amer/",
- "channelId": "msteams",
- "from": {
- "id": "29:1XJKJMvc5GBtc2JwZq0oj8tHZmzrQgFmB39ATiQWA85gQtHieVkKilBZ9XHoq9j7Zaqt7CZ-NJWi7me2kHTL3Bw",
- "name": "Megan Bowen",
- "aadObjectId": "7faf8ab2-3d56-4244-b585-20c8a42ed2b8"
- },
- "conversation": {
- "conversationType": "personal",
- "id": "a:17I0kl9EkpE1O9PH5TWrzrLNwnWWcfrU7QZjKR0WSfOpzbfcAg2IaydGElSo10tVr4C7Fc6GtieTJX663WuJCc1uA83n4CSrHSgGBj5XNYLcVlJAs2ZX8DbYBPck201w-"
- },
- "recipient": {
- "id": "28:c9e8c047-2a74-40a2-b28a-b162d5f5327c",
- "name": "Teams TestBot"
- },
- "textFormat": "plain",
- "text": "Hello Teams TestBot",
- "entities": [
- {
- "locale": "en-US",
- "country": "US",
- "platform": "Windows",
- "timezone": "America/Los_Angeles",
- "type": "clientInfo"
- }
- ],
- "channelData": {
- "tenant": {
- "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
- }
- },
- "locale": "en-US"
-}
-```
---
-## Send a message
-
-To send a text message, specify the string you want to send as the activity. In the bot's activity handler, use the turn context object's `SendActivityAsync` method to send a single message response. Use the object's `SendActivitiesAsync` method to send multiple responses at once. The following code shows an example of sending a message when a user is added to a conversation:
-
-The following code shows an example of sending a message:
-
-# [C#](#tab/dotnet)
-
-```csharp
-protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
-{
- await turnContext.SendActivityAsync(MessageFactory.Text($"Hello and welcome!"), cancellationToken);
-}
-
-```
-
-# [TypeScript](#tab/typescript)
-
-```typescript
-
-export class MyBot extends TeamsActivityHandler {
- constructor() {
- super();
- this.onMessage(async (context, next) => {
- await context.sendActivity('Hello and welcome!');
- await next();
- });
- }
-}
-```
-
-# [Python](#tab/python)
-
-<!-- Verify -->
-
-```python
-
-async def on_members_added_activity(
- self, members_added: [ChannelAccount], turn_context: TurnContext
-):
- for member in teams_members_added:
- await turn_context.send_activity(f"Welcome your new team member {member.id}")
- return
-
-```
-
-# [JSON](#tab/json)
-
-```json
-{
- "text": "hi",
- "textFormat": "plain",
- "type": "message",
- "timestamp": "2019-10-31T20:57:27.2347285Z",
- "localTimestamp": "2019-10-31T13:57:27.2347285-07:00",
- "id": "1572555447214",
- "channelId": "msteams",
- "serviceUrl": "https://smba.trafficmanager.net/amer/",
- "from": {
- "id": "29:1Xv-kvy4dKirR0rZfSF_kAVUzotoT1SXuEzkC9XGkuZng8YBw8qyu5uh4128fQRjlGgvEiRLx-0XP4KYMwcgdZw",
- "name": "Jane Doe",
- "aadObjectId": "df486eae-88fd-42a5-b45e-c581588186db"
- },
- "conversation": {
- "conversationType": "personal",
- "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
- "id": "a:1oAmWTVBBe9E0JrpGxauqNyx4CCE_iQf2ZuWon9D42722Fon3wYIpbhgbRChE3wgVS1Gwl9zS1pZy4FSu6-x1vGEq5KBQK-EbBgyPyeP_C-lbLBY3vxnGk9m9D_282jbg"
- },
- "recipient": {
- "id": "28:5baea8d1-d4ea-43a1-b101-882f4c8d9cb4",
- "name": "Imported Bot"
- },
- "entities": [
- {
- "locale": "en-US",
- "country": "US",
- "platform": "Windows",
- "type": "clientInfo"
- }
- ],
- "channelData": {
- "tenant": {
- "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
- }
- },
- "locale": "en-US"
-}
-```
---
-> [!NOTE]
-> Message splitting occurs when a text message and an attachment are sent in the same activity payload. This activity is split into separate activities by Microsoft Teams, one with just a text message and the other with an attachment. As the activity is split, you do not receive the message ID in response, which is used to [update or delete](~/bots/how-to/update-and-delete-bot-messages.md) the message proactively. It is recommended to send separate activities instead of depending on message splitting.
-
-Messages sent between users and bots include internal channel data within the message. This data allows the bot to communicate properly on that channel. The Bot Builder SDK allows you to modify the message structure.
-
-## Teams channel data
-
-The `channelData` object contains Teams-specific information and is a definitive source for team and channel IDs. Optionally, you can cache and use these IDs as keys for local storage. The `TeamsActivityHandler` in the SDK typically pulls out important information from the `channelData` object to make it easily accessible. However, you can always access the original data from the `turnContext` object.
-
-The `channelData` object is not included in messages in personal conversations, as these take place outside of a channel.
-
-A typical `channelData` object in an activity sent to your bot contains the following information:
-
-* `eventType`: Teams event type passed only in cases of [channel modification events](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
-* `tenant.id`: Azure Active Directory tenant ID passed in all contexts.
-* `team`: Passed only in channel contexts, not in personal chat.
- * `id`: GUID for the channel.
- * `name`: Name of the team passed only in cases of [team rename events](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
-* `channel`: Passed only in channel contexts when the bot is mentioned or for events in channels in teams where the bot has been added.
- * `id`: GUID for the channel.
- * `name`: Channel name passed only in cases of [channel modification events](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
-* `channelData.teamsTeamId`: Deprecated. This property is only included for backward compatibility.
-* `channelData.teamsChannelId`: Deprecated. This property is only included for backward compatibility.
-
-### Example channelData object (channelCreated event)
-
-The following code shows an example of channelData object:
-
-```json
-"channelData": {
- "eventType": "channelCreated",
- "tenant": {
- "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
- },
- "channel": {
- "id": "19:693ecdb923ac4458a5c23661b505fc84@thread.skype",
- "name": "My New Channel"
- },
- "team": {
- "id": "19:693ecdb923ac4458a5c23661b505fc84@thread.skype"
- }
-}
-```
-
-Messages received from or sent to your bot can include different types of message content.
-
-## Message content
-
-Your bot can send rich text, pictures, and cards. Users can send rich text and pictures to your bot.
-
-| Format | From user to bot | From bot to user | Notes |
-|--|||--|
-| Rich text | Γ£ö | Γ£ö | |
-| Pictures | ✔ | ✔ | Maximum 1024×1024 and 1 MB in PNG, JPEG, or GIF format. Animated GIF is not supported. |
-| Cards | Γ£û | Γ£ö | See the [Teams card reference](~/task-modules-and-cards/cards/cards-reference.md) for supported cards. |
-| Emojis | Γ£û | Γ£ö | Teams currently supports emojis through UTF-16, such as U+1F600 for grinning face. |
-
-You can also add notifications to your message using the `Notification.Alert` property.
-
-## Notifications to your message
-
-Notifications alert users about new tasks, mentions, and comments. These alerts are related to what users are working on or what they must look at by inserting a notice into their activity feed. For notifications to trigger from your bot message, set the `TeamsChannelData` objects `Notification.Alert` property to true. Whether or not a notification is raised depends on the individual user's Teams settings and you cannot override these settings. The notification type is either a banner or both a banner and an email.
-
-> [!NOTE]
-> The **Summary** field displays any text from the user as a notification message in the feed.
-
-The following code shows an example of adding notifications to your message:
-
-# [C#](#tab/dotnet)
-
-```csharp
-protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
-{
- var message = MessageFactory.Text("You'll get a notification, if you've turned them on.");
- message.TeamsNotifyUser();
-
- await turnContext.SendActivityAsync(message);
-}
-```
-
-# [TypeScript](#tab/typescript)
-
-```typescript
-this.onMessage(async (turnContext, next) => {
- let message = MessageFactory.text("You'll get a notification, if you've turned them on.");
- teamsNotifyUser(message);
-
- await turnContext.sendActivity(message);
-
- // By calling next() you ensure that the next BotHandler is run.
- await next();
-});
-```
-
-# [Python](#tab/python)
-
-```python
-
-async def on_message_activity(self, turn_context: TurnContext):
- message = MessageFactory.text("You'll get a notification, if you've turned them on.")
- teams_notify_user(message)
-
- await turn_context.send_activity(message)
-
-```
-
-# [JSON](#tab/json)
-
-```json
-{
- "type": "message",
- "timestamp": "2017-04-24T21:46:00.9663655Z",
- "localTimestamp": "2017-04-24T14:46:00.9663655-07:00",
- "serviceUrl": "https://callback.com",
- "channelId": "msteams",
- "from": {
- "id": "28:e4fda94a-4b80-40eb-9bf0-6314491bc793",
- "name": "The bot"
- },
- "conversation": {
- "id": "a:1pL6i0oY3C0K8oAj8"
- },
- "recipient": {
- "id": "29:1rsVJmSSFMScF0YFyCXpvNWlo",
- "name": "User"
- },
- "text": "John Phillips assigned you a weekly todo",
- "summary": "Don't forget to meet with Marketing next week",
- "channelData": {
- "notification": {
- "alert": true
- }
- },
- "replyToId": "1493070356924"
-}
-```
---
-To enhance your message, you can include pictures as attachments to that message.
-
-## Picture messages
-
-Pictures are sent by adding attachments to a message. For more information on attachments, see [Bot Framework documentation](/azure/bot-service/dotnet/bot-builder-dotnet-add-media-attachments).
-
-Pictures can be at most 1024×1024 and 1 MB in PNG, JPEG, or GIF format. Animated GIF is not supported.
-
-Specify the height and width of each image by using XML. In markdown, the image size defaults to 256×256. For example:
-
-* Use: `<img src="http://aka.ms/Fo983c" alt="Duck on a rock" height="150" width="223"></img>`.
-* Do not use: `![Duck on a rock](http://aka.ms/Fo983c)`.
-
-A conversational bot can include adaptive cards that simplify business workflows. Adaptive cards offer rich customizable text, speech, images, buttons, and input fields.
-
-## Adaptive cards
-
-Adaptive cards can be authored in a bot and shown in multiple apps such as Teams, your website, and so on. For more information, see [adaptive cards](~/task-modules-and-cards/cards/cards-reference.md#adaptive-card).
-
-The following code shows an example of sending a simple adaptive card:
-
-```json
-{
- "type": "AdaptiveCard",
- "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
- "version": "1.5",
- "body": [
- {
- "items": [
- {
- "size": "large",
- "text": " Simple Adaptivecard Example with a Textbox",
- "type": "TextBlock",
- "weight": "bolder",
- "wrap": true
- },
- ],
- "spacing": "extraLarge",
- "type": "Container",
- "verticalContentAlignment": "center"
- }
- ]
-}
-```
-
-To know more about cards and cards in bots, see [cards documentation](~/task-modules-and-cards/what-are-cards.md).
-
-The next section provides status code responses for errors generated from Bot APIs.
-
-## Status code responses
-
-Following are the status codes and their error code and message values:
-
-| Status code | Error code and message values | Description |
-|-|--|--|
-| 403 | **Code**: `ConversationBlockedByUser` <br/> **Message**: "User blocked the conversation with the bot." | User blocked the bot in 1:1 chat or a channel through moderation settings. |
-| 403 | **Code**: `BotNotInConversationRoster` <br/> **Message**: "The bot is not part of the conversation roster." | The bot is not part of the conversation. |
-| 403 | **Code**: `BotDisabledByAdmin` <br/> **Message**: "The tenant admin disabled this bot." | Tenant blocked the bot. |
-| 401 | **Code**: `BotNotRegistered` <br/> **Message**: ΓÇ£No registration found for this bot.ΓÇ¥ | The registration for this bot was not found. |
-| 412 | **Code**: `PreconditionFailed` <br/> **Message**: ΓÇ£Precondition failed, please try again.ΓÇ¥ | A precondition failed on one of our dependencies due to multiple concurrent operations on the same conversation. |
-| 404 | **Code**: `ConversationNotFound` <br/> **Message**: ΓÇ£Conversation not found.ΓÇ¥ | The conversation was not found. |
-| 413 | **Code**: `MessageSizeTooBig` <br/> **Message**: ΓÇ£Message size too large.ΓÇ¥ | The size on the incoming request was too large. |
-| 429 | **Code**: `Throttled` <br/> **Message**: ΓÇ£Too many requests.ΓÇ¥ Also returns when to retry after. | Too many requests were sent by the bot. For more information, see [rate limit](~/bots/how-to/rate-limit.md). |
-
-The next section illustrates a simple code sample that incorporates basic conversational flow into a Teams application.
-
-## Code sample
-
-Following are the code samples for Teams conversation bot:
-
-|Sample name | Description | .NETCore | Node.js | Python |
-|-|--|--|-|--|
-| Teams conversation bot | Messaging and conversation event handling. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/57.teams-conversation-bot)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/57.teams-conversation-bot)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/57.teams-conversation-bot) |
-
-## See also
-
-> [!div class="nextstepaction"]
-> [Send proactive messages](~/bots/how-to/conversations/send-proactive-messages.md)
-> [!div class="nextstepaction"]
-> [Subscribe to conversation events](~/bots/how-to/conversations/subscribe-to-conversation-events.md)
+A bot can also send proactive messages to users. A proactive message is any message sent by a bot that is not in response to a request from a user. You can format your bot messages to include rich cards that include interactive elements, such as buttons, text, images, audio, video, and so on. Bot can dynamically update messages after sending them, instead of having your messages as a static snapshots of data. Messages can also be deleted using the Bot Framework's `DeleteActivity` method.
## Next step > [!div class="nextstepaction"]
-> [Bot command menus](~/bots/how-to/create-a-bot-commands-menu.md)
+> [Messages in bot conversations](~/bots/how-to/conversations/conversation-messages.md)
platform Conversation Messages https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/conversations/conversation-messages.md
+
+ Title: Messages in bot conversations
+description: Describes ways to have a conversation with a Microsoft Teams bot
++
+keyword: receive message send message picture message channel data adaptive cards
++
+# Messages in bot conversations
+
+Each message in a conversation is an `Activity` object of type `messageType: message`. When a user sends a message, Teams posts the message to your bot. Teams sends a JSON object to your bot's messaging endpoint. Your bot examines the message to determine its type and responds accordingly.
+
+Basic conversations are handled through the Bot Framework connector, a single REST API. This API enables your bot to communicate with Teams and other channels. The Bot Builder SDK provides the following features:
+
+* Easy access to the Bot Framework connector.
+* Additional functionality to manage conversation flow and state.
+* Simple ways to incorporate cognitive services, such as natural language processing (NLP).
+
+Your bot receives messages from Teams using the `Text` property and it sends single or multiple message responses to the users.
+
+## Receive a message
+
+To receive a text message, use the `Text` property of the `Activity` object. In the bot's activity handler, use the turn context object's `Activity` to read a single message request.
+
+The following code shows an example of receiving a message:
+
+# [C#](#tab/dotnet)
+
+```csharp
+protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
+{
+ await turnContext.SendActivityAsync(MessageFactory.Text($"Echo: {turnContext.Activity.Text}"), cancellationToken);
+}
+
+```
+
+# [TypeScript](#tab/typescript)
+
+```typescript
+
+export class MyBot extends TeamsActivityHandler {
+ constructor() {
+ super();
+ this.onMessage(async (context, next) => {
+ await context.sendActivity(`Echo: '${context.activity.text}'`);
+ await next();
+ });
+ }
+}
+
+```
+
+# [Python](#tab/python)
+
+<!-- Verify -->
+```python
+
+async def on_message_activity(self, turn_context: TurnContext):
+ return await turn_context.send_activity(MessageFactory.text(f"Echo: {turn_context.activity.text}"))
+
+```
+
+# [JSON](#tab/json)
+
+```json
+{
+ "type": "message",
+ "id": "1485983408511",
+ "timestamp": "2017-02-01T21:10:07.437Z",
+ "localTimestamp": "2017-02-01T14:10:07.437-07:00",
+ "serviceUrl": "https://smba.trafficmanager.net/amer/",
+ "channelId": "msteams",
+ "from": {
+ "id": "29:1XJKJMvc5GBtc2JwZq0oj8tHZmzrQgFmB39ATiQWA85gQtHieVkKilBZ9XHoq9j7Zaqt7CZ-NJWi7me2kHTL3Bw",
+ "name": "Megan Bowen",
+ "aadObjectId": "7faf8ab2-3d56-4244-b585-20c8a42ed2b8"
+ },
+ "conversation": {
+ "conversationType": "personal",
+ "id": "a:17I0kl9EkpE1O9PH5TWrzrLNwnWWcfrU7QZjKR0WSfOpzbfcAg2IaydGElSo10tVr4C7Fc6GtieTJX663WuJCc1uA83n4CSrHSgGBj5XNYLcVlJAs2ZX8DbYBPck201w-"
+ },
+ "recipient": {
+ "id": "28:c9e8c047-2a74-40a2-b28a-b162d5f5327c",
+ "name": "Teams TestBot"
+ },
+ "textFormat": "plain",
+ "text": "Hello Teams TestBot",
+ "entities": [
+ {
+ "locale": "en-US",
+ "country": "US",
+ "platform": "Windows",
+ "timezone": "America/Los_Angeles",
+ "type": "clientInfo"
+ }
+ ],
+ "channelData": {
+ "tenant": {
+ "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
+ }
+ },
+ "locale": "en-US"
+}
+```
+++
+## Send a message
+
+To send a text message, specify the string you want to send as the activity. In the bot's activity handler, use the turn context object's `SendActivityAsync` method to send a single message response. Use the object's `SendActivitiesAsync` method to send multiple responses at once.
+
+The following code shows an example of sending a message when a user is added to a conversation:
+
+# [C#](#tab/dotnet)
+
+```csharp
+protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
+{
+ await turnContext.SendActivityAsync(MessageFactory.Text($"Hello and welcome!"), cancellationToken);
+}
+
+```
+
+# [TypeScript](#tab/typescript)
+
+```typescript
+
+export class MyBot extends TeamsActivityHandler {
+ constructor() {
+ super();
+ this.onMessage(async (context, next) => {
+ await context.sendActivity('Hello and welcome!');
+ await next();
+ });
+ }
+}
+```
+
+# [Python](#tab/python)
+
+<!-- Verify -->
+
+```python
+
+async def on_members_added_activity(
+ self, members_added: [ChannelAccount], turn_context: TurnContext
+):
+ for member in teams_members_added:
+ await turn_context.send_activity(f"Welcome your new team member {member.id}")
+ return
+
+```
+
+# [JSON](#tab/json)
+
+```json
+{
+ "text": "hi",
+ "textFormat": "plain",
+ "type": "message",
+ "timestamp": "2019-10-31T20:57:27.2347285Z",
+ "localTimestamp": "2019-10-31T13:57:27.2347285-07:00",
+ "id": "1572555447214",
+ "channelId": "msteams",
+ "serviceUrl": "https://smba.trafficmanager.net/amer/",
+ "from": {
+ "id": "29:1Xv-kvy4dKirR0rZfSF_kAVUzotoT1SXuEzkC9XGkuZng8YBw8qyu5uh4128fQRjlGgvEiRLx-0XP4KYMwcgdZw",
+ "name": "Jane Doe",
+ "aadObjectId": "df486eae-88fd-42a5-b45e-c581588186db"
+ },
+ "conversation": {
+ "conversationType": "personal",
+ "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
+ "id": "a:1oAmWTVBBe9E0JrpGxauqNyx4CCE_iQf2ZuWon9D42722Fon3wYIpbhgbRChE3wgVS1Gwl9zS1pZy4FSu6-x1vGEq5KBQK-EbBgyPyeP_C-lbLBY3vxnGk9m9D_282jbg"
+ },
+ "recipient": {
+ "id": "28:5baea8d1-d4ea-43a1-b101-882f4c8d9cb4",
+ "name": "Imported Bot"
+ },
+ "entities": [
+ {
+ "locale": "en-US",
+ "country": "US",
+ "platform": "Windows",
+ "type": "clientInfo"
+ }
+ ],
+ "channelData": {
+ "tenant": {
+ "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
+ }
+ },
+ "locale": "en-US"
+}
+```
+++
+> [!NOTE]
+> Message splitting occurs when a text message and an attachment are sent in the same activity payload. This activity is split into separate activities by Microsoft Teams, one with just a text message and the other with an attachment. As the activity is split, you do not receive the message ID in response, which is used to [update or delete](~/bots/how-to/update-and-delete-bot-messages.md) the message proactively. It is recommended to send separate activities instead of depending on message splitting.
+
+Messages sent between users and bots include internal channel data within the message. This data allows the bot to communicate properly on that channel. The Bot Builder SDK allows you to modify the message structure.
+
+## Teams channel data
+
+The `channelData` object contains Teams-specific information and is a definitive source for team and channel IDs. Optionally, you can cache and use these IDs as keys for local storage. The `TeamsActivityHandler` in the SDK pulls out important information from the `channelData` object to make it easily accessible. However, you can always access the original data from the `turnContext` object.
+
+The `channelData` object is not included in messages in personal conversations, as these take place outside of a channel.
+
+A typical `channelData` object in an activity sent to your bot contains the following information:
+
+* `eventType`: Teams event type passed only in cases of [channel modification events](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
+* `tenant.id`: Azure Active Directory tenant ID passed in all contexts.
+* `team`: Passed only in channel contexts, not in personal chat.
+ * `id`: GUID for the channel.
+ * `name`: Name of the team passed only in cases of [team rename events](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
+* `channel`: Passed only in channel contexts when the bot is mentioned or for events in channels in teams where the bot has been added.
+ * `id`: GUID for the channel.
+ * `name`: Channel name passed only in cases of [channel modification events](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
+* `channelData.teamsTeamId`: Deprecated. This property is only included for backward compatibility.
+* `channelData.teamsChannelId`: Deprecated. This property is only included for backward compatibility.
+
+### Example channelData object or channelCreated event
+
+The following code shows an example of channelData object:
+
+```json
+"channelData": {
+ "eventType": "channelCreated",
+ "tenant": {
+ "id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
+ },
+ "channel": {
+ "id": "19:693ecdb923ac4458a5c23661b505fc84@thread.skype",
+ "name": "My New Channel"
+ },
+ "team": {
+ "id": "19:693ecdb923ac4458a5c23661b505fc84@thread.skype"
+ }
+}
+```
+
+Messages received from or sent to your bot can include different types of message content.
+
+## Message content
+
+| Format | From user to bot | From bot to user | Notes |
+|--|||--|
+| Rich text | Γ£ö | Γ£ö | Your bot can send rich text, pictures, and cards. Users can send rich text and pictures to your bot. |
+| Pictures | ✔ | ✔ | Maximum 1024×1024 and 1 MB in PNG, JPEG, or GIF format. Animated GIF is not supported. |
+| Cards | Γ£û | Γ£ö | See the [Teams card reference](~/task-modules-and-cards/cards/cards-reference.md) for supported cards. |
+| Emojis | Γ£û | Γ£ö | Teams currently supports emojis through UTF-16, such as U+1F600 for grinning face. |
+
+You can also add notifications to your message using the `Notification.Alert` property.
+
+## Notifications to your message
+
+Notifications alert users about new tasks, mentions, and comments. These alerts are related to what users are working on or what they must look at by inserting a notice into their activity feed. For notifications to trigger from your bot message, set the `TeamsChannelData` objects `Notification.Alert` property to *true*. Whether or not a notification is raised depends on the individual user's Teams settings and you cannot override these settings. The notification type is either a banner, or both a banner and an email.
+
+> [!NOTE]
+> The **Summary** field displays any text from the user as a notification message in the feed.
+
+The following code shows an example of adding notifications to your message:
+
+# [C#](#tab/dotnet)
+
+```csharp
+protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
+{
+ var message = MessageFactory.Text("You'll get a notification, if you've turned them on.");
+ message.TeamsNotifyUser();
+
+ await turnContext.SendActivityAsync(message);
+}
+```
+
+# [TypeScript](#tab/typescript)
+
+```typescript
+this.onMessage(async (turnContext, next) => {
+ let message = MessageFactory.text("You'll get a notification, if you've turned them on.");
+ teamsNotifyUser(message);
+
+ await turnContext.sendActivity(message);
+
+ // By calling next() you ensure that the next BotHandler is run.
+ await next();
+});
+```
+
+# [Python](#tab/python)
+
+```python
+
+async def on_message_activity(self, turn_context: TurnContext):
+ message = MessageFactory.text("You'll get a notification, if you've turned them on.")
+ teams_notify_user(message)
+
+ await turn_context.send_activity(message)
+
+```
+
+# [JSON](#tab/json)
+
+```json
+{
+ "type": "message",
+ "timestamp": "2017-04-24T21:46:00.9663655Z",
+ "localTimestamp": "2017-04-24T14:46:00.9663655-07:00",
+ "serviceUrl": "https://callback.com",
+ "channelId": "msteams",
+ "from": {
+ "id": "28:e4fda94a-4b80-40eb-9bf0-6314491bc793",
+ "name": "The bot"
+ },
+ "conversation": {
+ "id": "a:1pL6i0oY3C0K8oAj8"
+ },
+ "recipient": {
+ "id": "29:1rsVJmSSFMScF0YFyCXpvNWlo",
+ "name": "User"
+ },
+ "text": "John Phillips assigned you a weekly todo",
+ "summary": "Don't forget to meet with Marketing next week",
+ "channelData": {
+ "notification": {
+ "alert": true
+ }
+ },
+ "replyToId": "1493070356924"
+}
+```
+++
+To enhance your message, you can include pictures as attachments to that message.
+
+## Picture messages
+
+Pictures are sent by adding attachments to a message. For more information on attachments, see [Bot Framework documentation](/azure/bot-service/dotnet/bot-builder-dotnet-add-media-attachments).
+
+Pictures can be at most 1024×1024 and 1 MB in PNG, JPEG, or GIF format. Animated GIF is not supported.
+
+Specify the height and width of each image by using XML. In markdown, the image size defaults to 256×256. For example:
+
+* Use: `<img src="http://aka.ms/Fo983c" alt="Duck on a rock" height="150" width="223"></img>`.
+* Do not use: `![Duck on a rock](http://aka.ms/Fo983c)`.
+
+A conversational bot can include Adaptive Cards that simplify business workflows. Adaptive Cards offer rich customizable text, speech, images, buttons, and input fields.
+
+## Adaptive Cards
+
+Adaptive Cards can be authored in a bot and shown in multiple apps such as Teams, your website, and so on. For more information, see [Adaptive Cards](~/task-modules-and-cards/cards/cards-reference.md#adaptive-card).
+
+The following code shows an example of sending a simple Adaptive Card:
+
+```json
+{
+ "type": "AdaptiveCard",
+ "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
+ "version": "1.5",
+ "body": [
+ {
+ "items": [
+ {
+ "size": "large",
+ "text": " Simple Adaptivecard Example with a Textbox",
+ "type": "TextBlock",
+ "weight": "bolder",
+ "wrap": true
+ },
+ ],
+ "spacing": "extraLarge",
+ "type": "Container",
+ "verticalContentAlignment": "center"
+ }
+ ]
+}
+```
+
+To know more about cards and cards in bots, see [cards documentation](~/task-modules-and-cards/what-are-cards.md).
+
+## Status code responses
+
+Following are the status codes and their error code and message values:
+
+| Status code | Error code and message values | Description |
+|-|--|--|
+| 403 | **Code**: `ConversationBlockedByUser` <br/> **Message**: User blocked the conversation with the bot. | User blocked the bot in 1:1 chat or a channel through moderation settings. |
+| 403 | **Code**: `BotNotInConversationRoster` <br/> **Message**: The bot is not part of the conversation roster. | The bot is not part of the conversation. |
+| 403 | **Code**: `BotDisabledByAdmin` <br/> **Message**: The tenant admin disabled this bot. | Tenant blocked the bot. |
+| 401 | **Code**: `BotNotRegistered` <br/> **Message**: No registration found for this bot. | The registration for this bot was not found. |
+| 412 | **Code**: `PreconditionFailed` <br/> **Message**: Precondition failed, please try again. | A precondition failed on one of our dependencies due to multiple concurrent operations on the same conversation. |
+| 404 | **Code**: `ConversationNotFound` <br/> **Message**: Conversation not found. | The conversation was not found. |
+| 413 | **Code**: `MessageSizeTooBig` <br/> **Message**: Message size too large. | The size on the incoming request was too large. |
+| 429 | **Code**: `Throttled` <br/> **Message**: Too many requests. Also returns when to retry after. | Too many requests were sent by the bot. For more information, see [rate limit](~/bots/how-to/rate-limit.md). |
+
+## Code sample
+
+|Sample name | Description | .NETCore | Node.js | Python |
+|-|--|--|-|--|
+| Teams conversation bot | Messaging and conversation event handling. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/57.teams-conversation-bot)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/57.teams-conversation-bot)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/57.teams-conversation-bot) |
+
+## See also
+
+> [!div class="nextstepaction"]
+> [Send proactive messages](~/bots/how-to/conversations/send-proactive-messages.md)
+> [!div class="nextstepaction"]
+> [Subscribe to conversation events](~/bots/how-to/conversations/subscribe-to-conversation-events.md)
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Bot command menus](~/bots/how-to/create-a-bot-commands-menu.md)
platform Send Proactive Messages https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/conversations/send-proactive-messages.md
Title: send proactive messages
-description: describes how to send proactive messages with your Microsoft Teams bot.
-
+ Title: Send proactive messages
+description: Describes how to send proactive messages with your Microsoft Teams bot.
+ Keywords: send a message get user ID channel ID conversation ID
Keywords: send a message get user ID channel ID conversation ID
[!INCLUDE [v4 to v3 pointer](~/includes/v4-to-v3-pointer-bots.md)]
-A proactive message is any message sent by a bot that is not in direct response to a request from a user. This can include messages like:
+A proactive message is any message sent by a bot that is not in response to a request from a user. This can include messages, such as:
* Welcome messages * Notifications * Scheduled messages
-For your bot to send a proactive message, it must have access to the user, group chat, or team that you want to send the message to. For a group chat or team, this means the app that contains your bot must be installed to that location first. You can [proactively install your app using Graph](#proactively-install-your-app-using-graph) in a team, if required or use an [app policy](/microsoftteams/teams-custom-app-policies-and-settings) to push apps out to teams and users in your tenant. For users, your app either must be installed for the user or your user must be part of a team where your app is installed.
+For your bot to send a proactive message to a user, group chat, or team, it must have access to send the message. For a group chat or team, the app that contains your bot must be first installed in that location. You can [proactively install your app using Microsoft Graph](#proactively-install-your-app-using-graph) in a team, if required, or use an [app policy](/microsoftteams/teams-custom-app-policies-and-settings) to push apps out to teams and users in your tenant. For users, your app either must be installed for the user or your user must be part of a team where your app is installed.
-Sending a proactive message is different than sending a regular message. In that, there is no active `turnContext` to use for a reply. You may also need to create the conversation before sending the message. For example, a new one-to-one chat or a new conversation thread in a channel. You cannot create a new group chat or a new channel in a team with proactive messaging.
+Sending a proactive message is different from sending a regular message. There is no active `turnContext` to use for a reply. You must create the conversation before sending the message. For example, a new one-to-one chat or a new conversation thread in a channel. You cannot create a new group chat or a new channel in a team with proactive messaging.
-At a high level the steps you'll need to complete to send a proactive message are:
+**To send a proactive message**
-1. [Get the user ID or team/channel ID](#get-the-user-id-or-teamchannel-id) (if needed).
-1. [Create the conversation or conversation thread](#create-the-conversation) (if needed).
+1. [Get the user ID, team ID, or channel ID](#get-the-user-id-team-id-or-channel-id), if required.
+1. [Create the conversation](#create-the-conversation), if required.
1. [Get the conversation ID](#get-the-conversation-id). 1. [Send the message](#send-the-message).
-The code snippets in the [examples](#examples) section are for creating a one-to-one conversation. For links to complete working samples for both one-to-one conversations and group or channels , see [code samples](#code-samples).
+For using proactive messages effectively, see [best practices for proactive messaging](#best-practices-for-proactive-messaging). For certain scenarios, you must [proactively install your app using Graph](#proactively-install-your-app-using-graph). The code snippets in the [samples](#samples) section are for creating a one-to-one conversation. For complete working samples for both one-to-one conversations and groups or channels, see [code sample](#code-sample).
-## Get the user ID or team/channel ID
+## Get the user ID, team ID or channel ID
-To create a new conversation or conversation thread in a channel, you need the correct ID. You can receive or retrieve this ID in multiple ways:
+To create a new conversation or conversation thread in a channel, you must have the correct ID. You can receive or retrieve this ID using any of the following:
-1. When your app is installed in any particular context, you'll receive a [`onMembersAdded` Activity](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
-1. When a new user is added to a context where your app is installed, you'll receive a [`onMembersAdded` Activity](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
-1. You can retrieve the [list of channels](~/bots/how-to/get-teams-context.md) in a team your app is installed.
-1. You can retrieve the [list of members](~/bots/how-to/get-teams-context.md) of a team your app is installed.
-1. Every Activity your bot receives must contain the required information.
+* When your app is installed in any particular context, you receive an [`onMembersAdded` activity](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
+* When a new user is added to a context where your app is installed, you receive an [`onMembersAdded` activity](~/bots/how-to/conversations/subscribe-to-conversation-events.md).
+* You can retrieve the [list of channels](~/bots/how-to/get-teams-context.md) in a team where your app is installed.
+* You can retrieve the [list of members](~/bots/how-to/get-teams-context.md) of a team where your app is installed.
+* Every activity your bot receives must contain the required information.
-Regardless of how you gain the information, you'll need to store the `tenantId` and either the `userId` or `channelId` to create a new conversation. You can also use the `teamId` to create a new conversation thread in the general or default channel of a team.
+Regardless of how you get the information, you must store the `tenantId` and either the `userId` or `channelId` to create a new conversation. You can also use the `teamId` to create a new conversation thread in the general or default channel of a team.
-The `userId` is unique to your bot Id and a particular user, you cannot re-use them between bots. The `channelId` is global, however, your bot must be installed in the team before you can send a proactive message to a channel.
+The `userId` is unique to your bot ID and a particular user. You cannot reuse the `userId` between bots. The `channelId` is global. However, your bot must be installed in the team before you can send a proactive message to a channel.
+
+After you have the user or channel information, you must create the conversation.
## Create the conversation
-After you have the user or channel information, you need to create the conversation if it doesn't already exist or you don't know the `conversationId`. You must only create the conversation once and make sure you store the `conversationId` value or `conversationReference` object to use in the future.
+You must create the conversation if it does not exist or you do not know the `conversationId`. You must only create the conversation once and store the `conversationId` value or `conversationReference` object.
+
+After the conversation is created, you must get the conversation ID.
## Get the conversation ID
-After the conversation is created, use either the `conversationReference` object or `conversationId` and `tenantId` to send the message. You can get this ID by either creating the conversation or storing it from any Activity sent to you from that context. Make certain that you store this ID.
+Use either the `conversationReference` object or `conversationId` and `tenantId` to send the message. You can get this ID by either creating the conversation or storing it from any activity sent to you from that context. Store this ID for reference.
+
+After you get the appropriate address information, you can send your message.
## Send the message
-Now that you have the right address information, you can send your message. If you're using the SDK, you'll do so using the `continueConversation` method, and the `conversationId` and `tenantId` to make a direct API call. You must set the `conversationParameters` correctly to successfully send your message. See the [examples](#examples) section or use one of the samples listed in the [code samples](#code-samples) section.
+If you are using the SDK, you must use the `continueConversation` method, and the `conversationId` and `tenantId` to make a direct API call to send the message. You must set the `conversationParameters` correctly to successfully send your message.
+
+Now that you have sent the proactive message, you must follow these best practices while sending proactive messages for better information exchange between users and the bot.
## Best practices for proactive messaging
-Sending proactive messages to users is a very effective way to communicate with your users. However, from their perspective, this message can appear completely unprompted, and in the case of welcome messages, it is the first time they have interacted with your app. Therefore, it is very important to use this functionality sparingly, don't spam your users, and to provide enough information to let users understand why they are being messaged.
+Sending proactive messages to users is a very effective way to communicate with your users. However, from their perspective, this message can appear completely unprompted, and in the case of welcome messages, it is the first time they have interacted with your app. Therefore, it is very important to use proactive messaging sparingly, not spam your users, and provide enough information to let users understand why they are receiving the messages.
### Welcome messages
-When using proactive messaging to send a welcome message to a user you must keep in mind that, for most people receiving the message, there is no context for why they are receiving it. This is also the first time they have interacted with your app. It is your opportunity to create a good first impression. The best welcome messages must include:
+When proactive messaging is used to send a welcome message to a user, there is no context for why the users receive the message. This is also the first time users interact with your app. It is an opportunity to create a good first impression. The best welcome messages must include:
-* **Why a user is receiving the message.** It must be very clear to the user why they are receiving the message. If your bot was installed in a channel and you sent a welcome message to all users, let them know what channel it was installed in and potentially who installed it.
-* **What do you offer.** What can they do with your app? What value can you bring to them?
-* **What should they do next.** Invite them to try out a command, or interact with your app in some way.
+* Why a user is receiving the message: It must be very clear to the user why they are receiving the message. If your bot was installed in a channel and you sent a welcome message to all users, let them know what channel it was installed in and who installed it.
+* What do you offer: Users must be able to identify what they can do with your app and what value can you bring to them.
+* What should they do next: Invite users to try out a command, or interact with your app.
-Remember, poor welcome messages can lead to users blocking your bot. Spend plenty of time crafting your welcome messages, and iterate on them if they are not having the desired effect.
+Poor welcome messages can lead to users blocking your bot. Write to the point and clear welcome messages. Iterate on the welcome messages if they are not having the desired effect.
### Notification messages
-When using proactive messaging to send notifications you must ensure your users have a clear path to take common actions based on your notification and a clear understanding of why the notification occurred. Good notification messages generally include:
+To send notifications using proactive messaging, ensure your users have a clear path to take common actions based on your notification. Ensure users have a clear understanding of why they have received a notification. Good notification messages generally include the following:
+
+* What happened: A clear indication of what happened to cause the notification.
+* What was the result: It must be clear what item was updated to cause the notification.
+* Who or what triggered it: Who or what took action that caused the notification to be sent.
+* What can users do in response: Make it easy for your users to take actions based on your notifications.
+* How can users opt-out: You must provide a path for users to opt-out of additional notifications.
-* **What happened.** A clear indication of what happened to cause the notification.
-* **What was the result.** It must be clear what item or thing was updated to cause the notification.
-* **Who/what triggered it.** Who or what took action that caused the notification to be sent.
-* **What can users do in response.** Make it easy for your users to take actions based on your notifications.
-* **How can users opt out.** You must provide a path for users to opt out of additional notifications.
+To send messages to a large group of users, for example to your organization, proactively install your app using Graph.
### Scheduled messages
When using proactive messaging to send scheduled messages to users, verify that
## Proactively install your app using Graph > [!Note]
-> Proactively installing apps using the Microsoft Graph is currently in beta.
+> Proactively installing apps using Graph is currently in beta.
-Occasionally it may be necessary to proactively message users that have not installed or interacted with your app previously. For example, you want to use the [company communicator](~/samples/app-templates.md#company-communicator) to send messages to your entire organization. For this scenario you can use the Graph API to proactively install your app for your users, then cache the necessary values from the `conversationUpdate` event your app receives upon installation.
+Proactively message users that have previously not installed or interacted with your app. For example, you want to use the [company communicator](~/samples/app-templates.md#company-communicator) to send messages to your entire organization. In this case, you can use the Graph API to proactively install your app for your users. Cache the necessary values from the `conversationUpdate` event your app receives upon installation.
-You can only install apps that are in your organizational app catalog or the Teams app store.
+You can only install apps that are in your organizational app catalog or the Teams App Store.
-See [Install apps for users](/graph/api/userteamwork-post-installedapps) in the Graph documentation and [Proactive bot installation and messaging in Teams with Microsoft Graph](../../../graph-api/proactive-bots-and-messages/graph-proactive-bots-and-messages.md). There is also a [Microsoft .NET framework sample](https://github.com/microsoftgraph/contoso-airlines-teams-sample/blob/283523d45f5ce416111dfc34b8e49728b5012739/project/Models/GraphService.cs#L176) on the GitHub platform.
+See [install apps for users](/graph/api/userteamwork-post-installedapps) in the Graph documentation and [proactive bot installation and messaging in Teams with Graph](../../../graph-api/proactive-bots-and-messages/graph-proactive-bots-and-messages.md). There is also a [Microsoft .NET framework sample](https://github.com/microsoftgraph/contoso-airlines-teams-sample/blob/283523d45f5ce416111dfc34b8e49728b5012739/project/Models/GraphService.cs#L176) on the GitHub platform.
-## Examples
+## Samples
-# [C#/.NET](#tab/dotnet)
+The following code shows a simple code sample that proactively installs your app using Graph:
+
+# [C#](#tab/dotnet)
```csharp [Route("api/notify")]
public class NotifyController : ControllerBase
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```javascript
POST /v3/conversations
} ```
-You must supply the user ID and the tenant ID. If the call succeeds, the API returns with the following response object.
+You must supply the user ID and the tenant ID. If the call succeeds, the API returns the following response object:
```json {
You must supply the user ID and the tenant ID. If the call succeeds, the API ret
-## Code samples
+## Code sample
-The official proactive messaging samples are as follows:
+The following table provides a simple code sample that incorporate basic conversation flow into a Teams application and how to create a new conversation thread in a channel in Teams:
-| Sample Name | Description | .NET | JavaScript | Python |
+| Sample name | Description | .NET | Node.js | Python |
|:-|:|:--|:-|:--|
-|Teams Conversation Basics | Demonstrates basics of conversations in Teams, including sending one-to-one proactive messages.|[.NET&nbsp;Core](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/csharp_dotnetcore/57.teams-conversation-bot)|[JavaScript](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/57.teams-conversation-bot) | [Python](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/python/57.teams-conversation-bot)|
-|Start new thread in a channel | Demonstrates creating a new thread in a channel. |[.NET&nbsp;Core](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/csharp_dotnetcore/58.teams-start-new-thread-in-channel)|[JavaScript](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/javascript_nodejs/58.teams-start-new-thread-in-channel)|[Python](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/python/58.teams-start-thread-in-channel) |
+|Teams conversation basics | Demonstrates basics of conversations in Teams, including sending one-to-one proactive messages.|[View](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/csharp_dotnetcore/57.teams-conversation-bot)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/57.teams-conversation-bot) | [View](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/python/57.teams-conversation-bot)|
+|Start new thread in a channel | Demonstrates creating a new thread in a channel. |[View](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/csharp_dotnetcore/58.teams-start-new-thread-in-channel)|[View](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/javascript_nodejs/58.teams-start-new-thread-in-channel)|[View](https://github.com/microsoft/BotBuilder-Samples/blob/master/samples/python/58.teams-start-thread-in-channel) |
+
+### Additional code sample
+
+> [!div class="nextstepaction"]
+> [Teams proactive messaging code samples](/samples/officedev/msteams-samples-proactive-messaging/msteams-samples-proactive-messaging/)
+
+## Next step
-## View additional code samples
->
> [!div class="nextstepaction"]
-> [**Teams proactive messaging code samples**](/samples/officedev/msteams-samples-proactive-messaging/msteams-samples-proactive-messaging/)
->
+> [Format your bot messages](~/bots/how-to/format-your-bot-messages.md)
platform Subscribe To Conversation Events https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/conversations/subscribe-to-conversation-events.md
Title: Subscribe to conversation events
+ Title: Conversation events
-description: How to subscribe to conversation events from your Microsoft Teams bot.
-
+description: How to work with conversation events from your Microsoft Teams bot.
+
-# Subscribe to conversation events
+
+# Conversation events in your Teams bot
[!INCLUDE [pre-release-label](~/includes/v4-to-v3-pointer-bots.md)]
-Microsoft Teams sends notifications to your bot for events that happen in scopes where your bot is active. You can capture these events in your code and take action on them, such as the following:
+When building your conversational bots for Microsoft Teams, you can work with conversation events. Teams sends notifications to your bot for conversation events that happen in scopes where your bot is active. You can capture these events in your code and take the following actions:
-* Trigger a welcome message when your bot is added to a team
-* Trigger a welcome message when a new team member is added or removed
-* Trigger a notification when a channel is created, renamed or deleted
-* When a bot message is liked by a user
+* Trigger a welcome message when your bot is added to a team.
+* Trigger a welcome message when a new team member is added or removed.
+* Trigger a notification when a channel is created, renamed, or deleted.
+* When a bot message is liked by a user.
## Conversation update events
-> [!Important]
-> New events can be added at any time, and your bot will begin to receive them.
-> You must design for the possibility of receiving unexpected events.
-> If you are using the Bot Framework SDK, your bot will automatically respond with a `200 - OK` to any events you do not choose to handle.
+You can use conversation update events to provide better notifications and more effective bot actions.
+
+> [!IMPORTANT]
+> * You can add new events any time and your bot begins to receive them.
+> * You must design your bot to receive unexpected events.
+> * If you are using the Bot Framework SDK, your bot automatically responds with a `200 - OK` to any events you choose not to handle.
+
+A bot receives a `conversationUpdate` event in either of the following cases:
-A bot receives a `conversationUpdate` event when it has been added to a conversation, other members have been added to or removed from a conversation, or conversation metadata has changed.
+* When bot has been added to a conversation.
+* Other members are added to or removed from a conversation.
+* Conversation metadata has changed.
-The `conversationUpdate` event is sent to your bot when it receives information on membership updates for teams where it has been added. It also receives an update when it has been added for the first time specifically for personal conversations.
+The `conversationUpdate` event is sent to your bot when it receives information on membership updates for teams where it has been added. It also receives an update when it has been added for the first time for personal conversations.
-The following table shows a list of Teams conversation update events, with links to more details.
+The following table shows a list of Teams conversation update events with more details:
-| Action Taken | EventType | Method Called | Description | Scope |
+| Action taken | EventType | Method called | Description | Scope |
| - | -- | -- | -- | -- |
-| channel created | channelCreated | OnTeamsChannelCreatedAsync | [A channel was created](#channel-created) | Team |
-| channel renamed | channelRenamed | OnTeamsChannelRenamedAsync | [A channel was renamed](#channel-renamed) | Team |
-| channel deleted | channelDeleted | OnTeamsChannelDeletedAsync | [A channel was deleted](#channel-deleted) | Team |
-| channel restored | channelRestored | OnTeamsChannelRestoredAsync | [A channel was restored](#channel-deleted) | Team |
-| members added | membersAdded | OnTeamsMembersAddedAsync | [A member added](#team-members-added) | All |
-| members removed | membersRemoved | OnTeamsMembersRemovedAsync | [A member was removed](#team-members-removed) | groupChat & team |
-| team renamed | teamRenamed | OnTeamsTeamRenamedAsync | [A Team was renamed](#team-renamed) | Team |
-| team deleted | teamDeleted | OnTeamsTeamDeletedAsync | [A Team was deleted](#team-deleted) | Team |
-| team archived | teamArchived | OnTeamsTeamArchivedAsync | [A Team was archived](#team-archived) | Team |
-| team unarchived | teamUnarchived | OnTeamsTeamUnarchivedAsync | [A Team was unarchived](#team-unarchived) | Team |
-| team restored | teamRestored | OnTeamsTeamRestoredAsync | [A Team was restored](#team-restored) | Team |
+| Channel created | channelCreated | OnTeamsChannelCreatedAsync | [A channel is created](#channel-created). | Team |
+| Channel renamed | channelRenamed | OnTeamsChannelRenamedAsync | [A channel is renamed](#channel-renamed). | Team |
+| Channel deleted | channelDeleted | OnTeamsChannelDeletedAsync | [A channel is deleted](#channel-deleted). | Team |
+| Channel restored | channelRestored | OnTeamsChannelRestoredAsync | [A channel is restored](#channel-deleted). | Team |
+| Members added | membersAdded | OnTeamsMembersAddedAsync | [A member is added](#team-members-added). | All |
+| Members removed | membersRemoved | OnTeamsMembersRemovedAsync | [A member is removed](#team-members-removed). | groupChat and team |
+| Team renamed | teamRenamed | OnTeamsTeamRenamedAsync | [A team is renamed](#team-renamed). | Team |
+| Team deleted | teamDeleted | OnTeamsTeamDeletedAsync | [A team is deleted](#team-deleted). | Team |
+| Team archived | teamArchived | OnTeamsTeamArchivedAsync | [A team is archived](#team-archived). | Team |
+| Team unarchived | teamUnarchived | OnTeamsTeamUnarchivedAsync | [A team is unarchived](#team-unarchived). | Team |
+| Team restored | teamRestored | OnTeamsTeamRestoredAsync | [A team is restored](#team-restored) | Team |
### Channel created
-The channel created event is sent to your bot whenever a new channel is created in a team your bot is installed in.
+The channel created event is sent to your bot whenever a new channel is created in a team where your bot is installed.
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of channel created event:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsChannelCreatedAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsChannelCreatedAsync(ChannelInfo channelInfo
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
<!-- From sample: botbuilder-js\libraries\botbuilder\tests\teams\conversationUpdate\src\conversationUpdateBot.ts -->
async def on_teams_channel_created(
### Channel renamed
-The channel renamed event is sent to your bot whenever a channel is renamed in a team your bot is installed in.
+The channel renamed event is sent to your bot whenever a channel is renamed in a team where your bot is installed.
+
+The following code shows an example of channel renamed event:
-# [C#/.NET](#tab/dotnet)
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsChannelRenamedAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsChannelRenamedAsync(ChannelInfo channelInfo
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def on_teams_channel_renamed(
* * *
-### Channel Deleted
+### Channel deleted
-The channel deleted event is sent to your bot whenever a channel is deleted in a team your bot is installed in.
+The channel deleted event is sent to your bot whenever a channel is deleted in a team where your bot is installed.
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of channel deleted event:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsChannelDeletedAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsChannelDeletedAsync(ChannelInfo channelInfo
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def on_teams_channel_deleted(
### Channel restored
-The channel restored event is sent to your bot whenever a channel that was previously deleted is restored in a team that your bot is already installed in.
+The channel restored event is sent to your bot whenever a channel that was previously deleted is restored in a team where your bot is already installed.
+
+The following code shows an example of channel restored event:
-# [C#/.NET](#tab/dotnet)
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsChannelRestoredAsync(ChannelInfo channelInfo, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsChannelRestoredAsync(ChannelInfo channelInf
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
<!-- From sample: botbuilder-js\libraries\botbuilder\tests\teams\conversationUpdate\src\conversationUpdateBot.ts -->
async def on_teams_channel_restored(
### Team members added
-The `teamMemberAdded` event is sent to your bot the first time it is added to a conversation and every time a new user is added to a team or group chat that your bot is installed in. The user information (ID) is unique for your bot and can be cached for future use by your service (such as sending a message to a specific user).
+The `teamMemberAdded` event is sent to your bot the first time it is added to a conversation. The event is sent to your bot every time a new user is added to a team or group chat where your bot is installed. The user information that is ID is unique for your bot and can be cached for future use by your service, such as sending a message to a specific user.
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of team members added event:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsMembersAddedAsync(IList<TeamsChannelAccount> teamsMembersAdded , TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsMembersAddedAsync(IList<TeamsChannelAccount
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
export class MyBot extends TeamsActivityHandler {
# [JSON](#tab/json)
-This is the message your bot will receive when the bot is added **to a team**.
+This is the message your bot receives when the bot is added to a team.
```json {
This is the message your bot will receive when the bot is added **to a team**.
} ```
-This is the message your bot will receive when the bot is added **to a one-to-one chat*.
+This is the message your bot receives when the bot is added to a one-to-one chat.
```json {
async def on_teams_members_added(
### Team members removed
-The `teamMemberRemoved` event is sent to your bot if it is removed from a team and every time any user is removed from a team that your bot is a member of. You can determine if the new member removed was the bot itself or a user by looking at the `Activity` object of the `turnContext`. If the `Id` field of the `MembersRemoved` object is the same as the `Id` field of the `Recipient` object, then the member removed is the bot, otherwise, it is a user. The bot's `Id` will generally be: `28:<MicrosoftAppId>`
+The `teamMemberRemoved` event is sent to your bot if it is removed from a team. The event is sent to your bot every time any user is removed from a team where your bot is a member. To determine if the new member removed was the bot itself or a user, check the `Activity` object of the `turnContext`. If the `Id` field of the `MembersRemoved` object is the same as the `Id` field of the `Recipient` object, then the member removed is the bot, else it is a user. The bot's `Id` generally is `28:<MicrosoftAppId>`.
+
+> [!NOTE]
+> When a user is permanently deleted from a tenant, `membersRemoved conversationUpdate` event is triggered.
-[!Note] When a user is permanently deleted from a tenant, `membersRemoved conversationUpdate` event is triggered.
+The following code shows an example of team members removed event:
-# [C#/.NET](#tab/dotnet)
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsMembersRemovedAsync(IList<ChannelAccount> membersRemoved, TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsMembersRemovedAsync(IList<ChannelAccount> m
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript
async def on_teams_members_removed(
Your bot is notified when the team it is in has been renamed. It receives a `conversationUpdate` event with `eventType.teamRenamed` in the `channelData` object.
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of team renamed event:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsTeamRenamedAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsTeamRenamedAsync(TeamInfo teamInfo, ITurnCo
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def on_teams_team_renamed(
Your bot is notified when the team it is in has been deleted. It receives a `conversationUpdate` event with `eventType.teamDeleted` in the `channelData` object.
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of team deleted event:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsTeamDeletedAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsTeamDeletedAsync(TeamInfo teamInfo, ITurnCo
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def on_teams_team_deleted(
### Team restored
-The bot receives a notification when the team is restored from deletion. The bot receives a `conversationUpdate` event with `eventType.teamrestored` in the `channelData` object.
+The bot receives a notification when a team is restored after being deleted. It receives a `conversationUpdate` event with `eventType.teamrestored` in the `channelData` object.
+
+The following code shows an example of team restored event:
-# [C#/.NET](#tab/dotnet)
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsTeamrestoredAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsTeamrestoredAsync(TeamInfo teamInfo, ITurnC
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def on_teams_team_restored(
The bot receives a notification when the team it is installed in is archived. It receives a `conversationUpdate` event with `eventType.teamarchived` in the `channelData` object.
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of team archived event:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsTeamArchivedAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsTeamArchivedAsync(TeamInfo teamInfo, ITurnC
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def on_teams_team_archived(
The bot receives a notification when the team it is installed in is unarchived. It receives a `conversationUpdate` event with `eventType.teamUnarchived` in the `channelData` object.
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of team unarchived event:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnTeamsTeamUnarchivedAsync(TeamInfo teamInfo, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnTeamsTeamUnarchivedAsync(TeamInfo teamInfo, ITur
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def on_teams_team_unarchived(
* * *
+Now that you have worked with the conversation update events, you can understand the message reaction events that occur for different reactions to a message.
+ ## Message reaction events
-The `messageReaction` event is sent when a user adds or removes reactions to a message which was sent by your bot. The `replyToId` contains the ID of the specific message, and the `Type` is the type of reaction in text format. The types of reactions include: "angry", "heart", "laugh", "like", "Sad", "surprised". This event does not contain the contents of the original message, so if processing reactions to your messages is important for your bot you'll need to store the messages when you send them.
+The `messageReaction` event is sent when a user adds or removes reactions to a message which was sent by your bot. The `replyToId` contains the ID of the message, and the `Type` is the type of reaction in text format. The types of reactions include angry, heart, laugh, like, sad, and surprised. This event does not contain the contents of the original message. If processing reactions to your messages is important for your bot, you must store the messages when you send them. The following table provides more information about the event type and payload objects:
| EventType | Payload object | Description | Scope | | | - | -- | -- |
-| messageReaction | reactionsAdded | [Reaction to bot message](#reactions-to-a-bot-message) | All |
-| messageReaction | reactionsRemoved | [Reaction removed from bot message](#reactions-removed-from-bot-message) | All |
+| messageReaction | reactionsAdded | [Reactions to a bot message](#reactions-to-a-bot-message) | All |
+| messageReaction | reactionsRemoved | [Reactions removed from bot message](#reactions-removed-from-bot-message) | All |
### Reactions to a bot message
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of reactions to a bot message:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnReactionsAddedAsync(IList<MessageReaction> messageReactions, ITurnContext<IMessageReactionActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnReactionsAddedAsync(IList<MessageReaction> messa
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
<!-- Verify -->
async def on_reactions_added(
### Reactions removed from bot message
-# [C#/.NET](#tab/dotnet)
+The following code shows an example of reactions removed from bot message:
+
+# [C#](#tab/dotnet)
```csharp protected override async Task OnReactionsRemovedAsync(IList<MessageReaction> messageReactions, ITurnContext<IMessageReactionActivity> turnContext, CancellationToken cancellationToken)
protected override async Task OnReactionsRemovedAsync(IList<MessageReaction> mes
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
<!-- Verify -->
async def on_reactions_removed(
* * *
-## Samples
-
-For sample code showing the bots conversation events, see:
+## Code sample
-[Microsoft Teams bots conversation events sample](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/57.teams-conversation-bot)
+The following table provides a simple code sample that incorporates bots conversation events into a Teams application:
+| Sample | Description | .NET Core |
+|--|- ||
+| Teams bots conversation events sample | Bot Framework v4 conversation bot sample for Teams. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/57.teams-conversation-bot)|
+## Next step
+> [!div class="nextstepaction"]
+> [Send proactive messages](~/bots/how-to/conversations/send-proactive-messages.md)
platform Create A Bot Commands Menu https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/create-a-bot-commands-menu.md
Title: Create a command menu for your bot description: How to create a command menu for your Microsoft Teams bot-+ + # Bot command menus [!INCLUDE [pre-release-label](~/includes/v4-to-v3-pointer-bots.md)] > [!Note]
-> Bot menus won't appear on mobile clients.
+> Bot menus do not appear on mobile clients.
-Add command menu for your bot allows you to define a set of core commands your bot can always respond to. The list of commands is presented to the user above the compose message area when they are conversing with your bot. Selecting a command from the list will insert the command string into the compose message box, then all users need to do is select **Send**.
+To define a set of core commands that your bot can respond to, you can add a command menu with a drop-down list of commands for your bot. The list of commands is presented to the users in the compose message area when they are in conversation with your bot. Select a command from the list to insert the command string into the compose message box and select **Send**.
![Bot command menu](./conversations/media/bot-menu-sample.png) ## Create a command menu for your bot
-Command menus are defined in your app manifest. You can either use App Studio to help you create them, or add them manually.
+Command menus are defined in your app manifest. You can either use **App Studio** to create them or add them manually in the app manifest.
+
+### Create a command menu for your bot using App Studio
-### Creating a command menu for your bot using App Studio
+A prerequisite to create a command menu for your bot is that you must edit an existing app manifest. The steps to add a command menu are the same, whether you create a new manifest or edit an existing one.
-The instructions here assume that you'll be editing an existing app manifest. The steps for adding a command menu are the same, whether you're creating a new manifest or editing an existing one.
+**To create a command menu for your bot using App Studio**
-1. Open App Studio from the ... overflow menu on the left navigation rail. If you don't have App Studio available you can download it. See [Installing App Studio](https://aka.ms/teams-app-studio#installing-app-studio) for more information on using App Studio.
+1. Open Teams and select **Apps** from the left pane. In the **Apps** page, search of **App Studio**, and select **Open**.
+ > [!NOTE]
+ > If you do not have **App Studio**, you can download it. For more information, see [installing App Studio](~/concepts/build-and-test/app-studio-overview.md#installing-app-studio).
![App Studio](./conversations/media/AppStudio.png)
-2. Once in App Studio, select the **Manifest editor** tab.
+2. In **App Studio**, select the **Manifest editor** tab. If you do not have an existing app package, you can create or import an existing app. For more information, see [update an app package](~/tutorials/get-started-dotnet-app-studio.md#use-app-studio-to-update-the-app-package).
-3. In the left column of the manifest editor view in the **Capabilities** section, select **Bots**.
+3. In the left pane of the **Manifest editor** and in the **Capabilities** section, select **Bots**.
-4. In the right column of the manifest editor view in the **Commands** section, select the **Add** button.
+4. In the right pane of the **Manifest editor** and in the **Commands** section, select **Add**. The **New Command** screen appears.
- ![App Studio Command Menu Add button](./conversations/media/AppStudio-CommandMenu-Add.png)
+ ![App Studio commands menu Add button](./conversations/media/AppStudio-CommandMenu-Add.png)
-5. The **New Command** screen appears. Enter the **Command text** that you want to have appear as the menu command, and the **Help text** that you want to have appear directly under the command text in the menu. This should be a brief explanation of the purpose of the command.
+5. Enter the **Command text** that must appear as the command menu for your bot.
-6. Next, select the scope(s) where you want this command menu to appear, then select the **Save** button.
+6. Enter the **Help text** that must appear under the command text in the menu. **Help text** must be a brief explanation of the purpose of the command.
- ![App Studio Command Menu Add button](./conversations/media/AppStudio-NewCommandMenu.png)
+7. Select the **Scope** check boxes to select where this command menu must appear, and select **Save**.
-### Creating a command menu for your bot by editing **Manifest.json**
+ ![App Studio new commands menu button](./conversations/media/AppStudio-NewCommandMenu.png)
-Another valid approach for creating a command menu is to create it directly in the manifest file while developing your bot source code. Here are a few things to keep in mind when using this approach:
+### Create a command menu for your bot by editing Manifest.json
-1. Each menu supports up to 10 commands.
+Another way to create a command menu is to create it directly in the manifest file while developing your bot source code. To use this method, follow these points:
-2. You can create a single command menu that will work in all scopes.
+* Each menu supports up to ten commands.
+* Create a single command menu that works in all scopes.
+* Create a different command menu for each scope.
-3. You can create a different command menu for each scope
+#### Manifest example for single menu for both scopes
-#### Manifest example - single menu for both scopes
+The manifest example code for single menu for both scopes is as follows:
```json {
Another valid approach for creating a command menu is to create it directly in t
} ```
-#### Manifest example - menu for each scope
+#### Manifest example for the menu for each scope
+
+The manifest example code for the menu for each scope is as follows:
```json {
Another valid approach for creating a command menu is to create it directly in t
} ```
-## Handling menu commands in your bot code
+You must handle menu commands in your bot code as you handle any message from users. You can handle menu commands in your bot code by parsing out the **\@Mention** portion of the message text.
+
+## Handle menu commands in your bot code
+
+Bots in a group or channel respond only when they are mentioned `@botname` in a message. Every message received by a bot when in a group or channel scope contains its name in the message text returned. Before handling the command being returned, your message parsing must handle the message received by a bot with its name.
-Bots in a group or channel respond only when they are mentioned ("@botname") in a message. As a result, every message received by a bot when in a group or channel scope will contain its own name in the message text returned. You need to ensure your message parsing handles that before handling the command being returned.
+> [!NOTE]
+> To handle the commands in code, they are sent to your bot as a regular message. You must handle them as you would handle any other message from your users. The commands in code insert pre-configured text into the text box. The user must then send that text as they do for any other message.
-> **Note** For handling the commands in code, they are sent to your bot as a regular message. So you need to handle them as you would do for any other message from your users. They are purely a UI treatment that inserts pre-configured text into the text box. The user must then send that text as they would do for any other message.
+# [C#](#tab/dotnet)
-# [C#/.NET](#tab/dotnet)
+You can parse out the **\@Mention** portion of the message text using a static method provided with the Microsoft Bot Framework. It is a method of the `Activity` class named `RemoveRecipientMention`.
-You can parse out the **\@Mention** portion of the message text using a static method provided with the Microsoft Bot Framework ΓÇö a method of the `Activity` class named `RemoveRecipientMention`.
+The C# code to parse out the **\@Mention** portion of the message text is as follows:
```csharp var modifiedText = turnContext.Activity.RemoveRecipientMention(); ```
-# [JavaScript/Node.js](#tab/javascript)
+# [JavaScript](#tab/javascript)
-You can parse out the **\@Mention** portion of the message text using a static method provided with the Microsoft Bot Framework ΓÇö a method of the `TurnContext` class named `removeMentionText`.
+You can parse out the **\@Mention** portion of the message text using a static method provided with the Bot Framework. It is a method of the `TurnContext` class named `removeMentionText`.
+
+The JavaScript code to parse out the **\@Mention** portion of the message text is as follows:
```javascript const modifiedText = TurnContext.removeMentionText(turnContext.activity, turnContext.activity.recipient.id);
const modifiedText = TurnContext.removeMentionText(turnContext.activity, turnCon
# [Python](#tab/python)
+You can parse out the **@Mention** portion of the message text using a static method provided with the Bot Framework. It is a method of the `TurnContext` class named `remove_recipient_mention`.
-You can parse out the **@Mention** portion of the message text using a static method provided with the Microsoft Bot Framework ΓÇö a method of the `TurnContext` class named `remove_recipient_mention`.
+The Python code to parse out the **\@Mention** portion of the message text is as follows:
```python modified_text = TurnContext.remove_recipient_mention(turn_context.activity)
modified_text = TurnContext.remove_recipient_mention(turn_context.activity)
* * *
+To enable smooth functioning of your bot code, there are few best practices that you must follow.
+ ## Command menu best practices
-* **Keep it simple**: The bot menu is meant to present the key capabilities of your bot.
-* **Keep it short**: Menu options shouldnΓÇÖt be extremely long and complex natural language statements ΓÇö they should be simple commands.
-* **Keep it invokable**: Bot menu actions/commands should always be available, regardless of the state of the conversation or the dialog the bot is in.
+Following are the command menu best practices:
+
+* Keep it simple: The bot menu is meant to present the key capabilities of your bot.
+* Keep it short: Menu options must not be long and must not be complex natural language statements. They must be simple commands.
+* Keep it invokable: Bot menu actions or commands must always be available, regardless of the state of the conversation or the dialog the bot is in.
+
+> [!NOTE]
+> If you remove any commands from your manifest, you must redeploy your app to implement the changes. In general, any changes to the manifest require you to redeploy your app.
+
+## Next step
-> **Note** If you remove any commands from your manifest, you will need to redeploy your app for the changes to take effect. In general, any changes to the manifest require this.
+> [!div class="nextstepaction"]
+> [Channel and group conversations](~/bots/how-to/conversations/channel-and-group-conversations.md)
platform Format Your Bot Messages https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/format-your-bot-messages.md
Title: Format your bot messages description: Add rich formatting to your bot messages-+ # Format your bot messages
-You can set the optional [`TextFormat`](/bot-framework/dotnet/bot-builder-dotnet-create-messages#customizing-a-message) property to control how your message's text content is rendered.
+Message formatting enables you to bring out the best in bot messages. You can format your bot messages to include rich cards that are attachments that contain interactive elements, such as buttons, text, images, audio, video, and so on.
+
+## Format text content
+
+To format your bot messages, you can set the optional [`TextFormat`](/bot-framework/dotnet/bot-builder-dotnet-create-messages#customizing-a-message) property to control how your bot message's text content is rendered.
Microsoft Teams supports the following formatting options:
-| TextFormat value | Description |
+| `TextFormat` value | Description |
| | |
-| plain | The text should be treated as raw text with no formatting applied.|
-| markdown | The text should be treated as Markdown formatting and rendered on the channel as appropriate. *See* [Formatting text content](#formatting-text-content) for supported styles. |
-| xml | The text is simple XML markup. *See* [Formatting text content](#formatting-text-content) for supported styles. |
+| plain | The text must be treated as raw text with no formatting applied.|
+| markdown | The text must be treated as markdown formatting and rendered on the channel as appropriate. |
+| xml | The text is simple XML markup. |
-## Formatting text content
+Teams supports a subset of markdown and XML or HTML formatting tags.
-Microsoft Teams supports a subset of Markdown and XML (HTML) formatting tags.
+Currently, the following limitations apply to formatting:
-Currently, the following limitations apply:
-
-* Text-only messages don't support table formatting.
+* Text-only messages do not support table formatting.
* Rich cards support formatting in the text property only, not in the title or subtitle properties.
-* Rich cards don't support Markdown or table formatting.
+* Rich cards do not support markdown or table formatting.
+
+After you format text content, ensure that your formatting works across all platforms supported by Microsoft Teams.
## Cross-platform support
-To ensure that your formatting works across all platforms supported by Microsoft Teams, be aware that some styles are not currently supported across all platforms.
+Some styles are currently not supported across all platforms. The following table provides a list of styles and which of these styles are supported in text-only messages and rich cards:
-| Style | Text-only messages | Rich cards (XML only) |
+| Style | Text-only messages | Rich cards - XML only |
| | :: | :: |
-| bold | Γ£ö | Γ£û |
-| italic | Γ£ö | Γ£ö |
-| header (levels 1&ndash;3) | Γ£û | Γ£ö |
-| strikethrough | Γ£û | Γ£ö |
-| horizontal rule | Γ£û | Γ£û |
-| unordered list | Γ£û | Γ£ö |
-| ordered list | Γ£û | Γ£ö |
-| preformatted text | Γ£ö | Γ£ö |
-| blockquote | Γ£ö | Γ£ö |
-| hyperlink | Γ£ö | Γ£ö |
-| image link | Γ£ö | Γ£û |
+| Bold | Γ£ö | Γ£û |
+| Italic | Γ£ö | Γ£ö |
+| Header (levels 1&ndash;3) | Γ£û | Γ£ö |
+| Strikethrough | Γ£û | Γ£ö |
+| Horizontal rule | Γ£û | Γ£û |
+| Unordered list | Γ£û | Γ£ö |
+| Ordered list | Γ£û | Γ£ö |
+| Preformatted text | Γ£ö | Γ£ö |
+| Blockquote | Γ£ö | Γ£ö |
+| Hyperlink | Γ£ö | Γ£ö |
+| Image link | Γ£ö | Γ£û |
+
+After checking cross-platform support, ensure that support by individual platforms is also available.
## Support by individual platform
-Support for text formatting varies by type of message and by platform.
+Support for text formatting varies by type of message and platform.
### Text-only messages
+The following table provides a list of styles and which of these styles are supported on desktop, iOS, and Android:
+ | Style | Desktop | iOS | Android | | | :: | :: | :: |
-| bold | Γ£ö | Γ£ö | Γ£ö |
-| italic | Γ£ö | Γ£ö | Γ£ö |
-| header (levels 1&ndash;3) | Γ£û | Γ£û | Γ£û |
-| strikethrough | Γ£ö | Γ£ö | Γ£û |
-| horizontal rule | Γ£û | Γ£û | Γ£û |
-| unordered list | Γ£ö | Γ£û | Γ£û |
-| ordered list | Γ£ö | Γ£û | Γ£û |
-| preformatted text | Γ£ö | Γ£ö | Γ£ö |
-| blockquote | Γ£ö | Γ£ö | Γ£ö |
-| hyperlink | Γ£ö | Γ£ö | Γ£ö |
-| image link | Γ£ö | Γ£ö | Γ£ö |
+| Bold | Γ£ö | Γ£ö | Γ£ö |
+| Italic | Γ£ö | Γ£ö | Γ£ö |
+| Header (levels 1&ndash;3) | Γ£û | Γ£û | Γ£û |
+| Strikethrough | Γ£ö | Γ£ö | Γ£û |
+| Horizontal rule | Γ£û | Γ£û | Γ£û |
+| Unordered list | Γ£ö | Γ£û | Γ£û |
+| Ordered list | Γ£ö | Γ£û | Γ£û |
+| Preformatted text | Γ£ö | Γ£ö | Γ£ö |
+| Blockquote | Γ£ö | Γ£ö | Γ£ö |
+| Hyperlink | Γ£ö | Γ£ö | Γ£ö |
+| Image link | Γ£ö | Γ£ö | Γ£ö |
### Cards
-See [Card Formatting](~/task-modules-and-cards/cards/cards-format.md) for support in cards.
+For card support, see [card formatting](~/task-modules-and-cards/cards/cards-format.md).
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Update and delete bot messages](~/bots/how-to/update-and-delete-bot-messages.md)
platform Get Teams Context https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/get-teams-context.md
Title: Get Team's specific context for your bot
+ Title: Get Teams specific context for your bot
description: How to get Microsoft Team's specific context for your bot, including the conversation roster, details, and channel list.-+
-# Get Team's specific context for your bot
+# Get Teams specific context for your bot
[!INCLUDE [pre-release-label](~/includes/v4-to-v3-pointer-bots.md)]
-A bot can access additional context data about a team or chat it is installed in. This information can be used to enrich the bot's functionality and provide a more personalized experience.
+A bot can access additional context data about a team or chat where it is installed. This information can be used to enrich the bot's functionality and provide a more personalized experience.
-## Fetching the roster or user profile
+## Fetch the roster or user profile
-Your bot can query for the list of members and their basic profiles, including Teams user IDs and Azure Active Directory (Azure AD) information such as name and objectId. You can use this information to correlate user identities, e.g., to check whether a user, logged into a tab through Azure AD credentials, is a member of the team. The sample code below uses the paged endpoint for retrieving the roster. For get conversation members, minimum or maximum page size depends on the implementation. Page size less than 50, are treated as 50, and page size greater than 500, are capped at 500. Although you may still use the non-paged version, it will be unreliable in large teams and should not be used. *See* [Changes to Teams Bot APIs for Fetching Team/Chat Members](~/resources/team-chat-member-api-changes.md) for additional information.
+Your bot can query for the list of members and their basic user profiles, including Teams user IDs and Azure Active Directory (AAD) information, such as name and objectId. You can use this information to correlate user identities. For example, to check whether a user logged into a tab through AAD credentials, is a member of the team. For get conversation members, minimum or maximum page size depends on the implementation. Page size less than 50, are treated as 50, and greater than 500, are capped at 500. Even if you use the non-paged version, it is unreliable in large teams and must not be used. For more information, see [changes to Teams Bot APIs for fetching team or chat members](~/resources/team-chat-member-api-changes.md).
-# [C#/.NET](#tab/dotnet)
+The following sample code uses the paged endpoint for fetching the roster:
+
+# [C#](#tab/dotnet)
```csharp public class MyBot : TeamsActivityHandler
public class MyBot : TeamsActivityHandler
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def _show_members(
# [JSON](#tab/json)
-You can directly issue a GET request on `/v3/conversations/{conversationId}/pagedmembers?pageSize={pageSize}&continuationToken={continuationToken}`, using the value of `serviceUrl` as the endpoint. The value of `serviceUrl` tends to be stable but can change. When a new message arrives, your bot should verify its stored value for `serviceUrl`. The response payload will also indicate if the user is a regular or anonymous user.
+You can directly issue a GET request on `/v3/conversations/{conversationId}/pagedmembers?pageSize={pageSize}&continuationToken={continuationToken}`, using the value of `serviceUrl` as the endpoint. The value of `serviceUrl` is stable but can change. When a new message arrives, your bot must verify its stored value for `serviceUrl`. The response payload also indicates if the user is a regular or anonymous user.
```http GET /v3/conversations/19:meeting_N2QzYTA3YmItYmMwOC00OTJmLThkYzMtZWMzZGU0NGIyZGI0@thread.v2/pagedmembers?pageSize=100&continuationToken=asdfasdfalkdsjfalksjdf
Response body
* * *
+After you fetch the roster or user profile, you can get details of a single member. Currently, to retrieve information for one or more members of a chat or team, use the Microsoft Teams bot APIs `TeamsInfo.GetMembersAsync` for C# or `TeamsInfo.getMembers` for TypeScript APIs.
+ ## Get single member details
-You can also retrieve the details of a particular user using their Teams user Id, UPN, or AAD Object Id.
+You can also retrieve the details of a particular user using their Teams user ID, UPN, or AAD Object ID.
+
+The following sample code is used to get single member details:
-# [C#/.NET](#tab/dotnet)
+# [C#](#tab/dotnet)
```csharp public class MyBot : TeamsActivityHandler
public class MyBot : TeamsActivityHandler
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def _show_members(
# [JSON](#tab/json)
-You can directly issue a GET request on `/v3/conversations/{conversationId}/members/{userId}`, using the value of `serviceUrl` as the endpoint. The value of `serviceUrl` tends to be stable but can change. When a new message arrives, your bot should verify its stored value for `serviceUrl`. This can be used for regular users and anonymous users.
+You can directly issue a GET request on `/v3/conversations/{conversationId}/members/{userId}`, using the value of `serviceUrl` as the endpoint. The value of `serviceUrl` is stable but can change. When a new message arrives, your bot must verify its stored value for `serviceUrl`. This can be used for regular users and anonymous users.
-Below is a response sample for regular user
+The following is the response sample for regular user:
```http GET /v3/conversations/19:ja0cu120i1jod12j@skype.net/members/29:1GcS4EyB_oSI8A88XmWBN7NJFyMqe3QGnJdgLfFGkJnVelzRGos0bPbpsfJjcbAD22bmKc4GMbrY2g4JDrrA8vM06X1-cHHle4zOE6U4ttcc
Response body
} ```
-Below is response for anonymous user
+The following is the response sample for anonymous user:
```http GET /v3/conversations/19:ja0cu120i1jod12j@skype.net/members/<anonymous user id>"
Response body
* * *
+After you get details of a single member, you can get details of the team. Currently, to retrieve information for a team, use the Microsoft Teams bot APIs `TeamsInfo.GetMemberDetailsAsync` for C# or `TeamsInfo.getTeamDetails` for TypeScript.
+ ## Get team's details
-When installed in a team, your bot can query for metadata about that team including the Azure AD groupId.
+When installed in a team, your bot can query for metadata about that team including the AAD group ID.
+
+The following sample code is used to get team's details:
-# [C#/.NET](#tab/dotnet)
+# [C#](#tab/dotnet)
```csharp public class MyBot : TeamsActivityHandler
public class MyBot : TeamsActivityHandler
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def _show_details(self, turn_context: TurnContext):
# [JSON](#tab/json)
-You can directly issue a GET request on `/v3/teams/{teamId}`, using the value of `serviceUrl` as the endpoint. The value of `serviceUrl` tends to be stable but can change. When a new message arrives, your bot should verify its stored value for `serviceUrl`.
+You can directly issue a GET request on `/v3/teams/{teamId}`, using the value of `serviceUrl` as the endpoint. The value of `serviceUrl` is stable but can change. When a new message arrives, your bot must verify its stored value for `serviceUrl`.
```http GET /v3/teams/19:ja0cu120i1jod12j@skype.net
Response body
* * *
+After you get details of the team, you can get the list of channels in a team. Currently, to retrieve information for a list of channels in a team, use the Microsoft Teams bot APIs `TeamsInfo.GetTeamChannelsAsync` for C# or `TeamsInfo.getTeamChannels` for TypeScript APIs.
+ ## Get the list of channels in a team Your bot can query the list of channels in a team. > [!NOTE]
->
->* The name of the default General channel is returned as `null` to allow for localization.
->* The channel ID for the General channel always matches the team ID.
+> * The name of the default General channel is returned as `null` to allow for localization.
+> * The channel ID for the General channel always matches the team ID.
+
+The following sample code is used to get the list of channels in a team:
-# [C#/.NET](#tab/dotnet)
+# [C#](#tab/dotnet)
```csharp public class MyBot : TeamsActivityHandler
public class MyBot : TeamsActivityHandler
} ```
-# [TypeScript/Node.js](#tab/typescript)
+# [TypeScript](#tab/typescript)
```typescript export class MyBot extends TeamsActivityHandler {
async def _show_channels(
# [JSON](#tab/json)
-You can directly issue a GET request on `/v3/teams/{teamId}/conversations`, using the value of `serviceUrl` as the endpoint. The value of `serviceUrl` tends to be stable but can change. When a new message arrives, your bot should verify its stored value for `serviceUrl`.
+You can directly issue a GET request on `/v3/teams/{teamId}/conversations`, using the value of `serviceUrl` as the endpoint. The value of `serviceUrl` is stable but can change. When a new message arrives, your bot must verify its stored value for `serviceUrl`.
```http GET /v3/teams/19%3A033451497ea84fcc83d17ed7fb08a1b6%40thread.skype/conversations
Response body
* * * [!INCLUDE [sample](~/includes/bots/teams-bot-samples.md)]+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Send and receive files through the bot](~/bots/how-to/bots-filesv4.md)
platform Rate Limit https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/rate-limit.md
Title: Rate limiting
+ Title: Optimize your bot with rate limiting in Teams
description: Rate limiting and best practices in Microsoft Teams+ keywords: teams bots rate limiting
-# Optimize your bot: rate limiting and best practices in Microsoft Teams
+# Optimize your bot with rate limiting in Teams
-As a general principle, your application should limit the number of messages it posts to an individual chat or channel conversation. This ensures an optimal experience that doesn't feel ΓÇ£spammyΓÇ¥ to your end users.
+Rate limiting is a method to limit messages to a certain maximum frequency. As a general principle, your application must limit the number of messages it posts to an individual chat or channel conversation. This ensures an optimal experience and messages do not appear as spam to your users.
-To protect Microsoft Teams and its users, the bot APIs rate-limit incoming requests. Apps that go over this limit receive an `HTTP 429 Too Many Requests` error status. All requests are subject to the same rate-limiting policy, including sending messages, channel enumerations, and roster fetches.
+To protect Microsoft Teams and its users, the bot APIs provide a rate limit for incoming requests. Apps that go over this limit receive an `HTTP 429 Too Many Requests` error status. All requests are subject to the same rate limiting policy, including sending messages, channel enumerations, and roster fetches.
-Because the exact values of rate limits are subject to change, we recommend your application implement the appropriate backoff behavior when the API returns `HTTP 429 Too Many Requests`.
+As the exact values of rate limits are subject to change, your application must implement the appropriate backoff behavior when the API returns `HTTP 429 Too Many Requests`.
-## Handling rate limits
+## Handle rate limits
When issuing a Bot Builder SDK operation, you can handle `Microsoft.Rest.HttpOperationException` and check for the status code.
+The following code shows an example of handling rate limits:
+ ```csharp try {
catch (HttpOperationException ex)
} ```
-## Best practices
+After you handle rate limits for bots, you can handle `HTTP 429` responses using an exponential backoff.
+
+## Handle `HTTP 429` responses
-In general, you should take simple precautions to avoid receiving `HTTP 429` responses. For instance, avoid issuing multiple requests to the same personal or channel conversation. Instead, consider batching the API requests.
+In general, you must take simple precautions to avoid receiving `HTTP 429` responses. For example, avoid issuing multiple requests to the same personal or channel conversation. Instead, create a batch of the API requests.
-Using an exponential backoff with a random jitter is the recommended way to handle 429s. This ensures that multiple requests don't introduce collisions on retries.
+Using an exponential backoff with a random jitter is the recommended way to handle 429s. This ensures that multiple requests do not introduce collisions on retries.
-## Example: detecting transient exceptions
+After you handle `HTTP 429` responses, you can go through the example for detecting transient exceptions.
-Here is a sample using exponential backoff via the Transient Fault Handling Application Block.
+## Detect transient exceptions example
-You can perform backoff and retries using [Transient Fault Handling](/previous-versions/msp-n-p/hh675232%28v%3dpandp.10%29). For guidelines on obtaining and installing the NuGet package, see [Adding the Transient Fault Handling Application Block to Your Solution](/previous-versions/msp-n-p/dn440719(v=pandp.60)?redirectedfrom=MSDN)). *See also* [Transient fault handling](/azure/architecture/best-practices/transient-faults).
+The following code shows an example of using exponential backoff using the transient fault handling application block:
```csharp public class BotSdkTransientExceptionDetectionStrategy : ITransientErrorDetectionStrategy
public class BotSdkTransientExceptionDetectionStrategy : ITransientErrorDetectio
} ```
-## Example: backoff
+You can perform backoff and retries using [transient fault handling](/previous-versions/msp-n-p/hh675232%28v%3dpandp.10%29). For guidelines on obtaining and installing the NuGet package, see [adding the transient fault handling application block to your solution](/previous-versions/msp-n-p/dn440719(v=pandp.60)?redirectedfrom=MSDN). See also [transient fault handling](/azure/architecture/best-practices/transient-faults).
+
+After you go through the example for detecting transient exceptions, go through the exponential backoff example. You can use exponential backoff instead of retrying on failures.
+
+## Backoff example
In addition to detecting rate limits, you can also perform an exponential backoff.
+The following code shows an example of exponential backoff:
+ ```csharp /** * The first parameter specifies the number of retries before failing the operation.
var retryPolicy = new RetryPolicy(new BotSdkTransientExceptionDetectionStrategy(
await retryPolicy.ExecuteAsync(() => connector.Conversations.ReplyToActivityAsync( (Activity)reply) ).ConfigureAwait(false); ```
-You can also perform a `System.Action` method execution with the retry policy described above. The referenced library also allows you to specify a fixed interval or a linear backoff mechanism.
+You can also perform a `System.Action` method execution with the retry policy described in this section. The referenced library also allows you to specify a fixed interval or a linear backoff mechanism.
-We recommend storing the value and strategy in a configuration file to fine-tune and tweak values at run time.
+Store the value and strategy in a configuration file to fine-tune and tweak values at run time.
-For more information, check out this handy guide on various retry patterns: [Retry pattern](/azure/architecture/patterns/retry).
+For more information, see [retry patterns](/azure/architecture/patterns/retry).
+
+You can also handle rate limit using the per bot per thread limit.
## Per bot per thread limit >[!NOTE]
->Message splitting at the service level will result in higher than expected requests per second (RPS). If you're concerned about approaching the limits, you should implement the backoff strategy described above. The values provided below are for estimation only.
+> Message splitting at the service level results in higher than expected requests per second (RPS). If you are concerned about approaching the limits, you must implement the [backoff strategy](#backoff-example). The values provided in this section are for estimation only.
+
+The per bot per thread limit controls the traffic that a bot is allowed to generate on a single conversation. A conversation here is 1:1 between bot and user, a group chat, or a channel in a team.
-This limit controls the traffic that a bot is allowed to generate on a single conversation. A conversation here is 1:1 between bot and user, a group-chat, or a channel in a team.
+The following table provides the per bot per thread limits:
-| **Scenario** | **Time-period (sec)** | **Max allowed operations** |
+| Scenario | Time period in seconds | Maximum allowed operations |
| | | |
-| Send to Conversation | 1 | 7 |
-| Send to Conversation | 2 | 8 |
-| Send to Conversation | 30 | 60 |
-| Send to Conversation | 3600 | 1800 |
-| Create Conversation | 1 | 7 |
-| Create Conversation | 2 | 8 |
-| Create Conversation | 30 | 60 |
-| Create Conversation | 3600 | 1800 |
-| Get Conversation Members| 1 | 14 |
-| Get Conversation Members| 2 | 16 |
-| Get Conversation Members| 30 | 120 |
-| Get Conversation Members| 3600 | 3600 |
-| Get Conversations | 1 | 14 |
-| Get Conversations | 2 | 16 |
-| Get Conversations | 30 | 120 |
-| Get Conversations | 3600 | 3600 |
+| Send to conversation | 1 | 7 |
+| Send to conversation | 2 | 8 |
+| Send to conversation | 30 | 60 |
+| Send to conversation | 3600 | 1800 |
+| Create conversation | 1 | 7 |
+| Create conversation | 2 | 8 |
+| Create conversation | 30 | 60 |
+| Create conversation | 3600 | 1800 |
+| Get conversation members| 1 | 14 |
+| Get conversation members| 2 | 16 |
+| Get conversation members| 30 | 120 |
+| Get conversation members| 3600 | 3600 |
+| Get conversations | 1 | 14 |
+| Get conversations | 2 | 16 |
+| Get conversations | 30 | 120 |
+| Get conversations | 3600 | 3600 |
>[!NOTE]
-> Previous versions of `TeamsInfo.getMembers` and `TeamsInfo.GetMembersAsync` APIs are being deprecated. They will be throttled to 5 requests per minute and return a maximum of 10K members per team. To update your Bot Framework SDK and the code to use the latest paginated API endpoints, see [Bot API changes for team and chat members](../../resources/team-chat-member-api-changes.md).
+> Previous versions of `TeamsInfo.getMembers` and `TeamsInfo.GetMembersAsync` APIs are being deprecated. They are throttled to five requests per minute and return a maximum of 10K members per team. To update your Bot Framework SDK and the code to use the latest paginated API endpoints, see [Bot API changes for team and chat members](../../resources/team-chat-member-api-changes.md).
+
+You can also handle rate limit using the per thread limit for all bots.
## Per thread limit for all bots
-This limit controls the traffic that all bots are allowed to generate across a single conversation. A conversation here is 1:1 between bot and user, a group-chat, or a channel in a team.
+The per thread limit for all bots controls the traffic that all bots are allowed to generate across a single conversation. A conversation here is 1:1 between bot and user, a group chat, or a channel in a team.
-| **Scenario** | **Time-period (sec)** | **Max allowed operations** |
+The following table provides the per thread limit for all bots:
+
+| Scenario | Time period in seconds | Maximum allowed operations |
| | | |
-| Send to Conversation | 1 | 14 |
-| Send to Conversation | 2 | 16 |
-| Create Conversation | 1 | 14 |
-| Create Conversation | 2 | 16 |
-| CreateConversation| 1 | 14 |
-| CreateConversation| 2 | 16 |
-| Get Conversation Members| 1 | 28 |
-| Get Conversation Members| 2 | 32 |
-| Get Conversations | 1 | 28 |
-| Get Conversations | 2 | 32 |
+| Send to conversation | 1 | 14 |
+| Send to conversation | 2 | 16 |
+| Create conversation | 1 | 14 |
+| Create conversation | 2 | 16 |
+| Create conversation| 1 | 14 |
+| Create conversation| 2 | 16 |
+| Get conversation members| 1 | 28 |
+| Get conversation members| 2 | 32 |
+| Get conversations | 1 | 28 |
+| Get conversations | 2 | 32 |
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Calls and meetings bots](~/bots/calls-and-meetings/calls-meetings-bots-overview.md)
+
platform Update And Delete Bot Messages https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/how-to/update-and-delete-bot-messages.md
[!INCLUDE [pre-release-label](~/includes/v4-to-v3-pointer-bots.md)]
+Your bot can dynamically update messages after sending them instead of having them as static snapshots of data. Messages can also be deleted using the Bot Framework's `DeleteActivity` method.
+ ## Update messages
-Your bot can dynamically update messages after sending them. You can use dynamic message updates for scenarios such as poll updates, modifying available actions after a button press, or any other asynchronous state change.
+You can use dynamic message updates for scenarios, such as poll updates, modifying available actions after a button press, or any other asynchronous state change.
-The new message need not match the original in type. For example, if the original message contained an attachment, the new message can be a simple text message.
+It is not necessary for the new message to match the original in type. For example, if the original message contains an attachment, the new message can be a simple text message.
# [C#](#tab/dotnet)
-To update an existing message, pass a new `Activity` object with the existing activity ID to the `UpdateActivityAsync` method of the `TurnContext` class. See [TurnContextClass](/dotnet/api/microsoft.bot.builder.turncontext?view=botbuilder-dotnet-stable&preserve-view=true).
+To update an existing message, pass a new `Activity` object with the existing activity ID to the `UpdateActivityAsync` method of the `TurnContext` class. For more information, see [TurnContextClass](/dotnet/api/microsoft.bot.builder.turncontext?view=botbuilder-dotnet-stable&preserve-view=true).
```csharp var newActivity = MessageFactory.Text("The new text for the activity");
await turnContext.UpdateActivityAsync(newActivity, cancellationToken);
# [TypeScript](#tab/typescript)
-To update an existing message, pass a new `Activity` object with the existing activity ID to the `updateActivity` method of the `TurnContext` object. See [updateActivity](/javascript/api/botbuilder-core/turncontext?view=botbuilder-ts-latest#updateactivity-partial-activity--&preserve-view=true).
+To update an existing message, pass a new `Activity` object with the existing activity ID to the `updateActivity` method of the `TurnContext` object. For more information, see [updateActivity](/javascript/api/botbuilder-core/turncontext?view=botbuilder-ts-latest#updateactivity-partial-activity--&preserve-view=true).
```typescript const newActivity = MessageFactory.text('The new text for the activity');
await turnContext.updateActivity(newActivity);
# [Python](#tab/python)
-To update an existing message, pass a new `Activity` object with the existing activity ID to the `update_activity` method of the `TurnContext` class. See [TurnContextClass](/python/api/botbuilder-core/botbuilder.core.turncontext?view=botbuilder-py-latest&preserve-view=true).
+To update an existing message, pass a new `Activity` object with the existing activity ID to the `update_activity` method of the `TurnContext` class. For more information, see [TurnContextClass](/python/api/botbuilder-core/botbuilder.core.turncontext?view=botbuilder-py-latest&preserve-view=true).
```python
update_result = await context.update_activity(new_activity)
# [REST API](#tab/rest)
->[!NOTE]
->You can develop Teams apps in any web programming technology and directly call the [Bot Connector service REST APIs](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0&preserve-view=true). To do so, you need to implement [Authentication](/azure/bot-service/rest-api/bot-framework-rest-connector-authentication?view=azure-bot-service-4.0&preserve-view=true) security procedures with your API requests.
+> [!NOTE]
+> You can develop Teams apps in any web programming technology and directly call the [bot connector service REST APIs](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0&preserve-view=true). To do this, you must implement [authentication](/azure/bot-service/rest-api/bot-framework-rest-connector-authentication?view=azure-bot-service-4.0&preserve-view=true) security procedures with your API requests.
-To update an existing activity within a conversation, include the `conversationId` and `activityId` in the request endpoint. To complete this scenario, you must cache the activity ID returned by the original POST call.
+To update an existing activity within a conversation, include the `conversationId` and `activityId` in the request endpoint. To complete this scenario, you must cache the activity ID returned by the original post call.
```http PUT /v3/conversations/{conversationId}/activities/{activityId} ```
-|Request |Response |
+|Request body | Returns |
|-|-|
-|An [Activity](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#activity-object&preserve-view=true) object |A [ResourceResponse](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#resourceresponse-object&preserve-view=true) object |
+| An [activity](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#activity-object&preserve-view=true) object | A [ResourceResponse](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#resourceresponse-object&preserve-view=true) object |
+* * *
+
+Now that you have updated messages, update the existing card on button selection for incoming activities.
## Update cards
To update the existing card on button selection, you can use `ReplyToId` of inco
# [C#](#tab/dotnet)
-To update existing card on a button click, pass a new `Activity` object with updated card and `ReplyToId` as activity ID to the `UpdateActivityAsync` method of the `TurnContext` class. See [TurnContextClass](/dotnet/api/microsoft.bot.builder.turncontext?view=botbuilder-dotnet-stable&preserve-view=true).
+To update existing card on a button selection, pass a new `Activity` object with updated card and `ReplyToId` as activity ID to the `UpdateActivityAsync` method of the `TurnContext` class. See [TurnContextClass](/dotnet/api/microsoft.bot.builder.turncontext?view=botbuilder-dotnet-stable&preserve-view=true).
+ ```csharp var activity = MessageFactory.Attachment(card.ToAttachment()); activity.Id = turnContext.Activity.ReplyToId;
await turnContext.UpdateActivityAsync(activity, cancellationToken);
# [TypeScript](#tab/typescript)
+To update existing card on a button selection, pass a new `Activity` object with updated card and `replyToId` as activity ID to the `updateActivity` method of the `TurnContext` object. See [updateActivity](/javascript/api/botbuilder-core/turncontext?view=botbuilder-ts-latest#updateactivity-partial-activity--&preserve-view=true).
-To update existing card on a button click, pass a new `Activity` object with updated card and `replyToId` as activity ID to the `updateActivity` method of the `TurnContext` object. See [updateActivity](/javascript/api/botbuilder-core/turncontext?view=botbuilder-ts-latest#updateactivity-partial-activity--&preserve-view=true).
```typescript const message = MessageFactory.attachment(card); message.id = context.activity.replyToId;
await context.updateActivity(message);
# [Python](#tab/python)
-To update existing card on a button click, pass a new `Activity` object with updated card and `reply_to_id` as activity ID to the `update_activity` method of the `TurnContext` class. See [TurnContextClass](/python/api/botbuilder-core/botbuilder.core.turncontext?view=botbuilder-py-latest&preserve-view=true).
+To update existing card on a button selection, pass a new `Activity` object with updated card and `reply_to_id` as activity ID to the `update_activity` method of the `TurnContext` class. See [TurnContextClass](/python/api/botbuilder-core/botbuilder.core.turncontext?view=botbuilder-py-latest&preserve-view=true).
```python updated_activity = MessageFactory.attachment(CardFactory.hero_card(card))
await turn_context.update_activity(updated_activity)
# [REST API](#tab/rest)
+> [!NOTE]
+> You can develop Teams apps in any web programming technology and directly call the [bot connector service REST APIs](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0&preserve-view=true). To do this, you must implement [authentication](/azure/bot-service/rest-api/bot-framework-rest-connector-authentication?view=azure-bot-service-4.0&preserve-view=true) security procedures with your API requests.
+ To update an existing activity within a conversation, include the `conversationId` and `activityId` in the request endpoint. To complete this scenario, you must cache the activity ID returned by the original post call. ```http
PUT /v3/conversations/{conversationId}/activities/{activityId}
|Request |Response | |-|-|
-| An [Activity](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#activity-object&preserve-view=true) object. | A [ResourceResponse](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#resourceresponse-object&preserve-view=true) object. |
+| An [activity](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#activity-object&preserve-view=true) object. | A [ResourceResponse](/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0#resourceresponse-object&preserve-view=true) object. |
-
+* * *
+
+Now that you have updated cards, you can delete messages using the Bot Framework.
## Delete messages
-In the Bot Framework, every message has its own unique activity identifier.
-Messages can be deleted using the Bot Framework's `DeleteActivity` method as shown here.
+In the Bot Framework, every message has its unique activity identifier. Messages can be deleted using the Bot Framework's `DeleteActivity` method.
# [C#](#tab/dotnet)
-To delete that message, pass that activity's ID to the `DeleteActivityAsync` method of the `TurnContext` class. See [TurnContext.DeleteActivityAsync Method](/dotnet/api/microsoft.bot.builder.turncontext.deleteactivityasync?view=botbuilder-dotnet-stable&preserve-view=true).
+To delete a message, pass that activity's ID to the `DeleteActivityAsync` method of the `TurnContext` class. For more information, see [TurnContext.DeleteActivityAsync Method](/dotnet/api/microsoft.bot.builder.turncontext.deleteactivityasync?view=botbuilder-dotnet-stable&preserve-view=true).
```csharp foreach (var activityId in _list)
foreach (var activityId in _list)
# [TypeScript](#tab/typescript)
-To delete that message, pass that activity's ID to the `deleteActivity` method of the `TurnContext` object. See [deleteActivity](/javascript/api/botbuilder-core/turncontext?view=botbuilder-ts-latest#deleteactivity-stringpartial-conversationreference--&preserve-view=true).
+To delete a message, pass that activity's ID to the `deleteActivity` method of the `TurnContext` object. For more information, see [deleteActivity](/javascript/api/botbuilder-core/turncontext?view=botbuilder-ts-latest#deleteactivity-stringpartial-conversationreference--&preserve-view=true).
```typescript for (let i = 0; i < activityIds.length; i++) {
for (let i = 0; i < activityIds.length; i++) {
# [Python](#tab/python)
-To delete that message, pass that activity's ID to the `delete_activity` method of the `TurnContext` object. See [activity-update-and-delete](https://github.com/microsoft/botbuilder-python/blob/c04ecacb22c1f4b43a671fe2f1e4782218391975/tests/teams/scenarios/activity-update-and-delete/bots/activity_update_and_delete_bot.py).
+To delete that message, pass that activity's ID to the `delete_activity` method of the `TurnContext` object. For more information, see [activity-update-and-delete](https://github.com/microsoft/botbuilder-python/blob/c04ecacb22c1f4b43a671fe2f1e4782218391975/tests/teams/scenarios/activity-update-and-delete/bots/activity_update_and_delete_bot.py).
```python for each activity_id in _list:
DELETE /v3/conversations/{conversationId}/activities/{activityId}
-## Code samples
+## Code sample
-The official conversation basics are as follows:
+The following code sample demonstrates basics of conversations:
| Sample name | Description | .NET | Node.js | Python | |:-|:|:--|:-|:--|
-|Teams Conversation Basics | Demonstrates basics of conversations in Teams, including message update and delete.|[View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/57.teams-conversation-bot)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/57.teams-conversation-bot) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/57.teams-conversation-bot)|
+|Teams conversation basics | Demonstrates basics of conversations in Teams, including message update and delete.|[View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/57.teams-conversation-bot)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/57.teams-conversation-bot) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/57.teams-conversation-bot)|
+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Get Teams context](~/bots/how-to/get-teams-context.md)
+
platform What Are Bots https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/bots/what-are-bots.md
Title: What are conversational bots?
+ Title: Bots in Microsoft Teams
-description: An overview of conversational bots in Microsoft Teams.
+description: An overview of bots in Microsoft Teams.
-# What are conversational bots in Microsoft Teams?
+# Bots in Microsoft Teams
-Conversational bots allow users to interact with your web service through text, interactive cards, and task modules. They're incredibly flexible ΓÇö conversational bots can be scoped to handling a few simple commands or complex, artificial-intelligence-powered and natural-language-processing virtual assistants. They can be one aspect of a larger application, or completely stand-alone.
+A bot also referred to as a chatbot or conversational bot is an app that runs simple and repetitive automated tasks performed by the users, such as customer service or support staff. Examples of bots in everyday use include, bots that provide information about the weather, make dinner reservations, or provide travel information. A bot interaction can be a quick question and answer, or it can be a complex conversation that provides access to services.
-The GIF below shows a user conversing with a bot in a one-to-one chat using both text and interactive cards. Finding the right mix of cards, text, and task modules is key to creating a useful bot. Don't forget, bots are much more than just text!
+> [!VIDEO https://www.youtube-nocookie.com/embed/zSIysk0yL0Q]
-![FAQ Plus gif](~/assets/images/FAQPlusEndUser.gif)
+Conversational bots allow users to interact with your web service through text, interactive cards, and task modules.
-## Build a bot for Teams with the Microsoft Bot Framework
+![Invoke bot using text](~/assets/images/invokebotwithtext.png)
-The [Microsoft Bot Framework](https://dev.botframework.com/) is a rich SDK for building bots using C#, Java, Python, and JavaScript. If you already have a bot that's based on the Bot Framework, you can easily adapt it to work in Microsoft Teams. We recommend you use either C# or Node.js to take advantage of our [SDKs](/microsoftteams/platform/#pivot=sdk-tools). These packages extend the basic Bot Builder SDK classes and methods as follows:
+![Invoke bot using card](~/assets/images/invokebotwithcard.png)
-* Use specialized card types like the Office 365 Connector card.
-* Consume and set Teams-specific channel data on activities.
-* Process messaging extension requests.
+<img src="~/assets/images/task-module-example.png" alt="Invoke bot using task module" width="400"/>
-Your Teams bot consists of three elements:
+Conversational bots are incredibly flexible and can be scoped to handle a few simple commands, or complex, artificial-intelligence-powered, and natural-language-processing tasks. They can be one aspect of a larger application, or be completely stand-alone.
-* A publicly accessible web service that you host.
-* Your bot registration with the Bot Framework.
-* Your Teams app package with your app manifest. This is what your users will install and connects the Teams client to your web service, routed through the Bot Service.
+Finding the right mix of cards, text, and task modules are key to create a useful bot. The following image shows a user conversing with a bot in a one-to-one chat using both, text and interactive cards:
-> [!IMPORTANT]
-> You can develop Teams apps in any web-programming technology and call the [Bot Framework REST APIs](/bot-framework/rest-api/bot-framework-rest-overview) directly, but you must perform all token handling yourself.
-> [!TIP]
-> Teams App Studio* helps you create and configure your app manifest, and can register your web service as a bot on the Bot Framework. It also contains a React control library and an interactive card builder. *See* [Getting started with Teams App Studio](~/concepts/build-and-test/app-studio-overview.md).
+Every interaction between the user and the bot is represented as an activity. When a bot receives an activity, it passes it on to its activity handlers. For more information, see [bot activity handlers](~/bots/bot-basics.md).
-## Create a chatbot for Teams with Microsoft Power Virtual Agents
+In addition, bots are apps that have a conversational interface. You can interact with a bot using text, interactive cards, and speech. A bot behaves differently depending on whether the conversation is a channel or group chat conversation, or it is a one-to-one conversation. Conversations are handled through the Bot Framework connector. For more information, see [conversation basics](~/bots/how-to/conversations/conversation-basics.md).
-[Power Virtual Agents](/power-virtual-agents/fundamentals-what-is-power-virtual-agents) is a chatbot service, built on the Microsoft Power platform and Bot Framework. The Power Virtual Agent development process uses a guided, no-code, graphical interface approach to empower every member of your team to easily create and maintain an intelligent virtual agent. Once you have completed creating your chatbot in the [Power Virtual Agents portal](https://powervirtualagents.microsoft.com), you can easily [integrate your Power Virtual Agents chatbot with Teams](how-to/add-power-virtual-agents-bot-to-teams.md). To get started creating your Power Virtual Agents chatbot, *see* the [Power Virtual Agents documentation](https://docs.microsoft.com/power-virtual-agents/).
+Your bot requires contextual information, such as user profile details to access relevant content and enhance the bot experience. For more information, see [get Teams context](~/bots/how-to/get-teams-context.md).
-## Webhooks and connectors
+You can also send and receive files through the bot using Graph APIs or Teams bot APIs. For more information, see [send and receive files through the bot](~/bots/how-to/bots-filesv4.md).
-Webhooks and connectors allow you to create a simple bot for basic interaction, like kicking off a workflow or other simple commands. They live only in the team in which you create them and are intended for simple processes specific to your company's workflow. *See* [What are webhooks and connectors?](~/webhooks-and-connectors/what-are-webhooks-and-connectors.md) for more information.
+In addition, rate limiting is used to optimize bots used for your Teams application. To protect Microsoft Teams and its users, the bot APIs provide a rate limit for incoming requests. For more information, see [optimize your bot with rate limiting in Teams](~/bots/how-to/rate-limit.md).
-## Where bots work best
+With Microsoft Graph APIs for calls and online meetings, Microsoft Teams apps can now interact with users using voice and video. For more information, see [calls and meetings bots](~/bots/calls-and-meetings/calls-meetings-bots-overview.md).
-Bots in Microsoft Teams can be part of a one-to-one conversation, a group chat, or a channel in a Team. Each scope will provide unique opportunities, and challenges, for your conversational bot.
+You can use the Teams bot APIs to get information for one or more members of a chat or team. For more information, see [changes to Teams bot APIs for fetching team or chat members](~/resources/team-chat-member-api-changes.md).
-### In a channel
-
-Channels contain threaded conversations between multiple people ΓÇö potentially lots of people (currently, up to two thousand). This potentially gives your bot massive reach, but individual interactions need to be concise. Traditional multi-turn interactions probably won't work well. Instead, look to use interactive cards or task modules, or potentially move the conversation to a one-to-one conversation if you need to collect lots of information. Your bot will also only have access to messages where it's `@mentioned` directly, although you can retrieve additional messages from the conversation using Microsoft Graph and elevated organization-level permissions.
-
-Some scenarios where bots excel in a channel include:
-
-* **Notifications**, particularly if you provide an interactive card for users to take additional information.
-* **Feedback scenarios** like polls and surveys.
-* Interactions that can be resolved in a **single request/response cycle**, where the results are useful for multiple members of the conversation.
-* **Social/fun bots** ΓÇö get an awesome cat image, randomly pick a winner, etc.
-
-### In a group chat
-
-Group chats are non-threaded conversations between three or more people. They tend to have fewer members than a channel, and are more transient. Similar to a channel, your bot will only have access to messages where it's `@mentioned` directly.
-
-Scenarios that work well in a channel will usually work just as well in a group chat.
-
-### In a one-to-one chat
-
-This is the traditional way for a conversational bot to interact with a user. They can enable incredibly diverse workloads. Q&A bots, bots that initiate workflows in other systems, bots that tell jokes, and bots that take notes are just a few examples. Just remember to consider whether a conversation-based interface is the best way to present your functionality.
-
-## Bot fails
-
-### Having multi-turn experiences in chat
-
-An extensive dialog between your bot and the user is a slow and overly complex way to get a task completed and it also requires the developer to maintain state. To exit this state a user must either time-out or type ΓÇ£*Cancel*ΓÇ¥. Above all, the process is unnecessarily tedious:
-
-USER: Schedule a meeting with Megan.
-
-BOT: IΓÇÖve found 200 results, please include a first and last name.
-
-USER: Schedule a meeting with Megan Bowen.
-
-BOT: OK, what time would you like to meet with Megan Bowen?
-
-USER: 1:00 pm.
-
-BOT: On which day?
-
-### Supporting too many commands
-
-A bot that supports excessive commands, especially a broad range of commands, will not be successful or viewed positively by users. Since there are only 6 visible commands in the current bot menu, anything more is unlikely to be used with any frequency. Bots that go deep into a specific area rather than trying to be a broad assistant will work and fare better.
-
-### Maintaining a large retrieval knowledge base with unranked responses
-
-Bots are best suited for short, quick interactions, not sifting through long lists looking for an answer.
-
-## Get started
-
-* [Teams conversation bot in C#/dotnet](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/57.teams-conversation-bot)
-* [Teams conversation bot in JavaScript](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/57.teams-conversation-bot)
-
-## Learn more
+## See also
> [!div class="nextstepaction"]
-> [The basics of bots in Teams](~/bots/bot-basics.md)
+> [Create a bot for Teams](~/bots/how-to/create-a-bot-for-teams.md)
+
+## Next step
> [!div class="nextstepaction"]
-> [Create a bot for Teams](~/bots/how-to/create-a-bot-for-teams.md)
+> [Bots and SDKs](~/bots/bot-features.md)
platform Build Messaging Extension https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/build-your-first-app/build-messaging-extension.md
# Build a messaging extension for Microsoft Teams
-There are two types of Teams app *messaging extensions*: [Search commands](../messaging-extensions/how-to/search-commands/define-search-command.md) and [action commands](../messaging-extensions/how-to/action-commands/define-action-command.md).
+There are two types of Teams *messaging extensions*: [Search commands](../messaging-extensions/how-to/search-commands/define-search-command.md) and [action commands](../messaging-extensions/how-to/action-commands/define-action-command.md).
In this lesson, you'll create a *search command* (also known as a *search-based messaging extension*), which is a shortcut for finding external content and sharing it in Teams. Users can access search commands from the [Teams compose or command box](../messaging-extensions/what-are-messaging-extensions.md).
It's important to understand that this isn't the same as a channel in Teams. In
* [Add authentication](../messaging-extensions/how-to/add-authentication.md) * [Create an action-based messaging extension](../messaging-extensions/how-to/action-commands/define-action-command.md) * [Microsoft Bot Framework](https://dev.botframework.com/)+
platform App Studio Overview https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/concepts/build-and-test/app-studio-overview.md
Each command requires a title and an ID. The command can optionally contain a de
* A user-friendly title * An optional description
+> [!NOTE]
+> To create messaging extension using app studio, see [create messaging extension using app studio](~/resources/create-messaging-extension-using-appstudio.md).
+ #### Test and Distribute Once you have finished defining your application, the Test and Distribute section allows you export your appΓÇÖs definition as a zip file which then can be shared and uploaded into the Teams client for testing. Clicking export downloads the zip file as *appname.zip* in your default download directory.
platform Test Data https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/concepts/build-and-test/test-data.md
With a Microsoft 365 developer subscription, you can use your Microsoft Teams ap
> [!NOTE] > For any tenant that you use, you must get the global administrator permissions to run the scripts.
-## Enable custom app sideloading
+### Optional step to allow upload of custom apps
+
+By default, only global admins or teams service admins can upload custom apps into the tenant app catalog. You can also enable all users to upload custom apps for their own use or to teams for testing.
+
+To enable this setting, you'll need to update the global App Setup Policy in your Teams Admin Portal.
+
+<img width="430px" src="~/assets/images/microsoft-teams-admin-center-screenshot.png" alt="Screenshot of App Setup Policy"/>
+
+## Optional step to enable custom app sideloading
Enabling custom app sideloading is optional. By default, only global admins or Teams service admins can upload custom apps into the tenant app catalog. You can also allow users to upload custom apps to Teams. For more information, see [manage app setup policies in Teams](/microsoftteams/teams-app-setup-policies).
platform Location Capability https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/concepts/device-capabilities/location-capability.md
Title: Integrate location capabilities description: How to use Teams JavaScript client SDK to leverage location capabilities keywords: location map capabilities native device permissions +
platform Qr Barcode Scanner Capability https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/concepts/device-capabilities/qr-barcode-scanner-capability.md
Title: Integrate QR or barcode scanner capability description: How to use Teams JavaScript client SDK to leverage QR or barcode scanner capability
-keywords: camera media qr code qrcode bar code barcode scanner scan capabilities native device permissions
+keywords: camera media qr code qrcode bar code barcode scanner scan capabilities native device permissions
+
microsoftTeams.media.scanBarCode((error: microsoftTeams.SdkError, decodedText: s
> [Integrate media capabilities in Teams](mobile-camera-image-permissions.md) > [!div class="nextstepaction"]
-> [Integrate location capabilities in Teams](location-capability.md)
+> [Integrate location capabilities in Teams](location-capability.md)
platform Teams Bot Samples https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/includes/bots/teams-bot-samples.md
## Teams bot samples
-For a fully working samples demonstrating some of this functionality, check out the Teams samples for Bot Framework
+For complete working samples demonstrating the functionality, see the following Teams samples for Bot Framework:
-| Sample | Description | .NET Core | JavaScript | Python |
+| Sample | Description | .NET Core | Node.js | Python |
|--|- ||||
-| Teams Conversation Bot | Messaging and conversation event handling. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/57.teams-conversation-bot)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/57.teams-conversation-bot)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/python/57.teams-conversation-bot) |
-| Authentication with OAuthPrompt| Authentication and basic messaging in Bot Framework v4. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/46.teams-auth)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/46.teams-auth)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/python/46.teams-auth) |
-|Teams File Upload | Exchanging files with a bot in a one-to-one conversation. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/56.teams-file-upload) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/56.teams-file-upload) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/python/56.teams-file-upload) |
-| Task Module | Demonstrating how to retrieve a Task Module and values from cards in it, for a Messaging Extension. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/54.teams-task-module) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/54.teams-task-module) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/54.teams-task-module) |
-| Start new thread in a channel | Demonstrating how to create a new thread in a channel. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/58.teams-start-new-thread-in-channel) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/58.teams-start-new-thread-in-channel) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/58.teams-start-thread-in-channel) |
+| Teams conversation bot | Messaging and conversation event handling. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/57.teams-conversation-bot)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/57.teams-conversation-bot)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/python/57.teams-conversation-bot) |
+| Authentication with OAuthPrompt| Authentication and basic messaging in Bot Framework v4. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/46.teams-auth)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/46.teams-auth)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/python/46.teams-auth) |
+|Teams file upload | Exchanging files with a bot in a one-to-one conversation. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/56.teams-file-upload) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/56.teams-file-upload) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/python/56.teams-file-upload) |
+| Task module | Retrieving a task module and values from cards in it for a messaging extension. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/54.teams-task-module) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/54.teams-task-module) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/54.teams-task-module) |
+| Start new thread in a channel | Creating a new thread in a channel. | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/csharp_dotnetcore/58.teams-start-new-thread-in-channel) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/javascript_nodejs/58.teams-start-new-thread-in-channel) | [View](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/58.teams-start-thread-in-channel) |
platform Learn More https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/includes/messaging-extensions/learn-more.md
Try it out in a quickstart:
-* Quickstarts for C#
- * [Messaging extension with action-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)
- * [Messaging extension with search-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)
-* Quickstarts for JavaScript
- * [Messaging extension with action-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action)
- * [Messaging extension with search-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)
+| Sample Name | .NET | Node.js |
+|:|:--|:-|
+|Messaging extension with action-based commands| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action) |
+|Messaging extension with search-based commands |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)|
platform V4 To V3 Pointer Bots https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/includes/v4-to-v3-pointer-bots.md
> [!Important]
-> The code samples in this section are based on 4.6 and later versions of the Bot Framework SDK. If you're looking for documentation for earlier versions, see the [Bots - v3 SDK](~/resources/bot-v3/bots-overview.md) section in the Resources folder of the documentation.
+> The code samples in this section are based on version 4.6 and later versions of the Bot Framework SDK. If you are looking for documentation for earlier versions, see the [bots - v3 SDK](~/resources/bot-v3/bots-overview.md) section in the Resources folder of the documentation.
platform Messaging Extension Design https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/design/messaging-extension-design.md
With search commands, people can use your messaging extension to quickly find ex
#### Compose box layout options
-You have some options for displaying messaging extension search results, including [list and grid views](../../messaging-Ask about extensions/how-to/search-commands/respond-to-search.md#respond-to-user-requests).
+You have some options for displaying messaging extension search results, including [list and grid views](../../messaging-extensions/how-to/search-commands/respond-to-search.md#respond-to-user-requests).
:::image type="content" source="../../assets/images/messaging-extension/search-result-layout.png" alt-text="Illustrations showing layout options for messaging extension search results." border="false":::
The following scenarios show the primary ways people use messaging extensions.
**2. Complete the action**. Your app can receive and process any content or data sent by the message action. This allows users to remain in their conversation and, the following example, not worry about entering information directly in your app. ### Preview links
The following example is a messaging extension opened from the compose box.
:::row::: :::column span=""::: #### Do: Integrate with single-sign on
SSO makes the sign-in process easier, faster, and secure. Also, if a user has al
:::column-end::: :::column span=""::: #### Don't: Take users away from the conversation
Messaging extensions aren't always easy to find. Include screenshots of how to u
:::row::: :::column span=""::: #### Do: Let Teams handle some of the design work if possible
If it makes sense for your use cases, consider creating a search-based messaging
:::column-end::: :::column span=""::: #### Don't: Embed your entire app in a task module
If your messaging extension requires action commands, keep the task module simpl
:::row::: :::column span=""::: #### Do: Take advantage of Teams color tokens
Each Teams theme has its own color scheme. To handle theme changes automatically
:::column-end::: :::column span=""::: #### Don't: Hard code color values
If you don't use Teams color tokens, your designs will be less scalable and take
:::row::: :::column span=""::: #### Do: Include action commands that make sense in context
Message actions should relate to what a user is looking at. For example, provide
:::column-end::: :::column span=""::: #### Don't: Include actions commands that aren't contextual
platform Create Task Module https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/how-to/action-commands/create-task-module.md
[!include[v4-to-v3-SDK-pointer](~/includes/v4-to-v3-pointer-me.md)]
-If you are not populating the task module with parameters defined in the app manifest, you must create the task module for users. Use either an Adaptive Card or an embedded web view.
+You can create the task module using an Adaptive Card or an embedded web view. To create a task module, you must perform the process called the initial invoke request. This document covers
+the initial invoke request, payload activity properties when a task module is invoked from 1:1 chat, group chat, channel (new post), channel (reply to thread), and command box.
+> [!NOTE]
+> If you are not populating the task module with parameters defined in the app manifest, you must create the task module for users with either an Adaptive Card or an embedded web view.
## The initial invoke request
-Using this method your service will receive an `Activity` object of type `composeExtension/fetchTask`, and you must respond with a `task` object containing either the adaptive card or a URL to the embedded web view. Along with the standard bot activity properties, the initial invoke payload contains the following request metadata:
+In the process of the initial invoke request, your service receives an `Activity` object of type `composeExtension/fetchTask`, and you must respond with a `task` object containing either an Adaptive Card or a URL to the embedded web view. Along with the standard bot activity properties, the initial invoke payload contains the following request metadata:
|Property name|Purpose| |||
Using this method your service will receive an `Activity` object of type `compos
|`name`| Type of command that is issued to your service. It must be `composeExtension/fetchTask`. | |`from.id`| ID of the user that sent the request. | |`from.name`| Name of the user that sent the request. |
-|`from.aadObjectId`| Azure Active Directory object id of the user that sent the request. |
+|`from.aadObjectId`| Azure Active Directory object ID of the user that sent the request. |
|`channelData.tenant.id`| Azure Active Directory tenant ID. | |`channelData.channel.id`| Channel ID (if the request was made in a channel). | |`channelData.team.id`| Team ID (if the request was made in a channel). |
-|`value.commandId` | Contains the Id of the command that was invoked. |
+|`value.commandId` | Contains the ID of the command that was invoked. |
|`value.commandContext` | The context that triggered the event. It must be `compose`. | |`value.context.theme` | The user's client theme, useful for embedded web view formatting. It must be `default`, `contrast` or `dark`. |
-### Payload activity properties when invoked a task module from 1:1 chat are listed in the following section:
+### Example
+
+The code for the initial invoke request is given in the following example:
+
+```json
+{
+ "type": "invoke",
+ "id": "f:bc319b1d-571a-194d-9ffb-11d7ab37c9ff",
+ "from": {
+ "id": "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A",
+ "name": "Olo Brockhouse",
+ "aadObjectId": "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
+ }
+ "channelData": {
+ "tenant": {
+ "id": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "source": {
+ "name": "compose"
+ }
+ },
+ "value": {
+ "commandId": "Test",
+ "commandContext": "compose",
+ "requestId": "fe50f49e5c74440bb2ebf07f49e9553c",
+ "context": {
+ "theme": "default"
+ }
+ },
+ "name": "composeExtension/fetchTask"
+```
+
+## Payload activity properties when a task module is invoked from 1:1 chat
+
+The payload activity properties when a task module is invoked from 1:1 chat are listed as follows:
|Property name|Purpose| |||
Using this method your service will receive an `Activity` object of type `compos
|`name`| Type of command that is issued to your service. It must be `composeExtension/fetchTask`. | |`from.id`| ID of the user that sent the request. | |`from.name`| Name of the user that sent the request. |
-|`from.aadObjectId`| Azure Active Directory object id of the user that sent the request. |
+|`from.aadObjectId`| Azure Active Directory object ID of the user that sent the request. |
|`channelData.tenant.id`| Azure Active Directory tenant ID. | |`channelData.source.name`| The source name from where task module is invoked. | |`ChannelData.legacy. replyToId`| Gets or sets the ID of the message to which this message is a reply. |
-|`value.commandId` | Contains the Id of the command that was invoked. |
+|`value.commandId` | Contains the ID of the command that was invoked. |
|`value.commandContext` | The context that triggered the event. It must be `compose`. | |`value.context.theme` | The user's client theme, useful for embedded web view formatting. It must be `default`, `contrast` or `dark`. |
-### Payload activity properties when invoked a task module from a group chat are listed in the following section:
+### Example
+
+The payload activity properties when a task module is invoked from 1:1 chat are given in the following example:
+
+```json
+{
+ "type": "invoke",
+ "id": "f:bc319b1d-571a-194d-9ffb-11d7ab37c9ff",
+ "from": {
+ "id": "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A",
+ "name": "Olo Brockhouse",
+ "aadObjectId": "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
+ }
+ "channelData": {
+ "tenant": {
+ "id": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "source": {
+ "name": "compose"
+ }
+ },
+ "value": {
+ "commandId": "Test",
+ "commandContext": "compose",
+ "requestId": "fe50f49e5c74440bb2ebf07f49e9553c",
+ "context": {
+ "theme": "default"
+ }
+ },
+ "name": "composeExtension/fetchTask"
+}
+```
+## Payload activity properties when a task module is invoked from a group chat
+
+The payload activity properties when a task module is invoked from a group chat are listed as follows:
|Property name|Purpose| |||
Using this method your service will receive an `Activity` object of type `compos
|`name`| Type of command that is issued to your service. It must be `composeExtension/fetchTask`. | |`from.id`| ID of the user that sent the request. | |`from.name`| Name of the user that sent the request. |
-|`from.aadObjectId`| Azure Active Directory object id of the user that sent the request. |
+|`from.aadObjectId`| Azure Active Directory object ID of the user that sent the request. |
|`channelData.tenant.id`| Azure Active Directory tenant ID. | |`channelData.source.name`| The source name from where task module is invoked. | |`ChannelData.legacy. replyToId`| Gets or sets the ID of the message to which this message is a reply. |
-|`value.commandId` | Contains the Id of the command that was invoked. |
+|`value.commandId` | Contains the ID of the command that was invoked. |
|`value.commandContext` | The context that triggered the event. It must be `compose`. | |`value.context.theme` | The user's client theme, useful for embedded web view formatting. It must be `default`, `contrast` or `dark`. |
-### Payload activity properties when invoked a task module from a channel (new post) are listed in the following section:
+### Example
+
+The payload activity properties when a task module is invoked from a group chat are given in the following example:
+
+```json
+{
+ "type": "invoke",
+ "id": "f:bf72031f-a17e-f99c-48dc-5c0714950d87",
+ "from": {
+ "id": "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A",
+ "name": "Olo Brockhouse",
+ "aadObjectId": "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
+ },
+ "conversation": {
+ "isGroup": true,
+ "conversationType": "groupChat",
+ "id": "19:d77be72390a1416e9644261e9064fa00@thread.skype",
+ "tenantId": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "channelData": {
+ "tenant": {
+ "id": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "source": {
+ "name": "compose"
+ }
+ },
+ "value": {
+ "commandId": "Test",
+ "commandContext": "compose",
+ "requestId": "213167a1e3b6428b93e186ea5407c759",
+ "context": {
+ "theme": "default"
+ }
+ },
+ "name": "composeExtension/fetchTask"
+}
+```
+
+## Payload activity properties when a task module is invoked from a channel (new post)
+
+The payload activity properties when a task module is invoked from a channel (new post) are listed as follows:
|Property name|Purpose| |||
Using this method your service will receive an `Activity` object of type `compos
|`name`| Type of command that is issued to your service. It must be `composeExtension/fetchTask`. | |`from.id`| ID of the user that sent the request. | |`from.name`| Name of the user that sent the request. |
-|`from.aadObjectId`| Azure Active Directory object id of the user that sent the request. |
+|`from.aadObjectId`| Azure Active Directory object ID of the user that sent the request. |
|`channelData.tenant.id`| Azure Active Directory tenant ID. | |`channelData.channel.id`| Channel ID (if the request was made in a channel). | |`channelData.team.id`| Team ID (if the request was made in a channel). | |`channelData.source.name`| The source name from where task module is invoked. | |`ChannelData.legacy. replyToId`| Gets or sets the ID of the message to which this message is a reply. |
-|`value.commandId` | Contains the Id of the command that was invoked. |
+|`value.commandId` | Contains the ID of the command that was invoked. |
|`value.commandContext` | The context that triggered the event. It must be `compose`. |
-|`value.context.theme` | The user's client theme, useful for embedded web view formatting. It must be `default`, `contrast` or `dark`. |
+|`value.context.theme` | The user's client theme, useful for embedded web view formatting. It must be `default`, `contrast`, or `dark`. |
+
+### Example
+
+The payload activity properties when a task module is invoked from a channel (new post) are given in the following example:
+
+```json
+{
+ "type": "invoke",
+ "id": "f:a5fbb109-c989-c449-ee83-71ac99919d4b",
+ "from": {
+ "id": "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A",
+ "name": "Olo Brockhouse",
+ "aadObjectId": "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
+ },
+ "conversation": {
+ "isGroup": true,
+ "conversationType": "channel",
+ "id": "19:6decf54d86d945e4b3924b63a9161a78@thread.skype",
+ "name": "parsable",
+ "tenantId": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "channelData": {
+ "channel": {
+ "id": "19:6decf54d86d945e4b3924b63a9161a78@thread.skype"
+ },
+ "team": {
+ "id": "19:acca514e83cb497e960e0b014d405336@thread.skype"
+ },
+ "tenant": {
+ "id": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "source": {
+ "name": "compose"
+ }
+ },
+ "value": {
+ "commandId": "Test",
+ "commandContext": "compose",
+ "requestId": "5336640edc7748b28ce2df43f5b45963",
+ "context": {
+ "theme": "default"
+ }
+ },
+ "name": "composeExtension/fetchTask"
+}
+```
-### Payload activity properties when invoked a task module from a channel (reply to thread) are listed in the following section:
+## Payload activity properties when a task module is invoked from a channel (reply to thread)
+
+The payload activity properties when a task module is invoked from a channel (reply to thread) are listed as follows:
|Property name|Purpose| |||
Using this method your service will receive an `Activity` object of type `compos
|`name`| Type of command that is issued to your service. It must be `composeExtension/fetchTask`. | |`from.id`| ID of the user that sent the request. | |`from.name`| Name of the user that sent the request. |
-|`from.aadObjectId`| Azure Active Directory object id of the user that sent the request. |
+|`from.aadObjectId`| Azure Active Directory object ID of the user that sent the request. |
|`channelData.tenant.id`| Azure Active Directory tenant ID. | |`channelData.channel.id`| Channel ID (if the request was made in a channel). | |`channelData.team.id`| Team ID (if the request was made in a channel). | |`channelData.source.name`| The source name from where task module is invoked. | |`ChannelData.legacy. replyToId`| Gets or sets the ID of the message to which this message is a reply. |
-|`value.commandId` | Contains the Id of the command that was invoked. |
+|`value.commandId` | Contains the ID of the command that was invoked. |
|`value.commandContext` | The context that triggered the event. It must be `compose`. | |`value.context.theme` | The user's client theme, useful for embedded web view formatting. It must be `default`, `contrast` or `dark`. |
-### Payload activity properties when invoked a task module from a command box are listed in the following section:
+### Example
+
+The payload activity properties when a task module is invoked from a channel (reply to thread) are given in the following example:
+
+```json
+{
+ "type": "invoke",
+ "id": "f:19ccc884-c792-35ef-2f40-d0ff43dcca71",
+ "from": {
+ "id": "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A",
+ "name": "Olo Brockhouse",
+ "aadObjectId": "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
+ },
+ "conversation": {
+ "isGroup": true,
+ "conversationType": "channel",
+ "id": "19:6decf54d86d945e4b3924b63a9161a78@thread.skype;messageid=1611060744833",
+ "name": "parsable",
+ "tenantId": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "channelData": {
+ "channel": {
+ "id": "19:6decf54d86d945e4b3924b63a9161a78@thread.skype"
+ },
+ "team": {
+ "id": "19:acca514e83cb497e960e0b014d405336@thread.skype"
+ },
+ "tenant": {
+ "id": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "source": {
+ "name": "compose"
+ }
+ },
+ "value": {
+ "commandId": "TEst",
+ "commandContext": "message",
+ "requestId": "7f7d22efe5414818becebcec649a7912",
+ "messagePayload": {
+ "linkToMessage": "https://teams.microsoft.com/l/message/19:6decf54d86d945e4b3924b63a9161a78@thread.skype/1611060744833",
+ "id": "1611060744833",
+ "replyToId": null,
+ "createdDateTime": "2021-01-19T12:52:24.833Z",
+ "lastModifiedDateTime": null,
+ "deleted": false,
+ "summary": null,
+ "importance": "normal",
+ "locale": "en-us",
+ "body": {
+ "contentType": "html",
+ "content": "<div><div><at id=\"0\">Testing outgoing Webhook-Nikitha</at> - Hi</div>\n</div>"
+ },
+ "from": {
+ "device": null,
+ "conversation": null,
+ "user": {
+ "userIdentityType": "aadUser",
+ "id": "b130c271-d2eb-45f9-83ab-9eb3fe3788bc",
+ "displayName": "Olo Brockhouse"
+ },
+ "application": null
+ },
+ "reactions": [],
+ "mentions": [
+ {
+ "id": 0,
+ "mentionText": "Testing outgoing Webhook-Nikitha",
+ "mentioned": {
+ "device": null,
+ "conversation": null,
+ "user": null,
+ "application": {
+ "applicationIdentityType": "webhook",
+ "id": "b8c1c68c-e290-4bdd-81c3-266f310751dc",
+ "displayName": "Testing outgoing Webhook-Nikitha"
+ }
+ }
+ }
+ ],
+ "attachments": []
+ },
+ "context": {
+ "theme": "default"
+ }
+ },
+ "name": "composeExtension/fetchTask"
+}
+```
+
+## Payload activity properties when a task module is invoked from a command box
+
+The payload activity properties when a task module is invoked from a command box are listed as follows:
|Property name|Purpose| |||
Using this method your service will receive an `Activity` object of type `compos
|`name`| Type of command that is issued to your service. It must be `composeExtension/fetchTask`. | |`from.id`| ID of the user that sent the request. | |`from.name`| Name of the user that sent the request. |
-|`from.aadObjectId`| Azure Active Directory object id of the user that sent the request. |
+|`from.aadObjectId`| Azure Active Directory object ID of the user that sent the request. |
|`channelData.tenant.id`| Azure Active Directory tenant ID. | |`channelData.source.name`| The source name from where task module is invoked. |
-|`value.commandId` | Contains the Id of the command that was invoked. |
+|`value.commandId` | Contains the ID of the command that was invoked. |
|`value.commandContext` | The context that triggered the event. It must be `compose`. |
-|`value.context.theme` | The user's client theme, useful for embedded web view formatting. It must be `default`, `contrast` or `dark`. |
+|`value.context.theme` | The user's client theme, useful for embedded web view formatting. It must be `default`, `contrast`, or `dark`. |
+
+### Example
-### Example fetchTask request
+The payload activity properties when a task module is invoked from a command box are given in the following example:
+
+```json
+{
+ "type": "invoke",
+ "id": "f:172560f1-95f9-3189-edb2-b7612cd1a3cd",
+ "id": "29:1aBjVi5MwCFfhPIV03E5uDdfpBFXp_2Yz-sjrvVg12oavg96cqpE_DiMhOpmN9zHeZpYbJcuUEKuSDy2AYWPz1A",
+ "name": "Olo Brockhouse",
+ "aadObjectId": "b130c271-d2eb-45f9-83ab-9eb3fe3788bc"
+ },
+ "conversation": {
+ "isGroup": true,
+ "conversationType": "channel",
+ "id": "19:6decf54d86d945e4b3924b63a9161a78@thread.skype",
+ "name": "parsable",
+ "tenantId": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "channelData": {
+ "channel": {
+ "id": "19:6decf54d86d945e4b3924b63a9161a78@thread.skype"
+ },
+ "team": {
+ "id": "19:acca514e83cb497e960e0b014d405336@thread.skype"
+ },
+ "tenant": {
+ "id": "0d9b645f-597b-41f0-a2a3-ef103fbd91bb"
+ },
+ "source": {
+ "name": "compose"
+ }
+ },
+ "value": {
+ "commandId": "TEst",
+ "commandContext": "compose",
+ "requestId": "d2ce690cdc2b4920a538e75882610a30",
+ "context": {
+ "theme": "default"
+ }
+ },
+ "name": "composeExtension/fetchTask"
+}
+```
+
+### Example
+
+The following code section is an example of `fetchTask` request:
# [C#/.NET](#tab/dotnet)
class TeamsMessagingExtensionsActionPreviewBot extends TeamsActivityHandler {
## Initial invoke request from a message
-When your bot is invoked from a message rather than the compose area or the command bar, the `value` object in the initial request must contain the details of the message your messaging extension is invoked from. See the following section for the example of this object . The `reactions` and `mentions` arrays are optional, and they are not present if there are no reactions or mentions in the original message.
+When your bot is invoked from a message, the `value` object in the initial invoke request must contain the details of the message that your messaging extension is invoked from. The `reactions` and `mentions` arrays are optional, and they are not present if there are no reactions or mentions in the original message.
+The following section is an example of the `value` object:
# [C#/.NET](#tab/dotnet)
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
## Respond to the fetchTask
-Respond to the invoke request with a `task` object that contains either a `taskInfo` object with the adaptive card or web URL, or a simple string message.
+Respond to the invoke request with a `task` object that contains either a `taskInfo` object with the Adaptive Card or web URL, or a simple string message.
|Property name|Purpose| |||
The schema for the taskInfo object is:
|`url`| The URL to be opened inside of the task module as an embedded web view.| |`fallbackUrl`| If a client does not support the task module feature, this URL is opened in a browser tab. |
-### With an adaptive card
+### Respond to the fetchTask with an Adaptive Card
+
+When using an adaptive card, you must respond with a `task` object with the `value` object containing an Adaptive Card.
-When using an adaptive card, you must respond with a `task` object with the `value` object containing an adaptive card.
+#### Example
-#### Example fetchTask response with an adaptive card
+The following code section is an example to `fetchTask` response with an adaptive card:
# [C#/.NET](#tab/dotnet)
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
* * *
-### With an embedded web view
+### Create a task module with an embedded web view
-When using an embedded web view, you must respond with a `task` object with the `value` object containing the URL to the web form you'd like to load. The domains of any URL you want to load must be included in the `validDomains` array in your app's manifest. See the [task module documentation](~/task-modules-and-cards/what-are-task-modules.md) for complete information on building your embedded web view.
+When using an embedded web view, you must respond with a `task` object with the `value` object containing the URL to the web form that you want to load. The domains of any URL you want to load must be included in the `validDomains` array in your app's manifest. For more information on building your embedded web view, see the [task module documentation](~/task-modules-and-cards/what-are-task-modules.md).
# [C#/.NET](#tab/dotnet)
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
### Request to install your conversational bot
-If the app contains a conversational bot, install the bot in the conversation before loading the task module. It is useful to get additional context for the task module. Typical example for this scenario is to fetch the roster to populate a people picker control or the list of channels in a team.
+If the app contains a conversational bot, install the bot in the conversation and then load the task module. The bot is useful to get additional context for the task module. An example for this scenario is to fetch the roster to populate a people picker control or the list of channels in a team.
+
+When the messaging extension receives the `composeExtension/fetchTask` invoke, check if the bot is installed in the current context to facilitate the flow. For example, check the flow with a get roster call. If the bot is not installed, return an Adaptive Card with an action that requests the user to install the bot. The user must have the permission to install the apps in that location for checking. If the app installation is unsuccessful, the user receives a message to contact the administrator.
-When the messaging extension receives the `composeExtension/fetchTask` invoke, check if the bot is installed in the current context to facilitate the flow. For example, check the flow with a get roster call. If the bot is not installed, return an Adaptive Card with an action that requests the user to install the bot. See the action in the following example. The user must have permission to install the apps in that location for checking. If the app installation is unsuccessful, the user receives a message to contact the administrator.
+#### Example
-#### Example of the response:
+The following code section is an example of the response:
```json {
When the messaging extension receives the `composeExtension/fetchTask` invoke, c
} ```
-After the installation, the bot receives another invoke message with `name = composeExtension/submitAction`, and `value.data.msteams.justInTimeInstall = true`.
+After the installation of conversational bot, it receives another invoke message with `name = composeExtension/submitAction`, and `value.data.msteams.justInTimeInstall = true`.
-#### Example of the invoke:
+#### Example
+
+The following code section is an example of the task response to the invoke:
```json {
After the installation, the bot receives another invoke message with `name = com
The task response to the invoke must be similar to that of the installed bot.
-#### Example of just-in time installation of app with Adaptive card:
+#### Example
+
+The following code section is an example of just-in time installation of app with Adaptive card:
```csharp private static Attachment GetAdaptiveCardAttachmentFromFile(string fileName)
private static Attachment GetAdaptiveCardAttachmentFromFile(string fileName)
* * *
-## Next steps
+## Code sample
+
+| Sample Name | Description | .NET | Node.js |
+|:|:--|:|:--|
+|Teams messaging extension action| Describes how to define action commands, create task module, and respond to task module submit action. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action) |
+|Teams messaging extension search | Describes how to define search commands and respond to searches. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)|
+
+## See also
+
+> [!div class="nextstepaction"]
+> [Define action commands](~/messaging-extensions/how-to/action-commands/define-action-command.md)
+
-If you allow your users to send a response back from the task module, you must handle the submit action.
+## Next step
-* [Create and respond with a task module](~/messaging-extensions/how-to/action-commands/respond-to-task-module-submit.md)
+> [!div class="nextstepaction"]
+> [Respond to action command](~/messaging-extensions/how-to/action-commands/respond-to-task-module-submit.md)
platform Define Action Command https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/how-to/action-commands/define-action-command.md
description: An overview of messaging extension action commands
+ # Define messaging extension action commands [!include[v4-to-v3-SDK-pointer](~/includes/v4-to-v3-pointer-me.md)]
-Action commands allow you present your users with a modal popup (called a task module in Teams) to collect or display information, then process their interaction and send information back to Teams. Before creating your command you'll need to decide:
+Action commands allow you to present your users with a modal popup called a task module in Teams. The task module collects or displays information, processes the interaction and sends the information back to Teams. This document guides you on how to select action command invoke locations, create your task module, send final message, or card, create action command using app studio, or create it manually.
+
+Before creating the action command you must decide the following factors:
+
+1. [Where can the action command be triggered from?](#select-action-command-invoke-locations)
+1. [How will the task module be created?](#select-how-to-create-your-task-module)
+1. [Will the final message or card be sent to the channel from a bot, or will the message or card be inserted into the compose message area for the user to submit?](#select-how-the-final-message-is-sent)
+
+## Select action command invoke locations
+
+First, you must decide the location from where your action command must be invoked. By specifying the `context` in your app manifest, your command can be invoked from one or more of the following locations:
+
+* Compose message area: The buttons at the bottom of the compose message area.
+* Command box: By @mentioning your app in the command box.
+ > [!NOTE]
+ > If messaging extension is invoked from the command box, you cannot respond with a bot message inserted directly into the conversation.
+
+* Message: Directly from an existing message through the `...` overflow menu on a message.
+ > [!NOTE]
+ > The initial invoke to your bot includes a JSON object containing the message from which it was invoked. You can process the message before presenting them with a task module.
+
+The following image displays the locations from where action command is invoked:
+
+![action command invoke locations](~/assets/images/messaging-extension-invoke-locations.png)
+
+## Select how to create your task module
+
+In addition to selecting where your command can be invoked from, you must also select how to populate the form in the task module for your users. You have the following three options for creating the form that is rendered inside the task module:
+
+* **Static list of parameters**: This is the simplest method. You can define a list of parameters in your app manifest the Teams client renders, but cannot control the formatting in this case.
+* **Adaptive Card**: You can select to use an Adaptive Card, which provides greater control over the UI, but still limits you on the available controls and formatting options.
+* **Embedded web view**: You can select to embed a custom web view in the task module to have a complete control over the UI and controls.
+
+If you select to create the task module with a static list of parameters and when the user submits the task module, the messaging extension is called. When using an embedded web view or an Adaptive Card, your messaging extension must handle an initial invoke event from the user, create the task module, and return it back to the client.
-1. Where can the action command be triggered from?
-1. How will the task module be created?
-1. Will the final message or card be sent to the channel from a bot, or will the message or card be inserted into the compose message area for the user to submit?
+## Select how the final message is sent
-## Choose action command invoke locations
+In most cases, the action command results in a card inserted into the compose message box. The user can send it into the channel or chat. In this case, the message comes from the user, and the bot cannot edit or update the card further.
-The first thing you need to decide is where your action command can be triggered (or more specifically, *invoked*) from. By specifying the `context` in your app manifest, your command can be invoked from one or more of the following locations:
+If the messaging extension is invoked from the compose box or directly from a message, your web service can insert the final response directly into the channel or chat. In this case, the Adaptive Card comes from the bot, the bot updates it, and replies to the conversation thread if needed. You must add the `bot` object to the app manifest using the same ID and defining the appropriate scopes.
-* The buttons at the bottom of the compose message area.
-* By @mentioning your app in the command box. Note: You cannot respond with a bot message inserted directly into the conversation if your messaging extension is invoked from the command box.
-* Directly from an existing message via the ... overflow menu on a message. Note: The initial invoke to your bot will include a JSON object containing the message from which it was invoked, which you can process before presenting them with a task module.
+## Add the action command to your app manifest
-## Choose how to build your task module
+To add the action command to the app manifest, you must add a new `composeExtension` object to the top level of the app manifest JSON. You can use one of the following ways to do so:
-In addition to choosing where your command can be invoked from, you must also chose how to populate the form in the task module for your users. You have three options for creating the form that is rendered inside the task module:
+* [Create an action command using App Studio](#create-an-action-command-using-app-studio)
+* [Create an action command manually](#create-an-action-command-manually)
-* **Static list of parameters** - This is the simplest option. You can define a list of parameters (input fields) in your app manifest the Teams client will render. You cannot control the formatting with this option.
-* **Adaptive card** - You can choose to use an adaptive card, which provides greater control over the UI, but still limits you on the available controls and formatting options.
-* **Embedded web view** - If you need complete control over the UI and controls, you can choose to embed a custom web view in the task module.
+### Create an action command using App Studio
-If you choose to create your task module with a static list of parameters, the first call to your messaging extension will be when a user submits the task module. When using an embedded web view or an adaptive card, your messaging extension will need to handle an initial invoke event from the user, create the task module, and return it back to the client.
+> [!NOTE]
+> The prerequisite to create an action command is that you have already created a messaging extension. For information on how to create a messaging extension, see [create a messaging extension](~/messaging-extensions/how-to/create-messaging-extension.md).
-## Choose how the final message will be sent
+**To create an action command**
-In most cases, your action command will result in a card inserted into the compose message box. Your user can then decide to send it into the channel or chat. The message in this case comes from the user, and your bot will not be able to edit or update the card further.
+1. Open **App Studio** from the Microsoft Teams client and select the **Manifest editor** tab.
+1. If you already created your app package in **App Studio**, select it from the list. If you have not created an app package, import an existing one.
+1. After importing an app package, select **Messaging extensions** under **Capabilities**. You get a pop-up window to set up the messaging extension.
+1. Select **Set up** in the window to include the messaging extension in your app experience. The following image displays the messaging extension set up window:
-If your messaging extension is triggered from the compose box or directly from a message, your web service can insert the final response directly into the channel or chat. In this case, the adaptive card comes from the bot, the bot will be able to update it, and the bot can also reply to the conversation thread if needed. You will need to add the `bot` object to your app manifest using the same Id and defining the appropriate scopes.
+ <img src="~/assets/images/messaging-extension/messaging-extension-set-up.png" alt="messaging extension set up" width="500"/>
+
+1. To create a messaging extension, you need a Microsoft registered bot. You can either use an existing bot or create a new bot. Select **Create new bot** option, give a name for the new bot, and select **Create**. The following image displays bot creation for messaging extension:
-## Add the command to your app manifest
+ <img src="~/assets/images/messaging-extension/create-bot-for-messaging-extension.png" alt="create bot for messaging extension" width="500"/>
-Now that you've decided how users will interact with your action command, it is time to add it to your app manifest. To do this you'll add a new `composeExtension` object to the top level of your app manifest JSON. You can either do so with the help of App Studio, or manually.
+1. Select **Add** in the **Command section** of the messaging extensions page to include the commands which decides the behaviour of messaging extension.
+The following image displays command addition for messaging extension:
-### Create a command using App Studio
+ <img src="~/assets/images/messaging-extension/include-command.png" alt="include command" width="500"/>
-The following steps assume you've already [created a messaging extension](~/messaging-extensions/how-to/create-messaging-extension.md).
+1. Select **Allow users to trigger actions in external services while inside of Teams**. The following image displays the action command selection:
-1. From the Microsoft Teams client, open **App Studio** and select the **Manifest Editor** tab.
-2. If you've already created your app package in App Studio, chose it from the list. If not, you can import an existing app package.
-3. Click the **Add** button in the Command section.
-4. Choose **Allow users to trigger actions in external services while inside of Teams**.
-5. If you want to use a static set of parameters to create your task module, select that option. Otherwise, choose to **Fetch a dynamic set of parameters from your bot**.
-6. Add a **Command Id** and a **Title**.
-7. Select where you want your action command to be triggered from.
-8. If you're using parameters for your task module, add the first one.
-9. Click Save
-10. If you need to add more parameters, click the **Add** button in the **Parameters** section to add them.
+ <img src="~/assets/images/messaging-extension/action-command-selection.png" alt="action command selection" width="500"/>
+
+1. To use a static set of parameters to create your task module, select **Define a set of static parameters for the command**.
-### Manually create a command
+ The following image displays the action command static parameter selection:
-To manually add your action-based messaging extension command to your app manifest, you'll need to add the follow parameters to your `composeExtension.commands` array of objects.
+ <img src="~/assets/images/messaging-extension/action-command-static-parameter-selection.png" alt="action command static parameter selection" width="500"/>
+
+ The following image displays an example static parameter set-up:
+
+ <img src="~/assets/images/messaging-extension/setting-up-of-static-parameter.png" alt="action command static parameter set-up" width="500"/>
+
+ The following image displays an example static parameter testing:
+
+ <img src="~/assets/images/messaging-extension/static-parameter-testing.png" alt="action command static parameter testing" width="500"/>
+
+1. To use dynamic parameters, select to **Fetch a dynamic set of parameters from your bot**. The following image displays the action command parameter selection:
+
+ <img src="~/assets/images/messaging-extension/action-command-dynamic-parameter-selection.png" alt="action command dynamic parameter selection" width="500"/>
+
+1. Add a **Command Id** and a **Title**.
+1. Select the location from where you want to invoke the action command. The following image displays the action command invoke location:
+
+ <img src="~/assets/images/messaging-extension/action-command-invoke-location.png" alt="action command invoke location" width="500"/>
+
+1. Select **Save**.
+1. To add more parameters, select the **Add** button in the **Parameters** section.
+
+### Create an action command manually
+
+To manually add your action-based messaging extension command to your app manifest, you must add the following parameters to the `composeExtension.commands` array of objects:
| Property name | Purpose | Required? | Minimum manifest version | |||||
-| `id` | Unique ID that you assign to this command. The user request will include this ID. | Yes | 1.0 |
-| `title` | Command name. This value appears in the UI. | Yes | 1.0 |
-| `type` | Must be `action` | No | 1.4 |
-| `fetchTask` | `true` for an adaptive card or embedded web view for your task module, `false` for a static list of parameters or when loading the web view by a `taskInfo` | No | 1.4 |
-| `context` | Optional array of values that defines where the messaging extension can be invoked from. Possible values are `message`, `compose`, or `commandBox`. Default is `["compose", "commandBox"]`. | No | 1.5 |
+| `id` | This property is an unique ID that you assign to this command. The user request includes this ID. | Yes | 1.0 |
+| `title` | This property is a command name. This value appears in the UI. | Yes | 1.0 |
+| `type` | This property must be an `action`. | No | 1.4 |
+| `fetchTask` | This property is set to `true` for an adaptive card or embedded web view for your task module, and`false` for a static list of parameters or when loading the web view by a `taskInfo`. | No | 1.4 |
+| `context` | This property is an optional array of values that defines where the messaging extension is invoked from. The possible values are `message`, `compose`, or `commandBox`. The default value is `["compose", "commandBox"]`. | No | 1.5 |
-If you are using a static list of parameters, you'll add them as well.
+If you are using a static list of parameters, you must also add the following parameters:
-| Property name | Purpose | Required? | Minimum manifest version |
+| Property name | Purpose | Is required? | Minimum manifest version |
|||||
-| `parameters` | Static list of parameters for the command. Only use when `fetchTask` is `false` | No | 1.0 |
-| `parameter.name` | The name of the parameter. This is sent to your service in the user request. | Yes | 1.0 |
-| `parameter.description` | Describes this parameterΓÇÖs purposes or example of the value that should be provided. This value appears in the UI. | Yes | 1.0 |
-| `parameter.title` | Short user-friendly parameter title or label. | Yes | 1.0 |
-| `parameter.inputType` | Set to the type of input required. Possible values include `text`, `textarea`, `number`, `date`, `time`, `toggle`. Default is set to `text` | No | 1.4 |
+| `parameters` | This property describes the static list of parameters for the command. Only use when `fetchTask` is `false`. | No | 1.0 |
+| `parameter.name` | This property describes the name of the parameter. This is sent to your service in the user request. | Yes | 1.0 |
+| `parameter.description` | This property describes the parameterΓÇÖs purposes or example of the value that should be provided. This value appears in the UI. | Yes | 1.0 |
+| `parameter.title` | This property is a short user-friendly parameter title or label. | Yes | 1.0 |
+| `parameter.inputType` | This property is set to the type of input required. The possible values include `text`, `textarea`, `number`, `date`, `time`, `toggle`. The default value is set to `text`. | No | 1.4 |
-If you are using an embedded web view, you can optionally add the `taskInfo` object to fetch your web view without calling your bot directly. If you choose to use this option, the behavior is similar to using a static list of parameters in that the first interaction with your bot will be [responding to the task module submit action](~/messaging-extensions/how-to/action-commands/respond-to-task-module-submit.md). If you are using a `taskInfo` object, be sure to also set the `fetchTask` parameter to `false`.
+If you are using an embedded web view, you can optionally add the `taskInfo` object to fetch your web view without calling your bot directly. If you select this option, the behavior is similar to that of using a static list of parameters. In that the first interaction with your bot is [responding to the task module submit action](~/messaging-extensions/how-to/action-commands/respond-to-task-module-submit.md). If you are using a `taskInfo` object, you must set the `fetchTask` parameter to `false`.
-| Property name | Purpose | Required? | Minimum manifest version |
+| Property name | Purpose | Is required? | Minimum manifest version |
|||||
-|`taskInfo`|Specify the task module to preload when using a messaging extension command| No | 1.4 |
-|`taskInfo.title`|Initial task module title|No | 1.4 |
-|`taskInfo.width`|Task module width - either a number in pixels or default layout such as 'large', 'medium', or 'small'|No | 1.4 |
-|`taskInfo.height`|Task module height - either a number in pixels or default layout such as 'large', 'medium', or 'small'|No | 1.4 |
-|`taskInfo.url`|Initial web view URL|No | 1.4 |
+|`taskInfo`|Specify the task module to preload when using a messaging extension command. | No | 1.4 |
+|`taskInfo.title`|Initial task module title. |No | 1.4 |
+|`taskInfo.width`|Task module width, either a number in pixels or default layout such as `large`, `medium`, or `small`. |No | 1.4 |
+|`taskInfo.height`|Task module height, either a number in pixels or default layout such as `large`, `medium`, or `small`.|No | 1.4 |
+|`taskInfo.url`|Initial web view URL.|No | 1.4 |
#### App manifest example
-The below is an example of a `composeExtensions` object defining two action commands. It is not an example of the complete manifest, for the full app manifest schema see: [App manifest schema](~/resources/schem).
+The following section is an example of a `composeExtensions` object defining two action commands. It is not an example of the complete manifest. For the complete app manifest schema, see [app manifest schema](~/resources/schem):
```json ...
The below is an example of a `composeExtensions` object defining two action comm
... ```
-## Next steps
+## Code sample
+
+| Sample Name | Description | .NET | Node.js |
+|:|:--|:|:--|
+|Teams messaging extension action| Describes how to define action commands, create task module, and respond to task module submit action. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action) |
+|Teams messaging extension search | Describes how to define search commands and respond to searches. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)|
+
+## Next step
-If you are using either an adaptive card or an embedded web view without a `taskInfo` object, you'll want to:
+If you are using either an Adaptive Card or an embedded web view without a `taskInfo` object, the next step is to:
-* [Create and respond with a task module](~/messaging-extensions/how-to/action-commands/create-task-module.md)
+> [!div class="nextstepaction"]
+> [Create and respond with a task module](~/messaging-extensions/how-to/action-commands/create-task-module.md)
-If you are using parameters or an embedded web view with a `taskInfo` object, the next step for you is to:
+If you are using the parameters or an embedded web view with a `taskInfo` object, the next step is to:
-* [Respond to task module submit](~/messaging-extensions/how-to/action-commands/respond-to-task-module-submit.md)
+> [!div class="nextstepaction"]
+> [Respond to task module submit](~/messaging-extensions/how-to/action-commands/respond-to-task-module-submit.md)
platform Respond To Task Module Submit https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/how-to/action-commands/respond-to-task-module-submit.md
[!include[v4-to-v3-SDK-pointer](~/includes/v4-to-v3-pointer-me.md)]
-After a user submits the task module, your web service receives a `composeExtension/submitAction` invoke message with the command ID and parameter values. Your app has five seconds to respond to the invoke, otherwise the user receives an error message **Unable to reach the app** and any reply to the invoke is ignored by the Teams client.
+This document guides you on how your app responds to the action commands, such as user's task module submit action.
+After a user submits the task module, your web service receives a `composeExtension/submitAction` invoke message with the command ID and parameter values. Your app has five seconds to respond to the invoke, otherwise the user receives an error message **Unable to reach the app**, and any reply to the invoke is ignored by the Teams client.
-You have the following options for responding:
+You have the following options to respond:
-* No response - You can choose to use the submit action to trigger a process in an external system, and not provide any feedback to the user. This can be useful for long-running processes, and you may choose to provide feedback in another manner (for example, with a [proactive message](~/bots/how-to/conversations/send-proactive-messages.md).
-* [Another task module](#respond-with-another-task-module) - You can respond with an additional task module as part of a multi-step interaction.
-* [Card response](#respond-with-a-card-inserted-into-the-compose-message-area) - You can respond with a card that the user can then interact with and/or insert into a message.
-* [Adaptive Card from bot](#bot-response-with-adaptive-card) - Insert an Adaptive Card directly into the conversation.
-* [Request the user authenticate](~/messaging-extensions/how-to/add-authentication.md)
-* [Request the user provide additional configuration](~/messaging-extensions/how-to/add-configuration-page.md)
+* No response: Use the submit action to trigger a process in an external system, and not provide any feedback to the user. This is useful for long-running processes, and you can select to provide feedback alternately. For example, you can give feedback with a [proactive message](~/bots/how-to/conversations/send-proactive-messages.md).
+* [Another task module](#respond-with-another-task-module): You can respond with an additional task module as part of a multi-step interaction.
+* [Card response](#respond-with-a-card-inserted-into-the-compose-message-area): You can respond with a card that the user can interact with or insert into a message.
+* [Adaptive Card from bot](#bot-response-with-adaptive-card): Insert an Adaptive Card directly into the conversation.
+* [Request the user to authenticate](~/messaging-extensions/how-to/add-authentication.md).
+* [Request the user to provide additional configuration](~/messaging-extensions/how-to/add-configuration-page.md).
-For authentication or configuration, after the user completes the flow the original invoke is re-sent to your web service. The following table shows which types of responses are available based on the invoke location `commandContext` of the messaging extension:
+For authentication or configuration, after the user completes the process, the original invoke is resent to your web service. The following table shows which types of responses are available based on the invoke location `commandContext` of the messaging extension:
-|Response Type | compose | command bar | message |
+|Response Type | Compose | Command bar | Message |
|--|:-:|:-:|::|
-|Card response | x | x | x |
-|Another task module | x | x | x |
-|Bot with Adaptive Card | x | | x |
-| No response | x | x | x |
+|Card response | Γ£ö | Γ£ö | Γ£ö |
+|Another task module | Γ£ö | Γ£ö | Γ£ö |
+|Bot with Adaptive Card | Γ£ö | x | Γ£ö |
+| No response | Γ£ö | Γ£ö | Γ£ö |
> [!NOTE] > * When you select **Action.Submit** through ME cards, it sends invoke activity with the name **composeExtension**, where the value is equal to the usual payload.
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
# [JSON](#tab/json)
-This is an example of the JSON object you receive. The `commandContext` parameter indicates where your messaging extension was triggered from. The `data` object contains the fields on the form as parameters, and the values the user submitted. The JSON object here is shortened to highlight the most relevant fields.
+This is an example of the JSON object that you receive. The `commandContext` parameter indicates where your messaging extension was triggered from. The `data` object contains the fields on the form as parameters, and the values the user submitted. The JSON object here is shortened to highlight the most relevant fields.
```json {
This is an example of the JSON object you receive. The `commandContext` paramete
## Respond with a card inserted into the compose message area
-The most common way to respond to the `composeExtension/submitAction` request is with a card inserted into the compose message area. The user can then choose to submit the card to the conversation. For more information on using cards see [cards and card actions](~/task-modules-and-cards/cards/cards-actions.md).
+The most common way to respond to the `composeExtension/submitAction` request is with a card inserted into the compose message area. The user submits the card to the conversation. For more information on using cards, see [cards and card actions](~/task-modules-and-cards/cards/cards-actions.md).
# [C#/.NET](#tab/dotnet)
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
## Respond with another task module
-You can choose to respond to the `submitAction` event with an additional task module. This can be useful when:
+You can select to respond to the `submitAction` event with an additional task module. This is useful when:
* You need to collect large amounts of information.
-* If you need to dynamically change what information you are collecting based on user input
-* If you need to validate the information submitted by the user and potentially resend the form with an error message if something is wrong.
+* You need to dynamically change the information you are collecting based on user input.
+* You need to validate the information submitted by the user and resend the form with an error message if something is wrong.
-The method for response is the same as [responding to the initial `fetchTask` event](~/messaging-extensions/how-to/action-commands/create-task-module.md). If you are using the Bot Framework SDK the same event triggers for both submit actions. This means you must add logic which determines the correct response.
+The method for response is the same as [responding to the initial `fetchTask` event](~/messaging-extensions/how-to/action-commands/create-task-module.md). If you are using the Bot Framework SDK the same event triggers for both submit actions. To make this work, you must add logic that determines the correct response.
## Bot response with Adaptive Card
->[!Note]
->This flow requires that you add the `bot` object to your app manifest, and that you have the necessary scope defined for the bot. Use the same ID as your messaging extension for your bot.
+> [!NOTE]
+> The prerequisite to get the bot response with an Adaptive card is that you must add the `bot` object to your app manifest, and define the required scope for the bot. Use the same ID as your messaging extension for your bot.
+
+You can also respond to the `submitAction` by inserting a message with an Adaptive Card into the channel with a bot. The user can preview the message before submitting it. This is very useful in scenarios where you gather information from the users before creating an Adaptive Card response, or when you update the card after someone interacts with it.
+
+The following scenario shows how the app Polly configures a poll without including the configuration steps in the channel conversation:
-You can also respond to the submit action by inserting a message with an Adaptive Card into the channel with a bot. Your user can preview the message before submitting it, and potentially edit or interact with it as well. This can be very useful in scenarios where you gather information from your users before creating an adaptive card response, or when you update the card after someone interacts with it. The following scenario shows how the app Polly uses this flow to configure a poll without including the configuration steps in the channel conversation:
+**To configure the poll**
-1. The user selects the messaging extension to trigger the task module.
-2. The user configures the poll with the task module.
-3. After submitting the task module the app uses the information provided to build the poll as an Adaptive Card and sends it as a `botMessagePreview` response to the client.
-4. The user can then preview the adaptive card message before the bot inserts it into the channel. If the app is not already a member of the channel, selecting `Send` adds it.
- 1. The user can also choose to `Edit` the message, which returns them to the original task module.
-5. Interacting with the adaptive card changes the message before sending it.
-6. After the user selects `Send` the bot posts the message to the channel.
+1. The user selects the messaging extension to invoke the task module.
+1. The user configures the poll with the task module.
+1. After submitting the task module, the app uses the information provided to build the poll as an Adaptive Card and sends it as a `botMessagePreview` response to the client.
+1. The user can then preview the Adaptive Card message before the bot inserts it into the channel. If the app is not already a member of the channel, select `Send` to add it.
-### Respond to initial submit action
+ > [!NOTE]
+ > * The users can also select to `Edit` the message, which returns them to the original task module.
+ > * Interaction with the Adaptive Card changes the message before sending it.
+1. After the user selects `Send` the bot posts the message to the channel.
-To enable this flow your task module should respond to the initial `composeExtension/submitAction` message with a preview of the card that the bot send to the channel. This gives the user the opportunity to verify the card before sending, and also attempt to install your bot in the conversation if it is not already installed.
+## Respond to initial submit action
+
+Your task module must respond to the initial `composeExtension/submitAction` message with a preview of the card that the bot sends to the channel. The user can verify the card before sending, and also try to install your bot in the conversation if the bot is not already installed.
# [C#/.NET](#tab/dotnet)
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
# [JSON](#tab/json)
->[!Note]
->The `activityPreview` must contain a `message` activity with exactly 1 adaptive card attachment. The `<< Card Payload >>` value is a placeholder for the card you wish to send.
+> [!NOTE]
+> * The `activityPreview` must contain a `message` activity with exactly one Adaptive Card attachment. The `<< Card Payload >>` value is a placeholder for the card you want to send.
```json {
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
### The botMessagePreview send and edit events
-Your message extension must respond now to two new varieties of the `composeExtension/submitAction` invoke, where `value.botMessagePreviewAction = "send"`and `value.botMessagePreviewAction = "edit"`.
+Your messaging extension must respond to two new types of the `composeExtension/submitAction` invoke, where `value.botMessagePreviewAction = "send"`and `value.botMessagePreviewAction = "edit"`.
# [C#/.NET](#tab/dotnet)
class TeamsMessagingExtensionsActionPreview extends TeamsActivityHandler {
### Respond to botMessagePreview edit
-If the user edits the card before sending by selecting the **Edit** button, you receive a `composeExtension/submitAction` invoke with `value.botMessagePreviewAction = edit`. You should typically respond by returning the task module you sent in response to the initial `composeExtension/fetchTask` invoke that began the interaction. This allows the user to start the process over by re-entering the original information. Use the available information to pre-populate the task module so the user does not have to fill out all of the information from scratch.
-
-See [responding to the initial `fetchTask` event](~/messaging-extensions/how-to/action-commands/create-task-module.md).
+If the user edits the card before sending, by selecting **Edit**, you receive a `composeExtension/submitAction` invoke with `value.botMessagePreviewAction = edit`. You must respond by returning the task module you sent, in response to the initial `composeExtension/fetchTask` invoke that began the interaction. This allows the user to start the process by re-entering the original information. Use the available information to update the task module so that the user need not fill out all information from scratch.
+For more information on responding to the initial `fetchTask` event, see [responding to the initial `fetchTask` event](~/messaging-extensions/how-to/action-commands/create-task-module.md).
### Respond to botMessagePreview send
-After the user selects the **Send** button, you receive a `composeExtension/submitAction` invoke with `value.botMessagePreviewAction = send`. Your web service has to create and send a proactive message with the Adaptive Card to the conversation, and also reply to the invoke.
+After the user selects the **Send**, you receive a `composeExtension/submitAction` invoke with `value.botMessagePreviewAction = send`. Your web service has to create and send a proactive message with the Adaptive Card to the conversation, and also reply to the invoke.
# [C#/.NET](#tab/dotnet)
You receive a new `composeExtension/submitAction` message similar to the followi
### User attribution for bots messages
-In scenarios where a bot sends messages on behalf of a user, attributing the message to that user can help with engagement and showcase a more natural interaction flow. This feature allows you to attribute a message from your bot to a user on whose behalf it was sent.
+In scenarios where a bot sends messages on behalf of a user, attributing the message to that user helps with engagement and showcase a more natural interaction flow. This feature allows you to attribute a message from your bot to a user on whose behalf it was sent.
-In the following image, on the left is a card message sent by a bot *without* user attribution and on the right is a card sent by a bot *with* user attribution.
+In the following image, on the left is a card message sent by a bot without user attribution and on the right is a card sent by a bot with user attribution.
-![Screenshot](../../../assets/images/messaging-extension/user-attribution-bots.png)
+![user attribution bots](../../../assets/images/messaging-extension/user-attribution-bots.png)
-To use the user attribution in teams, you must add the `OnBehalfOf` mention entity to `ChannelData` in your `Activity` payload that is sent to Teams.
+To use the user attribution in teams, you must add the `OnBehalfOf` mention entity to `ChannelData` in your `Activity` payload that is sent to Teams.
# [C#/.NET](#tab/dotnet-1)
To use the user attribution in teams, you must add the `OnBehalfOf` mention ent
* * *
-The following section is a description of the entities in the `OnBehalfOf` of Array:
- #### Details of `OnBehalfOf` entity schema
+The following section is a description of the entities in the `OnBehalfOf` Array:
+ |Field|Type|Description| |:|:|:|
-|`itemId`|Integer|Should be 0|
-|`mentionType`|String|Should be "person"|
-|`mri`|String|Message resource identifierΓÇï (MRI) of the person on whose behalf the message is sent. Message sender name would appear as "\<user\> via \<bot name\>".|
+|`itemId`|Integer|Describes identification of the item. Its value must be `0`.|
+|`mentionType`|String|Describes the mention of a "person".|
+|`mri`|String|Message resource identifierΓÇï (MRI) of the person on whose behalf the message is sent. Message sender name would appear as "\<user\> through \<bot name\>".|
|`displayName`|String|Name of the person. Used as fallback in case name resolution is unavailable.|
-## Next Steps
+## Code sample
+
+| Sample Name | Description | .NET | Node.js |
+|:|:--|:|:--|
+|Teams messaging extension action| Describes how to define action commands, create task module, and respond to task module submit action. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action) |
+|Teams messaging extension search | Describes how to define search commands and respond to searches. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)|
-Add a search command
+## Next Step
-* [Define search commands](~/messaging-extensions/how-to/search-commands/define-search-command.md)
+> [!div class="nextstepaction"]
+> [Define search commands](~/messaging-extensions/how-to/search-commands/define-search-command.md)
platform Add Authentication https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/how-to/add-authentication.md
## Identify the user
-Every request to your services includes the obfuscated ID of the user that performed the request, as well as the user's display name and Azure Active Directory object ID.
+Every request to your services includes the user ID, the user's display name and Azure Active Directory object ID.
```json "from": {
Every request to your services includes the obfuscated ID of the user that perfo
}, ```
-The `id` and `aadObjectId` values are guaranteed to be that of the authenticated Teams user. They can be used as keys to look up credentials or any cached state in your service. In addition, each request contains the Azure Active Directory tenant ID of the user, which can be used to identify the userΓÇÖs organization. If applicable, the request also contains the team and channel IDs from which the request originated.
+The `id` and `aadObjectId` values are guaranteed for the authenticated Teams user. They are used as keys to look up the credentials or any cached state in your service. In addition, each request contains the Azure Active Directory tenant ID of the user, which is used to identify the userΓÇÖs organization. If applicable, the request also contains the team Id and channel ID from which the request is originated.
## Authentication
-If your service requires user authentication, you need to sign in the user before he or she can use the messaging extension. If you have written a bot or a tab that signs in the user, this section should be familiar.
-
+If your service requires user authentication, the users must sign in before they use the messaging extension. The authentication steps are similar to that of a bot or tab.
The sequence is as follows: 1. User issues a query, or the default query is automatically sent to your service.
-2. Your service checks whether the user has first authenticated by inspecting the Teams user ID.
-3. If the user has not authenticated, send back an `auth` response with an `openUrl` suggested action including the authentication URL.
-4. The Microsoft Teams client launches a pop-up window hosting your webpage using the given authentication URL.
-5. After the user signs in, you should close your window and send an "authentication code" to the Teams client.
-6. The Teams client then reissues the query to your service, which includes the authentication code passed in step 5.
+1. Your service checks whether the user is authenticated by inspecting the Teams user ID.
+1. If the user is not authenticated, send back an `auth` response with an `openUrl` suggested action including the authentication URL.
+1. The Microsoft Teams client launches a dialog box hosting your webpage using the given authentication URL.
+1. After the user signs in, you should close your window and send an **authentication code** to the Teams client.
+1. The Teams client then reissues the query to your service, which includes the authentication code passed in Step 5.
-Your service should verify that the authentication code received in step 6 matches the one from step 5. This ensures that a malicious user does not try to spoof or compromise the sign-in flow. This effectively "closes the loop" to finish the secure authentication sequence.
+Your service should verify that the authentication code received in step 6 matches the one from step 5. This ensures that a malicious user does not try to spoof or compromise the sign in flow. This effectively "closes the loop" to finish the secure authentication sequence.
### Respond with a sign-in action
To prompt an unauthenticated user to sign in, respond with a suggested action of
``` > [!NOTE]
-> For the sign-in experience to be hosted in a Teams pop-up, the domain portion of the URL must be in your appΓÇÖs list of valid domains. (See [validDomains](~/resources/schem#validdomains) in the manifest schema.)
+> For the sign in experience to be hosted in a Teams pop-up window, the domain portion of the URL must be in your appΓÇÖs list of valid domains. For more information, see [validDomains](~/resources/schem#validdomains) in the manifest schema.
-### Start the sign-in flow
+### Start the sign in flow
-Your sign-in experience should be responsive and fit within a popup window. It should integrate with the [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client), which uses message passing.
+Your sign in experience must be responsive and fit within a pop-up window. It should integrate with the [Microsoft Teams JavaScript client SDK](/javascript/api/overview/msteams-client), which uses message passing.
-As with other embedded experiences running inside Microsoft Teams, your code inside the window needs to first call `microsoftTeams.initialize()`. If your code performs an OAuth flow, you can pass the Teams user ID into your window, which then can pass it to the OAuth sign-in URL.
+As with other embedded experiences running inside Microsoft Teams, your code inside the window needs to first call `microsoftTeams.initialize()`. If your code performs an OAuth flow, you can pass the Teams user ID into your window, which then passes it to the OAuth sign-in URL.
-### Complete the sign-in flow
+### Complete the sign in flow
-When the sign-in request completes and redirects back to your page, it should perform the following steps:
+When the sign in request completes and redirects back to your page, it must perform the following steps:
-1. Generate a security code. (This can be a random number.) You need to cache this code on your service, along with the credentials obtained through the sign-in flow (such as OAuth 2.0 tokens).
-2. Call `microsoftTeams.authentication.notifySuccess` and pass the security code.
+1. Generate a security code. This is a random number. You must cache this code on your service, along with the credentials obtained through the sign in flow, such as OAuth 2.0 tokens.
+1. Call `microsoftTeams.authentication.notifySuccess` and pass the security code.
-At this point, the window closes and control is passed to the Teams client. The client now can reissue the original user query, along with the security code in the `state` property. Your code can use the security code to look up the credentials stored earlier to complete the authentication sequence and then complete the user request.
+At this point, the window closes and control is passed to the Teams client. The client now reissues the original user query, along with the security code in the `state` property. Your code can use the security code to look up the credentials stored earlier to complete the authentication sequence and then complete the user request.
#### Reissued request example
platform Add Configuration Page https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/how-to/add-configuration-page.md
[!include[v4-to-v3-SDK-pointer](~/includes/v4-to-v3-pointer-me.md)]
-## Bot Framework Samples
+This document guides you on how to create messaging extensions that include a configuration page and Bot Service authentication using Bot Framework Teams search Auth Configuration samples. The samples also demonstrate how to create message extensions that accept search requests and return the results after the user has signed in.
-The Teams Search Auth Config for [**JavaScript/Node.js**](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/52.teams-messaging-extensions-search-auth-config) and [**C-Sharp/DotNetCore**](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/52.teams-messaging-extensions-search-auth-config) sample projects, found on GitHub, demonstrate how to create messaging extensions that include a configuration page and Bot Service authentication. The samples also demonstrate how to create message extensions that accept search requests and return the results after the user has signed in.
+## Code sample
+
+| Sample Name | Description | .NET | Node.js|
+|:|:--|:|:--|
+| Bot Framework Teams search Auth Configuration samples | Demonstrate how to create messaging extensions that include a configuration page and Bot Service authentication. The samples also demonstrate how to create message extensions that accept search requests and return the results after the user has signed in.|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/52.teams-messaging-extensions-search-auth-config)| [View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/52.teams-messaging-extensions-search-auth-config)|
+
+## Additional code sample
> [!div class="nextstepaction"] > [View more Bot Framework Samples on GitHub](https://github.com/microsoft/BotBuilder-Samples)
platform Link Unfurling https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/how-to/link-unfurling.md
[!include[v4-to-v3-SDK-pointer](~/includes/v4-to-v3-pointer-me.md)]
-> [!NOTE]
-> Currently, Link unfurling is not supported on Mobile clients.
+This document guides you on how to add link unfurling to your app manifest using App studio and manually. With link unfurling your app can register to receive an `invoke` activity when URLs with a particular domain are pasted into the compose message area. The `invoke` contains the full URL that was pasted into the compose message area, and you can respond with a card that the user can unfurl, providing additional information or actions. This works similar to a search command with the URL serving as the search term.
-With link unfurling your app can register to receive an `invoke` activity when URLs with a particular domain are pasted into the compose message area. The `invoke` will contain the full URL that was pasted into the compose message area, and you can respond with a card the user can *unfurl*, providing additional information or actions. This works very similarly to a [search command](~/messaging-extensions/how-to/search-commands/define-search-command.md), with the URL serving as the search term.
+> [!NOTE]
+> Currently, link unfurling is not supported on Mobile clients.
-The Azure DevOps messaging extension uses link unfurling to look for URLs pasted into the compose message area pointing to a work item. In the screenshot below, a user has pasted in a URL for a work item in Azure DevOps which the messaging extension has resolved into a card.
+The Azure DevOps messaging extension uses link unfurling to look for URLs pasted into the compose message area pointing to a work item. In the following image, a user has pasted a URL for a work item in Azure DevOps, which the messaging extension has resolved into a card:
![Example of link unfurling](~/assets/images/compose-extensions/messagingextensions_linkunfurling.png) ## Add link unfurling to your app manifest
- To add link unfurling to your app manifest add a new `messageHandlers` array to the `composeExtensions` section of your app manifest JSON. You can add the array either with the help of App Studio or manually. Domain listings can include wildcards, for example `*.example.com`. This matches exactly one segment of the domain; if you need to match `a.b.example.com` then use `*.*.example.com`.
+To add link unfurling to your app manifest, add a new `messageHandlers` array to the `composeExtensions` section of your app manifest JSON. You can add the array either with the help of App Studio or manually. Domain listings can include wildcards, for example `*.example.com`. This matches exactly one segment of the domain; if you need to match `a.b.example.com` then use `*.*.example.com`.
> [!NOTE]
-> Do not add domains that are outside your control, either directly or through wildcards. For example, yourapp.onmicrosoft.com is valid, but *.onmicrosoft.com is not valid. Also, the top-level domains are prohibited. For example, *.com, *.org.
+> Donot add domains that are not in your control, either directly or through wildcards. For example, `yourapp.onmicrosoft.com` is valid, but `*.onmicrosoft.com` is not valid. Also, the top-level domains are prohibited. For example, `*.com`, `*.org`.
-### Using App Studio
+### Add link unfurling using App Studio
-1. In App Studio, on the Manifest editor tab, load your app manifest.
-1. On the **Messaging Extension** page, add the domain you want to look for in the **Message handlers** section as in the screenshot below.
+1. Open **App Studio** from the Microsoft Teams client, and select the **Manifest Editor** tab.
+1. Load your app manifest.
+1. On the **Messaging Extension** page, add the domain that you want to look for in the **Message handlers** section. The following image explains the process:
-![message handlers section in App Studio](~/assets/images/link-unfurling.png)
+ ![message handlers section in App Studio](~/assets/images/link-unfurling.png)
+
+### Add link unfurling manually
-### Manually
+To enable your messaging extension to interact with links, first you must add the `messageHandlers` array to your app manifest. The following example explains how to add link unfurling manually:
-To enable your messaging extension to interact with links this way you'll first need to add the `messageHandlers` array to your app manifest as in the example below. This example is not the complete manifest, see [manifest reference](~/resources/schem) for a complete manifest example.
```json ...
To enable your messaging extension to interact with links this way you'll first
... ```
+For a complete manifest example, see [manifest reference](~/resources/schem).
+ ## Handle the `composeExtension/queryLink` invoke
-Once you've added the domain to listen on to the app manifest, you'll need to update your web service code to handle the invoke request. Use the URL you receive to search your service and create a card response. If you respond with more than one card, only the first will be used.
+After adding the domain to the app manifest, you must update your web service code to handle the invoke request. Use the received URL to search your service and create a card response. If you respond with more than one card, only the first card response is used.
-We support the following card types:
+The following card types are supported:
* [Thumbnail card](~/task-modules-and-cards/cards/cards-reference.md#thumbnail-card) * [Hero card](~/task-modules-and-cards/cards/cards-reference.md#hero-card) * [Office 365 Connector card](~/task-modules-and-cards/cards/cards-reference.md#office-365-connector-card) * [Adaptive Card](~/task-modules-and-cards/cards/cards-reference.md#adaptive-card)
-See [What are cards](~/task-modules-and-cards/what-are-cards.md) for an overview.
+### Example
# [C#/.NET](#tab/dotnet)
class TeamsLinkUnfurlingBot extends TeamsActivityHandler {
# [JSON](#tab/json)
-This is an example of the `invoke` sent to your bot.
+Following is an example of the `invoke` sent to your bot:
```json {
This is an example of the `invoke` sent to your bot.
} ```
-An example of the response is shown below.
+Following is an example of the response:
```json {
An example of the response is shown below.
``` * * *+
+## See also
+
+> [!div class="nextstepaction"]
+> [What are cards](~/task-modules-and-cards/what-are-cards.md)
platform Define Search Command https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/how-to/search-commands/define-search-command.md
[!include[v4-to-v3-SDK-pointer](~/includes/v4-to-v3-pointer-me.md)]
-Messaging extension search commands allow your users to search external systems and insert the results of that search into a message in the form of a card.
+Messaging extension search commands allow users to search external systems and insert the results of that search into a message in the form of a card. This document guides you on how to select search command invoke locations, and add the search command to your app manifest.
> [!NOTE]
-> The result card size limit is 28 KB. The card is not sent if its size exceeds 28 KB.
+> The result card size limit is 28 KB. The card is not sent if its size exceeds 28 KB.
-## Choose messaging extension invoke locations
+## Select search command invoke locations
-The first thing you need to decide is where your search command can be triggered (or specifically, *invoked*) from. Your search command can be invoked from one or both of the following locations:
+The search command is invoked from any one or both of the following locations:
-* The buttons at the bottom of the compose message area
-* By @mentioning in the command box
+* Compose message area: The buttons at the bottom of the compose message area.
+* Command box: By @mentioning in the command box.
-When invoked from the compose message area, your user will have the option of sending the results to the conversation. When invoked from the command box, the user can interact with the resulting card, or copy it for use elsewhere.
+When search command is invoked from the compose message area, the user sends the results to the conversation. When it is invoked from the command box, the user interacts with the resulting card, or copies it for use elsewhere.
-## Add the command to your app manifest
+The following image displays the invoke locations of the search command:
-Now that you've decided how users will interact with your search command, it is time to add it to your app manifest. To do this you'll add a new `composeExtension` object to the top level of your app manifest JSON. You can either do so with the help of App Studio, or manually.
+![search command invoke locations](~/assets/images/messaging-extension/search-command-invoke-locations.png)
-### Create a command using App Studio
+## Add the search command to your app manifest
-The prerequisite to create a search command is that you must already create a messaging extension. For information on how to create a messaging extension, see [create a messaging extension](~/messaging-extensions/how-to/create-messaging-extension.md).
+To add the search command to your app manifest, you must add a new `composeExtension` object to the top level of your app manifest JSON. You can add the search command either with the help of App Studio, or manually.
+
+### Create a search command using App Studio
+
+The prerequisite to create a search command is that you must already have created a messaging extension. For information on how to create a messaging extension, see [create a messaging extension](~/messaging-extensions/how-to/create-messaging-extension.md).
**To create a search command**
-1. From the Microsoft Teams client, open **App Studio**, and select the **Manifest editor** tab.
-1. If you already created an app package in the **App Studio**, choose it from the list. If you have not created an app package, import an existing one.
-1. After importing an app package, select **Messaging extensions** under **Capabilities**.
-1. Select **Add** in the **Command** section in the messaging extensions page.
-1. Choose **Allow users to query your service for information and insert that into a message**.
+1. Open **App Studio** from the Microsoft Teams client, and select the **Manifest Editor** tab.
+1. If you already created your app package in **App Studio**, select from the list. If you have not created an app package, import an existing one.
+1. After importing app package, select **Messaging extensions** under **Capabilities**. You get a pop-up window to set up the messaging extension.
+1. Select **Set up** in the window to include the messaging extension in your app experience. The following image displays the messaging extension set up page:
+
+ <img src="~/assets/images/messaging-extension/messaging-extension-set-up.png" alt="messaging extension set up" width="500"/>
+
+1. To create the messaging extension, you need a Microsoft registered bot. You can either use an existing bot or create a new bot. Select **Create new bot** option, give a name for the new bot, and select **Create**. The following image displays bot creation for messaging extension:
+
+ <img src="~/assets/images/messaging-extension/create-bot-for-messaging-extension.png" alt="create bot for messaging extension" width="500"/>
+
+1. Select **Add** in the **Command section** of the messaging extensions page to include the commands which decides the behaviour of messaging extension.
+The following image displays command addition for messaging extension:
+
+ <img src="~/assets/images/messaging-extension/include-command.png" alt="include command" width="500"/>
+1. Select **Allow users to query your service for information and insert that into a message**. The following image displays the search command parameter selection:
+
+ <img src="~/assets/images/messaging-extension/search-command-parameter-selection.png" alt="search command parameter selection" width="500"/>
+ 1. Add a **Command Id** and a **Title**.
-1. Select the location from where your search command must be triggered. Selecting **message** does not currently alter the behavior of your search command.
+1. Select the location from where your search command must be invoked. Selecting **message** does not currently alter the behavior of your search command. The following image displays the search command invoke location:
+
+ <img src="~/assets/images/messaging-extension/search-command-invoke-location-selection.png" alt="search command invoke location selection]" width="500"/>
+ 1. Add your search parameter and select **Save**.
-
-### Manually create a command
-To manually add your messaging extension search command to your app manifest, you'll need to add the following parameters to your `composeExtension.commands` array of objects.
+### Create a search command manually
+
+To manually add your messaging extension search command to your app manifest, you must add the following parameters to your `composeExtension.commands` array of objects:
| Property name | Purpose | Required? | Minimum manifest version | |||||
-| `id` | Unique ID that you assign to this command. The user request will include this ID. | Yes | 1.0 |
-| `title` | Command name. This value appears in the UI. | Yes | 1.0 |
-| `description` | Help text indicating what this command does. This value appears in the UI. | Yes | 1.0 |
-| `type` | Must be `query` | No | 1.4 |
-|`initialRun` | If set to **true**, indicates this command should be executed as soon as the user chooses this command in the UI. | No | 1.0 |
-| `context` | Optional array of values that defines the context the search action is available in. Possible values are `message`, `compose`, or `commandBox`. Default is `["compose", "commandBox"]`. | No | 1.5 |
+| `id` | This property is an unique ID that you assign to search command. The user request includes this ID. | Yes | 1.0 |
+| `title` | This property is a command name. This value appears in the user interface (UI). | Yes | 1.0 |
+| `description` | This property is a help text indicating what this command does. This value appears in the UI. | Yes | 1.0 |
+| `type` | This property must be a `query`. | No | 1.4 |
+|`initialRun` | If this property is set to **true**, it indicates this command should be executed as soon as the user selects this command in the UI. | No | 1.0 |
+| `context` | This property is an optional array of values that defines the context the search action is available in. The possible values are `message`, `compose`, or `commandBox`. The default is `["compose", "commandBox"]`. | No | 1.5 |
-You'll also need to add the details of the search parameter, which will define the text visible to your user in the Teams client.
+You must add the details of the search parameter, that defines the text visible to your user in the Teams client.
-| Property name | Purpose | Required? | Minimum manifest version |
+| Property name | Purpose | Is required? | Minimum manifest version |
|||||
-| `parameters` | Static list of parameters for the command. | No | 1.0 |
-| `parameter.name` | The name of the parameter. This is sent to your service in the user request. | Yes | 1.0 |
-| `parameter.description` | Describes this parameterΓÇÖs purposes or example of the value that should be provided. This value appears in the UI. | Yes | 1.0 |
-| `parameter.title` | Short user-friendly parameter title or label. | Yes | 1.0 |
-| `parameter.inputType` | Set to the type of input required. Possible values include `text`, `textarea`, `number`, `date`, `time`, `toggle`. Default is set to `text` | No | 1.4 |
+| `parameters` | This property defines a static list of parameters for the command. | No | 1.0 |
+| `parameter.name` | This property describes the name of the parameter. This is sent to your service in the user request. | Yes | 1.0 |
+| `parameter.description` | This property describes the parameterΓÇÖs purposes or example of the value that must be provided. This value appears in the UI. | Yes | 1.0 |
+| `parameter.title` | This property is a short user-friendly parameter title or label. | Yes | 1.0 |
+| `parameter.inputType` | This property is set to the type of the input required. Possible values include `text`, `textarea`, `number`, `date`, `time`, `toggle`. Default is set to `text`. | No | 1.4 |
-#### App manifest example
+#### Example
-Below is an example of a `composeExtensions` object defining a search command. It is not an example of the complete manifest, for the full app manifest schema see: [App manifest schema](~/resources/schem).
+Following section is an example of the simple app manifest of the `composeExtensions` object defining a search command:
```json {
Below is an example of a `composeExtensions` object defining a search command. I
... } ```
+For the complete app manifest, see [App manifest schema](~/resources/schem).
+
+## Code sample
+
+| Sample Name | Description | .NET | Node.js |
+|:|:--|:|:--|
+|Teams messaging extension action| Describes how to define action commands, create task module, and respond to task module submit action. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action) |
+|Teams messaging extension search | Describes how to define search commands and respond to searches. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)|
-## Next steps
+## Next step
-Now that you've added your search command, you'll need to [handle the search request](~/messaging-extensions/how-to/search-commands/respond-to-search.md).
+> [!div class="nextstepaction"]
+> [Respond to the search commands](~/messaging-extensions/how-to/search-commands/respond-to-search.md).
platform Respond To Search https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/how-to/search-commands/respond-to-search.md
description: How to respond to the search command from a messaging extension in
-# Respond to the search command
+# Respond to search command
[!include[v4-to-v3-SDK-pointer](~/includes/v4-to-v3-pointer-me.md)]
-Your web service will receive a `composeExtension/query` invoke message that contains a `value` object with the search parameters. This invoke is triggered:
+After the user submits the search command, your web service receives a `composeExtension/query` invoke message that contains a `value` object with the search parameters. This invoke is triggered with the following conditions:
* As characters are entered into the search box.
-* If `initialRun` is set to true in your app manifest, you'll receive the invoke message as soon as the search command is invoked. See [default query](#default-query).
+* `initialRun` is set to true in your app manifest, you receive the invoke message as soon as the search command is invoked. For more information, see [default query](#default-query).
-The request parameters itself are found in the `value` object in the request, which includes the following properties:
+This document guides you on how to respond to user requests in the form of cards and previews, and the conditions under which Microsoft Teams issues a default query.
+
+The request parameters are found in the `value` object in the request, which includes the following properties:
| Property name | Purpose | ||| | `commandId` | The name of the command invoked by the user, matching one of the commands declared in the app manifest. | | `parameters` | Array of parameters. Each parameter object contains the parameter name, along with the parameter value provided by the user. |
-| `queryOptions` | Pagination parameters: <br>`skip`: skip count for this query <br>`count`: number of elements to return |
+| `queryOptions` | Pagination parameters: <br>`skip`: Skip count for this query <br>`count`: Number of elements to return. |
# [C#/.NET](#tab/dotnet)
The JSON below is shortened to highlight the most relevant sections.
## Respond to user requests
-When the user performs a query, Microsoft Teams issues a synchronous HTTP request to your service. At that point, your code has 5 seconds to provide an HTTP response to the request. During this time, your service can perform additional lookup, or any other business logic needed to serve the request.
+When the user performs a query, Microsoft Teams issues a synchronous HTTP request to your service. At that point, your code has `5` seconds to provide an HTTP response to the request. During this time, your service can perform additional lookup, or any other business logic needed to serve the request.
-Your service should respond with the results matching the user query. The response must indicate an HTTP status code of `200 OK` and a valid application/json object with the following body:
+Your service must respond with the results matching the user query. The response must indicate an HTTP status code of `200 OK` and a valid application or JSON object with the following properties:
|Property name|Purpose| ||| |`composeExtension`|Top-level response envelope.|
-|`composeExtension.type`|Type of response. The following types are supported: <br>`result`: displays a list of search results <br>`auth`: asks the user to authenticate <br>`config`: asks the user to set up the messaging extension <br>`message`: displays a plain text message |
-|`composeExtension.attachmentLayout`|Specifies the layout of the attachments. Used for responses of type `result`. <br>Currently the following types are supported: <br>`list`: a list of card objects containing thumbnail, title, and text fields <br>`grid`: a grid of thumbnail images |
-|`composeExtension.attachments`|Array of valid attachment objects. Used for responses of type `result`. <br>Currently the following types are supported: <br>`application/vnd.microsoft.card.thumbnail` <br>`application/vnd.microsoft.card.hero` <br>`application/vnd.microsoft.teams.card.o365connector` <br>`application/vnd.microsoft.card.adaptive`|
+|`composeExtension.type`|Type of response. The following types are supported: <br>`result`: Displays a list of search results <br>`auth`: Asks the user to authenticate <br>`config`: Asks the user to set up the messaging extension <br>`message`: Displays a plain text message |
+|`composeExtension.attachmentLayout`|Specifies the layout of the attachments. Used for responses of type `result`. <br>Currently, the following types are supported: <br>`list`: A list of card objects containing thumbnail, title, and text fields <br>`grid`: A grid of thumbnail images |
+|`composeExtension.attachments`|Array of valid attachment objects. Used for responses of type `result`. <br>Currently, the following types are supported: <br>`application/vnd.microsoft.card.thumbnail` <br>`application/vnd.microsoft.card.hero` <br>`application/vnd.microsoft.teams.card.o365connector` <br>`application/vnd.microsoft.card.adaptive`|
|`composeExtension.suggestedActions`|Suggested actions. Used for responses of type `auth` or `config`. | |`composeExtension.text`|Message to display. Used for responses of type `message`. | ### Response card types and previews
-We support the following attachment types:
+Teams supports the following card types:
* [Thumbnail card](~/task-modules-and-cards/cards/cards-reference.md#thumbnail-card) * [Hero card](~/task-modules-and-cards/cards/cards-reference.md#hero-card) * [Office 365 Connector card](~/task-modules-and-cards/cards/cards-reference.md#office-365-connector-card) * [Adaptive Card](~/task-modules-and-cards/cards/cards-reference.md#adaptive-card)
-See [What are cards](~/task-modules-and-cards/what-are-cards.md) for an overview.
+To have a better understanding and overview on cards, see [what are cards](~/task-modules-and-cards/what-are-cards.md).
-To learn how to use the thumbnail and hero card types, see [Add cards and card actions](~/task-modules-and-cards/cards/cards-actions.md).
+To learn how to use the thumbnail and hero card types, see [add cards and card actions](~/task-modules-and-cards/cards/cards-actions.md).
-For additional documentation regarding the Office 365 Connector card, see [Using Office 365 Connector cards](~/task-modules-and-cards/cards/cards-reference.md#office-365-connector-card).
+For additional information regarding the Office 365 Connector card, see [Using Office 365 Connector cards](~/task-modules-and-cards/cards/cards-reference.md#office-365-connector-card).
-The result list is displayed in the Microsoft Teams UI with a preview of each item. The preview is generated in one of two ways:
+The result list is displayed in the Microsoft Teams UI with a preview of each item. The preview is generated in one of the two ways:
* Using the `preview` property within the `attachment` object. The `preview` attachment can only be a Hero or Thumbnail card. * Extracted from the basic `title`, `text`, and `image` properties of the attachment. These are used only if the `preview` property is not set and these properties are available.
-You can display a preview of an Adaptive Card or Office 365 Connector card in the result list simply by its preview property. This is not necessary if the results are already hero or thumbnail cards. If you use the preview attachment, it must be either a Hero or Thumbnail card. If no preview property is specified, the preview of the card will fail and nothing will be displayed.
+You can display a preview of an Adaptive Card or Office 365 Connector card in the result list using its preview property. The preview property is not necessary if the results are already Hero or Thumbnail cards. If you use the preview attachment, it must be either a Hero or Thumbnail card. If no preview property is specified, the preview of the card fails and nothing is displayed.
### Response example
class TeamsMessagingExtensionsSearchBot extends TeamsActivityHandler {
## Default query
-If you set `initialRun` to `true` in the manifest, Microsoft Teams issues a "default" query when the user first opens the messaging extension. Your service can respond to this query with a set of pre-populated results. This can be useful when your search command requires authentication or configuration, displaying recently viewed items, favorites, or any other information that is not dependent on user input.
+If you set `initialRun` to `true` in the manifest, Microsoft Teams issues a **default** query when the user first opens the messaging extension. Your service can respond to this query with a set of pre-populated results. This is useful when your search command requires authentication or configuration, displaying recently viewed items, favorites, or any other information that is not dependent on user input.
-The default query has the same structure as any regular user query, with the `name` field set to `initialRun` and `value` set to `true` as in the object below.
+The default query has the same structure as any regular user query, with the `name` field set to `initialRun` and `value` set to `true` as shown in the following object:
```json {
The default query has the same structure as any regular user query, with the `na
} ```
-## Next Steps
+## Code sample
+
+| Sample Name | Description | .NET | Node.js |
+|:|:--|:|:--|
+|Teams messaging extension action| Describes how to define action commands, create task module, and respond to task module submit action. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action) |
+|Teams messaging extension search | Describes how to define search commands and respond to searches. |[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)|[View](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)|
+
+## See also
-Add authentication and/or configuration
+> [!div class="nextstepaction"]
+> [Add configuration to a messaging extension](~/messaging-extensions/how-to/add-configuration-page.md)
+
+## Next step
-* [Add authentication to a messaging extension](~/messaging-extensions/how-to/add-authentication.md)
-* [Add configuration to a messaging extension](~/messaging-extensions/how-to/add-configuration-page.md)
+> [!div class="nextstepaction"]
+> [Add authentication to a messaging extension](~/messaging-extensions/how-to/add-authentication.md)
-Deploy configuration
-* [Deploy your app package](~/concepts/deploy-and-publish/apps-upload.md)
platform What Are Messaging Extensions https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/messaging-extensions/what-are-messaging-extensions.md
Title: What are messaging extensions?
+ Title: Messaging extensions
description: An overview of messaging extensions on the Microsoft Teams platform
-# What are messaging extensions?
+# Messaging extensions
-Messaging extensions allow users to interact with your web service through buttons and forms in the Microsoft Teams client. They can search, or initiate actions, in an external system from the compose message area, the command box, or directly from a message. You can then send the results of that interaction back to the Microsoft Teams client, typically in the form of a richly formatted card.
+Messaging extensions allow the users to interact with your web service through buttons and forms in the Microsoft Teams client. They can search or initiate actions in an external system from the compose message area, the command box, or directly from a message. You can send back the results of that interaction to the Microsoft Teams client in the form of a richly formatted card. This document gives an overview of the messaging extension, tasks performed under different scenarios, working of messaging extension, action and search commands, and link unfurling.
-The screenshot below shows the locations where messaging extensions can be invoked from.
+The following image displays the locations from where messaging extensions are invoked:
![messaging extension invoke locations](~/assets/images/messaging-extension-invoke-locations.png)
-## What kinds of tasks are they good for?
+## Scenarios where messaging extensions are used
-**Scenario:** I need some external system to do something and I want the result of the action to be sent back to my conversation.\
-**Example:** Reserve a resource and let the channel know what day/time you reserved it for.
+| Scenario | Example |
+|:--|:--|
+|You want some external system to do an action and the result of the action to be sent back to your conversation.|Reserve a resource and allow the channel to know the reserved time slot.|
+|You want to find something in an external system, and share the results with the conversation.|Search for a work item in Azure DevOps, and share it with the group as an Adaptive Card.|
+|You want to complete a complex task involving multiple steps or lots of information in an external system, and share the results with a conversation.|Create a bug in your tracking system based on a Teams message, assign that bug to Bob, and send a card to the conversation thread with the bug's details.|
-**Scenario:** I need to find something in an external system, and I want to share the results with my conversation.\
-**Example:** Search for a work item in Azure DevOps, and share it with the group as an adaptive card.
+## Understand how messaging extensions work
-**Scenario:** I need to complete a complex task involving multiple steps (or lots of information) in an external system, and the results should be shared with a conversation.\
-**Example:** Create a bug in your tracking system based on a Teams message, assign that bug to Bob, then send a card to the conversation thread with the bug's details.
+A messaging extension consists of a web service that you host and an app manifest, which defines where your web service is invoked from in the Microsoft Teams client. The web service takes advantage of the Bot Framework's messaging schema and secure communication protocol, so you must register your web service as a bot in the Bot Framework.
-## How do messaging extensions work?
+> [!NOTE]
+> Though you can create the web service manually, use [Bot Framework SDK](https://github.com/microsoft/botframework) to work with the protocol.
-A messaging extension consists of a web service you host and your app manifest which defines where your web service can be invoked from in the Microsoft Teams client. They take advantage of the Bot Framework's messaging schema and secure communication protocol, so you'll also need to register your web service as a bot in the Bot Framework. Although you can create your web service completely by hand, we recommend you take advantage of the [Bot Framework SDK](https://github.com/microsoft/botframework) to make working with the protocol simpler.
-
-In the app manifest for your Microsoft Teams app you'll define a single messaging extension with up to ten different commands. Each command defines a type (action or search), and the locations in the client it can be invoked from (compose message area, command bar, and/or message). Once invoked, your web service will receive an HTTPS message with a JSON payload including all the relevant information. You'll respond with a JSON payload, letting the Teams client know what interaction to enable next.
+In the app manifest for Microsoft Teams app, a single messaging extension is defined with up to ten different commands. Each command defines a type, such as action or search and the locations in the client from where it is invoked. The invoke locations are compose message area, command bar, and message. On invoke, the web service receives an HTTPS message with a JSON payload including all the relevant information. Respond with a JSON payload, allowing the Teams client to know the next interaction to enable.
## Types of messaging extension commands
-The type of messaging extension command defines the UI elements and interaction flows available to your web service. Some interactions, like authentication and configuration, are available for both types of commands.
+There are two types of messaging extension commands, action command and search command. The messaging extension command type defines the UI elements and interaction flows available to your web service. Some interactions, such as authentication and configuration are available for both types of commands.
### Action commands
-Action commands allow you to present your users with a modal popup to collect or display information. When they submit the form, your web service can respond by inserting a message into the conversation directly, or by inserting a message into the compose message area and allowing the user to submit the message. You can even chain multiple forms together for more complex workflows.
-
-They can be triggered from the compose message area, the command box, or from a message. When invoked from a message, the initial JSON payload sent to your bot will include the entire message it was invoked from.
+Action commands are used to present the users with a modal popup to collect or display information. When the user submits the form, your web service responds by inserting a message into the conversation directly or by inserting a message into the compose message area. After that the user can submit the message. You can chain multiple forms together for more complex workflows.
+The action commands are triggered from the compose message area, the command box, or from a message. When the command is invoked from a message, the initial JSON payload sent to your bot includes the entire message it was invoked from. The following image displays the messaging extension action command task module:
![messaging extension action command task module](~/assets/images/task-module.png) ### Search commands
-Search commands allow your users to search an external system for information (either manually through a search box, or by pasting a link to a monitored domain into the compose message area), then insert the results of the search into a message. In the most basic search command flow, the initial invoke message will include the search string the user submitted. You'll respond with a list of cards and card previews. The Teams client will render the card previews in a list for the end user to select from. When the user selects a card, the full-size card will be inserted into the compose message area.
+Search commands allow the users to search an external system for information either manually through a search box, or by pasting a link to a monitored domain into the compose message area, and insert the results of the search into a message. In the most basic search command flow, the initial invoke message includes the search string that the user submitted. You respond with a list of cards and card previews. The Teams client renders a list of card previews for the user. When the user selects a card from the list, the full-size card is inserted into the compose message area.
-They can be triggered from the compose message area or the command box. Unlike action commands, they cannot be triggered from a message.
+The cards are triggered from the compose message area or the command box and not triggered from a message. They can not be triggered from a message.
+The following image displays the messaging extension search command task module:
![messaging extension search command](~/assets/images/search-extension.png)
-### Link unfurling
+> [!NOTE]
+> For more information on cards, see [what are cards](../task-modules-and-cards/what-are-cards.md).
+
+## Link unfurling
+
+A web service is invoked when a URL is pasted in the compose message area. This functionality is known as link unfurling. You can subscribe to receive an invoke when URLs containing a particular domain are pasted into the compose message area. Your web service can "unfurl" the URL into a detailed card, providing more information than the standard website preview card. You can add buttons to allow the users to immediately take action without leaving the Microsoft Teams client.
+The following images display link unfurling feature when a link is pasted in messaging extension:
+
+![unfurl link](../assets/images/messaging-extension/unfurl-link.png)
-You also have the option to invoke your service when a URL is pasted in the compose message area. This functionality, known as **link unfurling**, allows you to subscribe to receive an invoke when URLs containing a particular domain are pasted into the compose message area. Your web service can "unfurl" the URL into a detailed card, providing more information than the standard website preview card. You can even add buttons to allow your users to immediately take action without leaving the Microsoft Teams client.
+![link unfurling](../assets/images/messaging-extension/link-unfurl.gif)
-## Get Started
-Ready to get started building? Try one of our quickstarts:
+## See also
-* **C#**
- * [Messaging extension with action-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)
- * [Messaging extension with search-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)
-* **JavaScript**
- * [Messaging extension with action-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action)
- * [Messaging extension with search-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)
+> [!div class="nextstepaction"]
+> [Create a messaging extension](../build-your-first-app/build-messaging-extension.md)
-## Learn more
+## Next step
-Build a messaging extension:
+> [!div class="nextstepaction"]
+> [Define action messaging extension command](~/messaging-extensions/how-to/action-commands/define-action-command.md)
-* [Create a messaging extension](~/messaging-extensions/how-to/create-messaging-extension.md)
-* [Define action messaging extension command](~/messaging-extensions/how-to/action-commands/define-action-command.md)
-* [Define search messaging extension command](~/messaging-extensions/how-to/search-commands/define-search-command.md)
+> [!div class="nextstepaction"]
+> [Define search messaging extension command](~/messaging-extensions/how-to/search-commands/define-search-command.md)
platform Auth Bot AAD https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bot-authentication/auth-bot-AAD.md
Title: Authentication for bots using Azure Active Directory description: Describes Azure AD authentication in Teams and how to use it in your bots keywords: teams authentication bots AAD+ Last updated 03/01/2018 # Authenticate a user in a Microsoft Teams bot
platform Auth Flow Bot https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bot-authentication/auth-flow-bot.md
Title: Authentication flow for bots description: Describes authentication flow in bots keywords: teams authentication flow bots+ Last updated 03/01/2018 # Microsoft Teams authentication flow for bots
platform Auth Oauth Card https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bot-authentication/auth-oauth-card.md
Title: Using Azure Bot Service for Authentication in Teams description: Describes the Azure Bot Service OAuthCard and how it is used for authentication+ keywords: teams authentication OAuthCard OAuth card Azure Bot Service # Using Azure Bot Service for Authentication in Teams
There are currently some restrictions to where you can use the OAuthCard. These
## How does the Azure Bot Service help me do authentication?
-Full documentation using the OAuthCard is available in the topic: [Add authentication to your bot via Azure Bot Service](/azure/bot-service/bot-builder-tutorial-authentication?view=azure-bot-service-3.0). Note that this topic is in the Azure Bot Framework documentation set, and is not specific to Teams.
+Full documentation using the OAuthCard is available in the topic: [Add authentication to your bot via Azure Bot Service](/azure/bot-service/bot-builder-tutorial-authentication?view=azure-bot-service-3.0&preserve-view=true). Note that this topic is in the Azure Bot Framework documentation set, and is not specific to Teams.
The following sections tell how to use the OAuthCard in Teams.
Because access tokens are sensitive information, you may not wish to have them s
## Getting started with OAuthCard in Teams > [!NOTE]
-> This guide is using the Bot Framework v3 SDK. You can find the v4 implementation [here](/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp). You will still need to create a manifest and include token.botframework.com in the `validDomains` section, because otherwise the Sign in button will not open the authentication window. Use the [App Studio](~/concepts/build-and-test/app-studio-overview.md) to generate your manifest.
+> This guide is using the Bot Framework v3 SDK. You can find the v4 implementation [here](/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp&preserve-view=true). You will still need to create a manifest and include token.botframework.com in the `validDomains` section, because otherwise the Sign in button will not open the authentication window. Use the [App Studio](~/concepts/build-and-test/app-studio-overview.md) to generate your manifest.
YouΓÇÖll first need to configure your Azure bot service to set up external authentication providers. Read [Configuring identity providers](~/concepts/authentication/configure-identity-provider.md) for detailed steps.
platform Bots Conv Channel https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bot-conversations/bots-conv-channel.md
Title: Channel and Group chat conversations with bots description: Describes the end-to-end scenario of having a conversation with a bot in a channel in Microsoft Teams keywords: teams scenarios channels conversation bot+ Last updated 06/25/2019 # Channel and Group chat conversations with a Microsoft Teams bot
platform Bots Conv Personal https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bot-conversations/bots-conv-personal.md
Title: 1-on-1 conversations with bots description: Describes the end-to-end scenario of having a 1-on-1 conversation with a bot in Microsoft Teams keywords: teams scenarios 1on1 1to1 conversation bot+ Last updated 05/20/2019 # Have a personal (one-on-one) conversation with a Microsoft Teams bot [!include[v3-to-v4-SDK-pointer](~/includes/v3-to-v4-pointer-bots.md)]
-Microsoft Teams allows users to engage in direct conversations with bots built on the [Microsoft Bot Framework](/azure/bot-service/?view=azure-bot-service-3.0). Users can find bots in the Discover Apps gallery and add them to their Teams experience for personal conversations. Team owners and users with the appropriate permissions can also add bots as team members (see [Interact in a team channel](~/resources/bot-v3/bot-conversations/bots-conv-channel.md)), which not only makes them available in that team's channels, but for personal chat for all of those users as well.
+Microsoft Teams allows users to engage in direct conversations with bots built on the [Microsoft Bot Framework](/azure/bot-service/?view=azure-bot-service-3.0&preserve-view=true). Users can find bots in the Discover Apps gallery and add them to their Teams experience for personal conversations. Team owners and users with the appropriate permissions can also add bots as team members (see [Interact in a team channel](~/resources/bot-v3/bot-conversations/bots-conv-channel.md)), which not only makes them available in that team's channels, but for personal chat for all of those users as well.
Personal chat differs from chat in channels in that the user does not need to @mention the bot. If a bot is used in multiple contexts (personal, groupChat or channel) you will need to detect if the bot is in a group chat or channel, and process messages a little differently. See [Interact in a team channel or group chat](~/resources/bot-v3/bot-conversations/bots-conv-proactive.md) for more details.
platform Bots Conv Proactive https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bot-conversations/bots-conv-proactive.md
Title: Proactive messages description: Describes bots can start a conversation in Microsoft Teams+ keywords: teams scenarios proactive messaging conversation bot # Proactive messaging for bots
platform Bots Cards https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-cards.md
Title: Using cards in bots description: Describes cards and how they are used in bot messages keywords: bots cards messaging+ Last updated 03/29/2018 # Cards in bot conversations
platform Bots Context https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-context.md
Title: Get context for your Microsoft Teams bot description: Describes how to get context for bots in Microsoft Teams keywords: teams bots context+ Last updated 05/20/2019 # Get context for your Microsoft Teams bot
var connector = new ConnectorClient(new Uri(context.Activity.ServiceUrl));
var clientinfo = context.Activity.Entities[0]; await context.PostAsync($"ClientInfo: clientinfo "); }
-```
+```
platform Bots Files https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-files.md
Title: Sending and receiving files from a bot description: Describes how to send and receive files from a bot keywords: teams bots files send receive+ Last updated 05/20/2019 # Send and receive files through your bot
platform Bots Menus https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-menus.md
Title: Add a bot menu description: Describes how to create menus for bots in Microsoft Teams keywords: teams bots menus creation+ Last updated 05/20/2019 # Add a bot menu in Microsoft Teams
platform Bots Message Format https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-message-format.md
Title: Bot message format description: Describes the details of formatting for bot messages keywords: teams scenarios channels conversation bot message+ Last updated 05/20/2019 # Message formatting for bots
platform Bots Notification Only https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-notification-only.md
Title: Notification-only bots description: Describes what notification-only bots are in Microsoft Teams keywords: teams bots notification+ Last updated 01/29/2020 # Notification-only bots in Microsoft Teams
platform Bots Notifications https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-notifications.md
Title: Handle bot events
description: Describes how to handle events in bots for Microsoft Teams keywords: teams bots events Last updated 05/20/2019+
platform Bots Test https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-test.md
Title: Test and debug your bot description: Describes how to test bots in Microsoft Teams keywords: teams bots testing+ Last updated 03/20/2019 # Test and debug your Microsoft Teams bot
Occasionally it may be necessary to test your bot without installing it as an ap
The Bot Framework Emulator is a desktop application that allows bot developers to test and debug their bots, either locally or remotely. Using the emulator, you can chat with your bot and inspect the messages that your bot sends and receives. This can be useful for verifying that your bot is available and responding, however the emulator will not allow you to test any Teams-specific functionality you've added to your bot, nor will responses from your bot be an accurate visual representation of how they will be rendered in Teams. If you need to test either of those things it is best to [upload your bot](#test-by-uploading-to-teams).
-Complete instructions on the Bot Framework Emulator can be found [here](/azure/bot-service/bot-service-debug-emulator?view=azure-bot-service-4.0).
+Complete instructions on the Bot Framework Emulator can be found [here](/azure/bot-service/bot-service-debug-emulator?view=azure-bot-service-4.0&preserve-view=true).
### Talk to your bot directly by Id
You can also initiate a conversation with your bot by using its Id. Two methods
* From within Microsoft Teams, on the **Chat** pane, select the **Add chat** icon. For **To:**, paste your bot's Microsoft App ID.
- ![Getting the AppID for the bot](~/assets/images/bots_uploading.png)
+ ![Uploading the AppID for the bot](~/assets/images/bots_uploading.png)
The app ID should resolve to your bot name.
platform Bots Text Formats https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-text-formats.md
Title: Supported text formatting in conversations description: Describes text formatting support in bot conversations keywords: bots conversations messaging+ Last updated 03/29/2018 # Formatting bot messages
platform Bots With Tabs https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/bot-v3/bots-with-tabs.md
Title: Combine bots with tabs description: Describes how to use tabs and bots together keywords: teams bots tabs development+ Last updated 03/15/2018 # Combine bots with tabs
platform Create Messaging Extension Using Appstudio https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/create-messaging-extension-using-appstudio.md
+
+ Title: Create a messaging extension using App Studio
+
+description: Learn how to create a Microsoft Teams messaging extension using App Studio.
+++
+# Create a messaging extension using App Studio
+
+> [!TIP]
+> Looking for a faster way to get started? Create a [messaging extension](../build-your-first-app/build-messaging-extension.md) using the Microsoft Teams Toolkit.
+
+At a high level, you'll need to complete the following steps to create a messaging extension.
+
+1. Prepare your development environment
+2. Create and deploy your web service (while developing use a tunneling service like ngrok to run it locally)
+3. Register your web service with the Bot Framework
+4. Create your app package
+5. Upload your package to Microsoft Teams
+
+Creating your web service, creating your app package, and registering your web service with the Bot Framework can be done in any order. Because those three pieces are so intertwined, no matter which order you do them in you'll need return to update the others. Your registration needs the messaging endpoint from your deployed web service, and your web service needs the Id and password created from your registration. Your app manifest also needs that Id to connect Teams to your web service.
+
+As you're building your messaging extension, you'll regularly be moving between changing your app manifest, and deploying code to your web service. When working with the app manifest, keep in mind that you can either manually manipulate the JSON file, or make changes through App Studio. Either way, you'll need to re-deploy (upload) your app in Teams when you make a change to the manifest, but there's no need to do so when you deploy changes to your web service.
++
+## Create your web service
+
+The heart of your messaging extension is your web service. It will define a single route, typically `/api/messages`, to receive all requests on. If you're getting started from scratch, you have a few options to choose from.
+
+* Use one of our [quickstarts](#learn-more) tutorials that will guide you through the creation of your web service.
+* Choose one of the messaging extension samples available in the [Bot Framework sample repository](https://github.com/Microsoft/BotBuilder-Samples) to start from.
+* If you're using JavaScript, use the [Yeoman generator for Microsoft Teams](https://github.com/OfficeDev/generator-teams) to scaffold your Teams app, including your web service.
+* Create your web service from scratch. You can choose to add the Bot Framework SDK for your language, or you can work directly with the JSON payloads.
+
+## Register your web service with the Bot Framework
+
+Messaging extensions take advantage of the Bot Framework's messaging schema and secure communication protocol; if you don't already have one you'll need to register your web service on the Bot Framework. The Microsoft App Id (we'll refer to this as your Bot Id from inside of Teams, to identify it from other App Id's you might be working with) and the messaging endpoint your register with the Bot Framework will be used in your messaging extension to receive and respond to requests. If you're using an existing registration, make sure you [enable the Microsoft Teams channel](/azure/bot-service/bot-service-manage-channels.md?view=azure-bot-service-4.0&preserve-view=true).
+
+If you follow one of the quickstarts or start from one of the available samples you'll be guided through registering your web service. If you want to manually register your service you have three options to do so. If you choose to register without using an Azure subscription you will not be able to take advantage of the simplified OAuth authentication flow provided by the Bot Framework. You will be able to migrate your registration to Azure after creation.
+
+* If you have an Azure subscription (or want to create a new one), you can register your web service manually using the Azure Portal. Create a "Bot Channels Registration" resource. You can choose the free pricing tier, as messages from Microsoft Teams do not count towards your total allowable messages per month.
+* If you do not wish to use an Azure subscription, you can use the [legacy registration portal](https://dev.botframework.com/bots/new).
+* App Studio can also help you register your web service (bot). Web services registered through App Studio are not registered in Azure. You can use the [legacy portal](https://dev.botframework.com/bots) to view, manage, and migrate your registrations.
+
+## Create your app manifest
+
+You can either use App Studio to help you create your app manifest, or create it manually.
+
+### Create your app manifest using App Studio
+
+You can use the App Studio app from within the Microsoft Teams client to help create your app manifest.
+
+1. In the Teams client, open App Studio from the **...** overflow menu on the left navigation rail. If it isn't already installed, you can do so by searching for it.
+2. On the **Manifest editor** tab select **Create a new app** (or if you're adding a messaging extension to an existing app, you can import your app package)
+3. Add your app details (see [manifest schema definition](~/resources/schem) for full descriptions of each field).
+4. On the **Messaging extensions** tab click the **Setup** button.
+5. You can either create a new web service (bot) for your messaging extension to use, or if you've already registered one select/add it here.
+6. If necessary, update your bot endpoint address to point to your bot. It should look something like `https://someplace.com/api/messages`.
+7. The **Add** button in the **Command** section will guide you through adding commands to your messaging extension. See the [Learn more](#learn-more) section for links to more information on adding commands. Remember you can define up to 10 commands for your messaging extension.
+8. The **Message Handlers** section allows you to add a domain that your messaging will trigger on. See [link unfurling](~/messaging-extensions/how-to/link-unfurling.md) for more information.
+
+From the **Finish => Test and distribute** tab you can **Download** your app package (which includes your app manifest as well as your app icons), or **Install** the package.
+
+### Create your app manifest manually
+
+As with bots and tabs, you update the [app manifest](~/resources/schem#composeextensions) of your app to include the messaging extension properties. These properties govern how your messaging extension appears and behaves in the Microsoft Teams client. Messaging extensions are supported beginning with v1.0 of the manifest.
+
+#### Declare your messaging extension
+
+To add a messaging extension, include a new top-level JSON structure in your app manifest with the `composeExtensions` property. You create a single messaging extension for your app, with up to 10 commands.
+
+> [!NOTE]
+> The manifest refers to messaging extensions as `composeExtensions`. This is to maintain backward compatibility.
+
+The extension definition is an object that has the following structure:
+
+| Property name | Purpose | Required? |
+||||
+| `botId` | The unique Microsoft app ID for the bot as registered with the Bot Framework. This should typically be the same as the ID for your overall Teams app. | Yes |
+| `canUpdateConfiguration` | Enables **Settings** menu item. | No |
+| `commands` | Array of commands that this messaging extension supports. You are limited to 10 commands. | Yes |
+
+#### Define your commands
+
+Your messaging extension should declare one or more commands, which define where your users can trigger your messaging extension, and the type of interaction. See [learn more](#learn-more) for more information on messaging extension commands.
+
+#### Simple manifest example
+
+The following example is a simple messaging extension object in the app manifest with a search command. This is not the entire app manifest file, just the part specific to messaging extensions. See [app manifest schema](~/resources/schem) for a complete example.
+
+```json
+...
+"composeExtensions": [
+ {
+ "botId": "abcd1234-1fc5-4d97-a142-35bb662b7b23",
+ "canUpdateConfiguration": true,
+ "commands": [
+ {
+ "id": "searchCmd",
+ "description": "Search you ToDo's",
+ "title": "Search",
+ "initialRun": true,
+ "parameters": [
+ {
+ "name": "searchKeyword",
+ "description": "Enter your search keywords",
+ "title": "Keywords"
+ }
+ ]
+ }
+ ]
+ }
+]
+...
+```
+
+#### Complete app manifest example
+
+```json
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.8/MicrosoftTeams.schema.json",
+ "manifestVersion": "1.5",
+ "version": "1.0",
+ "id": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
+ "packageName": "com.microsoft.teams.samples.Todo",
+ "developer": {
+ "name": "John Developer",
+ "websiteUrl": "http://todobotservice.azurewebsites.net/",
+ "privacyUrl": "http://todobotservice.azurewebsites.net/privacy",
+ "termsOfUseUrl": "http://todobotservice.azurewebsites.net/termsofuse"
+ },
+ "name": {
+ "short": "To Do",
+ "full": "To Do"
+ },
+ "description": {
+ "short": "Find or create a new task in To Do",
+ "full": "Find or create a new task in To Do"
+ },
+ "icons": {
+ "outline": "todo-outline.jpg",
+ "color": "todo-color.jpg"
+ },
+ "accentColor": "#ff6a00",
+ "composeExtensions": [
+ {
+ "botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
+ "canUpdateConfiguration": true,
+ "commands": [
+ {
+ "id": "searchCmd",
+ "description": "Search you Todo's",
+ "title": "Search",
+ "initialRun": true,
+ "context": ["commandBox", "compose"],
+ "parameters": [
+ {
+ "name": "searchKeyword",
+ "description": "Enter your search keywords",
+ "title": "Keywords"
+ }
+ ]
+ },
+ {
+ "id": "addTodo",
+ "description": "Create a To Do item",
+ "title": "Create To Do",
+ "type": "action",
+ "context": ["commandBox", "message", "compose"],
+ "parameters": [
+ {
+ "name": "Name",
+ "description": "To Do Title",
+ "title": "Title",
+ "inputType": "text"
+ },
+ {
+ "name": "Description",
+ "description": "Description of the task",
+ "title": "Description",
+ "inputType": "textarea"
+ },
+ {
+ "name": "Date",
+ "description": "Due date for the task",
+ "title": "Date",
+ "inputType": "date"
+ }
+ ]
+ },
+ {
+ "id": "reassignTodo",
+ "description": "Reassign a todo item",
+ "title": "Reassign a todo item",
+ "type": "action",
+ "fetchTask": true,
+ "parameters": [
+ {
+ "name": "Name",
+ "title": "Title"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "permissions": [
+ "identity",
+ "messageTeamMembers"
+ ],
+ "validDomains": [
+ "todobotservice.azurewebsites.net",
+ "*.todobotservice.azurewebsites.net"
+ ]
+}
+```
+
+## Add your invoke message handlers
+
+When your users trigger your messaging extension you'll need to handle the initial invoke message, collect some information from the user, then process that information and respond appropriately. To do that, you'll first need to decide what kind of commands you want to add to your messaging extension and either [add an action commands](~/messaging-extensions/how-to/action-commands/define-action-command.md) or [add a search commands](~/messaging-extensions/how-to/search-commands/define-search-command.md).
+
+## Messaging extensions in Teams meetings
+
+> [!NOTE]
+> If a meeting or group chat has federated users in the roster, Teams suppresses access to messaging extensions for all users, including the organizer.
+
+Once a meeting begins, Teams participants can interact directly with your messaging extension during a live call. Consider the following when building your in-meeting messaging extension:
+
+1. **Location**. Your messaging extension can be invoked from the compose message area, the command box, or @mentioned in the meeting chat.
+
+1. **Metadata**. When your messaging extension is invoked it can identify the user and tenant from `userId` and `tenantId`. The `meetingId` can be found as part of the `channelData` object. Your app can use the `userId` and `meetingId` for the `GetParticipant` API request to retrieve user roles.
+
+1. **Command type**. If your message extension uses [action-based commands](../messaging-extensions/what-are-messaging-extensions.md#action-commands), it should follow tabs [single sign-on](../tabs/how-to/authentication/auth-aad-sso.md) authentication.
+
+1. **User experience**. You messaging extension should look and behave the same as it would outside a meeting.
+
+## Next steps
+
+* [Create action commands](~/messaging-extensions/how-to/action-commands/define-action-command.md)
+* [Create search commands](~/messaging-extensions/how-to/search-commands/define-search-command.md)
+* [Link unfurling](~/messaging-extensions/how-to/link-unfurling.md)
+
+## Learn more
+
+Try it out in a quickstart:
+
+* Quickstarts for C#
+ * [Messaging extension with action-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/51.teams-messaging-extensions-action)
+ * [Messaging extension with search-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/50.teams-messaging-extensions-search)
+* Quickstarts for JavaScript
+ * [Messaging extension with action-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/51.teams-messaging-extensions-action)
+ * [Messaging extension with search-based commands](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/50.teams-messaging-extensions-search)
+
+Learn more about Teams development concepts:
+
+* [Understand Teams app capabilities](../concepts/capabilities-overview.md)
+* [What are messaging extensions?](../messaging-extensions/what-are-messaging-extensions.md)
platform Media Formats https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/media-formats.md
keywords: teams bots media formats
# Supported media formats for bots
-Bots on Microsoft Teams supports only the following media formats for audio and video content.
+Bots on Microsoft Teams supports only the following media formats for audio and video content:
| Format | More information | | | |
Bots on Microsoft Teams supports only the following media formats for audio and
| MP3 | https://en.wikipedia.org/wiki/MP3 | | Opus | http://opus-codec.org/ | | MP4 | https://en.wikipedia.org/wiki/MPEG-4 |+
+## Next step
+
+> [!div class="nextstepaction"]
+> [Changes to Teams bot APIs for fetching Team or chat members](~/resources/team-chat-member-api-changes.md)
platform Create Extensions https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/messaging-extension-v3/create-extensions.md
Title: Initiate actions with messaging extensions description: Create Action-based messaging extensions to allow users to trigger external services+ keywords: teams messaging extensions messaging extensions search # Initiate actions with messaging extensions
platform Messaging Extensions Overview https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/messaging-extension-v3/messaging-extensions-overview.md
Title: Develop messaging extensions description: Describes how to get started with messaging extensions in Microsoft Teams+ keywords: teams messaging extensions messaging extensions # Develop messaging extensions for Microsoft Teams
platform Search Extensions https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/messaging-extension-v3/search-extensions.md
Title: Search with messaging extensions description: Describes how to develop search based messaging extensions keywords: teams messaging extensions messaging extensions search+ Last updated 07/20/2019 # Search with messaging extensions
platform Manifest Schema https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/schema/manifest-schema.md
This version string must follow the [semver](http://semver.org/) standard (MAJOR
**Required** ΓÇö Microsoft app ID
-The ID is a unique Microsoft-generated identifier for the app. You have an ID if your bot is registered through the Microsoft Bot Framework or your tab's web app already signs in with Microsoft. You must enter the ID here. Otherwise, you must generate a new ID at the Microsoft Application Registration Portal ([My Applications](https://apps.dev.microsoft.com)). Use the same ID if you add a bot.
+The ID is a unique Microsoft-generated identifier for the app. You have an ID if your bot is registered through the Microsoft Bot Framework or your tab's web app already signs in with Microsoft. You must enter the ID here. Otherwise, you must generate a new ID at the [Microsoft Application Registration Portal](https://aka.ms/appregistrations). Use the same ID if you add a bot.
> [!NOTE] > If you are submitting an update to your existing app in AppSource, the ID in your manifest must not be modified.
platform Team Chat Member Api Changes https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/team-chat-member-api-changes.md
keywords: bot framework apis team members roster
-# Changes to Teams bot APIs for fetching team and chat members
+
+# Teams bot API changes to fetch team or chat members
>[!NOTE]
-> We've started with the deprecation process for `TeamsInfo.getMembers` and `TeamsInfo.GetMembersAsync` APIs. Initially, they will be heavily throttled to 5 requests per minute and return a maximum of 10K members per team. This will result in the full roster not being returned as team size increases.
->
-> **You must update to version 4.10 or higher of the Bot Framework SDK** and switch to the paginated API endpoints, or the `TeamsInfo.GetMemberAsync` single user API. This also applies to your bot even if you're not directly using these APIs, as older SDKs call these APIs during [membersAdded](../bots/how-to/conversations/subscribe-to-conversation-events.md#team-members-added) events. To view the list of upcoming changes, see [API changes](team-chat-member-api-changes.md#api-changes).
+> The deprecation process for `TeamsInfo.getMembers` and `TeamsInfo.GetMembersAsync` APIs have started. Initially, they are heavily throttled to five requests per minute and return a maximum of 10K members per team. This results in the full roster not being returned as team size increases.
+> You must update to version 4.10 or higher of the Bot Framework SDK and switch to the paginated API endpoints, or the `TeamsInfo.GetMemberAsync` single user API. This also applies to your bot even if you are not directly using these APIs, as older SDKs call these APIs during [membersAdded](../bots/how-to/conversations/subscribe-to-conversation-events.md#team-members-added) events. To view the list of upcoming changes, see [API changes](team-chat-member-api-changes.md#api-changes).
+
+Currently, bot developers who want to retrieve information for one or more members of a chat or team use the Microsoft Teams bot APIs `TeamsInfo.GetMembersAsync` for C# or `TeamsInfo.getMembers` for TypeScript or Node.js APIs. For more information, see [fetch roster or user profile](../bots/how-to/get-teams-context.md#fetch-the-roster-or-user-profile). These APIs have several shortcomings.
-Currently, bot developers who want to retrieve information for one or more members of a chat or team use the Microsoft Teams bot APIs `TeamsInfo.GetMembersAsync` (for C#) or `TeamsInfo.getMembers` (for TypeScript/Node.js) APIs [(documented here)](../bots/how-to/get-teams-context.md#fetching-the-roster-or-user-profile). These APIs have several shortcomings today:
+Currently, if you want to retrieve information for one or more members of a chat or team, you can use the [Microsoft Teams bot APIs](https://docs.microsoft.com/microsoftteams/platform/bots/how-to/get-teams-context?tabs=dotnet#fetch-the-roster-or-user-profile) `TeamsInfo.GetMembersAsync` for C# or `TeamsInfo.getMembers` for TypeScript or Node.js APIs. These APIs have the following shortcomings:
-* **For large teams, performance is poor and timeouts are more likely.** The maximum team size has grown considerably since Microsoft Teams was released in early 2017. Since `GetMembersAsync`/`getMembers` returns the entire member list, it takes a long time for the API call to return for large teams, and itΓÇÖs not uncommon for the call to time out and you have to try again.
-* **Getting profile details for a single user is cumbersome.** To get the profile information for a single user, you have to retrieve the entire member list and then search for the one you want. True, thereΓÇÖs a helper function in the Bot Framework SDK to make it simpler, but under the covers itΓÇÖs not efficient.
+* For large teams, performance is poor and timeouts are more likely: The maximum team size has grown considerably since Teams was released in early 2017. As `GetMembersAsync` or `getMembers` returns the entire member list, it takes a long time for the API call to return for large teams, and it is common for the call to time out and you have to try again.
+* Getting profile details for a single user is difficult: To get the profile information for a single user, you have to retrieve the entire member list and then search for the one you want. There is a helper function in the Bot Framework SDK to make it simpler, but it is not efficient.
-Separately, with the introduction of org-wide teams, we realized it was time to better align these APIs with Office 365 privacy controls: bots used in large teams are able to retrieve basic profile information, which is similar to the `User.ReadBasic.All` Microsoft Graph permission. Tenant administrators have a great deal of control over which apps and bots can be used in their tenant, but these settings are different than the ones governing Microsoft Graph.
+With the introduction of organization wide teams, there is a requirement to better align these APIs with Office 365 privacy controls. Bots used in large teams are able to retrieve basic profile information similar to the `User.ReadBasic.All` Microsoft Graph permission. Tenant administrators have a great deal of control over which apps and bots can be used in their tenant, but these settings are different from Microsoft Graph.
-HereΓÇÖs a sample JSON representation of whatΓÇÖs returned by these APIs today. IΓÇÖll refer to some of the fields below.
+The following code provides a sample JSON representation of what is returned by Teams bot APIs:
```json [{
HereΓÇÖs a sample JSON representation of whatΓÇÖs returned by these APIs today.
}] ```
-## API changes
+## API Changes
+
+Following are the upcoming API changes:
+
+* A new API is created [`TeamsInfo.GetPagedMembersAsync`](https://docs.microsoft.com/microsoftteams/platform/bots/how-to/get-teams-context?tabs=dotnet#fetch-the-roster-or-user-profile) for retrieving profile information for members of a chat or team. This API is now available with the Bot Framework 4.8 SDK. For development in all other versions, use the [`GetConversationPagedMembers`](https://docs.microsoft.com/dotnet/api/microsoft.bot.connector.conversationsextensions.getconversationpagedmembersasync?view=botbuilder-dotnet-stable&preserve-view=true) method.
-Here are the upcoming API changes:
+ > [!NOTE]
+ > In either v3 or v4, the best action is to upgrade to the latest point release that is 3.30.2 or 4.8 respectively.
-* We've created a new API [`TeamsInfo.GetPagedMembersAsync`](~/bots/how-to/get-teams-context.md?tabs=dotnet#fetching-the-roster-or-user-profile) for retrieving profile information for members of a chat/team. This API is now available with the Bot Framework 4.10 SDK. For development in all other versions use the [`GetConversationPagedMembers`](/dotnet/api/microsoft.bot.connector.conversationsextensions.getconversationpagedmembersasync?view=botbuilder-dotnet-stable&preserve-view=true) method.
- > [!NOTE]
- > In either v3 or v4, the best action is to upgrade to the latest point release.
-* We've created a new API [`TeamsInfo.GetMemberAsync`](~/bots/how-to/get-teams-context.md?tabs=dotnet#get-single-member-details) for retrieving the profile information for a single user. It takes the ID of the team/chat and a [UPN](https://docs.microsoft.com/windows/win32/ad/naming-properties#userprincipalname) (`userPrincipalName`, *see above*), Azure Active Directory Object ID (`objectId`, *see above*), or the Teams user ID (`id`, *see above*) as parameters and returns the profile information for that user.
- > [!NOTE]
- > We're changing `objectId` to `aadObjectId` to match what it's called in the `Activity` object of a Bot Framework message. The new API is available with version 4.10 of the Bot Framework SDK. It will soon be available in the Teams SDK extension Bot Framework 3.x as well; meanwhile you can use the [REST](~/bots/how-to/get-teams-context.md?tabs=json#get-single-member-details) endpoint.
-* `TeamsInfo.GetMembersAsync` (C#) and `TeamsInfo.getMembers` (TypeScript/Node.js) is formally deprecated and will stop working in late 2021. Please update your bots to use the paged APIs. (This also applies to the [underlying REST API these APIs use](~/bots/how-to/get-teams-context.md?tabs=json).)
-* By late 2021, bots will not be able to proactively retrieve the `userPrincipalName` or `email` properties for members of a chat/team and will need to use Microsoft Graph to retrieve them. Specifically, `userPrincipalName` and `email` properties won't be returned from the new `GetConversationPagedMembers` API starting in late 2021. Bots will have to use Microsoft Graph with an access token to retrieve this information. This is obviously a major change: We must make it easier for bots to get an access token, and we must streamline and simplify the end-user consent process.
+* A new API is created [`TeamsInfo.GetMemberAsync`](https://docs.microsoft.com/microsoftteams/platform/bots/how-to/get-teams-context?tabs=dotnet#get-single-member-details) for retrieving the profile information for a single user. It takes the ID of the team or chat and a [UPN](https://docs.microsoft.com/windows/win32/ad/naming-properties#userprincipalname) that is `userPrincipalName`, Azure Active Directory Object ID `objectId`, or the Teams user ID `id` as parameters and returns the profile information for that user.
-## Feedback and more information
+ > [!NOTE]
+ > `objectId` is changed to `aadObjectId` to match what is called in the `Activity` object of a Bot Framework message. The new API is available with version 4.8 of the Bot Framework SDK. It is also available in the Teams SDK extension Bot Framework 3.x. Meanwhile, you can use the [REST](https://docs.microsoft.com/microsoftteams/platform/bots/how-to/get-teams-context?tabs=json#get-single-member-details) endpoint.
-We'll use this page for providing up to date information on these changes. If you have questions, use the "Send feedback > on this page" in the **Feedback** section below.
+* `TeamsInfo.GetMembersAsync` in C# and `TeamsInfo.getMembers` in TypeScript or Node.js is formally deprecated. Once the new API is available, you must update your bots to use it. This also applies to the [underlying REST API that these APIs use](https://docs.microsoft.com/microsoftteams/platform/bots/how-to/get-teams-context?tabs=json#tabpanel_CeZOj-G++Q_json).
+* By late 2021, bots cannot proactively retrieve the `userPrincipalName` or `email` properties for members of a chat or team. Bots must use Graph to retrieve them. The `userPrincipalName` and `email` properties are not returned from the new `GetConversationPagedMembers` API starting in late 2021. Bots have to use Graph with an access token to retrieve information. It must be made easier for bots to get an access token and streamline and simplify the end-user consent process.
platform Troubleshoot https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/resources/troubleshoot.md
Title: Troubleshoot your app description: Troubleshoot issues or errors while building apps for Microsoft Teams keywords: teams apps development troubleshooting+ Last updated 07/09/2018
Bots in channels receive messages only when they are explicitly @mentioned, even
### My bot doesn't understand my commands when in a channel
-Because bots in channels only receive messages when they are @mentioned, all messages that your bot receives in a channel include that @mention in the text field. It is a best practice to strip the bot name itself out of all incoming text messages before passing along to your parsing logic. Review [mentions](../bots/how-to/conversations/channel-and-group-conversations.md#working-with-mentions) for tips on how to handle this case.
+Because bots in channels only receive messages when they are @mentioned, all messages that your bot receives in a channel include that @mention in the text field. It is a best practice to strip the bot name itself out of all incoming text messages before passing along to your parsing logic. Review [mentions](../bots/how-to/conversations/channel-and-group-conversations.md#work-with-mentions) for tips on how to handle this case.
## Issues with packaging and uploading
platform App Templates https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/samples/app-templates.md
Quick Responses is a Microsoft Teams app that delivers a robust solution for eff
![Sample view of responses](../assets/images/quick-responses.png)
+## Quiz &#9734;
+
+Quiz is a custom [Teams messaging extension](../messaging-extensions/what-are-messaging-extensions.md) app that enables you to create a quiz within a chat or a channel for knowledge check and instantaneous results. You can use Quiz for, In-class and offline exams, Knowledge check within team, and for fun quizzes within a team. Quiz app is supported across multiple platforms, such as Teams desktop, browser, iOS, and Android clients. This app is ready for deployment as part of your existing Microsoft 365 subscription.
+
+[Get it on GitHub](https://github.com/OfficeDev/microsoft-teams-apps-quiz)
+
+ :::column span="1":::
+ ![Create Quiz in Teams view](../assets/images/quiz-app-template-compose-view.gif)
## Rapid Assist
A project can include multiple tasks, and various projects can be assigned to em
![Time Tally](../assets/images/11zon_gif.gif)
+## Training &#9734;
+
+Training is a custom [Teams messaging extension](../messaging-extensions/what-are-messaging-extensions.md) app that enables users to publish a training within a chat or a channel for offline knowledge sharing and upskilling. The app is supported across multiple Teams platform clients, such as desktop, browser, iOS, and Android. This app is ready for deployment as part of your Microsoft 365 subscription.
+
+[Get it on GitHub](https://github.com/OfficeDev/microsoft-teams-apps-training)
+
+ :::column span="1":::
+ ![Create Training in Teams view](../assets/images/training-app-template-compose-view.gif)
+ ## Virtual Rounding Hospital and emergency room providers make dozens, and often hundreds of **rounds** per day. These quick check-ins on patients are intended to provide a status check on how the patient is doing and ensure that the patientΓÇÖs concerns are addressed. While rounding is an essential practice to ensure patients are being monitored by multiple types of providers, they represent a huge drain on PPE, because for each visit, from each provider, a new mask, and new set of gloves must be used. With this app templates, medical workers can easily conduct rounds virtually, through a Microsoft Teams meeting between the provider and the patient.
platform Integrating Web Apps https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/samples/integrating-web-apps.md
Almost everything in Teams can be linked to directly with a [deep link](../conce
Consider the types of messages your Teams app might send now and in the long term. If you think your app will ever have a multi-threaded conversation, a [bot](../bots/what-are-bots.md) might offer more flexibility than a [webhook](../webhooks-and-connectors/what-are-webhooks-and-connectors.md).
-Bots also allow you to send *proactive messages* to individual users or channels. These are unprompted messages triggered by an outside event and not a message sent to a bot. (For example, your bot can send a welcome message when it's installed or a new user joins a channel.)
+Bots also allow you to send *proactive messages* to individual users or channels. These are unprompted messages triggered by an outside event and not a message sent to a bot. (For example, your bot can send a welcome message when it's installed or a new user joins a channel.)
-Sending proactive messages requires Teams-specific identifiersΓÇöyou can capture this information by [fetching roster or user profile data](../bots/how-to/get-teams-context.md#fetching-the-roster-or-user-profile), [subscribing to conversation events](../bots/how-to/conversations/subscribe-to-conversation-events.md), or using [Microsoft Graph](https://docs.microsoft.com/graph/teams-proactive-messaging).
+Sending proactive messages requires Teams-specific identifiersΓÇöyou can capture this information by [fetching roster or user profile data](../bots/how-to/get-teams-context.md#fetch-the-roster-or-user-profile), [subscribing to conversation events](../bots/how-to/conversations/subscribe-to-conversation-events.md), or using [Microsoft Graph](https://docs.microsoft.com/graph/teams-proactive-messaging).
Be careful not to spam users with excessive messages. If the Teams capability supports it, consider letting users configure notification settings for your app (for example, "Don't send me unprompted messages.").
platform Access Teams Context https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/tabs/how-to/access-teams-context.md
Title: Get context for your tab description: Describes how to get user context to your tabs+ keywords: teams tabs user context
platform Cards Actions https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/task-modules-and-cards/cards/cards-actions.md
Title: Add card actions in a bot description: Describes card actions in Microsoft Teams and how to use them in your bots+ keywords: teams bots cards actions + # Card actions Cards used by bots and messaging extensions in Teams support the following activity ([`CardAction`](/bot-framework/dotnet/bot-builder-dotnet-add-rich-card-attachments#process-events-within-rich-cards)) types. Note that these actions differ from `potentialActions` for Office 365 Connector cards when used from Connectors.
platform Cards Format https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/task-modules-and-cards/cards/cards-format.md
Title: Text formatting in cards description: Describes card text formatting in Microsoft Teams keywords: teams bots cards format+ Last updated 03/29/2018
The date and localization features mentioned in this topic are not supported in
### Mention support within Adaptive cards v1.2
-Card based mentions are supported in Web, Desktop and mobile clients. You can add @ mentions within an Adaptive card body for bots and messaging extension responses. To add @ mentions in cards, follow the same notification logic and rendering as that of message based [mentions in channel and group chat conversations](../../bots/how-to/conversations/channel-and-group-conversations.md#working-with-mentions ).
+Card based mentions are supported in web, desktop and mobile clients. You can add @ mentions within an adaptive card body for bots and messaging extension responses. To add @ mentions in cards, follow the same notification logic and rendering as that of message based [mentions in channel and group chat conversations](../../bots/how-to/conversations/channel-and-group-conversations.md#work-with-mentions).
Bots and messaging extensions can include mentions within the card content in [TextBlock](https://adaptivecards.io/explorer/TextBlock.html) and [FactSet](https://adaptivecards.io/explorer/FactSet.html) elements.
platform Task Modules Bots https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/task-modules-and-cards/task-modules/task-modules-bots.md
Title: Using Task Modules in Microsoft Teams bots description: How to use task modules with Microsoft Teams bots, including Bot Framework cards, Adaptive cards, and deep links.+ keywords: task modules teams bots # Using task modules from Microsoft Teams bots
platform Task Modules Tabs https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/task-modules-and-cards/task-modules/task-modules-tabs.md
Title: Using Task Modules in Microsoft Teams tabs
-description: Explains how invoke task modules from Teams tabs using the Microsoft Teams client SDK.
+description: Explains how to invoke task modules from Teams tabs using the Microsoft Teams client SDK.
+ keywords: task modules teams tabs client sdk + # Using task modules in tabs Adding a task module to your tab can greatly simplify your user's experience for any workflows that require data input. Task modules allow you to gather their input in a Teams-aware popup. A good example of this is editing Planner cards; you can use task modules to create a similar experience.
platform What Are Cards https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/task-modules-and-cards/what-are-cards.md
Title: Introducing cards description: Describes cards and how they are used in bots, connectors and messaging extensions+ keywords: connectors bots cards messaging + # Cards A *card* is a user-interface (UI) container for short or related pieces of information. Cards can have multiple properties and attachments. Cards can include buttons which can trigger [Card actions](~/task-modules-and-cards/cards/cards-actions.md).
platform Connectors Using https://github.com/MicrosoftDocs/msteams-docs/commits/master/msteams-platform/webhooks-and-connectors/how-to/connectors-using.md
Application rate limits control the traffic that a connector or an incoming webh
*See also* [Office 365 Connectors ΓÇö Microsoft Teams](https://docs.microsoft.com/connectors/teams/)
-A [retry logic with exponential back-off](/azure/architecture/patterns/retry) like below would mitigate rate limiting for cases where requests are exceeding the limits within a second. Please follow [best practices](../../bots/how-to/rate-limit.md#best-practices) to avoid hitting the rate limits.
+A [retry logic with exponential back-off](/azure/architecture/patterns/retry) like below would mitigate rate limiting for cases where requests are exceeding the limits within a second. Refer [HTTP 429 responses](../../bots/how-to/rate-limit.md#handle-http-429-responses) to avoid hitting the rate limits.
```csharp // Please note that response body needs to be extracted and read