Let’s build a custom Microsoft Graph connector

Waldek Mastykarz

Welcome back to our journey into the world of Microsoft Graph connectors! If you’re eager to integrate external data sources into Microsoft Graph to appear across Microsoft 365 experiences, you’re in the right place. This post provides a step-by-step guide to creating custom connections, opening the door to new data insights and collaboration capabilities. Let’s dive in!

Getting started

The best way to understand how Microsoft Graph connectors work is to look at a simple example. For this article, we’ll use a .NET-based sample that shows how you can ingest local markdown files extracting metadata from their frontmatter (e.g., title, description, tags, date, etc.).

Screenshot of cocal markdown files imported to Microsoft 365 using a custom Microsoft Graph connector displayed in Microsoft Search results

PRO TIP: We have samples available in other programming languages available too. See Graph connector samples in the Sample Solution Gallery for the latest Graph connector samples.

The sample is a .NET console application project that consists of the following key files:

  • setup.ps1 – a PowerShell script that creates an Entra app registration, grants it the necessary API permissions with admin consent and configures a client secret
  • ConnectionConfiguration.cs – defines the external connection and its schema
  • ConnectionService.cs – implements the portion of the connector that manages the external connection
  • ContentService.cs – implements the portion of the connector that manages external content

Connection configuration

Because the Microsoft Graph .NET SDK is strongly typed, you have access to the types, models, and properties as you configure the connection using Microsoft Graph entities from the SDK.

Connection service

The connection service is responsible for managing the external connection where you’ll ingest content from outside sources. In this sample, it creates the external connection and configures its schema using the information from the ConnectionConfiguration class.

PRO TIP: Creating schema is a long-running operation, taking upwards of a few minutes. To wait for its completion, the sample uses a custom middleware.

Content service

The content service is responsible for processing and enriching the external data items that are ingested into Microsoft Graph by Graph connectors so that it matches the schema defined by the external connection. It performs tasks such as indexing, extraction, normalization, and enrichment of the data items.

Extract, Transform, Load… sound familiar?

If you’ve worked with data integration in the past, the Extract Transform Load (ETL) term will sound familiar – that’s exactly what a Graph connector is doing! It’s extracting data from a source store, changing its shape and loading it to a destination store.

The contents of the Extract and Transform methods will be different for each data source.

The Extract method connects to the external data source and loads its data. If you’re importing content that’s secured and shouldn’t be visible to everyone in the organization, be sure to retrieve the permissions configured on the items.

PRO TIP: Read more about sending access control lists (ACLs) on items here; and how to create external groups if ACLs from the source system are different from Microsoft Entra IDs here.

Also, if you work with a large data source, you should consider only retrieving content that has changed since the last ingestion. The result of the Extract method is a collection of entities that represent content and metadata (and optionally permissions and activities) from the external system.

The Transform method is responsible for transforming the data to match the schema defined on the external connection. Here, you’ll also ensure that each item has a unique ID, dates are properly formatted, and URLs are absolute so that users can navigate to the original content items in the external system. The Transform method returns a collection of ExternalItem objects that represent the items from the external system that should be ingested to Microsoft 365.

PRO TIP: While you could combine the Extract and Transform method in one, we suggest keeping them separate. It helps separate the concerns of these methods and maintain a better overview of the ingestion process.

Finally, the Load method is responsible for ingesting external items to Microsoft 365 using Microsoft Graph APIs. If your Graph connector supports incremental ingestion, this is where you should record the date and time of the last successful ingestion.

It’s time to build

Now that we know how a Graph connector is built, let’s run it to see it working in practice.

PRO TIP: Before continuing, be sure to install prerequisites listed in the sample’s readme file.

Create Microsoft Entra app registration

To begin, let’s create the Microsoft Entra app registration. Start PowerShell and run .\setup.ps1. The script will use the Microsoft Graph PowerShell SDK to create a new Entra app registration. It will grant it API permissions which the Graph connector requires to create the external connection and ingest content. It will also grant admin consent for these permissions. Finally, it will create a client secret and store information about the Entra app registration in .NET user secrets so that the Graph connector’s code can access it.

Build the Graph connector

Next, build the Graph connector’s code. In the command line, run dotnet build or use its equivalent in your IDE. Change the working directory to bin\Debug\net7.0 where the compiled binaries are stored. Then, run .\connector create-connection. This will use the connection service to create the external connection and configure its schema.

PRO TIP: Provisioning schema takes several minutes, and we recommend that you check its status every minute to avoid unnecessary use of Microsoft Graph APIs.

When the connection is created, you can proceed with importing the content. In the terminal run .\connector load-content. This will start the content service and have it extract, transform and load the content.

Include content in all search results

To see the imported content in search results, the easiest way is to include it in the All results vertical. In the browser, go to admin.microsoft.com. From the side navigation, choose Settings > Search & intelligence. Activate the Data sources tab.

In the list of data sources, locate the newly created Waldek Mastykarz (blog); .NET source and click the Include Connector Results link to include content from this data source in all results.

Next, go to microsoft365.com and sign in with your work account. In the navbar, search for how to test api. You should see a result like the following:

Congratulations! You’ve just used Microsoft Search to find external content ingested using a custom Microsoft Graph connector.

Next steps

You’ve just built and used a simple custom Microsoft Graph connector built on .NET that ingests local markdown files to Microsoft 365. Microsoft Graph connectors offer a lot of flexibility for controlling what content is imported to Microsoft Graph and who can access it.

Try other Graph connector samples built by Microsoft and the Microsoft 365 community, to see what’s possible, and check out our documentation to learn more about Microsoft Graph connectors.

More resources:

Happy coding!


Leave a comment

Feedback usabilla icon