Find leads by scraping engagers from a competitor's top LinkedIn posts. Given one or more company page URLs, scrapes recent posts, ranks by engagement, selects the top N, extracts all reactors and commenters, ICP-classifies, and exports CSV. Use when someone wants to "find leads engaging with competitor content" or "scrape people who interact with [company]'s LinkedIn posts".
npx gooseworks install --all # then, in Claude Code, Cursor, or Codex: /gooseworks use the competitor-post-engagers skill
Find ICP-fit leads by scraping engagers from a competitor's top-performing LinkedIn posts. Given one or more company page URLs, this skill finds their highest-engagement recent posts, extracts everyone who reacted or commented, and classifies by ICP fit.
Core principle: Scrape all posts in one call per company, then locally rank and select the top N. This minimizes Apify costs while maximizing lead quality.
Ask the user these questions:
https://www.linkedin.com/company/11x-ai/)Save config in the current working directory (or user-specified path):
competitor-post-engagers-config.jsonConfig JSON structure:
{
"name": "<run-name>",
"company_urls": ["https://www.linkedin.com/company/<competitor>/"],
"days_back": 30,
"max_posts": 50,
"max_reactions": 500,
"max_comments": 200,
"top_n_posts": 1,
"icp_keywords": ["sales", "revenue", "growth", "SDR", "BDR", "outbound"],
"exclude_keywords": ["software engineer", "developer", "designer"],
"enrich_companies": true,
"competitor_company_names": ["<competitor-name>"],
"industry_keywords": ["freight", "logistics", "trucking", "transportation", "3pl", "supply chain", "carrier", "brokerage", "shipping", "warehousing"],
"output_dir": "output"
}enrich_companies — Enable Apollo company enrichment (default: true). Set to false or use --skip-company-enrich to skip.competitor_company_names — Company names to exclude from enrichment (the competitor itself).industry_keywords — Industry terms that indicate ICP fit. Matched against Apollo's industry field.The output_dir is relative to the script directory by default. Override it with an absolute path to write output to a specific location.
python3 skills/competitor-post-engagers/scripts/competitor_post_engagers.py \
--config competitor-post-engagers-config.json \
[--test] [--yes] [--skip-company-enrich] [--top-n 3] [--max-runs 30]Flags:
--config (required) — path to config JSON--test — small limits (20 posts, 50 profiles, 1 top post)--yes — skip cost confirmation prompts--skip-company-enrich — skip Apollo company enrichment step (saves credits)--top-n — override top_n_posts from config--max-runs — override Apify run limitStep 1: Scrape company posts + engagers — For each company URL, one Apify call using harvestapi/linkedin-company-posts with scrapeReactions: true, scrapeComments: true. Returns posts, reactions, and comments in a single dataset.
Step 2: Rank & select top posts — Filter posts by time window (days_back), rank by total engagement (reactions + comments), select top N per company. Then extract engagers (reactors + commenters) only from those selected posts. Deduplication by name. Score engagers by position:
+3 Commenter (higher intent)+2 Position matches ICP keywords-5 Position matches exclude keywordsStep 3: Company enrichment (Apollo) — Extract unique company names from engagers, call apollo.enrich_organization(name=...) for each. Returns industry, employee count, description, and location. ~1 Apollo credit per unique company. Merge data back to all engagers from that company. Skip with --skip-company-enrich or "enrich_companies": false.
Step 4: ICP classify & export — Classify as Likely ICP / Possible ICP / Unknown / Tech Vendor. Uses both headline keyword matching AND company industry data (from Step 3) — if the engager's company industry matches industry_keywords, they're classified as "Likely ICP" regardless of role. Export CSV.
| Parameter | Test | Standard |
|---|---|---|
| Posts scraped per company | 20 | 50 |
| Max reactions | 50 | 500 |
| Max comments | 50 | 200 |
| Est. Apify cost (1 company) | ~$0.10 | ~$0.50-1 |
| Est. Apollo credits (company enrich) | ~10-20 | ~30-80 unique companies |
| Est. Apollo cost | ~$0.05-0.10 | ~$0.15-0.40 |
Present results:
Common adjustments:
icp_keywords or add exclude_keywordsicp_keywordstop_n_posts or adjust days_back--test mode or lower max_reactions/max_commentsCSV exported to {output_dir}/{name}-engagers-{date}.csv:
| Column | Description |
|---|---|
| Name | Full name |
| LinkedIn URL | Profile link |
| Role | Parsed from headline |
| Company | Parsed from headline |
| Company Industry | From Apollo enrichment |
| Company Size | Estimated employee count from Apollo |
| Company Description | Short company description from Apollo |
| Company Location | City, State, Country from Apollo |
| Source Page | Which competitor's page |
| Post URL | Link to the specific post |
| Post Preview | First 120 chars of post content |
| Engagement Type | Comment or Reaction |
| Comment Text | Their comment (personalization gold) |
| ICP Tier | Likely ICP / Possible ICP / Unknown / Tech Vendor |
| Pre-Filter Score | Priority score from pre-filter |
APIFY_API_TOKEN in .envAPOLLO_API_KEY in .env (for company enrichment)harvestapi/linkedin-company-posts (post + engager scraping)organizations/enrich (company industry/size lookup, 1 credit per company)Trigger phrases:
Test mode:
python3 skills/competitor-post-engagers/scripts/competitor_post_engagers.py \
--config competitor-post-engagers-config.json --test --yesFull run:
python3 skills/competitor-post-engagers/scripts/competitor_post_engagers.py \
--config competitor-post-engagers-config.json --yesenrich_companies — Enable Apollo company enrichment (default: true). Set to false or use --skip-company-enrich to skip.competitor_company_names — Company names to exclude from enrichment (the competitor itself).industry_keywords — Industry terms that indicate ICP fit. Matched against Apollo's industry field.--config (required) — path to config JSON--test — small limits (20 posts, 50 profiles, 1 top post)Assemble an expert/educator motion-graphic LISTICLE video ad from a config — a spoken authoritative voiceover carries a numbered listicle while N web-animated hyperframe beats (HTML plus the Web Animations API, one branded design system of alternating tiles, big hero numerals, and glass-pill callouts) are rendered frame-by-frame via Playwright and anchored to the VO's word-level timestamps, periodic color-graded B-roll windows give visual breath, and captions burn ONLY inside those B-roll windows (2-word chunks, ASS Format header carrying a Name field so none drop) with the VO mixed under a low music bed. This is the FREE deterministic assembly stage (Playwright beat render plus ffmpeg concat plus window-masked caption burn plus VO-and-music mix plus final composite) — the VO, the music bed, and the stock B-roll come from create-vo-elevenlabs, create-music-elevenlabs, and media-proxy. Use for the vo-anchored-motion-listicle format.
Assemble a stop-motion hand-swatch-cycle product-demo ad from a config — a sequence of still PLATES (one hand swiping a single-barrel cosmetic across a cream skin-patch, the barrel + swatch changing per plate while the hand, background, crop, and lighting stay locked) is PNG→mp4 loop-encoded at each plate's own stop-motion hold (fast motion frames 150–250ms, per-shade ~380ms, hero beats 1100–1800ms), concat-demuxed with HARD cuts into a silent master, closed on a Playwright HTML-rendered branded end card (serif tagline + sans subtitle + real logo SVG over a hero BG, never AI-rendered text), and muxed with a pre-sourced music track playing under the end card with a fade tail (no VO). This is the FREE deterministic assembly stage (loop-encode + concat-demux + end-card render + music mux); the master-anchor plate, shade plates, and end-card BG come from create-image-gpt-image-fal and the track from create-music-elevenlabs. Use for the stopmotion-hand-swatch-cycle format.
Assemble a split-screen creator ad from a config — a two-zone vertical composite where a supplied AI-creator lip-sync take fills the BOTTOM ~48% while real 16:9 product/demo clips run uncropped in the TOP ~52%, each top clip contain-fit with a darkened blurred cover-scale fill of the same clip (never black bars), a 3px brand-color divider between the zones, the creator slice cover-fit per the per-scene VO timing, scenes hard-concatenated with the body audio being the concatenated creator VO slices, an end card held on the last sharp frame ~3s, then the ASSEMBLED cut transcribed with local Whisper (not the raw VO — concat drops inter-scene silence) and word-level captions burned in the chosen style. This is the FREE deterministic assembly + caption stage (two-zone composite + blurred fill + divider + hard-concat + end card + captions); the VO comes from create-vo-elevenlabs, the anchor from create-image-gpt-image-fal, and the whole-VO lip-sync from a paid VEED Fabric 1.0 take (a no-atom upstream input). Use for the split-screen-creator format.