Exercise - Configure an external connection and deploy schema

Completed

In this exercise, you build a custom Copilot 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 Copilot connector project

Start, by creating a new Copilot connector project. While you could create the project and all necessary files manually, in this example you use the template GitHub repository for Copilot 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-copilot-connectors-typescript.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. Restore project dependencies by running npm install.

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

In the code editor:

  1. Open the src/config.ts file. In the config.connection object:
    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 Copilot 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:
    1. If you use bash:
      1. Make the setup script executable by running: chmod +x setup.sh.
      2. Start the setup script by running: ./setup.sh.
    2. If you use PowerShell, start the setup script by running: .\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.
  5. In the code editor, open the src/env.ts file, which contains information about the newly created app registration.

Important

For simplicity, the script stores app registration information in the src/env.ts file. In a production scenario, you should store this information securely, for example in Azure Key Vault.

The setup script uses the open-source CLI for Microsoft 365 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 Copilot 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 config.ts file.

  2. From the config.connection object, remove the activitySettings and searchSettings properties. You don't need them for this exercise.

  3. Notice the current value of the config.connection.schema.properties array.

    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 Copilot connectors to define at least these three properties and designate them with the appropriate semantic labels.

  4. To the config.connection.schema.properties array, add a new property named description:

    {
      name: 'description',
      type: '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:

    import { ExternalConnectors } from '@microsoft/microsoft-graph-types';
    
    export const config = {
      connection: {
        id: 'msgraphdocs',
        name: 'Microsoft Graph documentation',
        description: 'Documentation for Microsoft Graph API which explains what Microsoft  Graph is and how to use it.',
        // https://learn.microsoft.com/graph/connecting-external-content-manage-schema
        schema: {
          baseType: 'microsoft.graph.externalItem',
          // Add properties as needed
          properties: [
            {
              name: 'title',
              type: 'string',
              isQueryable: true,
              isSearchable: true,
              isRetrievable: true,
              labels: [
                'title'
              ]
            },
            {
              name: 'url',
              type: 'string',
              isRetrievable: true,
              labels: [
                'url'
              ]
            },
            {
              name: 'iconUrl',
              type: 'string',
              isRetrievable: true,
              labels: [
                'iconUrl'
              ]
            },
            {
              name: 'description',
              type: 'string',
              isQueryable: true,
              isSearchable: true,
              isRetrievable: true
            }
          ]
        }
      } as ExternalConnectors.ExternalConnection
    };
    
  6. Save your changes

Review connection creation code

The Copilot 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 src/createConnection.ts file.

In the code editor:

  1. Open the src/createConnection.ts file.
  2. The file contains two functions: createConnection and createSchema. The createConnection function creates the external connection, and the createSchema function provisions the schema.

If you recall, provisioning external connection schema is a long-running operation. The code in the createSchema function 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 src/completeJobWithDelayMiddleware.ts file.

Test the code

The last step left is to verify that the code is working correctly.

In a command line:

  1. Change the working directory to the project folder.
  2. Build the project by running npm run build.
  3. Create the external connection by running npm run start:createConnection.
  4. Wait several minutes for the connection and schema to be created.