Get change notifications for messages in Teams channels and chats using Microsoft Graph
Change notifications enable you to subscribe to changes (create, update, and delete) to messages in a channel or chat. Change notifications provide a low latency model by allowing you to maintain a subscription. You can also get the resource data in the notifications and therefore avoid calling the API to get the payload.
Subscribe to changes at the tenant level
To track all changes related to messages in a tenant, you can use subscriptions at a tenant level for channel and chat messages. This requires you to create two subscriptions: one to track all messages across channels, and one to track all messages across chats.
Subscribe to messages across all channels
To get change notifications for all messages and replies across channels in a tenant, subscribe to /teams/getAllMessages. This resource supports including resource data in the notification.
Note: This API has licensing and payment requirements. It supports both
model=Aandmodel=Bquery parameters. If no model is specified, evaluation mode will be used.
Permissions
| Permission type | Permissions (from least to most privileged) | Supported versions |
|---|---|---|
| Delegated (work or school account) | Not supported. | Not supported. |
| Delegated (personal Microsoft account) | Not supported. | Not supported. |
| Application | ChannelMessage.Read.All | beta, v1.0 |
Example
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/teams/getAllMessages",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Subscribe to messages across all chats
To get change notifications for all messages across chats in a tenant, subscribe to /chats/getAllMessages. This resource supports including resource data in the notification.
Note: This API has licensing and payment requirements. It supports both
model=Aandmodel=Bquery parameters. If no model is specified, evaluation mode will be used.
Permissions
| Permission type | Permissions (from least to most privileged) | Supported versions |
|---|---|---|
| Delegated (work or school account) | Not supported. | Not supported. |
| Delegated (personal Microsoft account) | Not supported. | Not supported. |
| Application | Chat.Read.All | beta, v1.0 |
Example
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated,deleted",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/chats/getAllMessages",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Subscribe to messages in a channel
To track messages and replies in a channel, you can create a change notification subscription at a channel level. To do this, subscribe to /teams/{team-id}/channels/{channel-id}/messages. This resource supports including resource data in the notification in both delegated and application-only mode.
Channel-level subscriptions also support keyword-based search via the $search query parameter.
Permissions
| Permission type | Permissions (from least to most privileged) | Supported in version |
|---|---|---|
| Delegated (work or school account) | ChannelMessage.Read.All | beta, v1.0 |
| Delegated (personal Microsoft account) | Not supported. | Not supported. |
| Application | ChannelMessage.Read.Group*, ChannelMessage.Read.All | beta, v1.0 |
Note: Permissions marked with * are supported as part of resource-specific consent.
Example 1: Subscribe to all messages (and replies) in a channel
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/teams/{team-id}/channels/{channel-id}/messages",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Example 2: Subscribe to messages (and replies) in a channel that contain certain text
The following request will send messages that contain Hello to the subscriber.
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/teams/{team-id}/channels/{channel-id}/messages?$search=Hello",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Example 3: Subscribe to messages (and replies) in a channel without resource data
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/teams/{team-id}/channels/{channel-id}/messages",
"includeResourceData": false,
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Example 4: Subscribe to messages (and replies) in a channel that mention a specific user
To get notifications only for messages where a specific user has been mentioned, you can specify the user's ID (9a6eb4d1-826b-48b1-9627-b50836c8fee9 in this example) in the query.
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/teams/{team-id}/channels/{channel-id}/messages?$filter=mentions/any(u: u/mentioned/user/id eq '9a6eb4d1-826b-48b1-9627-b50836c8fee9')",
"includeResourceData": false,
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Subscribe to messages in a chat
To track messages in a chat, you can create a change notification subscription at a chat level. To do this, subscribe to /chats/{chat-id}/messages. This resource supports including resource data in the notification in both delegated and application-only mode.
Chat-level subscriptions also support keyword-based search via the $search query parameter.
Note. Subcribing to messages in a chat is currently in preview.
Permissions
| Permission type | Permissions (from least to most privileged) | Supported in version |
|---|---|---|
| Delegated (work or school account) | Chat.Read | beta, v1.0 |
| Delegated (personal Microsoft account) | Not supported. | Not supported. |
| Application | ChatMessage.Read.Chat*, Chat.Read.All | beta, v1.0 |
Note: Permissions marked with * are supported as part of resource-specific consent for the beta version only currently.
Example 1: Subscribe to messages in a chat
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/chats/{chat-id}/messages",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Example 2: Subscribe to messages in a chat that contain certain text
The following request will send messages that contain Hello to the subscriber.
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/chats/{chat-id}/messages?$search=Hello",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Example 3: Subscribe to messages (and replies) in a chat without resource data
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/chats/{chat-id}/messages",
"includeResourceData": false,
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Example 4: Subscribe to message in a chat in which a specific user is mentioned
To get notifications only for messages in which a specific user has been mentioned, you can specify the user's ID (9a6eb4d1-826b-48b1-9627-b50836c8fee9 in this example) in the query.
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/chats/{chat-id}/messages?$filter=mentions/any(u: u/mentioned/user/id eq '9a6eb4d1-826b-48b1-9627-b50836c8fee9')",
"includeResourceData": false,
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Subscribe to changes at the user level
To track messages across all chats a particular user is part of, you can create a change notification subscription at a user level. To do this, subscribe to /users/{user-id}/chats/getAllMessages. This resource supports including resource data in the notification in both delegated and application-only modes.
User-level chat messaging subscriptions also support keyword-based search via the $search query parameter.
Note: In the future, Microsoft may require you or your customers to pay additional fees based on the amount of data accessed through the API.
Permissions
| Permission type | Permissions (from least to most privileged) | Supported in version |
|---|---|---|
| Delegated (work or school account) | Chat.Read, Chat.ReadWrite | beta |
| Delegated (personal Microsoft account) | Not supported. | Not supported. |
| Application | Chat.Read.All, Chat.ReadWrite.All | beta |
Example: Subscribe to messages across all chats a particular user is part of
POST https://graph.microsoft.com/beta/subscriptions
Content-Type: application/json
{
"changeType": "created,updated,deleted",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/users/{user-id}/chats/getAllMessages",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
Notification payloads
Depending on your subscription, you can either get the notification with resource data, or without it. Subscribing with resource data allows you to get the message payload along with the notification, removing the need to call back and get the content.
Notifications with resource data
For notifications with resource data, the payload looks like the following. This payload is for a message sent in a chat.
{
"value": [{
"subscriptionId": "10493aa0-4d29-4df5-bc0c-ef742cc6cd7f",
"changeType": "created",
"clientState": "<<--SpecifiedClientState-->>",
"subscriptionExpirationDateTime": "2021-02-02T10:30:34.9097561-08:00",
"resource": "chats('19:8ea0e38b-efb3-4757-924a-5f94061cf8c2_97f62344-57dc-409c-88ad-c4af14158ff5@unq.gbl.spaces')/messages('1612289765949')",
"resourceData": {
"id": "1612289765949",
"@odata.type": "#Microsoft.Graph.chatMessage",
"@odata.id": "chats('19:8ea0e38b-efb3-4757-924a-5f94061cf8c2_97f62344-57dc-409c-88ad-c4af14158ff5@unq.gbl.spaces')/messages('1612289765949')"
},
"encryptedContent": {
"data": "<<--EncryptedContent-->",
"dataKey": "<<--EnryptedDataKeyUsedForEncryptingContent-->>",
"encryptionCertificateId": "<<--IdOfTheCertificateUsedForEncryptingDataKey-->>",
"encryptionCertificateThumbprint": "<<--ThumbprintOfTheCertificateUsedForEncryptingDataKey-->>"
},
"tenantId": "<<--TenantForWhichNotificationWasSent-->>"
}],
"validationTokens": ["<<--ValidationTokens-->>"]
}
For details about how to validate tokens and decrypt the payload, see Set up change notifications that include resource data.
The decrypted notification payload looks like the following. The payload conforms to the chatMessage schema. The payload is similar to that returned by GET operations.
{
"id": "1612289992105",
"replyToId": null,
"etag": "1612289992105",
"messageType": "message",
"createdDateTime": "2021-02-02T18:19:52Z",
"lastModifiedDateTime": "2021-02-02T18:19:52.105Z",
"lastEditedDateTime": null,
"deletedDateTime": null,
"subject": null,
"summary": null,
"chatId": "19:8ea0e38b-efb3-4757-924a-5f94061cf8c2_97f62344-57dc-409c-88ad-c4af14158ff5@unq.gbl.spaces",
"importance": "normal",
"locale": "en-us",
"webUrl": null,
"from": {
"application": null,
"device": null,
"user": {
"id": "8ea0e38b-efb3-4757-924a-5f94061cf8c2",
"displayName": "Ramjot Singh",
"userIdentityType": "aadUser"
},
"conversation": null
},
"body": {
"contentType": "text",
"content": "test"
},
"channelIdentity": null,
"attachments": [],
"mentions": [],
"policyViolation": null,
"reactions": [],
"replies": [],
"hostedContents": []
}
Notifications without resource data
Notifications without resource data give you enough information to make GET calls to get the message content. Subscriptions for notifications without resource data do not require an encryption certificate (because actual resource data isn't sent over).
The payload looks like the following. This payload is for a message sent in a channel.
{
"subscriptionId": "9f9d1ed0-c9cc-42e7-8d80-a7fc4b0cda3c",
"changeType": "created",
"tenantId": "<<--TenantForWhichNotificationWasSent-->>",
"clientState": "<<--SpecifiedClientState-->>",
"subscriptionExpirationDateTime": "2021-02-02T11:26:41.0537895-08:00",
"resource": "teams('fbe2bf47-16c8-47cf-b4a5-4b9b187c508b')/channels('19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2')/messages('1612293113399')",
"resourceData": {
"id": "1612293113399",
"@odata.type": "#Microsoft.Graph.chatMessage",
"@odata.id": "teams('fbe2bf47-16c8-47cf-b4a5-4b9b187c508b')/channels('19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2')/messages('1612293113399')"
}
}
The resource and @odata.id properties can be used to make calls to Microsoft Graph to get the payload for the message. GET calls will always return the current state of the message. If the message is changed between when the notification is sent and when the message is retrieved, the operation will return the updated message.
See also
الملاحظات
إرسال الملاحظات وعرضها المتعلقة بـ