Exercise - Configure an external connection and deploy schema

Completed

In this exercise, you build a custom Microsoft Graph connector as a console application. You register a new Microsoft Entra app registration and add the code to create an external connection and deploy its schema.

Create a new Graph connector project

Start, by creating a new Graph connector project. While you could create the project and all necessary files manually, in this example you use the template GitHub repository for Graph connectors. The benefit of using the template repository is that it creates a simple project for you with the necessary files and dependencies, saving you time.

In a command line:

  1. Clone the template repository by running git clone https://github.com/microsoft/learn-microsoft-graph-connectors-dotnet.git

    Tip

    If you don't have git installed or you don't have a GitHub account, you can download the repository as a ZIP file. Extract the ZIP file to a folder on your computer to continue with the exercise.

  2. Change the working directory to the cloned repository.

  3. Open the newly created project in your code editor.

In the code editor:

  1. Open the ConnectionConfiguration.cs file. In the object returned by the ExternalConnection getter:
    1. Change the value of the Id property to msgraphdocs.
    2. Change the value of the Name property to Microsoft Graph documentation.
    3. Change the value of the Description property to Documentation for Microsoft Graph API which explains what Microsoft Graph is and how to use it.
  2. Save your changes.

Tip

The README.md file in the generated project contains more information about the different files and folders in the project. Take a moment to read it and familiarize yourself with the project structure.

Register a new Microsoft Entra app registration

The project you created contains a setup script that creates and configures a new Microsoft Entra app registration. The Graph connector uses this app registration to authenticate with Microsoft 365.

In a command line:

  1. Change the working directory to the project folder.
  2. Run the setup script: .\setup.ps1
  3. When prompted, sign in to your Microsoft 365 tenant with your work account.
  4. Wait for the script to finish creating the app registration. The script creates an Entra app registration named Microsoft Graph documentation.
  5. When the script finishes, it securely stores the app registration information in user secrets.

The setup script uses the Microsoft Graph PowerShell SDK to create a new Microsoft Entra app registration in your tenant. It configures the app registration with Microsoft Graph API permissions required to create an external connection and ingest content. It also configures the app registration with a secret to allow authenticating without user interaction.

Tip

To explore the app registration configuration, in a web browser:

  1. Go to the Azure Portal at https://portal.azure.com.
  2. From the navigation, select Microsoft Entra ID.
  3. From the side navigation, select App registrations.
  4. From the list of app registrations, select the app registration created by the setup script.
  5. Explore the different properties, such as API permissions, Certificates & secrets, and Authentication.

Define external connection and schema configuration

The next step is to define the external connection and schema that the Graph connector should use. Because the connector's code needs access to the external connection's ID in several places, store it in a central place in your code.

In the code editor:

  1. Open the ConnectionConfiguration.cs file.

  2. From the object returned by the ExternalConnection property, remove the ActivitySettings and SearchSettings properties. You don't need them for this exercise.

  3. Notice the schema properties returned by the Schema property.

    The first property is title, which stores the title of the external item imported to Microsoft 365. The item's title is a part of the full-text index (IsSearchable = true). Users can also explicitly query for its contents in keyword queries (IsQueryable = true). The title can be also retrieved and displayed in search results (IsRetrievable = true). The title property represents the item's title, which you indicate using the Title semantic label.

    Next, there's the url property, which stores the original URL of the external item. Users use this URL to navigate to the external item from search results or Copilot from Microsoft 365. URL is one of the properties that Microsoft 365 Copilot requires, which is why you map it using the Url semantic label.

    Finally, there's the iconUrl property that stores the URL of the icon for each item. Microsoft 365 Copilot requires this property and it needs to be mapped using the IconUrl semantic label.

    Microsoft 365 Copilot requires Graph connectors to define at least these three properties and designate them with the appropriate semantic labels.

  4. To the Properties array, add a new property named description:

    new Property
    {
      Name = "description",
      Type = PropertyType.String,
      IsQueryable = true,
      IsSearchable = true,
      IsRetrievable = true
    }
    

    The description property stores the summary of the contents of the external item. Its definition is similar to the title. There's however no semantic label for the description, which is why you don't define it.

  5. The complete code looks as follows:

    using System.Text.Json;
    using Microsoft.Graph.Models;
    using Microsoft.Graph.Models.ExternalConnectors;
    
    static class ConnectionConfiguration
    {
      private static Dictionary<string, object>? _layout;
      private static Dictionary<string, object> Layout
      {
        get
        {
          if (_layout is null)
          {
            var adaptiveCard = File.ReadAllText("resultLayout.json");
            _layout = JsonSerializer.Deserialize<Dictionary<string, object>>(adaptiveCard);
          }
    
          return _layout!;
        }
      }
    
      public static ExternalConnection ExternalConnection
      {
        get
        {
          return new ExternalConnection
          {
            Id = "msgraphdocs",
            Name = "Microsoft Graph documentation",
            Description = "Documentation for Microsoft Graph API which explains what Microsoft Graph is and how to use it."
          };
        }
      }
    
      public static Schema Schema
      {
        get
        {
          return new Schema
          {
            BaseType = "microsoft.graph.externalItem",
            Properties = new()
            {
              new Property
              {
                Name = "title",
                Type = PropertyType.String,
                IsQueryable = true,
                IsSearchable = true,
                IsRetrievable = true,
                Labels = new() { Label.Title }
              },
              new Property
              {
                Name = "url",
                Type = PropertyType.String,
                IsRetrievable = true,
                Labels = new() { Label.Url }
              },
              new Property
              {
                Name = "iconUrl",
                Type = PropertyType.String,
                IsRetrievable = true,
                Labels = new() { Label.IconUrl }
              },
              new Property
              {
                Name = "description",
                Type = PropertyType.String,
                IsQueryable = true,
                IsSearchable = true,
                IsRetrievable = true
              }
            }
          };
        }
      }
    }
    
  6. Save your changes

Review connection creation code

The Graph connector project generator creates code that creates the external connection and provisions its schema. You can use it without any changes. Before you do, have a look at it to understand how it works. The code is in the ConnectionService.cs file.

In the code editor:

  1. Open the ConnectionService.cs file.
  2. The file contains two methods: CreateConnection and CreateSchema. The CreateConnection method creates the external connection, and the CreateSchema method provisions the schema.

If you recall, provisioning external connection schema is a long-running operation. The code in the CreateSchema method however doesn't seem to be waiting for the schema to be provisioned. The Microsoft Graph client in this project uses a custom middleware that waits for the operation to complete. Because this middleware handles waiting for the operation to complete, the CreateSchema function doesn't need to include any other code and only needs to await the API request. The middleware is in the CompleteJobWithDelayHandler.cs file.

Test the code

The last step left is to verify that the code is working correctly. The Program.cs file contains the entry point for the application. It uses the System.CommandLine package to define a command that you invoke by starting the application from the command line.

In a command line:

  1. Open a terminal.
  2. Change the working directory to the project folder.
  3. Run dotnet build to build the project.
  4. Start the app by running dotnet run -- create-connection.
  5. Wait several minutes for the connection and schema to be created.