Sending messages to Connectors and Webhooks

To send a message through your Office 365 Connector or incoming webhook, you post a JSON payload to the webhook URL. Typically this payload will be in the form of an Office 365 Connector Card.

You can also use this JSON to create cards containing rich inputs, such as text entry, multi-select, or picking a date and time. The code that generates the card and posts to the webhook URL can be running on any hosted service. These cards are defined as part of actionable messages, and are also supported in cards used in Teams bots and Messaging extensions.

Example Connector message

{
    "@type": "MessageCard",
    "@context": "http://schema.org/extensions",
    "themeColor": "0076D7",
    "summary": "Larry Bryant created a new task",
    "sections": [{
        "activityTitle": "![TestImage](https://47a92947.ngrok.io/Content/Images/default.png)Larry Bryant created a new task",
        "activitySubtitle": "On Project Tango",
        "activityImage": "https://teamsnodesample.azurewebsites.net/static/img/image5.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": "http://..."
        }]
    }, {
        "@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": "http://..."
        }]
    }, {
        "@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": "http://..."
        }]
    }]
}

This message produces the following card in the channel.

Screenshot of a Connector card

Creating actionable messages

The example in the preceding section includes three visible buttons on the card. Each button is defined in the potentialAction property of the message by using ActionCard actions, each containing an input type: a text field, a date picker, or a multi-choice list. Each ActionCard action has an associated action, for example HttpPOST.

Connector cards support three types of actions:

  • ActionCard Presents one or more input types and associated actions
  • HttpPOST Sends a POST request to a URL
  • OpenUri Opens a URI in a separate browser or app; optionally targets different URIs based on operating systems

(A fourth action, ViewAction, is still supported but no longer needed; use OpenUri instead.)

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 A 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.

isMultiSelect style default
false or not specified compact
true expanded

If you want a multiselect list initially displayed in the compact style, you must specify both "isMultiSelect": true and "style": true.

Note

Specifying compact for the style property in Microsoft Teams is the same as specifying normal for the style property in Microsoft Outlook.

For all other details about Connector card actions, see Actions in the actionable message card reference.

Setting up a custom incoming webhook

Follow these steps to see how to send a simple card to a Connector.

  1. In Microsoft Teams, choose More options () next to the channel name and then choose Connectors.
  2. Scroll through the list of Connectors to Incoming Webhook, and choose Add.
  3. Enter a name for the webhook, upload an image to associate with data from the webhook, and choose Create.
  4. Copy the webhook to the clipboard and save it. You'll need the webhook URL for sending information to Microsoft Teams.
  5. Choose Done.

Post a message to the webhook using cURL

The following steps use cURL. We assume that you have this installed and are familiar with its basic usage.

  1. From the command line, enter the following cURL command:

    curl -H "Content-Type: application/json" -d "{\"text\": \"Hello World\"}" <YOUR WEBHOOK URL>
    
  2. If the POST succeeds, you should see a simple 1 output by curl.

  3. Check the Microsoft Team client. You should see the new card posted to the team.

Post a message to the webhook using PowerShell

The following steps use PowerShell. We assume that you have this installed and are familiar with its basic usage.

  1. From the PowerShell prompt, enter the following command:

    Invoke-RestMethod -Method post -ContentType 'Application/Json' -Body '{"text":"Hello World!"}' -Uri <YOUR WEBHOOK URL>
    
  2. If the POST succeeds, you should see a simple 1 output by Invoke-RestMethod.

  3. Check the Microsoft Teams channel associated with the webhook URL. You should see the new card posted to the channel.

  • Include two icons, following the instructions in Icons.
  • Modify the icons portion of the manifest to refer to the file names of the icons instead of URLs.

The following manifest.json file contains the basic elements needed to test and submit your app.

Note

Replace id and connectorId in the following example with the GUID of your Connector.

Example manifest.json with Connector

{
  "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
  "manifestVersion": "1.5",
  "id": "e9343a03-0a5e-4c1f-95a8-263a565505a5",
  "version": "1.0",
  "packageName": "com.sampleapp",
  "developer": {
    "name": "Publisher",
    "websiteUrl": "https://www.microsoft.com",
    "privacyUrl": "https://www.microsoft.com",
    "termsOfUseUrl": "https://www.microsoft.com"
  },
  "description": {
    "full": "This is a small sample app we made for you! This app has samples of all capabilities Microsoft Teams supports.",
    "short": "This is a small sample app we made for you!"
  },
  "icons": {
    "outline": "sampleapp-outline.png",
    "color": "sampleapp-color.png"
  },
  "connectors": [
    {
      "connectorId": "e9343a03-0a5e-4c1f-95a8-263a565505a5",
      "scopes": [
        "team"
      ]
    }
  ],
  "name": {
    "short": "Sample App",
    "full": "Sample App"
  },
  "accentColor": "#FFFFFF",
  "needsIdentity": "true"
}

Testing your Connector

To test your Connector, upload it to a team as you would with any other app. You can create a .zip package using the manifest file from the Connectors Developer Dashboard (modified as directed in the preceding section) and the two icon files.

After you upload the app, open the Connectors list from any channel. Scroll to the bottom to see your app in the Uploaded section.

Screenshot of uploaded section in Connector dialog box

You can now launch the configuration experience. Be aware that this flow occurs entirely within Microsoft Teams through a pop-up window. Currently, this behavior differs from the configuration experience in Connectors that we created; we are working on unifying the experiences.

To verify that an HttpPOST action is working correctly, use your custom incoming webhook.

Rate limiting for Connectors

This limit controls the traffic that a connector or an incoming webhook is allowed to generate on a channel.

Time-period (sec) Max allowed message requests
1 4
30 60
3600 100
7200 150

A retry logic with exponential back-off like below would mitigate rate limiting for cases where requests are exceeding the limits within a second. Please follow best practices 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 your end users.