title | description | author | ms.localizationpriority | ms.subservice | ms.custom |
---|---|---|---|---|---|
Get change notifications for messages in Teams channels and chats using Microsoft Graph |
Change notifications enable you to listen to changes to messages in channel or chat |
RamjotSingh |
high |
teams |
scenarios:getting-started |
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.
Continue with this article about scenarios for the chatMessage resource in the channel or chat context. Or, find out about change notifications for other Microsoft Teams resources.
Note
If you request a subscription expirationDateTime that is more than 1 hour in the future, you must subscribe to lifecycle notifications by including a lifecycleNotificationUrl property in your subscription request. Otherwise your subscription request will fail with the following error message: lifecycleNotificationUrl is a required property for subscription creation on this resource when the expirationDateTime value is set to greater than 1 hour.
To track all changes related to messages in a tenant, you can use subscriptions at a tenant level for channel and chat messages, creating two subscriptions: one to track all messages across channels, and one to track all messages across chats.
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.
[!INCLUDE teams-model-A-and-B-disclaimer]
Permission type | Permissions (from least to most privileged) |
---|---|
Delegated (work or school account) | Not supported. |
Delegated (personal Microsoft account) | Not supported. |
Application | ChannelMessage.Read.All |
POST https://graph.microsoft.com/v1.0/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}"
}
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.
[!INCLUDE teams-model-A-and-B-disclaimer]
Permission type | Permissions (from least to most privileged) |
---|---|
Delegated (work or school account) | Not supported. |
Delegated (personal Microsoft account) | Not supported. |
Application | Chat.Read.All |
POST https://graph.microsoft.com/v1.0/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}"
}
To track messages and replies in a channel, you can create a change notification subscription at a channel level by subscribing 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.
Permission type | Permissions (from least to most privileged) |
---|---|
Delegated (work or school account) | ChannelMessage.Read.All |
Delegated (personal Microsoft account) | Not supported. |
Application | ChannelMessage.Read.Group*, ChannelMessage.Read.All |
Note: Permissions marked with * are supported as part of resource-specific consent.
POST https://graph.microsoft.com/v1.0/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}"
}
The following request sends messages that contain Hello
to the subscriber.
POST https://graph.microsoft.com/v1.0/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}"
}
POST https://graph.microsoft.com/v1.0/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}"
}
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/v1.0/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}"
}
To track messages in a chat, you can create a change notification subscription at a chat level by subscribing 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.
Permission type | Permissions (from least to most privileged) |
---|---|
Delegated (work or school account) | Chat.Read |
Delegated (personal Microsoft account) | Not supported. |
Application | ChatMessage.Read.Chat*, Chat.Read.All |
Note: Permissions marked with * are supported as part of resource-specific consent for the beta version only currently.
POST https://graph.microsoft.com/v1.0/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}"
}
The following request sends messages that contain Hello
to the subscriber.
POST https://graph.microsoft.com/v1.0/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}"
}
POST https://graph.microsoft.com/v1.0/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}"
}
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/v1.0/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}"
}
To track messages across all chats a particular user is part of, you can create a change notification subscription at a user level by subscribing 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.
[!INCLUDE teams-model-B-disclaimer]
Permission type | Permissions (from least to most privileged) |
---|---|
Delegated (work or school account) | Chat.Read, Chat.ReadWrite |
Delegated (personal Microsoft account) | Not supported. |
Application | Chat.Read.All, Chat.ReadWrite.All |
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}"
}
To get change notifications for all messages across chats in a tenant where a specific Teams app is installed, subscribe to /appCatalogs/teamsApps/{teams-app-id}/installedToChats/getAllMessages
. This resource supports including resource data in the notification.
[!INCLUDE teams-model-B-disclaimer]
Permission type | Permissions (from least to most privileged) |
---|---|
Delegated (work or school account) | Not supported. |
Delegated (personal Microsoft account) | Not supported. |
Application | Chat.Read.WhereInstalled, Chat.ReadWrite.WhereInstalled |
POST https://graph.microsoft.com/v1.0/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/appCatalogs/teamsApps/386bbcdb-1e1c-4f3f-b7d0-ad7b9ea6cf7c/installedToChats/getAllMessages",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
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.
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 give you enough information to make GET calls to get the message content. Subscriptions for notifications without resource data don't 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 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 returns the updated message.
- Microsoft Graph change notifications
- Get change notifications for teams and channels using Microsoft Graph
- Get change notifications for membership changes in teams and channels using Microsoft Graph
- Get change notifications for chats using Microsoft Graph
- Get change notifications for chat membership using Microsoft Graph
- Microsoft Teams API overview