Skip to main content
Developers have asked us a recurring question: can I detect what posts my prospects are liking and commenting on, and use that as a hook for cold outreach? This guide walks through a complete working example that does exactly that, end to end, from picking a target profile to writing a personalized DM for each prospect. For a single-call snippet, see LinkedIn outreach hooks. This guide is the full pipeline.

What you will build

A five-stage pipeline that starts with a sender and a target LinkedIn profile and ends with a folder of personalized draft DMs ready for human review.
  1. Stage 0 — Fetch the sender’s own LinkedIn profile and summarize their voice and current company so the LLM has writing style and signature context.
  2. Stage 1 — Pull recent posts from the target profile (typically a high-signal author your prospects follow).
  3. Stage 2 — Find everyone who reacted to or commented on those posts, filter out teammates and noise, then enrich the top prospects with full profiles.
  4. Stage 3 — Scrape each prospect’s own recent LinkedIn activity so the DM can reference what they actually care about.
  5. Stage 4 — Draft a personalized DM per prospect with an LLM and render a demo.html preview for review.

The example repo

Clone the example to follow along:
git clone https://github.com/the-hog/hog-linkedin-outreach
cd hog-linkedin-outreach
The repo is MIT licensed, a single Python file, and uses only the Python standard library. OpenAI is called via raw HTTP through urllib, not the openai package, so there is no pip install step.

Endpoints used

The pipeline uses six The Hog LinkedIn endpoints plus OpenAI for summarization and DM drafting.
EndpointWhat it returns
linkedin/profileFull profile including experience, education, current company
linkedin/profile-postsRecent posts from a profile
linkedin/post-reactionsWho reacted to a specific post
linkedin/post-commentsWho commented on a specific post
linkedin/profile-reactionsWhat a profile reacted to elsewhere
linkedin/profile-commentsWhat a profile commented on elsewhere
OpenAI chat.completionsSender voice summary, prospect summaries, and final DM drafts

The data flow

Each stage caches its output to disk so re-running the script is cheap. The cache filenames double as a tour of the pipeline:
FileStageContents
00a_sender_profile.json0Raw sender profile from linkedin/profile
00b_sender_summary.txt0LLM-generated voice and company summary for the sender
01_target_posts.json1Recent posts from the target profile
02_potential_prospects.json2Everyone who reacted to or commented on the target posts
02b_top_prospects.json2Filtered and ranked list after exclusions
02c_enriched_prospects.json2Top prospects with full profiles attached
03_prospect_activity.json3Each prospect’s own recent reactions and comments
04_personalized_messages.json4Final draft DMs
demo.html4Browser-ready preview of every draft side by side

The personalization payoff

Templated outreach fails because the recipient can tell it could have been sent to anyone. This pipeline gives the LLM enough specific context to write something that could only have been sent to one person. For each DM, the model receives:
  • Sender voice from the sender summary, so the draft sounds like the person sending it.
  • Recipient context from the prospect’s enriched profile, so the DM grounds in their role and company.
  • The specific post they engaged with, including its text and author, so the opener is a real reference.
  • Their own words when they left a comment, so the DM can quote or paraphrase what they actually said.
  • Their broader activity from profile-reactions and profile-comments, so the DM can connect their public interests to your pitch.
The output is a DM that references real things the recipient said and did this week.

Filtering for safety

Two config knobs at the top of the script keep your own teammates and obvious noise out of the prospect list:
  • EXCLUDE_COMPANIES — drop anyone whose current company in their experience history matches one of these. This catches teammates whose LinkedIn headline does not mention the company name (a common gap that a headline-only filter misses).
  • EXCLUDE_HEADLINE_KEYWORDS — drop anyone whose headline contains these substrings, useful for filtering investors, recruiters, or competitors when you do not want to message them.
The experience-based filter requires the prospect enrichment step. The cheaper headline filter runs first, so the script only spends profile credits on prospects that survive the initial cut.

Costs and runtime

RunHog callsOpenAI callsWall time
First run~20 to 25~405 to 10 minutes
Subsequent runsNear zeroNear zeroSeconds
Every stage reads from its cache file if present, so iterating on prompts, exclusion lists, or DM templates does not re-burn credits.

Customizing

Open the script and look for the CONFIG block near the top (around lines 50 to 80). The variables you will change most often:
VariableWhat it controls
SENDER_USERNAMEYour LinkedIn username, used to fetch your profile and seed the sender voice summary
TARGET_USERNAMEThe author whose post engagement you want to mine for prospects
EXCLUDE_COMPANIESCompany names to drop from the prospect list (catches teammates)
MAX_PROSPECTS_FOR_OUTREACHCap on how many prospects make it through to the DM draft stage
Past those, the prompt strings for the sender summary, prospect summary, and DM draft live inline and are easy to tune.
Review every drafted DM before sending. The script produces drafts, not approved messages. Respect LinkedIn’s terms of service and outreach rules in your market.