Using the Office 365 Connector Incoming WebHook to Post Service Health Information

Office 365 Connectors

Exploiting Office 365 Connectors for Groups and Teams

Office 365 Groups and Microsoft Teams both support Connectors, which allow cards representing information drawn from a wide range of network data resources to be created in group conversations or team chats.

A card holds a snippet of information extracted from a network data source, like Twitter or an RSS feed for a blog. They’re not intended to be full extracts, such as the complete text of a blog post. Instead, cards are there to notify users about events. Some cards include methods, like a hyperlink, to bring users to the original source.

Connector sources

The set of network sources that Connectors support is now over 90, including those featured on project activities (Trello, Asana, and Wunderlist), customer relationships (Salesforce, Dynamics 365, and Zendesk), news (Bing News, Twitter, and RSS feeds), and developer tools (GitHub and Visual Studio). In addition, an “Incoming Webhook” connector is available as a generic link to allow developers to fetch data from other services to an Outlook group. Programmers can use the webhook to create a link to a group for a company-specific system or some other network data source for which a connector does not currently exist.

Connecting one of these sources to a group or team is simple. Use OWA or a Teams client to select the source to which you want to connect, give the necessary credentials to authenticate to the data source, find the data you want to extract, and let the data flow.

It’s also worth noting that Microsoft is working on “actionable messages” that leverage a subset of the connectors available for groups and teams. The same idea applies in that items from a network source flow from the source to a destination (in this case, a user’s Inbox) and are created there as cards. The cards are “actionable” because the user can interact with the content. For example, an actionable card created from a tweet allows you to retweet or like the tweet while cards created through the Twitter connector for a group are read-only. The feature is now in preview.

Creating Your Own Source for Connectors

Nice as it is to have so many out-of-the-box connectors, it’s always interesting to be able to link up your own data source. Microsoft makes this straightforward by providing the Incoming Webhook connector.

The function of the Incoming Webhook connector is to receive incoming HTTP requests containing simple JSON-format payloads. Once received, the connector routes the information to a destination Office 365 Group or Microsoft Team (the webhook address) where the information is created as a new card. If the connector links to a team, a new chat is created using the inbound information.

Therefore, to connect a data source to a group or team, all you need to do is:

  1. Identify the data source to use. Any data source is acceptable if you can extract relevant information from it.
  2. Decide on the destination – an Office 365 group or a team.
  3. Create an Incoming Webhook connector for the destination.
  4. Extract data from the source and format the data as a JSON payload.
  5. Post the data to the webhook address.

Sounds easy enough. Let’s figure out what needs to be done to get something going.

Identify a Data Source

I decided to use the Office 365 Service Communication API as a data source, mostly because it can be used with PowerShell. Microsoft is currently previewing V2 of the API, so the PowerShell code to interrogate service health is likely to change when V2 is generally available. However, it works for now and that’s enough for test purposes.

Create an Incoming Webhook Connector

Before we can create a new connector, we need an Office 365 Group to host the cards that we’re going to create. I created a new group from OWA and then selected the Connectors option in the toolbar. I then selected Incoming Webhook from the list of available connectors and then Add to arrive at the screen shown in Figure 1. Here we decide what to call the webhook and whether to replace the default icon with a different image. Although I uploaded an image, OWA had the good taste to ignore it thereafter when displaying cards. The image appears in Outlook, so that is a little bug.

New Webhook connector
Figure 1: Creating a new Incoming Webhook Connector (image credit: Tony Redmond)

When you click Create, Office 365 responds with a URL. This is the webhook address that you need to specify to route information to the connector. The webhook address is of the form:

https://outlook.office365.com/webhook/f47702b9-d4a9-414a-9056-d6b0230ebfa9@b662313f-14fc-43a2-9a7a-d2e27f4f3478/IncomingWebhook/5f6096b8eb304191b09553e56a909253/eff4cd58-1bb8-4899-94de-795f656b4a18

The webbook address is a critical piece of information because without it you can’t route items to the destination group or team. Copy it to the clipboard and store it for use. If you forget to do this, you can always access the webhook address by managing the connector.

Extract Data

Now the fun part begins because we have to write some code to extract the data from the source that we want to use. For this example, we’re going to import the Office 365 Service Communications module into a PowerShell session that is already connected to Exchange Online. We then fetch details about current service incidents using the API to create a set of objects. Before you can use the Office 365 Service Communications module, you’ll have to fetch and install it using an administrator account:

[PS] C:\> Find-Module O365ServiceCommunications | Install-Module -Scope CurrentUser

After the module is installed, we can connect and use it to fetch service information.

[PS] C:\> Import-Module O365ServiceCommunications
$O365ServiceSession = New-SCSession -Credential $O365Cred
$Incidents = Get-SCEvent -EventTypes Incident -PastDays 2 -SCSession $O365ServiceSession | Sort StartTme -Descending | Select-Object Id, Status, StartTime,
@{n='ServiceName'; e={$_.AffectedServiceHealthStatus.servicename}},
@{n='Message';e={$_.messages[0].messagetext}}

Formatting Payloads

Payloads enable us to transmit information through the connector to end up in the group. The important things to remember are that:

  • Some practice is needed to master the creation of the JSON content using PowerShell. It is best to start with a basic card and then gradually build up the full content for the cards you want to create.
  • Full information about how to format the JSON payload is available in the Office 365 Connectors API Reference.
  • Posting to the connector depends on proper formatting of the payload. You might be able to convert your payload to JSON successfully using the ConvertTo-JSON cmdlet only to find that the payload is rejected when it is submitted to the connector using the Invoke-RestMethod All of which leads to hours of fun debugging payloads.

So here goes. First, we put the webhook address into a variable to make it easier to handle. We also create some other variables to use in the card.

$InfoFeed = " https://outlook.office365.com/webhook/f47702b9-d4a9-414a-9056-d6b0230ebfa9@b662313f-14fc-43a2-9a7a-d2e27f4f3478/IncomingWebhook/5f6096b8eb304191b09553e56a909253/eff4cd58-1bb8-4899-94de-795f656b4a18”

Now we build the JSON payload in a PowerShell variable. For this example, we extract details of the latest service incident from the set retrieved from the Service Communications API. Note how different elements of a service incident are formatted in name-value pairs.

$InfoBit = ConvertTo-Json -Depth 4 @{
Text = "Office 365 Service Update"
Title = "New Office 365 Service Information at " + (Get-Date -Format U)
Summary = $Incidents.ServiceName[0] + " incident"
sections = @(
  @{
  facts = @(
     @{
     name = "Incident Number"
     value = $Incidents.ID[0]
     },
     @{
     name = "Affected Service:"
     value = $Incidents.ServiceName[0]
     },
     @{
     name = "Current Status:"
     value = $Incidents.Status[0]
     },
     @{
     name = "Start date:"
     value = Get-Date $Incidents.StartTime[0] -Format u
     },
     @{
     name = "Information:"
     value = $Incidents.Message[0]
     }
   )
  }
 )
}

Submitting the Payload

The Invoke-RestMethod cmdlet submits the payload to the connector, which is identified by the webhook address.

Invoke-RestMethod -ContentType "Application/Json" -Method Post -Body $InfoBit -Uri $InfoFeed

If everything goes well, the cmdlet will respond with 1 (one) to indicate that the post was successful. And of course, a new card should appear in the target group (Figure 2).

Office 365 service incident via webhook
Figure 2: A service incident posted via the Incoming Webhook connector (image credit: Tony Redmond)

No Checking

One thing you’ll have noticed about this code is that it features no error checking. We grab the latest service incident and use it. No validation is present to see if any service incidents are present (a simple check against $Incidents.Count would be enough) nor do we verify whether the service incident has already been posted to the group. But the joy of PowerShell is the speed in which you can prove that something works. Adding the code normally found in operational-quality scripts can be left to later.

Connectors are Fun

It’s surprising just how much value can be extracted through Office 365 Connectors for both Office 365 Groups and Microsoft Teams. The out-of-the-box connectors are very functional, but it’s great to be able to use the Incoming Webhook connector to grab information from other systems and post that data too.

Follow Tony on Twitter @12Knocksinna.

Want to know more about how to manage Office 365? Find what you need to know in “Office 365 for IT Pros,” the most comprehensive eBook covering all aspects of Office 365. Available in PDF and EPUB formats (suitable for iBooks) or for Amazon Kindle.