Goal

In this how to guide, we will go over how to build a LinkedIn integration! We will use the recorder-based auth session feature in Intuned to create a browser automation project that exposes an API to allow us to manage LinkedIn requests on a LinedIn account. The guide is meant to show how to use the recorder-based auth session in Intuned and is also meant to show how to build a LinkedIn integration - we will create APIs related to managing connections but this can be expanded to any automation on LinkedIn or other services with similar authentication workflow.

Follow this guide step by step or you can use the Recorder based auth sessions project template to get a jump start. You can also watch a walkthrough of this guide below:

Step by step

1. Create a project and enable auth-sessions

In this guide, we will use Recorder-based auth sessions. This feature works by creating a new browser session (streamed to user machine) and enabling the user to authenticate on the target service. The auth session is then captured and stored in Intuned to be used when authenticated APIs are used.

  1. Navigate to https://app.intuned.io/projects
  2. Click New to create a new project
  3. Navigate to Intuned.json, which serves as the IDE settings
  4. Select Auth Session tab and set the following configurations
    • Toggle Enable auth sessions on
    • Set Auth session type to Recorder
    • Set Start URL to https://www.linkedin.com/login. Start URL is the URL where we initialize the recorder session to.
    • Set Finish URL to https://www.linkedin.com/feed. After the user finishes authentication, the browser will navigate to this URL, when we detect that, we will capture the auth session and close the browser.

To learn more about recorder-based auth sessions, check out Recorder-based auth sessions.

2. implement the check function

Auth sessions require a check function to be implemented. This function is called before executing any authenticated action (API). If the function returns false, this signals that the auth session is expired/invalid and the auth session will be marked as expired for Recorder-based auth sessions. The API that was called will return 401 in this case.

  1. Navigate to auth-sessions/check.ts file and write the script to verify that the auth session is valid.
import { BrowserContext, Page } from "@intuned/playwright-core";

async function check(page: Page, context: BrowserContext): Promise<boolean> {
  await page.goto("https://www.linkedin.com", { waitUntil: "load" });
  return page.url().includes("feed");
}

export default check;

3. Create the authenticated LinkedIn APIs

  1. Create APIs for all actions you would like to automate on LinkedIn.
    • Create an API named get-connection-requests.ts and write the script to retrieve connection requests.
import { BrowserContext, Page } from "@intuned/playwright-core";
import { extendPlaywrightPage } from "@intuned/sdk/playwright";

interface Params {}

export default async function handler(
  params: Params,
  _playwrightPage: Page,
  context: BrowserContext
) {
  const page = extendPlaywrightPage(_playwrightPage);

  await page.goto("https://www.linkedin.com/mynetwork/invitation-manager/");
  await page.getByText("Manage invitations").waitFor({
    state: "visible",
  });

  const connectionRequests = await page.extractArrayOptimized({
    label: "connection-requests",
    itemEntityName: "connection-request",
    itemEntitySchema: {
      type: "object",
      properties: {
        name: {
          type: "string",
          description: "inviter name",
          primary: true,
        },
        title: {
          type: "string",
          description: "inviter title",
        },
        profileUrl: {
          type: "string",
          description: "inviter profile url",
        },
      },
      required: ["name", "title", "profileUrl"],
    },
  });

  return connectionRequests;
}
  • Create an API named accept-connection-request.ts and write the script to accept connection request.
import { BrowserContext, Page } from "@intuned/playwright-core";
import { extendPlaywrightPage } from "@intuned/sdk/playwright";

interface Params {
  inviterName: string;
}

export default async function handler(
  params: Params,
  _playwrightPage: Page,
  context: BrowserContext
) {
  const page = extendPlaywrightPage(_playwrightPage);

  await page.goto("https://www.linkedin.com/mynetwork/invitation-manager/");
  await page.getByText("Manage invitations").waitFor({
    state: "visible",
  });

  const invitationLocator = page.locator(".invitation-card", {
    hasText: params.inviterName,
  });

  const isInvitationVisible = await invitationLocator.isVisible();
  if (!isInvitationVisible) {
    return {
      success: false,
      message: "invitation not found",
    };
  }

  await invitationLocator.getByRole("button", { name: "Accept" }).click();

  return {
    success: true,
  };
}

4. Validate the APIs in the IDE and Deploy

  1. Create an auth session in the IDE
  2. Validate get-connection-requests and accept-connection-request APIs with the auth session you created in the previous step.

5. Deploy and validate the deployed APIs

  1. deploy the project

  2. Create auth session for the deployed project

  3. Validate get-connection-requests and accept-connection-request APIs with an simple async request

(Optional) How to build UX to allow users to “connect to LinkedIn”

One main use case of auth session is building integration with services that require user authentication and has no APIs. For example, lets assume that you are building a sales platform and you to automate the process of liking posts or sending connection requests on LinkedIn. To do this on behalf of your users, you would need to build a UX that allows users to connect their LinkedIn accounts to your sales platform. To see an example of this, please checkout the following project and use it as a guide:

(Optional) How to use Jobs API with auth sessions

This section is an optional section that talks about how you can create authenticated jobs in Intuned. Jobs are a way to schedule recurring or batched/grouped executions. For more info about Jobs, checkout Jobs.

In this example, we want to call the get-connection-requests API and send the result to a webhook on a regular based (1 week). We will create a job that does this.

Creating jobs can be done via UI or API. For this example, we will use the UI. Checkout Jobs API overview for more info.

  • Get a webhook url, for testing, you can use https://webhook.site/ to get a temp url. In a real scenario, you will use your own webhook url and persist the data to store.

  • Go to the Jobs tab in the UX and create a new job with the following config. Don’t forget to replace <YOUR_WEBHOOK_URL> with your webhook url and <AUTH_SESSION_ID> with the auth session id you want to run this job with.

{
  "id": "li-connect-requests-webhook",
  "configuration": {
    "retry": {
      "initialInterval": 60000,
      "maximumAttempts": 5,
      "backoffCoefficient": 2
    },
    "runMode": "Order-Irrelevant",
    "version": "v1",
    "maxConcurrentRequests": 3
  },
  "sink": {
    "type": "webhook",
    "url": "<YOUR_WEBHOOK_URL>"
  },
  "schedule": {
    "intervals": [
      {
        "every": "7d"
      }
    ]
  },
  "authSession": {
    "id": "<AUTH_SESSION_ID>",
  },
  "payload": [
    {
      "apiName": "get-connection-requests",
      "parameters": { }
    }
  ]
}

(Optional) How to use Queue API with auth sessions

This section is an optional section that talks about how you can use the rate limited queue feature in Intuned with auth sessions. Queues are a way to control sequential tasks and setup rate limits on them. For more info about Queues, check out Queues.

The main use case for queues is to control the execution and set strict rate limits on it. In this example, we want to make sure all pending requests are accepted in time, however, we want to stick to strict rate limits for executing those APIs (accept-connection-request - to accept connections).

Creating queues can be done via API. Check out Queue API overview for more info.

Notes:

  • don’t forget to replace <YOUR_WEBHOOK_URL> with your webhook url and <YOUR_AUTH_SESSION_ID> with the auth session id you want to run this queue with.
  • this queue will at most execute 3 actions at with in 1 hour.
{
    id: "li-accept-request-queue",
    configuration: {
      runMode: "Default",
      retry: {
        maximumAttempts: 3,
      },
      rateLimits: [
        {
          limit: 3,
          duration: "1h",
        },
      ],
    },
    sink: {
      type: "webhook",
      url: "<YOUR_WEBHOOK_URL>",
    },
    authSession: {
      id: "<YOUR_AUTH_SESSION_ID>"
    }
  }
  • As you are made aware of pending requests, you can seamlessly append to the queue using the following input payload
{
  apiName: "add-new-user",
  parameters: {
    "inviterName": "Faisal Ilaiwi"
  }
}