SOUTHWORKS Dev Team
February 7, 2018
Not so long ago, I worked on a project where we take advantage of the Microsoft Graph API to perform some tasks. So far, nothing special as it’s not rocket science nowadays to call a REST API, it is just a simple script to call. To add something more interesting to this scenario, we needed to call this functionality from Microsoft Flow (it would be the same using similar products like IFTTT or Zapier, basically we had a workflow that needs to execute a certain functionality). Based on that, our code needed to be triggered from within the workflow tool and the simplest solution here was to call a web endpoint that executes it (this is one of the most common actions in all the workflow tools).
In addition to that, we knew that the demand of the workflow might change a lot over time. It could be intensely used from time to time (let’s say a random number of 1000 requests in less than a minute as an example) and then it may not be called again for weeks or months. Here is where Azure Functions shows its benefits as it can scale as needed and it only cost you when it’s used while, if we would have chosen to use a web app, we would need to pay for at least one instance every month regardless it was used or not.
So, the first step to work on this was to resolve the scenario locally (without the workflow tool nor Azure). Basically, we need to resolve the functionality itself first and in order to do that, we develop a node.js script that uses request to call the Microsoft Graph API for groups to create a new Security Group (a group without distribution list that is used to controlling user access to in-app resources).
The following code shows how the API is consumed from that script. Note that the token and the name are passed by parameter. Additionally, this function returns a Promise that is successfully resolved when the group is correctly created and rejected when is not.The createGroup function: https://gist.github.com/nbellocam/e79f0c858610912733292e546df11317
The createGroup function: https://gist.github.com/nbellocam/e79f0c858610912733292e546df11317
In order to call Microsoft Graph API, we needed to be authenticated and that is why in the previous section we have a token as a parameter of the function which was used to perform the request. To be able to obtain that token, first we need to register a new Web Application within the Office 365 Azure Active Directory. The following are the steps that you will need to register it.
Once that we have the registered applications along with the client id and secret, we should add the following code to generate the token. Note that we are using the adal npm package to do this easier, calling the acquireTokenWithClientCredentials method of the AuthenticationContext object. Additionally, we have some constants that need to be updated with the client id and secret obtained before as well as the tenant name.
The getToken function: https://gist.github.com/nbellocam/b2cb28d8ed79f51a4bcd891bb537a6f2
So, putting all together you will get something like the following.
Putting all together: https://gist.github.com/nbellocam/b6f0ae0d14df140cfdf3e50c3984f5b2
If you try to run the code you have until now, you will end up with an error because the group will not be correctly created as the registered app doesn’t have the required permissions.
For each Graph API call you will need a different set of permissions, in this particular case you will need to grant the app created before in the Azure Portal, the Group.ReadWrite.All permission (more information about the Create group endpoint here). The following steps describe how to configure the permissions to your app.
Now that we have the node.js code ready, we need to update it a bit to use it from an Azure Function. Basically, as we are going to use an HTTP trigger, we need to update the code to receive the name of the new group as parameter in the query string. Also, we might need to return something like the result instead of just showing it in the log. Moreover, we should replace the console object with context for logging and add a call to context.done() to mark that the Function completed running.
The following code shows how it ends up with all the required changes.
The Azure Function code: https://gist.github.com/nbellocam/640552babdf6b3d0fd1c786b80c911aa
Note that we replaced console with context for logging as specified before and we also added the required calls to done to tell the Function manager that the function completed its execution. Additionally, for retrieving the parameter from the query string we are using the second parameter of the Function, req, which contains the request information including the query parameters data.
Remember that you will need to publish the npm dependencies along with the Azure Functions (more information here).
All you have to do now is deploy the Azure Function and hook it up to your Workflow (or just perform the requests to it as needed). You can find this applied to a more complex scenario where external users are invited to the Office 365 tenant and added to groups which are dynamically created here.
Originally published by Nicolás Bello Camilletti for SOUTHWORKS on Medium 07 February 2018