Files
twenty/packages/twenty-apps/browser-extension/README.md
T
Nabhag MotivarasandGitHub e09b67158e [HACKTOBERFEST] LINKEDIN EXTENSION (#15521)
# Twenty Browser Extension


A Chrome browser extension for capturing LinkedIn profiles (people and
companies) directly into Twenty CRM. This is a basic **v0** focused
mostly on establishing a architectural foundation.

## Overview

This extension integrates with LinkedIn to extract profile information
and create records in Twenty CRM. It uses **WXT** as the framework -
initially tried Plasmo, but found WXT to be significantly better due to
its extensibility and closer alignment with the Chrome extension APIs,
providing more control and flexibility.

## Architecture

### Package Structure

The extension consists of two main packages:

1. **`twenty-browser-extension`** - The main extension package (WXT +
React)
2. **`twenty-apps/browser-extension`** - Serverless functions for API
interactions

### Extension Components

#### Entrypoints

- **Background Script** (`src/entrypoints/background/index.ts`)
  - Handles extension messaging protocol
  - Manages API calls to serverless functions
  - Coordinates communication between content scripts and popup

- **Content Scripts**
- **`add-person.content`** - Injects UI button on LinkedIn person
profiles
- **`add-company.content`** - Injects UI button on LinkedIn company
profiles
- Both scripts use WXT's `createIntegratedUi` for seamless DOM injection
  - Extract profile data from LinkedIn DOM

- **Popup** (`src/entrypoints/popup/`)
  - React-based popup UI
  - Displays extracted profile information
  - Provides buttons to save person/company to Twenty

#### Messaging System

Uses `@webext-core/messaging` for type-safe communication between
extension components:

```typescript
// Defined in src/utils/messaging.ts
- getPersonviaRelay() - Relays extraction from content script
- getCompanyviaRelay() - Relays extraction from content script
- extractPerson() - Extracts person data from LinkedIn DOM
- extractCompany() - Extracts company data from LinkedIn DOM
- createPerson() - Creates person record via serverless function
- createCompany() - Creates company record via serverless function
- openPopup() - Opens extension popup
```

#### Serverless Functions

Located in
`packages/twenty-apps/browser-extension/serverlessFunctions/`:

- **`/s/create/person`** - Creates a new person record in Twenty
- **`/s/create/company`** - Creates a new company record in Twenty
- **`/s/get/person`** - Retrieves existing person record (placeholder)
- **`/s/get/company`** - Retrieves existing company record (placeholder)

## Development Guide

### Prerequisites

- Twenty CLI installed globally: `npm install -g twenty-cli`
- API key from Twenty: https://twenty.com/settings/api-webhooks

### Setup
   ```
1. **Configure environment variables:**
   - Set `TWENTY_API_URL` in the serverless function configuration
- Set `TWENTY_API_KEY` (marked as secret) in the serverless function
configuration
- For local development, create a `.env` file or configure via
`wxt.config.ts`

### Development Commands

```bash
# Start development server with hot reload
npx nx run dev twenty-browser-extension

# Build for production
npx nx run build twenty-browser-extension

# Package extension for distribution
npx nx run package twenty-browser-extension
```

### Development Workflow

1. **Start the dev server:**
   ```bash
   npx nx run dev twenty-browser-extension
   ```
   This starts WXT in development mode with hot module reloading.

2. **Load extension in Chrome:**
   - Navigate to `chrome://extensions/`
   - Enable "Developer mode"
   - Click "Load unpacked"
   - Select `packages/twenty-browser-extension/dist/chrome-mv3-dev/`

3. **Test on LinkedIn:**
- Navigate to a LinkedIn person profile:
`https://www.linkedin.com/in/...`
- Navigate to a LinkedIn company profile:
`https://www.linkedin.com/company/...`
   - The "Add to Twenty" button should appear in the profile header
   - Click the button to open the popup and save to Twenty

### Project Structure

```
packages/twenty-browser-extension/
├── src/
│   ├── common/
│   │   └── constants/      # LinkedIn URL patterns
│   ├── entrypoints/
│   │   ├── background/     # Background service worker
│   │   ├── popup/          # Extension popup UI
│   │   ├── add-person.content/  # Content script for person profiles
│   │   └── add-company.content/ # Content script for company profiles
│   ├── ui/                 # Shared UI components and theme
│   └── utils/              # Messaging utilities
├── public/                 # Static assets (icons)
├── wxt.config.ts          # WXT configuration
└── project.json            # Nx project configuration
```

## Current Status (v0)

This is a foundational version focused on architecture. Current
features:

 Inject UI buttons into LinkedIn profiles
 Extract person and company data from LinkedIn
 Display extracted data in popup
 Create person records in Twenty
 Create company records in Twenty

## Planned Features

- [ ] Provide a way to have API key and custom remote URLs.
- [ ] Detect if record already exists and prevent duplicates
- [ ] Open existing Twenty record when clicked (instead of creating
duplicate)
- [ ] Sidepanel Overlay UI for rich profile viewing/editing
- [ ] Enhanced data extraction (email, phone, etc.)
- [ ] Better error handling

# Demo


https://github.com/user-attachments/assets/0bbed724-a429-4af0-a0f1-fdad6997685e



https://github.com/user-attachments/assets/85d2301d-19ee-43ba-b7f9-13ed3915f676
2025-11-04 15:52:06 +01:00

3.2 KiB

Browser Extension Serverless Functions

Serverless functions for the Twenty browser extension. These functions handle API interactions between the browser extension and the Twenty backend.

Overview

This package contains serverless functions that are deployed to your Twenty workspace. The browser extension calls these functions to create and retrieve records in Twenty CRM.

Functions

Create Person

Endpoint: /s/create/person

Creates a new person record in Twenty from LinkedIn profile data.

Parameters:

  • firstName (string) - Person's first name
  • lastName (string) - Person's last name

Response: Created person object

Create Company

Endpoint: /s/create/company

Creates a new company record in Twenty from LinkedIn company profile data.

Parameters:

  • name (string) - Company name

Response: Created company object

Get Person

Endpoint: /s/get/person

Retrieves an existing person record from Twenty (placeholder implementation).

Get Company

Endpoint: /s/get/company

Retrieves an existing company record from Twenty (placeholder implementation).

Setup

Prerequisites

Configuration

  1. Authenticate with Twenty CLI:

    twenty auth login
    
  2. Sync serverless functions to your workspace:

    twenty app sync
    
  3. Configure environment variables:

    • TWENTY_API_URL - Your Twenty API URL (e.g., https://your-workspace.twenty.com)
    • TWENTY_API_KEY - Your Twenty API key (marked as secret)

Environment variables can be configured via the Twenty CLI or the Twenty web interface after syncing.

How It Works

  1. The browser extension extracts data from LinkedIn profiles
  2. The extension calls the serverless functions via the background script
  3. Serverless functions authenticate with your Twenty API using the configured API key
  4. Functions create or retrieve records in your Twenty workspace
  5. Response is sent back to the extension for user feedback

File Structure

serverlessFunctions/
├── create-person/
│   ├── serverlessFunction.manifest.jsonc  # Function configuration
│   └── src/
│       └── index.ts                        # Function implementation
├── create-company/
│   ├── serverlessFunction.manifest.jsonc
│   └── src/
│       └── index.ts
├── get-person/
│   ├── serverlessFunction.manifest.jsonc
│   └── src/
│       └── index.ts
└── get-company/
    ├── serverlessFunction.manifest.jsonc
    └── src/
        └── index.ts

Development

These functions are managed by the Twenty CLI and are deployed to your workspace. After making changes:

  1. Update the function code in src/index.ts
  2. Run twenty app sync to deploy changes to your workspace
  3. Test the functions via the browser extension or Twenty API directly
  • twenty-browser-extension - The main browser extension that calls these functions
  • See packages/twenty-browser-extension/README.md for the complete extension documentation