{"id":3858,"date":"2020-02-28T12:43:40","date_gmt":"2020-02-28T19:43:40","guid":{"rendered":"https:\/\/developer.microsoft.com\/en-us\/office\/blogs\/?p=3858"},"modified":"2020-02-28T12:43:40","modified_gmt":"2020-02-28T19:43:40","slug":"announcing-change-notifications-for-microsoft-teams-messages","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/announcing-change-notifications-for-microsoft-teams-messages\/","title":{"rendered":"Announcing change notifications for Microsoft Teams messages"},"content":{"rendered":"<p>One of the most common requests we receive in UserVoice is change notifications for messages.\u00a0 Developers want to build apps that can listen to Microsoft Teams messages in near-real time, without polling, to enable scenarios such as bots that listen to messages on which they aren&#8217;t @mentioned, or assist with enterprise information archiving and data loss prevention. \u00a0We are pleased to announce that developers can now <a href=\"https:\/\/docs.microsoft.com\/graph\/api\/subscription-post-subscriptions?view=graph-rest-beta\">subscribe to change notifications<\/a> for Microsoft Teams messages. This feature is available in beta on the Microsoft Graph API.<\/p>\n<p>Using the Microsoft Graph <a href=\"https:\/\/docs.microsoft.com\/graph\/api\/subscription-post-subscriptions?view=graph-rest-beta\">POST \/subscriptions<\/a> API, developers can subscribe to messages in a particular channel (<a href=\"https:\/\/docs.microsoft.com\/graph\/api\/channel-list-messages?view=graph-rest-beta\">\/teams\/{id}\/channels\/{id}\/messages<\/a>) or in a particular 1:1 or group chat thread\u00a0(<a href=\"https:\/\/docs.microsoft.com\/graph\/api\/chatmessage-list?view=graph-rest-beta\">\/chats\/{id}\/messages<\/a>). You can hear about new messages, replies, edits, reactions, and deletes.<\/p>\n<p>Developers can also subscribe to all messages in a tenant. This requires the creation of two subscriptions: one for the <a href=\"https:\/\/docs.microsoft.com\/graph\/api\/subscription-post-subscriptions?view=graph-rest-beta\">\/teams\/allMessages<\/a> resource and one for <a href=\"https:\/\/docs.microsoft.com\/graph\/api\/subscription-post-subscriptions?view=graph-rest-beta\">\/chats\/allMessages<\/a>. Note that during the preview, you may use this API without fees, subject to the <a href=\"https:\/\/docs.microsoft.com\/legal\/microsoft-apis\/terms-of-use?context=graph\/context\">Microsoft APIs Terms of Use<\/a>. However, users of apps that use the API might be required to have subscriptions to specific Microsoft 365 offerings. Upon general availability, Microsoft may require you or your customers to pay additional fees based on the amount of data accessed through the API.<\/p>\n<p>As with all Microsoft Graph webhooks, creating a subscription starts with passing in the URL of the webhook you wish Graph to call back to, and validating the subscription creation within your web service. When a new message arrives, Graph will send that message to your webhook. <a href=\"https:\/\/docs.microsoft.com\/graph\/api\/resources\/chatmessage?view=graph-rest-beta\">Teams messages<\/a> are the first Graph resource to support <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/webhooks-with-resource-data\">webhooks with resource data<\/a>, so you don\u2019t need to make a second API call to retrieve the message text.<\/p>\n<p><span data-contrast=\"none\">Example \u2014 Setting up a Teams message subscription<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span><\/p>\n<pre class=\"\"><b><span data-contrast=\"auto\">POST https:\/\/graph.microsoft.com\/beta\/subscriptions\u00a0<\/span><\/b><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">{<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">  \"resource\": \"<\/span><a href=\"mailto:teams\/97edf8ce-b0f5-4bc8-91e8-7c73185f18c0\/channels\/19:945129d1eede4536a6a9811e71d7b2a6@thread.skype\/messages\"><span data-contrast=\"none\">teams\/97edf8ce-b0f5-4bc8-91e8-7c73185f18c0\/channels\/19:945129d1eede4536a6a9811e71d7b2a6@thread.skype\/messages<\/span><\/a><span data-contrast=\"auto\">\",<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\"> \u00a0<\/span><span data-contrast=\"auto\">\"notificationUrl\": \"<\/span><a href=\"https:\/\/1234.ngrok.io\/subscription\"><span data-contrast=\"none\">https:\/\/apps.contoso.com\/messageswebhookhandler<\/span><\/a><span data-contrast=\"auto\">\",<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:257}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">  \"changeType\": \"created,updated,deleted\",<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">  \"clientState\": \"6b5acd8b-98d1-48be-a8be-e12842fadcd5\",<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">  \"expirationDateTime\": \"2020-02-13T01:33:09.1416264Z\",<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">  \"encryptionCertificate\": \"MIIDNDCCAhygAwIBAgIQLR3AKZYNS42E<\/span><span data-contrast=\"auto\">....<\/span><span data-contrast=\"auto\">\",<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">  \"encryptionCertificateId\": \"70ffad80b880496a968e83091174a979\",<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">  \"includeProperties\": \"True\"<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span>\n<span data-contrast=\"auto\">}<\/span><span data-contrast=\"none\">\u00a0<\/span><\/pre>\n<p><span data-contrast=\"auto\">After you request the subscription, Microsoft Graph will ping your URL to confirm that it wants notifications. <\/span><span data-contrast=\"auto\">As subsequent messages are updated, you will see requests to your web services that look as follows:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span><\/p>\n<pre class=\"\">POST https:\/\/apps.contoso.com\/messageswebhookhandler\u00a0\n{\n  \"value\": [\n    {\n      <strong>\"encryptedContent\": {\n<\/strong>        <strong>\"data\": \"zotuEncwI9pBgKeFMcUlxBs3u+I6pvH54skorpmLQjf8pi2....\",<\/strong> \n        \"dataSignature\": \"E\/GsVEUAzZGbunSNlx8IPBKjgab\/lqga2\/A+iO\/vMME=\",\n        \"dataKey\": \"lXMs2rLdpx\/uCB4iZv2ahU23X\/...\", \n        \"encryptionCertificateId\": \"70ffad80b880496a968e83091174a979\", \n        \"encryptionCertificateThumbprint\": \"84DAB632CC42024DD80441A1B0C307B953BD5A2E\" \n      },\n      \"subscriptionId\": \"da94613a-d11a-41e2-b635-295a59b29f3b\",\n      \"changeType\": \"created\",\n      \"tenantId\": \"139d16b4-7223-43ad-b9a8-674ba63c7924\",\n      \"clientState\": \"ClientSecret\",\n      \"subscriptionExpirationDateTime\": \"2020-02-13T01:33:09.1416264+00:00\",\n      \"resource\": \"teams('9403afc6-f959-413d-ba83-873ace7b51c7')\/channels('19:fbc4cd1ea9ff4cd89cf1d734cf9e3c87@thread.skype')\/messages('1581553690121')\/replies('1581554024315')\",\n      \"resourceData\": {\n        \"id\": \"1581554024315\",\n        \"@odata.type\": \"#Microsoft.Graph.ChatMessage\",\n        \"@odata.id\": \"teams('9403afc6-f959-4312-ba83-873ace7b51c7')\/channels('19:fbc4cd1ea9ff4cd89cf1d734cf9e3c87@thread.skype')\/messages('1581553690121')\/replies('1581554024315')\"\n      }\n    }\n  ],\n  \"validationTokens\": [\n    \"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6I.....\"\n  ]\n}<\/pre>\n<p>Decrypting the\u00a0encryptedContent\u00a0gives the full message details:<\/p>\n<pre class=\"\">{\n<strong>  \"body\": {<\/strong>\n<strong>    \"contentType\": \"text\",<\/strong>\n<strong>    \"content\": \"Hello world!\"<\/strong>\n<strong>  },<\/strong>\n  \"id\": \"1581554024315\",\n  \"replyToId\": \"1581553690121\",\n  \"etag\": \"1581554024315\",\n  \"messageType\": \"message\",\n  \"createdDateTime\": \"2020-02-13T00:33:44Z\",\n  \"lastModifiedDateTime\": null,\n  \"deletedDateTime\": null,\n  \"subject\": null,\n  \"summary\": null,\n  \"importance\": \"normal\",\n  \"locale\": \"en-us\",\n  \"webUrl\": \"https:\/\/teams.microsoft.com\/l\/message\/19%3Afbc4cd1ea9ff4cd89cf1d734cf9e3c87%40thread.skype\/1581554024315?groupId=9403afc6-f959-4312-ba83-873ace7b51c7&amp;tenantId=139d16b4-7223-43ad-b9a8-674ba63c7924&amp;createdTime=1581554024000&amp;parentMessageId=1581553690121\",\n  \"from\": {\n    \"application\": null,\n    \"device\": null,\n    \"user\": {\n      \"id\": \"7ed20f7a-09c6-4a47-8ebf-a6a1f2588624\",\n      \"displayName\": \"Megan Bowen\",\n      \"userIdentityType\": \"aadUser\"\n    },\n    \"conversation\": null\n  },\n  \"attachments\": [],\n  \"mentions\": [],\n  \"policyViolation\": null,\n  \"reactions\": [],\n  \"replies\": [],\n  \"hostedContents\": []\n}<\/pre>\n<h3><span data-contrast=\"none\">Next steps<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559738&quot;:40,&quot;335559739&quot;:0,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"none\">You can get started by\u00a0<\/span><span data-contrast=\"none\">trying<\/span><span data-contrast=\"none\">\u00a0<\/span><span data-contrast=\"none\">out\u00a0<\/span><span data-contrast=\"none\">the<\/span><span data-contrast=\"none\">\u00a0<\/span><a href=\"https:\/\/github.com\/microsoftgraph\/csharp-webhook-with-resource-data\"><span data-contrast=\"none\">sample app<\/span><\/a><span data-contrast=\"none\">.<\/span><span data-contrast=\"none\">\u00a0 See<\/span><span data-contrast=\"none\">\u00a0the<\/span><span data-contrast=\"none\">\u00a0<\/span><a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/api\/subscription-post-subscriptions?view=graph-rest-beta&amp;tabs=http\"><span data-contrast=\"none\">documentation<\/span><\/a><span data-contrast=\"none\">\u00a0for more information about Microsoft Teams messaging webhooks.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">If you have any feedback about or suggestions for these APIs, please let us know via\u00a0<\/span><a href=\"https:\/\/microsoftgraph.uservoice.com\/forums\/920506-microsoft-graph-feature-requests?category_id=359626\"><span data-contrast=\"none\">User Voice<\/span><\/a><span data-contrast=\"none\">\u00a0(under Teamwork).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">Happy hacking!<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span><\/p>\n<p><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}\" data-wac-het=\"1\">\u00a0<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the most common requests we receive in UserVoice is change notifications for messages.\u00a0 Developers want to build apps that can listen to Teams messages in near-real time, without polling, to enable scenarios such as bots that listen to messages on which they aren&#8217;t @mentioned, or assist with enterprise information archiving and data loss prevention. \u00a0We are pleased to announce that developers can now subscribe to change notifications for Microsoft Teams messages. This feature is available in beta on the Microsoft Graph API.<\/p>\n","protected":false},"author":69096,"featured_media":25159,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3,128],"tags":[63],"class_list":["post-3858","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-graph","category-microsoft-teams","tag-webhooks"],"acf":[],"blog_post_summary":"<p>One of the most common requests we receive in UserVoice is change notifications for messages.\u00a0 Developers want to build apps that can listen to Teams messages in near-real time, without polling, to enable scenarios such as bots that listen to messages on which they aren&#8217;t @mentioned, or assist with enterprise information archiving and data loss prevention. \u00a0We are pleased to announce that developers can now subscribe to change notifications for Microsoft Teams messages. This feature is available in beta on the Microsoft Graph API.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/3858","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/69096"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=3858"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/3858\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/25159"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=3858"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=3858"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=3858"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}