cancel
Showing results for 
Search instead for 
Did you mean: 
janbakker

Build a custom connector for Microsoft Graph API

Introduction

In the last couple of days, I created my first custom connector based on the Microsoft Graph API. This was a great learning experience for me, but I struggled a little bit to find all the information in one place. There is a lot to learn here, and all of this was new to me, so there was a lot of 'Googling' from time to time. So I decided to write it all down, for everybody to read. I suggest you also check out this video. This video got me started in the first place. 

So, why do we want to build a custom connector in the first place? Let me quickly sum up some of the benefits that come with custom connectors:

  • Flexibility. You can go beyond the default capabilities of the certified connectors and extend your flows to other APIs.
  • Ease of use. Once you have built your connector it's easy to use, just like any other connector. You don't have to manually build your HTTP requests.
  • Reduce costs. With custom connectors, you can bypass premium connectors like HTTP.
  • Security. The (authentication) IDs and secrets will not be visible in your flows. 

With that being said: on with the show!

Microsoft Graph reference

So, where do you begin? I think it's best if you start exploring the Grah API reference. This will give you an idea of what is possible. This reference guide will also give some good examples of how to use the API, and what responses you can expect. For the Microsoft Graph API, there are two reference pages:

In my connector, I used the phoneAuthenticationMethod API, which I also explained in this blog post. The reference page is your starting point, but you can also use the documentation to create your descriptions in your connector. This way, you'll align with the actual documentation that Microsoft provides. Keep this page open all the time while creating your connector, I will help you out a lot. 

To quickly test out the APIs, I suggest you use the Microsoft Graph Explorer. This will give you instant access to trough delegating and consent. Once you understand the API, you can go on an build the samples in Postman.

508-02-08-2020.png

 

Create an app registration

The Microsoft Graph API uses OAuth 2.0 authentication. For that, we need to create a service principal (app registration) in our Azure Active Directory tenant. This is used for both Postman to design the connector and for the custom connector itself later on. Creating an app registration is pretty easy, but the API permissions will depend on what API you are using. Since we are using the phoneAuthenticationMethod API, we can simply look it up in the reference guide. We need this in the next step. 

 

453-01-08-2020.png

 

To create the app registration, head over the Azure Active Directory admin portal, and create a new app registration. 

454-01-08-2020.png

 

Give it a name that you will easily recognize later, and click Register. We'll need to add https://www.postman.com/oauth2/callback as our web redirect URL. 

466-01-08-2020.png

 

Next, we are going to add the API permissions. Add the Graph API permissions UserAuthenticationMethod.ReadWrite.All that we looked up earlier. In this case, pick the delegated permissions. 

456-01-08-2020.png

 

Don't forget to grant admin consent on behalf of the organization. 

457-01-08-2020.png

We also need a secret passcode. Create one, give it the life-time that you prefer, and copy this to notepad. You need to do this right away because the secret will be masked after a while. 

458-01-08-2020.png

There is a couple of more information that we have to collect from the app registration. Copy and paste the Directory and Client ID in the same notepad for later use. 

459-01-08-2020.png

 

Now that we have registered our app registration, set the permission, and created the secret, we can continue to our next step. 

 

Create a Postman collection and grab a token

If you have not installed Postman yet, you can grab your installer here. Please install Postman and launch the tool to get started. Create a new environment and workspace if launch it for the first time. I'm not going to much into detail about Postman itself, since we only focus on the collection today. 

Create a new collection and give it a name. 

461-01-08-2020.png

 

Next, go the Authorization tab to create a token. Choose Get New Access Token and pick OAuth 2.0 as the authentication type. Fill in all the details like the image below.

467-01-08-2020.png

 

  1. The name of the token. Doesn't really matter.
  2. Make sure you select Authorization code
  3. Enter https://www.postman.com/oauth2/callback as the callback URL
  4. See 5.
  5. You can grab both URLs from your app registration page, under Endpoints. 470-01-08-2020.png
  6. The client ID can be copied from the overview page of the app registration, like the image above here.
  7. The secret that you created earlier (and stored in Notepad)
  8. This is the URL of the Graph API permissions, in our case https://graph.microsoft.com/UserAuthenticationMethod.ReadWrite.All You can copy the URL from the API permissions page. 471-01-08-2020.png

Click Use Token and Create to create the collection. If you don't have an access token, you will be asked to authenticate with a prompt. Authenticate with your Azure AD account to get the access token. 

468-01-08-2020.png

 

Create your queries/requests

Now that we have created our collection, we can start by designing our queries. Click Add requests and give it a proper name and description. This is important because these values will end up in your customer connector. I copied the values from the Graph API reference page. 

473-01-08-2020.png

 

Next, we'll add the query. GET https://graph.microsoft.com/beta/me/authentication/phoneMethods is provided as an example in the reference page, so we start with that one. 

Enter the query and hit send.

474-01-08-2020.png

 

1. Use GET to pull the information.

2. The query URL as provided on the reference page. 

3. The output of the query. This user has not registered any phone methods, so the result is empty. 

In our next query, we are going to add a phone method for a specific user. Click Add Request and enter https://graph.microsoft.com/beta/users/AllanD@M365x482316.OnMicrosoft.com/authentication/phoneMethod... This time we use POST and we replace 'me' with the user/UPN format, to do this on behalf on another user. 

476-01-08-2020.png

 

Because we are going to add a phone method, the query also needs a body with extra information. We need to provide the phone number and type. Make sure, you select JSON as a format and select the RAW button. 

 

 

{
  "phoneNumber": "+1 2065555555",
  "phoneType": "mobile"
}

 

 

479-01-08-2020.png

 

Hit Send and check the output of the query. If the query works, don't forget to save it. 

480-01-08-2020.png

 

How to use path and global variables

Now that we build our first queries, let's take this a step further. Since both query URL(path) and body have to be dynamic, we are going to use variables. 

Go to the last created query and replace AllanD@M365x482316.OnMicrosoft.com for:

 

 

:userID

 

 

 

Enter AllanD@M365x482316.OnMicrosoft.com in the value field. We now created our first path variable.

481-01-08-2020.png

 

Next, we create a global variable for our phone number. Go back to the properties of the collection and hit the Variables tab. 

482-01-08-2020.png

 

Add a new variable give it a proper name and paste in the value that you want to test with. 

Hit Update to save the variable and go back to the body of your query. Replace the phone number with {{phonenumber}} (yes, double brackets). The variable will light up in amber. 

483-01-08-2020.png

 

1. Path variable

2. Global variable. You can use these variables in all queries in the collection. 

I added one more variable to define the phone type. We come back to this variable later. 

497-01-08-2020.png

Variables like this, they will be exported to Power Automate later on. This way, you don't have to adjust the queries on the custom connector page. More on that later.

 

Create responses, save examples

As we saw earlier, a query can have different outputs. You can save these responses as an example so that they are captured in the collection. This is recommended so that Power Automate can parse the output. By saving the response to the query, they are included in the export file. You can add multiple responses to a single query. 

486-01-08-2020.png

 

Make sure that you save the example. 

487-01-08-2020.png

You can now add more queries to the collection. The concept is the same for either DELETE, PATCH, or other actions. 

Save the collection when you are done. 

 

Import your Postman collection into Power Automate

We used Postman for our preparing work, but now the queries are sorted out and tested, you can transfer the collection to Power Automate. First, export the collection as a V1 file. 

488-01-08-2020.png

489-01-08-2020.png

 

Next, head over to the Power Automate portal and expand the Data section. Click Custom Connectors, hit + New custom connector, and select Import a Postman collection

490-01-08-2020.png

 

Browse for the JSON file, give it a name and click Continue to import the file. 

491-01-08-2020.png

 

On the first page, upload a logo, pick a background color, and check if the base URL is right.

492-01-08-2020.png

 

Go ahead to the next page, Security. 

495-01-08-2020.png

 

  1. Select OAth 2.0
  2. Select Azure Active Directory as our identity provider
  3. Enter your client ID (application ID) from your Azure AD app registration
  4. Enter your client secret from your Azure AD app registration
  5. Use the default URL https://login.windows.net
  6. Use common as your tenant ID
  7. User https://graph.microsoft.com as the resource URL
  8. When you save the connector, the URL is provided. Add this URL as a redirect URL to your app registration, just like the Postman callback URL.

496-01-08-2020.png

Hit create/update connector to save the changes. (9)

 

Finishing touch

On the next page, you'll find all the queries that you build with Postman, including the variables. I go over the most important settings. 

500-01-08-2020.png

 

The General section is populated with information from Postman. You can adjust the values if you want.

1. The summary of the action

2. A short description of the action

3. A unique ID. 

Next, you see the actual query and the variables. 

501-01-08-2020.png

 

1. The full path of the query.

2. Here is the path variable that we created earlier. 

3. You can customize the variable to your needs

4. The body content

If we zoom in on the UserID variable (edit), we see a couple of settings here.

502-01-08-2020.png

 

1. The name of the parameter

2. A short description with a small explanation 

3. The default value. This will be populated in the flow as the default value

4. Sets whether this parameter is required. Check this for all your queries. 

5. The format of the parameter

If we zoom in on the body, we will find the 2 parameters phone number and phone type

504-01-08-2020.png

 

For the phone type, I created a dropdown menu with possible values. Enter the values comma-separated. 

503-01-08-2020.png

 

To give you an idea of how these values are shown in the flow, I created some examples.

513-02-08-2020.png

 

Example with default value:

Example with default valueExample with default value

 

 

Example without a default value. The summary is shown.

When you don't add a default value, the summary is shownWhen you don't add a default value, the summary is shown

 

An example of a dropdown list:

524-02-08-2020.png

 

If you have not added sample responses in Postman earlier, you can add them here also. The JSON will be parsed so that you can use the response in your flow. 

509-02-08-2020.png

 

When you design complex connectors, your configuration can become messed up sometimes. You can peek "under the hood" with the swagger editor. This will give you a bit more options to edit your connector directly.

511-02-08-2020.png

 

Test the connector

On the last page of the wizard, you are able to test the queries. First, you'll need to create a new connection. When you are successfully authenticated, you an kick off the tests. 

505-01-08-2020.png

 

When all the tests are successful, save the connector one more time. You're done! Ready to use your connector. 🎉

506-01-08-2020.png

 

Share your connector

When you created your connector, it's time to push it out to the community. Of course, this is not mandatory, but it will help out al lot of organizations. You can simply export your connector, brush out any personal ID's and upload the connector files to your personal Github page. 

519-02-08-2020.png

 

You can also add your connector to the Microsoft repository. When you do this, your connector becomes open source so that the community can contribute and add changes or fixes. 

 

To export the files from Power Automate, you need Python and the Paconn CLI tool. This page gives a brief instruction on how to use it, but basically, it comes down to these 3 steps: 

1. Login using a browser session. This will give to tool access to your Power Automate environment. 

2. Download the connector and select the environment. 

3. Pick the connector that you want to download

520-02-08-2020.png

 

The files are downloaded so that you can create a pull request to add them to the Microsoft repo. The best way to do that is using Github desktop. Follow the instructions here

521-02-08-2020.png

 

One last word

You might wonder: what about triggers? How does that work? Well, that's a whole different story, since you have to deal with either delta query or webhook subscriptions to make that work. So I left that out on purpose otherwise this blog post would be too complicated. (I'm sorry if it already is 😅) I would love to work that out in a separate post, so stay tuned.

Yeah I know, this was a pretty large blog post, but I want to try to cover all the steps that I had to find out myself by building the connector from scratch, without any knowledge upfront. It was a cool learning experience and some of you might have additional tips and tricks on this. Please, let me know in the comments. 

I hope this will give you an idea of what is possible with Power Automate and the Graph API. You can build some pretty nice flows with this and provide solutions that are not available with the current tools. Even without a deep understanding of all the components, you can come real close to become a real developer 😎

Being a cloud consultant myself, I normally wouldn't touch any code other than some PowerShell scripts, but Power Automate has opened a whole new world for me. Now I can go the extra mile for my clients and give them exactly what they need. I did a blog post on my own website to show off the customer connector that I built to prepopulate MFA en SSPR phone methods.

522-02-08-2020.png

This is a great example of how the world of Identity protection and Power Automate come together to solve some of the problems now everybody is working from home. Please check it out. 

Stay safe and creative!

Comments

Hi @janbakker, I discovered this post via MeasureUp while preparing for PL-400, love it!

Thanks a lot for the great effort of this detailed howto

Wow, thanks so much, really helpful.

@janbakkerthank you so much for this explanation!

 

In the POST method, when I try to change my own mobile number, I get the error:

{
    "error": {
        "code": "scopeReadWriteMissingForSelfTarget",
        "message": "Missing required scope UserAuthenticationMethod.ReadWrite for self-target operation",
        "innerError": {
            "message": "Missing required scope UserAuthenticationMethod.ReadWrite for self-target operation",
            "date": "2023-02-14T13:01:47",
            "request-id": "21fee6d2-2651-4de9-8b51-d0c37747c223",
            "client-request-id": "21fee6d2-2651-4de9-8b51-d0c37747c223"
        }
    }
}

 

When trying to change someone else's phone, I get:

 

{
    "error": {
        "code": "badRequest",
        "message": "Mobile phone method is already registered for this account.",
        "innerError": {
            "message": "Mobile phone method is already registered for this account.",
            "date": "2023-02-14T13:15:57",
            "request-id": "463941b7-e01a-46d3-ae17-243437422e76",
            "client-request-id": "463941b7-e01a-46d3-ae17-243437422e76"
        }
    }
}

 

In both these cases, the VALUE field in the Path Variables is set to the user email addresses.

 

Thus, I can't copy the Responses as examples and I'm stuck here.

 

Double checked the permissions in Azure.

 

Thanks in advance for helping!

@WebPortal Both responses are by design. You cannot set your own methods using Graph API, and it looks that other user already has a mobile phone registered. You can only have one mobile phone number.  

 

Thanks for the article, it was very helpfull! Alas, I', struggling with a few things that I cannot seem to find a solution for.

 

And the first has to do do with the whole oauth concept and custom connector.  To test the custom connector, which includes both client id and decret (and app registrations with the appropriate access rights) - I still need to create a connection by signing in - and looking at the token the connector sends, it appearantly try to "impersonate" and not using application access. Any idea why?

 

And two... it seems like the custom connector wizard in power automate lives it's own life. I'm starting out registering as a general Oauth connections, but as soon as I save/creates/updates it it reverts to Azure Ad Authentication. Did you struggle with the same thing, or?

 

I'm trying to access the Azure B2C catalog using the graph api (and this seems to confuse the custom connector wizard (using the "common" tenant name)).

About the Author
  • Experienced Consultant with a demonstrated history of working in the information technology and services industry. Skilled in Office 365, Azure, SharePoint Online, PowerShell, Nintex, K2, SharePoint Designer workflow automation, PowerApps, Microsoft Flow, PowerShell, Active Directory, Operating Systems, Networking, and JavaScript. Strong consulting professional with a Bachelor of Engineering (B.E.) focused in Information Technology from Mumbai University.
  • I am a Microsoft Business Applications MVP and a Senior Manager at EY. I am a technology enthusiast and problem solver. I work/speak/blog/Vlog on Microsoft technology, including Office 365, Power Apps, Power Automate, SharePoint, and Teams Etc. I am helping global clients on Power Platform adoption and empowering them with Power Platform possibilities, capabilities, and easiness. I am a leader of the Houston Power Platform User Group and Power Automate community superuser. I love traveling , exploring new places, and meeting people from different cultures.
  • Read more about me and my achievements at: https://ganeshsanapblogs.wordpress.com/about MCT | SharePoint, Microsoft 365 and Power Platform Consultant | Contributor on SharePoint StackExchange, MSFT Techcommunity
  • Encodian Owner / Founder - Ex Microsoft Consulting Services - Architect / Developer - 20 years in SharePoint - PowerPlatform Fan
  • Founder of SKILLFUL SARDINE, a company focused on productivity and the Power Platform. You can find me on LinkedIn: https://linkedin.com/in/manueltgomes and twitter http://twitter.com/manueltgomes. I also write at https://www.manueltgomes.com, so if you want some Power Automate, SharePoint or Power Apps content I'm your guy 🙂
  • I am the Owner/Principal Architect at Don't Pa..Panic Consulting. I've been working in the information technology industry for over 30 years, and have played key roles in several enterprise SharePoint architectural design review, Intranet deployment, application development, and migration projects. I've been a Microsoft Most Valuable Professional (MVP) 15 consecutive years and am also a Microsoft Certified SharePoint Masters (MCSM) since 2013.
  • Big fan of Power Platform technologies and implemented many solutions.
  • Passionate #Programmer #SharePoint #SPFx #M365 #Power Platform| Microsoft MVP | SharePoint StackOverflow, Github, PnP contributor
  • Web site – https://kamdaryash.wordpress.com Youtube channel - https://www.youtube.com/channel/UCM149rFkLNgerSvgDVeYTZQ/