Create and send messages
Important
Microsoft 365 Connectors (previously called Office 365 Connectors) are nearing deprecation, and the creation of new Microsoft 365 Connectors will soon be blocked. For more information on the schedule and how the Workflows app provides a more flexible and secure experience, see retirement of Microsoft 365 connectors within Microsoft Teams.
How can you create a webhook in Teams?
To automatically post to a chat or channel when a webhook request is received, use the predefined workflow templates or create a workflow from scratch using the When a Teams webhook request is received trigger. For more information, see post a workflow when a webhook request is received in Microsoft Teams..
For more information about the When a Teams webhook request is received trigger, see Microsoft Teams - Webhook.
If you've already built Office 365 Connectors:
Create a Power Automate connector: Power Automate enhances the widely used Workflows apps in Teams. It's the scalable and secure approach to transmit data programmatically into and out of Teams. If you adopt this method, you can create workflow templates for posting alerts from your product to Teams channels. This approach simplifies user adoption of the new method. For more information, see Power Automate for enterprise developers, ISVs, and partners.
Update your Teams app: You can enhance your current Teams app. For example, you can enable users to set up proactive messages based on trigger events within your system. For more information, see how bots can post to channels through proactive messages.
Known issues
- Workflows app can't post in private channels as a flow bot. However, it can post on behalf of a user.
- Workflows support Adaptive Cards only. It doesn't support the older message card format that Office 365 Connectors use. The support for the use of message card format within Workflows becomes available from mid-October. For more information, see how to convert connector message card format to Adaptive Card.
- Workflows don't offer third-party connectors such as DataDog and Jenkins.
- Workflows can only be created in your default environment.
Limitations
Workflows are linked only to specific users (referred to as owners of the workflow) and not to a Teams team or channel. Workflows can become orphan flows in the absence of an owner if no co-owners assigned. To maintain continuity in the business process automated by the flow, admins can add one or more co-owners and grant them full control over the workflow. They can also add authentication for connections, if any, and enable the flow if it has been disabled. For more information, see manage orphan flows.
To create and send actionable messages, use either an Incoming Webhook or a Microsoft 365 connector. However, the actionable messages are accessible only to users with an Exchange Online license.
Create actionable messages
The actionable messages include six visible buttons on the card. Each button is defined in the potentialAction
property of the message by using ActionCard
actions, each with an input type, a text field, a date picker, or a multiple-choice list. Each ActionCard
has an associated action, for example HttpPOST
.
The connector cards support the following actions:
ActionCard
: Presents one or more input types and associated actions.HttpPOST
: Sends POST request to a URL.OpenUri
: Opens URI in a separate browser or app. Optionally, targets different URIs based on operating systems.
The ActionCard
action supports three input types:
TextInput
: A single line or multiline text field with an optional length limit.DateInput
: A date selector with an optional time selector.MultichoiceInput
: An enumerated list of choices offering either a single selection or multiple selections.
MultichoiceInput
supports a style
property that controls whether the list initially appears fully expanded. The default value of style
depends on the value of isMultiSelect
as follows:
isMultiSelect |
default style |
---|---|
false or not specified |
compact |
true |
expanded |
To display the multiple-selection list in the compact style, specify "isMultiSelect": true
and "style": true
.
For more information on connector card actions, see Actions.
Note
- Specifying
compact
for thestyle
property in Microsoft Teams is the same as specifyingnormal
for thestyle
property in Microsoft Outlook. - For the HttpPOST action, the bearer token is included with the requests. This token includes the Microsoft Entra identity of the Microsoft 365 user who took the action.
Send a message through Incoming Webhook or connector for Microsoft 365 Groups
To send a message through your Incoming Webhook or connector for Microsoft 365 Groups, post a JSON payload to the webhook URL. This payload must be in the form of a connector card for Microsoft 365 Groups.
You can also use this JSON to create cards containing rich inputs, such as text entry, multiselect, or selecting date and time. The code that generates the card and posts it to the webhook URL can run on any hosted service. These cards are defined as part of actionable messages and are also supported in cards used in Teams bots and message extensions.
Example of connector message
An example of connector message is as follows:
{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "0076D7",
"summary": "Larry Bryant created a new task",
"sections": [{
"activityTitle": "Larry Bryant created a new task",
"activitySubtitle": "On Project Tango",
"activityImage": "https://adaptivecards.io/content/cats/3.png",
"facts": [{
"name": "Assigned to",
"value": "Unassigned"
}, {
"name": "Due date",
"value": "Mon May 01 2017 17:07:18 GMT-0700 (Pacific Daylight Time)"
}, {
"name": "Status",
"value": "Not started"
}],
"markdown": true
}],
"potentialAction": [{
"@type": "ActionCard",
"name": "Add a comment",
"inputs": [{
"@type": "TextInput",
"id": "comment",
"isMultiline": false,
"title": "Add a comment here for this task"
}],
"actions": [{
"@type": "HttpPOST",
"name": "Add comment",
"target": "https://video2.skills-academy.com/outlook/actionable-messages"
}]
}, {
"@type": "ActionCard",
"name": "Set due date",
"inputs": [{
"@type": "DateInput",
"id": "dueDate",
"title": "Enter a due date for this task"
}],
"actions": [{
"@type": "HttpPOST",
"name": "Save",
"target": "https://video2.skills-academy.com/outlook/actionable-messages"
}]
}, {
"@type": "OpenUri",
"name": "Learn More",
"targets": [{
"os": "default",
"uri": "https://video2.skills-academy.com/outlook/actionable-messages"
}]
}, {
"@type": "ActionCard",
"name": "Change status",
"inputs": [{
"@type": "MultichoiceInput",
"id": "list",
"title": "Select a status",
"isMultiSelect": "false",
"choices": [{
"display": "In Progress",
"value": "1"
}, {
"display": "Active",
"value": "2"
}, {
"display": "Closed",
"value": "3"
}]
}],
"actions": [{
"@type": "HttpPOST",
"name": "Save",
"target": "https://video2.skills-academy.com/outlook/actionable-messages"
}]
}]
}
The following image is an example of the connector message card in a channel:
Send messages using cURL and PowerShell
To post a message in the webhook with cURL, follow these steps:
Install cURL from cURL website.
From the command line, enter the following cURL command:
// on macOS or Linux curl -H 'Content-Type: application/json' -d '{"text": "Hello World"}' <YOUR WEBHOOK URL>
// on Windows curl.exe -H "Content-Type:application/json" -d "{'text':'Hello World'}" <YOUR WEBHOOK URL>
Note
If the POST succeeds, you must see a simple 1 output by
curl
.Check the Teams client for the new card posted.
Send Adaptive Cards using an Incoming Webhook
Note
- All native Adaptive Card schema elements, except
Action.Submit
, are fully supported. - The supported actions are Action.OpenURL, Action.ShowCard, and Action.ToggleVisibility.
To send Adaptive Cards with text or a Base64 encoded image through an Incoming Webhook, follow these steps:
- Set up a custom webhook in Teams.
- Create Adaptive Card JSON file using the following code:
{
"type":"message",
"attachments":[
{
"contentType":"application/vnd.microsoft.card.adaptive",
"contentUrl":null,
"content":{
"$schema":"http://adaptivecards.io/schemas/adaptive-card.json",
"type":"AdaptiveCard",
"version":"1.2",
"body":[
{
"type": "TextBlock",
"text": "For Samples and Templates, see [https://adaptivecards.io/samples](https://adaptivecards.io/samples)"
}
]
}
}
]
}
The properties for Adaptive Card JSON file are as follows:
- The
"type"
field must be"message"
. - The
"attachments"
array contains a set of card objects. - The
"contentType"
field must be set to Adaptive Card type. - The
"content"
object is the card formatted in JSON.
Test your Adaptive Card with Postman:
- Test the Adaptive Card using Postman to send a POST request to the URL, created to set up Incoming Webhook.
- Paste the JSON file in the body of the request and view the Adaptive Card message in Teams.
Tip
Use Adaptive Card code samples and templates to test the body of POST request.
Rate limiting for connectors
Application rate limits control the traffic that a connector or an Incoming Webhook is permitted to generate on a channel. Teams tracks requests using a fixed rate window and incremental counter measured in seconds. If more than four requests are made in a second, the client connection is throttled until the window refreshes for the duration of the fixed rate.
Transactions per second thresholds
The following table provides the time based transaction details:
Time in seconds | Maximum allowed requests |
---|---|
1 | 4 |
30 | 60 |
3600 | 100 |
7200 | 150 |
86400 | 1800 |
Note
A retry logic with exponential back-off can mitigate rate limiting for cases where requests are exceeding the limits within a second. Refer HTTP 429 responses to avoid hitting the rate limits.
// Please note that response body needs to be extracted and read
// as Connectors do not throw 429s
try
{
// Perform Connector POST operation
var httpResponseMessage = await _client.PostAsync(IncomingWebhookUrl, new StringContent(content));
// Read response content
var responseContent = await httpResponseMessage.Content.ReadAsStringAsync();
if (responseContent.Contains("Microsoft Teams endpoint returned HTTP error 429"))
{
// initiate retry logic
}
}
These limits are in place to reduce spamming a channel by a connector and ensures an optimal experience to users.
See also
Platform Docs