Teams Activity Notifications using Azure Services
15 May 2021Introduction
The Microsoft Teams activity feed is a great way to notify users of any items that require their attention. These notifications appear in the Activity tab of Microsoft Teams client and contain multiple bits of information that give details about the activity notification. For example, the below activity notification informs the user about the sender, notification reason, and some other helpful information.
The Microsoft Graph Activity Feed API allows us to send such activity notifications to users and extend this functionality in custom apps. This article explores one such approach of delivering activity notifications to users in Teams using an Azure Event Grid, Azure Function, Teams App, and Microsoft Graph. This solution can be used for sending activity notifications triggered from any external events or custom apps to users in Teams.
Solution Design
The below diagram describes the different components and steps to send the activity notifications to users using Azure AD App credentials.
- Any custom app publishes an event to an Event Grid Custom Topic sending notification details like userId, taskId, notificationUrl.
- The event notifies the Event Grid Subscription for this topic.
- An associated Event Grid triggered Azure Function gets called from the subscription.
- This function calls Microsoft Graph API using an AAD App’s credentials to send the activity notification to Teams user.
Solution Components
The below sections highlight the different components involved in the solution and the role they play.
Teams App Manifest
A Microsoft Teams app is required to use the Microsoft Graph Activity Feed API. This app specifies the types of activity notifications that need to be delivered and AAD App Registration details for the activity notifications. This app requires installation for all the users to whom notifications need to be delivered. The below steps need to be followed at a high level to update the Teams app manifest for sending activity notifications:
- Create an Azure AD App Registration and grant it the TeamsActivity.Send application permissions on Microsoft Graph.
- Create a Client Secret for this app and copy it somewhere along with the ClientId and TenantId as these would be required later.
- Create a Teams app manifest (or reuse an existing one), with manifest version 1.7 or higher, and add the below sections to it:
- webApplicationInfo section with the App ID and a redirect URI of the AAD App Registration created in the previous step.
"webApplicationInfo": { "id": "f0f1763a-c8c6-413e-8e50-e33828fa0ccf", "resource": "https://localhost.com" }
- activities section with the different types of activities we want to deliver.
"activities": { "activityTypes": [ { "type": "taskCreated", "description": "Task Created Activity", "templateText": "{actor} created task {taskId} for you" //The Actor + Reason specifying who did what action } ] }
- webApplicationInfo section with the App ID and a redirect URI of the AAD App Registration created in the previous step.
The complete Teams app manifest for this solution is available here.
Azure Function
An event grid triggered Azure Function would get executed every time our custom event occurs. This function would be making the Microsoft Graph API calls to send the activity notification to the user. It would require the previously copied Azure AD App Registration’s credentials to authenticate with Microsoft Graph API. The below steps help create the Azure Function:
- Create an Event Grid Triggered C# Azure Function in VS Code and add the Microsoft.Graph and Microsoft.Identity.Client Nuget packages.
- Call the Users.Teamwork.SendActivityNotification method of the Graph SDK to send the activity notification to a user.
GraphServiceClient graphServiceClient = new GraphServiceClient(authenticationProvider);
var topic = new TeamworkActivityTopic
{
Source = TeamworkActivityTopicSource.Text,
Value = "New Task Created", //Topic text
WebUrl = notificationUrl
};
var activityType = "taskCreated";
var previewText = new ItemBody
{
Content = "A new task has been created for you" //Text Preview for the activity notification.
};
var templateParameters = new List<KeyValuePair>()
{
new KeyValuePair
{
Name = "taskId",
Value = taskId
}
};
await graphServiceClient.Users[userId].Teamwork
.SendActivityNotification(topic, activityType, null, previewText, templateParameters)
.Request()
.PostAsync();
- Deploy the code to an Azure Function App using the VS Code Azure Function extension.
Full source code of the Azure Function for this solution is available here.
Azure Event Grid
Azure Event Grid is a service to build event-based applications. It has a subscription-based architecture with a Topic, where the publisher can send events, and that topic can have multiple Subscriptions that can call event handlers. Further details are available here.
For our solution, an Event Grid Custom Topic is provisioned to which any external publisher or custom app can send events. This custom topic would have a subscription that would trigger the Azure Function created above. The below steps help achieve this functionality:
- Create an Azure Event Grid Topic.
- Create an Event Subscription for the topic and select the Azure Function as the endpoint.
- Get the Event Grid Topic endpoint and Access Key values and copy them somewhere.
- Using Postman/Curl, send a POST request to the Topic endpoint along with the Access Key value in the aeg-sas-key request header and the below data in the request body.
- userId is the user’s Id in Microsoft Graph to whom the notification needs to be delivered. It gets retrieved by calling the https://graph.microsoft.com/v1.0/me?$select=id endpoint in Microsoft Graph Explorer.
- taskId can be any Id to identify the notification task.
- notificationUrl can be a Teams app deep link that should open when the user clicks on the notification.
[
{
"id": "165466",
"eventType": "taskCreated",
"subject": "myTasks/newTask",
"eventTime": "2020-15-05T13:52:13Z",
"data": {
"userId": "d80e2e60-4674-4092-ad44-5478ca51e397",
"taskId": "165466",
"notificationUrl": "https://teams.microsoft.com/l/entity/e0943252-73eb-43cd-8162-e1532f8265db/MyTasks"
},
"dataVersion": "1.0"
}
]
If everything is working as per expectation, then there must be an activity notification sent to the user that will appear as a popup and in the Activity tab of Teams.
Conclusion
Similarly, the Post request to the event grid topic can be forwarded using any custom application that would trigger the Azure Function to send activity notifications to Teams users on-demand using the App credentials.