Install
$ agentstack add skill-felipesalinasr-fsr-stack-linkedin-comment-to-outreach ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
LinkedIn Comment to Outreach Pipeline
Overview
End-to-end orchestrator that takes a single LinkedIn post URL and produces a fully loaded, paused Instantly cold email campaign. The core principle: chain 5 focused sub-skills with a user checkpoint between each phase so the operator stays in control while the heavy lifting is automated.
When to use
- User provides a LinkedIn post URL and wants to reach out to its commenters
- User asks to "run the linkedin pipeline", "scrape and email", or "linkedin comment to outreach"
- User wants a complete path from a LinkedIn post to a live Instantly campaign
- User needs commenters scraped, stored in Airtable, enriched with Apollo, sequenced, and loaded into Instantly in one flow
When NOT to use
- Targeting people who reacted to a post (use
linkedin-reaction-to-outreachinstead) - Just scraping commenters with no outreach (use
linkedin-comment-scraperdirectly) - Just enriching an existing list (use
apollo-enrichmentdirectly) - Just writing a cold email sequence without a lead source (use
cold-email-sequencedirectly) - Just creating an Instantly campaign from leads you already have (use
instantly-campaigndirectly)
Prerequisites
- Always check if a tool is available in Composio first
- MCP tools: Apify, Airtable, Apollo.io
- API key:
INSTANTLY_API_KEYenvironment variable (see../SETUP.md) - Airtable base: Existing base ID (user provides or we discover via
list_bases) - User input needed for Phase 4: Social proof, product description, CTA preferences, sender name
The Pipeline
LinkedIn Post URL
|
v
[1. linkedin-comment-scraper] -- Apify scrape, deduplicate
|
v
[2. airtable-lead-loader] -- Create table, batch load records
|
v
[3. apollo-enrichment] -- Bulk email lookup, update Airtable, create contacts
|
v
[4. cold-email-sequence] -- Co-write 3 emails with user (interactive)
|
v
[5. instantly-campaign] -- Create campaign, load leads, configure accounts
|
v
Campaign ready for review (paused)
Phase 1: Scrape (Skill: linkedin-comment-scraper)
Input: LinkedIn post URL from user Output: ./output/linkedin_commenters.json
- Validate the LinkedIn post URL
- Test scrape with
maxItems: 20 - Full scrape with
maxItems: 500 - Deduplicate by
profileUrl, remove null profiles - Save to
./output/linkedin_commenters.json
Checkpoint: Report to user: "Scraped X unique commenters from [Author]'s post. Proceeding to Airtable."
Phase 2: Store (Skill: airtable-lead-loader)
Input: ./output/linkedin_commenters.json, Airtable Base ID Output: Airtable table populated, record IDs saved
- List Airtable bases, confirm with user
- Create table: "LinkedIn Commenters - [Author Name]"
- Include all fields: scrape data + enrichment fields + outreach tracking
- Batch load via parallel agents (4 agents for speed or more if possible)
- Verify load count
Checkpoint: Report: "Loaded X records into Airtable. Starting Apollo enrichment."
Phase 3: Enrich (Skill: apollo-enrichment)
Input: Airtable Base ID, Table ID Output: Airtable updated with emails, Apollo contacts created
- Pull all records from Airtable
- Batch into groups of 10 for Apollo bulk match
- Run enrichment via parallel agents
- Update Airtable records with email, company, title, location
- Create Apollo contacts under label: "LinkedIn Comments - [Author] Post"
- Re-fetch records with emails, save to
./output/apollo_contacts.json
Checkpoint: Report: "Found emails for X out of Y people (Z% match rate). X contacts ready for outreach."
Phase 4: Write (Skill: cold-email-sequence)
Input: User context (product, social proof, trigger), contact count Output: {campaign-name}-sequence.md
This is the interactive step. Work with the user one email at a time:
- Gather inputs: trigger, product, social proof, CTA, sender name
- Draft Email 1 (Day 0) -- present, refine, lock
- Draft Email 2 (Day 3) -- present, refine, lock
- Draft Email 3 (Day 7) -- present, refine, lock
- Save complete sequence to file
Key rules:
- James Shields framework (personalize subject not body, 3 sentences + PS, low-friction CTA)
- No em dashes, no exclamation points, no formatting
- Each email approved before moving to next
- NEW social proof for each email (never repeat)
Checkpoint: "Sequence locked. Ready to load into Instantly."
Phase 5: Launch (Skill: instantly-campaign)
Input: Sequence file, ./output/apollo_contacts.json, INSTANTLY_API_KEY Output: Paused Instantly campaign with all leads loaded
- Read
INSTANTLY_API_KEYfrom environment (see../SETUP.md) - List connected email accounts
- Create campaign with all 3 email steps
- Sanitize bodies -- remove all
&characters (Instantly bug) - Verify all step bodies are non-empty
- Bulk load leads (up to 1000 per call)
- Attach all sending accounts
- Leave campaign PAUSED
Final report to user:
- Campaign name and status (paused)
- Number of leads loaded
- Sending accounts
- Schedule (Mon-Fri, 8-5 Pacific,
America/Vancouver-- handles DST automatically) - "Review in Instantly dashboard. Say 'go' when ready to launch."
Quick Reference
| Phase | Sub-skill | Input | Output | |-------|-----------|-------|--------| | 1 | linkedin-comment-scraper | LinkedIn post URL | ./output/linkedin_commenters.json | | 2 | airtable-lead-loader | commenters JSON, base ID | Airtable table populated | | 3 | apollo-enrichment | Airtable base + table ID | ./output/apollo_contacts.json, Apollo contacts | | 4 | cold-email-sequence | User context, contact count | {campaign-name}-sequence.md | | 5 | instantly-campaign | sequence file, contacts JSON, INSTANTLY_API_KEY | Paused Instantly campaign |
Timing expectations:
| Phase | Duration | |-------|----------| | 1. Scrape | 2-5 minutes (Apify run time) | | 2. Store | 3-10 minutes (parallel agent loading) | | 3. Enrich | 5-15 minutes (Apollo calls + Airtable updates) | | 4. Write | 10-30 minutes (interactive with user) | | 5. Launch | 2-5 minutes (API calls) | | Total | ~30-60 minutes |
Common Mistakes
| Phase | Failure mode | Fix | |-------|--------------|-----| | 1. Scrape | Only 20 results returned | Re-run with maxItems: 500 | | 1. Scrape | Invalid LinkedIn URL | Verify with user, try WebFetch to resolve canonical URL | | 2. Store | Token limit on list_records | Save records to file, parse with jq/Python | | 2. Store | Batch limit exceeded | Split into chunks of 10 | | 3. Enrich | Low match rate (<40%) | Normal for some audiences. Proceed with what you have. | | 3. Enrich | Cached data missing emails | Re-fetch from Airtable after enrichment completes | | 4. Write | User wants major changes | Rewrite from scratch, do not patch | | 5. Launch | Empty body on Instantly side | Ampersand in text. Strip all & characters before upload. | | 5. Launch | Timezone rejected by Instantly | Use America/Vancouver for Pacific (handles DST automatically) |
Example
A worked walkthrough using placeholder inputs:
- User: "Run the linkedin pipeline on
https://www.linkedin.com/posts/janedoe_example-activity-12345" - Phase 1: Scrape commenters via Apify. Result: 187 unique commenters saved to
./output/linkedin_commenters.json. Report: "Scraped 187 unique commenters from Jane Doe's post. Proceeding to Airtable." - Phase 2: Create Airtable table "LinkedIn Commenters - Jane Doe" in base
appXXXXXXXXXXXXXX, batch load 187 records via 4 parallel agents. Report: "Loaded 187 records into Airtable. Starting Apollo enrichment." - Phase 3: Bulk match 187 records via Apollo in batches of 10. Find emails for 92 people (49% match rate). Update Airtable, create Apollo contacts under label "LinkedIn Comments - Jane Doe Post", save 92 verified leads to
./output/apollo_contacts.json. Report: "Found emails for 92 out of 187 people (49% match rate). 92 contacts ready for outreach." - Phase 4: Interactively co-write 3-email sequence with user. Gather: trigger ("Jane's post on RevOps"), product ("Taxflow"), social proof, CTA, sender name. Draft, refine, and lock each email. Save to
jane-doe-revops-sequence.md. Report: "Sequence locked. Ready to load into Instantly." - Phase 5: Read
INSTANTLY_API_KEYfrom env. Create campaign "LinkedIn - Jane Doe RevOps", strip all&characters from bodies, load all 92 leads in one bulk call, attach all connected sending accounts, leave PAUSED. Schedule: Mon-Fri 8-5 Pacific (America/Vancouver). - Final report: Campaign name, status (paused), 92 leads loaded, sending accounts, schedule, and "Review in Instantly dashboard. Say 'go' when ready to launch."
Output
- Airtable table with all commenters + enrichment data
- Apollo contacts under named label
- Email sequence file in workspace
- Instantly campaign (paused) with 3 email steps, all leads loaded, all sending accounts attached, ready to activate on user command
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: felipesalinasr
- Source: felipesalinasr/fsr-stack
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.