{"id":40285,"date":"2021-06-16T00:27:10","date_gmt":"2021-06-16T07:27:10","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/premier-developer\/?p=40285"},"modified":"2021-06-15T07:23:23","modified_gmt":"2021-06-15T14:23:23","slug":"getting-started-with-graph-api-and-teams","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/premier-developer\/getting-started-with-graph-api-and-teams\/","title":{"rendered":"Getting Started with Graph API and Teams"},"content":{"rendered":"<p><a href=\"https:\/\/www.linkedin.com\/in\/reedrobison\/\" target=\"_blank\" rel=\"noopener\">Reed Robison<\/a> extends a simple JavaScript Single-Page Application (SPA) to integrate with Teams using Microsoft Graph API.<\/p>\n<hr \/>\n<p>In my <a href=\"https:\/\/devblogs.microsoft.com\/premier-developer\/getting-started-with-graph-api-and-graph-explorer\/\">last post<\/a>, I covered a basic introduction to Graph API using Graph Explorer and a developer tenant. This is the easiest way to get started with Graph API. In this post, I\u2019ll look at how to setup an app registration and move some of these concepts into a custom application that uses Graph API.\u00a0 We&#8217;ll build on an existing Graph Tutorial, review some concepts, and add support for sending a chat message in Teams.<\/p>\n<p>Before you go through this, be sure you have a <a href=\"https:\/\/developer.microsoft.com\/en-us\/microsoft-365\/dev-program\">developer tenant setup<\/a> and verify that you can successful sign in.<\/p>\n<h3>Building the Graph Tutorial Sample App<\/h3>\n<p>There are several different samples you could build on found in <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/tutorials\">Microsoft Graph Tutorials<\/a>. Let\u2019s start with this very basic <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/tutorials\/javascript\">JavaScript sample<\/a> that uses a single-page app and Node to spin up a HTTP server to host it. There are a LOT of tutorial samples out there that use different languages, dev environments, tools, etc. The code may <em>look<\/em> different, but the concepts are all similar. Once you get the concepts down, it\u2019s easy to adapt them in whatever language and environment you prefer.<\/p>\n<p>The existing MS graph tutorial for <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/tutorials\/javascript?tutorial-step=1\">Create a JavaScript single-page app<\/a> tutorial has you copy and paste to create six files (index.html, style.css, auth.js, graph.js, ui.js, and config.js) that make up the code.\u00a0 You can use any editor you like. I used VS Code but there are no dependencies on the tool you use. Just create the files in the same directory you started your web server using npx.<\/p>\n<h3>Step #1 is to <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/tutorials\/javascript?tutorial-step=1\">Create the JavaScript Single-page app<\/a>.<\/h3>\n<p>When you complete this step, browse to <a href=\"http:\/\/localhost:8080\">http:\/\/localhost:8080<\/a> and if all goes well, you should see the app load in your browser:<\/p>\n<p><img decoding=\"async\" width=\"1277\" height=\"421\" class=\"wp-image-40286\" src=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-7.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-7.png 1277w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-7-300x99.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-7-1024x338.png 1024w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-7-768x253.png 768w\" sizes=\"(max-width: 1277px) 100vw, 1277px\" \/><\/p>\n<p>Before this app is functional, we need to configure the app registration and auth library before the sign-in will work.\u00a0 We&#8217;ll do that in the next steps 2 and 3.<\/p>\n<p><strong>An important note before you continue.<\/strong> Online samples are great&#8211; when they work. Technology is always moving forward and that means things change constantly. Azure AD and MS Graph are no exception, so you may find many of the online samples need some tweaking to make them work if things have changed since they were created.\u00a0 If you find that something has changed and the info below no longer works for any reason, leave a comment and I\u2019ll update my post.<\/p>\n<p>I picked the <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/tutorials\/javascript?tutorial-step=1\">Create a JavaScript single-page app<\/a> because there are almost no dependencies to break or SDKs to install, but there are still a few config changes I needed to make:<\/p>\n<p>1) Azure AD recently started to enforce \u201c<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/active-directory\/fundamentals\/concept-fundamentals-security-defaults\">Security Defaults<\/a>\u201d which will try to require Multi-Factor authentication. That\u2019s a good practice, but for the sake of this demo and getting started\u2013 we don\u2019t want to dive too deep yet and I don\u2019t to get into MFA yet. You will need to turn off security defaults to start with (or else you need to work through setting up MFA)\n<img decoding=\"async\" width=\"1133\" height=\"907\" class=\"wp-image-40287\" src=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-8.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-8.png 1133w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-8-300x240.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-8-1024x820.png 1024w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-8-768x615.png 768w\" sizes=\"(max-width: 1133px) 100vw, 1133px\" \/><\/p>\n<p>2) Also, when you setup the App Registration, AAD will default the client type to Web. Make sure you follow the tutorial and change this to Single-Page Application (SPA) or auth will not work from the JavaScript test app.<\/p>\n<p>3) Use a Private or Incognito browsing session when you test to ensure you get to pick the credentials that get passed during development.<\/p>\n<h3><strong>Step #2 is to <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/tutorials\/javascript?tutorial-step=2\">register the sample app in the portal<\/a><\/strong><\/h3>\n<p>As you work through <strong>Step 2<\/strong>, you will sign in to Azure Active Directory using the developer account and tenant you setup earlier.<\/p>\n<p>Make sure you copy the App ID when you are done (you\u2019ll need this ID to update your code). Your ID will be different than the screen shot below as these are uniquely generated every time you register an application.<\/p>\n<p><img decoding=\"async\" width=\"987\" height=\"383\" class=\"wp-image-40288\" src=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-9.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-9.png 987w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-9-300x116.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-9-768x298.png 768w\" sizes=\"(max-width: 987px) 100vw, 987px\" \/><\/p>\n<h3>Step #3 is to <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/tutorials\/javascript?tutorial-step=3\">Add Azure AD Authentication to the app<\/a><\/h3>\n<p><strong>Step 3<\/strong> modifies config.js to wire up the authentication and fully implements auth.js for MSAL. You should have filled in your config.js with your ClientId from your app registration.<\/p>\n<p>I don\u2019t want to re-create all the tutorial instructions here (you can follow the 3 Steps in the base tutorial), but for the sake of understanding the concepts of what you did, let\u2019s review:<\/p>\n<ol>\n<li>You launched a local web server to host the app using Node (npx http-server -c -1)<\/li>\n<li>You created a simple web app using JavaScript consisting of index.html, style.css, auth.js, graph.js, ui.js, and config.js in the directory where you launched the web server.<\/li>\n<li>Of those files, auth.js and graph.js handle the authentication using MSAL. Config.js is the configuration passed into MSAL which contains your App ID and the scopes needed to complete the calls the Graph API.<\/li>\n<li>You created an App Registration in AAD for the JavaScript Single-Page Application.<\/li>\n<li>You updated the authentication code in the app with your newly registered App ID, local URI, and configured the MSAL code to handle the tokens returned from AAD.<\/li>\n<\/ol>\n<p>Once all this is done, you should be able to browse to <a href=\"http:\/\/localhost:8080\">http:\/\/localhost:8080<\/a> and successfully sign-in.<\/p>\n<p><em>*<\/em><strong><em>Tip<\/em><\/strong><em> \u2013 Use Private or Incognito browsing sessions when using dev\/test tenants and alternate accounts. This will avoid the browser trying to use cached or active credentials that can complicate auth scenarios where you want to use an alternate account.<\/em><\/p>\n<p>This sample authenticates your app to AAD using MSAL and pulls some basic profile info to display on the home page.<\/p>\n<p><img decoding=\"async\" width=\"1343\" height=\"477\" class=\"wp-image-40289\" src=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-10.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-10.png 1343w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-10-300x107.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-10-1024x364.png 1024w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-10-768x273.png 768w\" sizes=\"(max-width: 1343px) 100vw, 1343px\" \/><\/p>\n<p><strong>Troubleshooting<\/strong><\/p>\n<ul>\n<li>Make sure you can load the basic web page you created. If it\u2019s not loading at all, make sure your local web server is running, check the ports, etc.<\/li>\n<li>If the sign-in fails, use dev tools like F12 to set some breakpoints and see where it is failing. Make sure you copied the code verbatim from the tutorial and updated the right App ID in the config.js file.<\/li>\n<li>Check your app registration to make sure it\u2019s configured for a Single-Page Application (SPA) and the redirect URI is properly set to your local web server on port 8080.<\/li>\n<\/ul>\n<p>At this point, you should be able to run the tutorial app and sign-in. If that\u2019s working, we can move on to something new. If that\u2019s not working, review the Troubleshooting section above or debug to understand steps you might have missed in the tutorial.<\/p>\n<p>The standard tutorial continues to add support for Calendar queries and event creation. You can walk through that, but I\u2019m going to stop short of Step 4. I want to explore what it might look like to integrate some entirely new APIs you could choose off MS Graph, like Teams.<\/p>\n<h3>Adding Microsoft Graph Calls to integrate with Teams<\/h3>\n<p>Teams is exposed through Microsoft Graph API, and to send a message via Teams, it basically follows this pattern:<\/p>\n<ul>\n<li>Build and register a sample application.<\/li>\n<li>Acquire a token to call MSGraph within the application.<\/li>\n<li>Get the User ID of each person you want to include in the chat (<a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/api\/user-get?view=graph-rest-1.0&amp;tabs=http\">API<\/a>)<\/li>\n<li>Create a new Chat (must include the ID of all the users to do this) which returns a chat ID (<a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/api\/chat-post?view=graph-rest-1.0&amp;tabs=http\">API<\/a>)<\/li>\n<li>Send a Message using the Chat ID (using a simple message or some type of card message) (<a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/api\/chatmessage-post?view=graph-rest-1.0&amp;tabs=http\">API<\/a>)<\/li>\n<\/ul>\n<p>To send a chat message, you need two user accounts to create the conversation. In this example, I\u2019m using my default dev tenant account (reedr@graphfun.onmicrosoft.com) and janedoe@graphfun.onmicrosoft.com (which I created in the <a href=\"https:\/\/devblogs.microsoft.com\/premier-developer\/getting-started-with-graph-api-and-graph-explorer\/\">first post<\/a> in this series). You can use any two accounts you want for testing purposes, but keep in mind that <strong>to send a chat message, the signed-in (authenticated) user needs to be one of those accounts.<\/strong> I recommend you sign in with your dev tenant account and use that in additional to one other account that you create for testing purposes. If you didn\u2019t walk through my first post on Graph Explorer, you can manually create a second user in your tenant to test with.<\/p>\n<h3><strong>Add a Teams Menu to the App<\/strong><\/h3>\n<p>To modify this sample to send a Teams chat message, we need to add a UI handler to kick off the code. To do this, we simply add two things to ui.js.<\/p>\n<ol>\n<li>Add a fourth item to the View constant:\n<pre class=\"prettyprint\">const Views = { error: 1, home: 2, calendar: 3, teams: 4 };<\/pre>\n<\/li>\n<li>Add a teamsNav element to the ShowAuthenticatedNav routine so it shows on the menu after a user has signed-in:\n<pre class=\"prettyprint\">function showAuthenticatedNav(user, view) {\r\n  authenticatedNav.innerHTML = '';\r\n\r\n  if (user) {\r\n    \/\/ Add Calendar link\r\n    var calendarNav = createElement('li', 'nav-item');\r\n\r\n    var calendarLink = createElement('button',\r\n      `btn btn-link nav-link${view === Views.calendar ? ' active' : '' }`,\r\n      'Calendar');\r\n      calendarLink.setAttribute('onclick', 'getEvents();');\r\n      calendarNav.appendChild(calendarLink);\r\n      authenticatedNav.appendChild(calendarNav);\r\n  \r\n    var teamsNav = createElement('li', 'nav-item');\r\n      var teamsLink = createElement('button',\r\n      `btn btn-link nav-link${view === Views.teams ? ' active' : '' }`,\r\n      'Teams');\r\n      teamsLink.setAttribute('onclick', 'createChat();');\r\n      teamsNav.appendChild(teamsLink);\r\n      authenticatedNav.appendChild(teamsNav);\r\n  \r\n  }\r\n}\r\n<\/pre>\n<\/li>\n<\/ol>\n<p>This simply adds \u201cTeams\u201d to the UI that calls createChat() when we click on it.<\/p>\n<h3>Add the code to Send a Chat<\/h3>\n<p>Let\u2019s add the code for createChat into graph.js and then we\u2019ll walk through what it takes to make it work and how we arrived at the code below.<\/p>\n<pre class=\"prettyprint\">\/\/ Example of how to look up user by principal name to get their ID \r\n  async function getUserByName(name) {\r\n    console.log('Lookingup ID for '+name)\r\n    return await graphClient\r\n        .api('\/users\/'+name)\r\n        \/\/ Only get the fields used by the app\r\n        .select('id,displayName,mail,userPrincipalName')\r\n        .get()\r\n        .then((response) =&gt; \r\n        {\r\n            console.log('Found ID '+response.id+' for user '+name);\r\n            return response.id;\r\n        }\r\n    );\r\n}  \r\n\r\n\/\/ Example of how to create a chat and send a message \r\nasync function createChat() {\r\n    \r\n    var user1name = \"reedr@graphfun.onmicrosoft.com\";\r\n    var user2name = \"janedoe@graphfun.onmicrosoft.com\";\r\n    var user1 =   await getUserByName(user1name);\r\n    var user2 =   await getUserByName(user2name);\r\n        \r\n    \r\n    var conversation = 'undefined';\r\n    var chat = {\r\n        chatType: 'oneOnOne',\r\n        members: [\r\n            {\r\n            '@odata.type': '#microsoft.graph.aadUserConversationMember',\r\n            roles: ['owner'],\r\n            'user@odata.bind': 'https:\/\/graph.microsoft.com\/v1.0\/users(\\''+user1+'\\')'\r\n            },\r\n            {\r\n            '@odata.type': '#microsoft.graph.aadUserConversationMember',\r\n            roles: ['owner'],\r\n            'user@odata.bind': 'https:\/\/graph.microsoft.com\/v1.0\/users(\\''+user2+'\\')'\r\n            }\r\n        ]\r\n        };\r\n\r\n        console.log('Creating a chat between '+user1name+'('+user1+')'+' and '+user2name+'('+user2+')');\r\n        \/\/ Create the chat\r\n        await graphClient\r\n        .api('\/chats')\r\n        .header(\"content-type\", \"application\/json\")\r\n        .post(chat)\r\n        .then((odata) =&gt; {\r\n        conversation = odata.id;\r\n        console.log(odata.id);\r\n        });  \r\n\r\n    \/\/ Send a simple text chat\r\n    console.log('Sending simple text chat message...');\r\n    if (conversation !== \"undefined\"  )\r\n    {\r\n        const chatMessage = {\r\n            body: {\r\n                content: 'Message sent from my application'\r\n            }\r\n            };\r\n            \r\n            await graphClient.api('\/chats\/'+conversation+'\/messages')\r\n                .post(chatMessage);\r\n    }\r\n\r\n    \r\n}\r\n<\/pre>\n<p>If you copy and past this code, you\u2019ll need to update the user1 and user2 respectively with your tenant accounts.<\/p>\n<p>The final piece of this is to expand the scopes of our MSAL request in config.js to include the permissions we need to make these calls:<\/p>\n<pre class=\"prettyprint\">const msalRequest = {\r\n    scopes: [\r\n        'Chat.Create',\r\n        'Chat.ReadWrite',\r\n        'ChatMessage.Send',\r\n        'Chat.ReadWrite',\r\n        'User.ReadBasic.All',\r\n        'Directory.Read.All',\r\n        'Directory.AccessAsUser.All',\r\n    ]\r\n  }\r\n<\/pre>\n<p><strong>How did we arrive at the code above?<\/strong><\/p>\n<p>Let\u2019s talk about how we arrived at the code for createChat().<\/p>\n<p>To call Graph API, we built an application and registered it with AAD (using the tutorial sample). This sample uses MSAL to provide the sign-in code and acquire tokens. We tested that with some simple calls to get the signed-in user information and verified that works. From there, we wanted to call Teams APIs.<\/p>\n<p>If you look at the Teams APIs and what\u2019s involved to send a Chat Message, it consists of users, a conversation, and the message itself. I need to get the IDs of the people that are part of the message and I need to setup a new chat between those users to get a chat ID. Once I have all that, I can send a message in the chat.<\/p>\n<p>I created getUserByName() to look up the ID for each user I want to add to my chat. That simply makes a Graph API call for users as defined <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/api\/user-get\">here<\/a>.<\/p>\n<p>Once I have the IDs of the users, I create a chat between those users as defined <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/api\/chat-post\">here<\/a> and implemented in the first part of my createChat() routine. I\u2019m simply telling Teams to create a new chat using those IDs.<\/p>\n<p>Once a chat is successful created, I can send a message between users using the chat ID. The basics of this call are defined <a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/api\/chatmessage-post\">here<\/a>.<\/p>\n<p><strong>Permissions<\/strong><\/p>\n<p>You can do all this with just a few REST calls to Graph API, but you also need to think through permissions. How do I know which permission I need in my scope or consent?<\/p>\n<p>The documentation for every Graph API will include a section on Permissions. For example, the \u201c<a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/api\/user-get?view=graph-rest-1.0&amp;tabs=http#permissions\">Get a user<\/a>\u201d includes details on the following permissions:<\/p>\n<p><span style=\"font-size: 10pt;\">One of the following permissions is required to call this API. To learn more, including how to choose permissions, see\u00a0<a href=\"https:\/\/docs.microsoft.com\/en-us\/graph\/permissions-reference\">Permissions<\/a>.<\/span><\/p>\n<table>\n<thead>\n<tr>\n<th><span style=\"font-size: 10pt;\"><strong>Permission type<\/strong><\/span><\/th>\n<th><span style=\"font-size: 10pt;\"><strong>Permissions (from least to most privileged)<\/strong><\/span><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><span style=\"font-size: 10pt;\">Delegated (work or school account)<\/span><\/td>\n<td><span style=\"font-size: 10pt;\">User.Read, User.ReadWrite, User.ReadBasic.All, User.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All, Directory.AccessAsUser.All<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-size: 10pt;\">Delegated (personal Microsoft account)<\/span><\/td>\n<td><span style=\"font-size: 10pt;\">User.Read, User.ReadWrite<\/span><\/td>\n<\/tr>\n<tr>\n<td><span style=\"font-size: 10pt;\">Application<\/span><\/td>\n<td><span style=\"font-size: 10pt;\">User.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><span style=\"font-size: 10pt;\">Calling the\u00a0\/me\u00a0endpoint requires a signed-in user and therefore a delegated permission. Application permissions are not supported when using the\u00a0\/me\u00a0endpoint.<\/span><\/p>\n<p>Working through all the individual Graph APIs I\u2019m calling for Teams, I arrived at the list added to config.js. You can do the same thing for any Graph API by examining the APIs you plan to call and adding those required permissions into your scope.<\/p>\n<p><strong>Testing the Teams APIs<\/strong><\/p>\n<p>If you have added the code to enable sending a Teams Chat and want to test this, refresh the app and click on Teams once you sign-in. If you open a debug window (F12 in Edge) you can also see the call details occurring.<\/p>\n<p><img decoding=\"async\" width=\"1229\" height=\"413\" class=\"wp-image-40290\" src=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-11.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-11.png 1229w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-11-300x101.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-11-1024x344.png 1024w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-11-768x258.png 768w\" sizes=\"(max-width: 1229px) 100vw, 1229px\" \/><\/p>\n<p><img decoding=\"async\" width=\"563\" height=\"283\" class=\"wp-image-40291\" src=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-12.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-12.png 563w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-12-300x151.png 300w\" sizes=\"(max-width: 563px) 100vw, 563px\" \/><\/p>\n<p>Open another tab and log into the Teams Web client to see the message was sent.<\/p>\n<p><img decoding=\"async\" width=\"943\" height=\"253\" class=\"wp-image-40292\" src=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-13.png\" srcset=\"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-13.png 943w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-13-300x80.png 300w, https:\/\/devblogs.microsoft.com\/premier-developer\/wp-content\/uploads\/sites\/31\/2021\/06\/word-image-13-768x206.png 768w\" sizes=\"(max-width: 943px) 100vw, 943px\" \/><\/p>\n<p>Graph API exposes a convenient and simple REST API to integrate with a wide range of Microsoft Products and Services. Once you familiarize yourself with the basics of App Registrations, API permissions, and working with an authentication library, it\u2019s easy to apply common patterns and simplify development with services exposed by Microsoft Graph.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, I\u2019ll look at how to setup an app registration and move some of these concepts into a custom application that uses Graph API.\u00a0 We&#8217;ll build on an existing Graph Tutorial, review some concepts, and add support for sending a chat message in Teams.<\/p>\n","protected":false},"author":582,"featured_media":40293,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[10617],"tags":[227,1134,324],"class_list":["post-40285","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-graph-api","tag-graphapi","tag-microsoft-teams","tag-rest"],"acf":[],"blog_post_summary":"<p>In this post, I\u2019ll look at how to setup an app registration and move some of these concepts into a custom application that uses Graph API.\u00a0 We&#8217;ll build on an existing Graph Tutorial, review some concepts, and add support for sending a chat message in Teams.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/40285","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/users\/582"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/comments?post=40285"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/40285\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media\/40293"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media?parent=40285"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/categories?post=40285"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/tags?post=40285"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}