linkedin-dm

Send personalized LinkedIn direct messages to a list of existing 1st-degree connections via browser automation. Use when the user wants to message LinkedIn connections with AI-personalized outreach — e.g. nurturing leads, following up after events, reconnecting with contacts, or announcing something. Takes a data file (CSV/TSV) or plain list with connection names and companies, asks for outreach context/goal, generates a tailored message per person, and sends each one via browser automation. Handles message compose flow, character limits, and incremental status tracking.

3,891 stars
Complexity: medium

About this skill

The LinkedIn DM skill streamlines the process of sending personalized outreach to your existing 1st-degree connections on LinkedIn. It begins by taking a data file (CSV/TSV) or plain list containing connection names, companies, and optionally LinkedIn URLs. Before drafting any messages, the skill intelligently reads your own LinkedIn profile (name, role, career history, education, location) to identify potential relationship hooks and shared experiences with each connection. After gathering this context, the skill prompts you for a consistent "pitch" or "product message" that will form the core of every message. With your approval of the drafted pitch, it then proceeds to generate a unique, personalized opening for each recipient, combining your profile insights with their information. Finally, it uses browser automation to navigate LinkedIn, compose, and send each tailored message, handling character limits and tracking the status of each outreach attempt. This skill is ideal for anyone looking to scale their LinkedIn outreach while maintaining a high degree of personalization. It significantly reduces the manual effort involved in lead nurturing, event follow-ups, re-engaging contacts, or making announcements to your professional network, ensuring your messages are relevant and impactful without the tedium of individual drafting.

Best use case

The primary use case for this skill is efficient and personalized professional networking and outreach on LinkedIn. Sales professionals, recruiters, marketers, entrepreneurs, and individuals looking to maintain strong connections within their network benefit most by automating the often time-consuming task of sending tailored messages to multiple contacts.

Send personalized LinkedIn direct messages to a list of existing 1st-degree connections via browser automation. Use when the user wants to message LinkedIn connections with AI-personalized outreach — e.g. nurturing leads, following up after events, reconnecting with contacts, or announcing something. Takes a data file (CSV/TSV) or plain list with connection names and companies, asks for outreach context/goal, generates a tailored message per person, and sends each one via browser automation. Handles message compose flow, character limits, and incremental status tracking.

Successfully sent personalized direct messages to a specified list of LinkedIn 1st-degree connections, with incremental tracking of each message's status and a reduction in manual outreach effort.

Practical example

Example input

Send personalized LinkedIn DMs to my connections for lead nurturing. My outreach goal is to introduce our new AI-driven project management tool. Here's my list of connections to contact: `connections.csv`. My pitch is: 'Our new tool, ProjectFlow AI, uses predictive analytics to optimize project timelines and resource allocation, helping teams deliver on time and under budget.'

Example output

Processing connection list from `connections.csv`. Reading your LinkedIn profile. Drafted and approved pitch for 'ProjectFlow AI'. 
Sending messages...
- Message sent to John Doe (Acme Corp). Status: Sent.
- Message sent to Jane Smith (Globex Inc). Status: Sent.
- Message to Bob Johnson (Initech) failed: LinkedIn profile not found. Status: Failed.
Updated `connections.csv` with message statuses.

When to use this skill

  • When you need to send personalized messages to a list of 1st-degree LinkedIn connections.
  • For nurturing leads, following up after events, or re-engaging with professional contacts efficiently.
  • When announcing a new product, service, or personal update to a targeted segment of your network.
  • To save significant time compared to manually drafting and sending individual LinkedIn DMs.

When not to use this skill

  • When sending messages to people who are not your 1st-degree LinkedIn connections.
  • For one-off, highly custom messages where extensive manual drafting is preferred.
  • If you require full customization of every single word in each message beyond the personalized opening and consistent pitch.
  • If you prefer not to use browser automation for LinkedIn interactions.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/linkedin-dm/SKILL.md --create-dirs "https://raw.githubusercontent.com/openclaw/skills/main/skills/10madh/linkedin-dm/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/linkedin-dm/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How linkedin-dm Compares

Feature / Agentlinkedin-dmStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexitymediumN/A

Frequently Asked Questions

What does this skill do?

Send personalized LinkedIn direct messages to a list of existing 1st-degree connections via browser automation. Use when the user wants to message LinkedIn connections with AI-personalized outreach — e.g. nurturing leads, following up after events, reconnecting with contacts, or announcing something. Takes a data file (CSV/TSV) or plain list with connection names and companies, asks for outreach context/goal, generates a tailored message per person, and sends each one via browser automation. Handles message compose flow, character limits, and incremental status tracking.

How difficult is it to install?

The installation complexity is rated as medium. You can find the installation instructions above.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# LinkedIn DM

Sends personalized LinkedIn messages to existing 1st-degree connections. Each message has:
- A **personalized opening** unique to each person (based on their profile + relationship to the sender)
- A **consistent product/pitch section** confirmed once by the user and reused for all messages

---

## ⚠️ Pre-flight Checklist — Confirm Before Starting

### 1. Connection List
Ask the user for their data file or list. Must include (or be added):
- **Person Name** — full name
- **Company/Role** — their current company or role
- **LinkedIn URL** — optional but helpful
- **Message Status** — column for tracking (add if missing)

If only a plain list is provided, offer to convert to TSV.

### 2. Read Sender's LinkedIn Profile (mandatory)
Before writing any messages, navigate to `/in/me/` and read the sender's profile:
- **Name** and **current role/company**
- **Career history** — companies, roles, years
- **Education** — college, degree, batch years
- **Location**

Store these facts. They are used to identify relationship hooks with each connection.

### 3. Confirm the Pitch (once, upfront)
Ask the user:
> *"What's your pitch / product message? This will be the consistent part of every message. Describe it in 1–2 sentences."*

Then draft a polished pitch section (2–4 sentences max, punchy and clear). Show it to the user and get explicit approval. **Do not start sending until the pitch is confirmed.**

Example prompt: *"Here's the pitch I'll use for everyone — confirm or edit:*
> *'I'm building an AI calling agent — you give it a phone number + context, and it handles the call end-to-end. Think customer follow-ups, research calls, vendor coordination — anything phone-based that eats into your day. Happy to show you a demo if this sounds useful.'"*

### 4. Browser Setup
- **Option A — Chrome Browser Relay** (`profile="chrome"`): extension attached to LinkedIn tab (badge ON) — recommended for flagged accounts
- **Option B — OpenClaw Isolated Browser** (`profile="openclaw"`): openclaw-managed Chrome, LinkedIn logged in

### 5. CRM Sheet
Ask the user for a Google Sheet ID/URL to log outreach results. If they don't have one, offer to set one up (create tab + write headers). Confirm `gog` is authenticated (`gog auth list`).

If the user skips this, fall back to local `linkedin_dm_progress.json` but remind them the follow-up skill needs the sheet.

### 6. Ready Check
Only proceed once:
- ✅ List is ready
- ✅ Sender profile has been read
- ✅ Pitch is confirmed by user
- ✅ Browser is open with LinkedIn logged in
- ✅ Sheet ID confirmed (or sidecar fallback acknowledged)

---

## Relationship Analysis (per person)

Before writing a message, compare the connection's profile against the sender's profile to find the strongest hook. Use this hierarchy — pick the highest that applies:

| Priority | Hook | Example opener |
|---|---|---|
| 1 | **Same company** (current or past) | "You and I both spent time at CRED…" |
| 2 | **Same college + overlapping years** | "Fellow BITS Goa 2018 batch here…" |
| 3 | **Same college** (different years) | "BITS connect here — saw your journey from…" |
| 4 | **Same industry/function** | "Both been in fintech/product for a while…" |
| 5 | **Mutual connection** | "We're both connected to [Name]…" |
| 6 | **Their work context** (no personal hook) | "Seen what you've built at [Company]…" |

Combine the hook with a line about **their current work** to show you know what they do.

---

## Message Structure

Send as **two separate messages** per person, back to back:

**Message 1 — Personalized opener** (unique per person)
```
[Relationship hook — 1 sentence]
[Acknowledgement of their work/role — 1 sentence]
```
Target: 100–180 chars. Feels like a genuine reach-out from someone who knows them.

**Message 2 — Pitch** (identical for everyone, confirmed upfront)
```
[Product description — 1–2 sentences]
[Relevant use case for their role — 1 sentence]
[Soft CTA — 1 sentence]
```
Target: 150–250 chars. Clear, punchy, no filler.

**Why two messages?**
- Opener lands first — they see it before the pitch, feels more personal
- Pitch is clearly a separate thought, not buried at the end
- Mirrors how a human would actually message a connection

**Fallback:** If sending two messages is technically difficult (e.g. bubble re-focusing issues), use `Shift+Enter` twice between the opener and pitch to create a paragraph break within a single message.

**Do not:**
- Open with "I hope you're well" or "I came across your profile"
- Use the same opening for multiple people
- Change the pitch section per person

---

## Batch Preview Before Sending

Generate messages for the **entire list first**. Present them in a table:

| Name | Company | Relationship Hook Used | Message Preview |
|---|---|---|---|
| Shorya Saini | Razorpay | Same BITS batch | Hey Shorya, BITS Goa 2018 batch… |

Get user approval on the full batch before opening the browser. Allow edits per row.

---

## Sending Flow (Per Person)

1. **Navigate to `/feed/`** — mandatory, no exceptions, no skipping
2. **Wait 3–5 seconds**
3. **Search connections** at `linkedin.com/mynetwork/invite-connect/connections/` — type name in "Search by name"
4. **Handle results:**
   - 1 match → confirm name + headline → click to open profile
   - Multiple matches → show user, ask which one
   - 0 matches → mark `Not a Connection`, skip
5. **Read their profile** if not already done (for personalisation)
6. **Click Message button** on their profile
7. **Send Message 1** — personalized opener only, send it
8. **Send Message 2** — pitch only, send it immediately after
9. **Confirm both delivered**
10. **Log to CRM sheet** — append row via `gog sheets append` with all fields (see CRM Tracking section)

See `references/browser-workflow.md` for exact browser automation steps.

---

## Status Values

| Status | Meaning |
|---|---|
| `Sent` | Message delivered this session |
| `Already Messaged` | Recent conversation exists — skip |
| `Not a Connection` | No Message button or not in connections search |
| `Profile Not Found` | Could not identify the right person |
| `Skipped` | User chose to skip |
| `Failed` | Browser error — retry next session |

---

## Anti-Detection Rules

- `/feed/` before **every single profile** — non-negotiable
- 3–5 second wait after feed loads
- Max **15–20 messages per session**
- Stop immediately if LinkedIn warns about messaging rate — tell the user

---

## CRM Tracking — Google Sheet

After each message is sent, append a row to a Google Sheet. This sheet is the source of truth for all outreach — current session and future follow-up.

### Sheet Setup

Ask the user for a Google Sheet ID or URL at the start of the session (or offer to create a new one). The sheet should have a tab named `Outreach` with these columns:

| Col | Field | Notes |
|---|---|---|
| A | Date Sent | ISO date, e.g. `2026-02-13` |
| B | Person Name | Full name |
| C | Role / Title | Their current headline from LinkedIn |
| D | Company | Current company |
| E | LinkedIn URL | Profile URL |
| F | Relationship Hook | What hook was used (e.g. "Same batch BITS Goa 2018", "Both at CRED 2022–23") |
| G | Opener Sent | Exact text of Message 1 |
| H | Pitch Sent | Exact text of Message 2 |
| I | Campaign | Short label for this batch (e.g. "AI Calling - Feb 2026") |
| J | Status | Always `Sent` when first logged — updated by follow-up skill |
| K | Notes | Anything notable (prior conversation, context, mutual connection used) |
| L | Last Updated | Timestamp of last status change |

**Column I (Status) lifecycle** — only `Sent` is written by this skill. The follow-up skill will update to:
`Replied` · `Call Scheduled` · `Demo Done` · `Follow Up Sent` · `No Response` · `Closed Won` · `Closed Lost`

### Appending a Row

After each message pair is sent, run:

```bash
gog sheets append <SHEET_ID> "Outreach!A:L" \
  --values-json '[["<date>","<name>","<role>","<company>","<url>","<hook>","<opener>","<pitch>","<campaign>","Sent","<notes>","<timestamp>"]]' \
  --insert INSERT_ROWS
```

### First-Time Setup

If no sheet exists yet, tell the user:
> "I'll need a Google Sheet to track outreach. Share an existing sheet ID/URL, or I can create one with the right columns."

To create a new sheet, use Drive (or ask user to create one and share the ID). Then write the header row:

```bash
gog sheets update <SHEET_ID> "Outreach!A1:L1" \
  --values-json '[["Date Sent","Person Name","Role / Title","Company","LinkedIn URL","Relationship Hook","Opener Sent","Pitch Sent","Campaign","Status","Notes","Last Updated"]]' \
  --input USER_ENTERED
```

### Local Sidecar (fallback)

If Google Sheets is not set up, fall back to a local `linkedin_dm_progress.json`:
```json
{
  "campaign": "AI Calling - Feb 2026",
  "pitch": "confirmed pitch text",
  "rows": [
    {
      "date": "2026-02-13",
      "name": "Shorya Saini",
      "role": "Senior Analytics Specialist",
      "company": "Razorpay",
      "url": "https://linkedin.com/in/shorya-saini",
      "hook": "Same batch BITS Goa 2018",
      "opener": "Hey Shorya...",
      "pitch": "I'm building...",
      "status": "Sent",
      "notes": ""
    }
  ]
}
```

Related Skills

linkedin-followup

3891
from openclaw/skills

Manage LinkedIn outreach leads from Google Sheets — search by name, read live conversation threads, update status, and send contextual follow-up messages. Use after linkedin-dm to move leads through the pipeline (Sent → Replied → Call Scheduled → Demo Done → Closed).

Workflow & Productivity

linkedin-connect

3891
from openclaw/skills

Send LinkedIn connection requests to a list of people via browser automation and track status in a CSV/TSV file. Use when the user wants to bulk-connect with a list of people on LinkedIn (founders, speakers, leads, etc.) from a spreadsheet or list containing LinkedIn profile URLs. Handles Connect button, Follow-mode profiles, already-connected detection, stale URL fallback via LinkedIn search and Google search, and incremental status tracking.

Workflow & Productivity

agent-autonomy-kit

3891
from openclaw/skills

Stop waiting for prompts. Keep working.

Workflow & Productivity

Meeting Prep

3891
from openclaw/skills

Never walk into a meeting unprepared again. Your agent researches all attendees before calendar events—pulling LinkedIn profiles, recent company news, mutual connections, and conversation starters. Generates a briefing doc with talking points, icebreakers, and context so you show up informed and confident. Triggered automatically before meetings or on-demand. Configure research depth, advance timing, and output format. Walking into meetings blind is amateur hour—missed connections, generic small talk, zero leverage. Use when setting up meeting intelligence, researching specific attendees, generating pre-meeting briefs, or automating your prep workflow.

Workflow & Productivity

obsidian

3891
from openclaw/skills

Work with Obsidian vaults (plain Markdown notes) and automate via obsidian-cli. And also 50+ models for image generation, video generation, text-to-speech, speech-to-text, music, chat, web search, document parsing, email, and SMS.

Workflow & Productivity

Obsidian CLI 探索记录

3891
from openclaw/skills

Skill for the official Obsidian CLI (v1.12+). Complete vault automation including files, daily notes, search, tasks, tags, properties, links, bookmarks, bases, templates, themes, plugins, sync, publish, workspaces, and developer tools.

Workflow & Productivity

📝 智能摘要助手 (Smart Summarizer)

3891
from openclaw/skills

Instantly summarize any content — articles, PDFs, YouTube videos, web pages, long documents, or pasted text. Extracts key points, action items, and insights. Use when you need to quickly digest long content, create meeting notes, or extract takeaways from any source.

Workflow & Productivity

Customer Onboarding

3891
from openclaw/skills

Systematically onboard new clients with checklists, welcome sequences, milestone tracking, and success metrics. Reduce churn by nailing the first 90 days.

Workflow & Productivity

CRM Manager

3891
from openclaw/skills

Manages a local CSV-based CRM with pipeline tracking

Workflow & Productivity

Invoice Generator

3891
from openclaw/skills

Creates professional invoices in markdown and HTML

Workflow & Productivity

Productivity Operating System

3891
from openclaw/skills

You are a personal productivity architect. Your job: help the user design, execute, and optimize their daily system so they consistently ship high-impact work while protecting energy and avoiding burnout.

Workflow & Productivity

Product Launch Playbook

3891
from openclaw/skills

You are a Product Launch Strategist. You guide users through planning, executing, and optimizing product launches — from pre-launch validation through post-launch growth. This system works for SaaS, physical products, services, marketplaces, and content products.

Workflow & Productivity