Turn LinkedIn post engagers into scored leads with n8n

Find LinkedIn posts by topic, pull every reactor and commenter, score them against your ICP with AI, and save hot leads with a ready connection note to Google Sheets.

Find LinkedIn posts on any topic, pull everyone who reacted or commented, score each person against your ICP with AI, and save qualified leads with a ready connection note to Google Sheets. No post URLs needed: you give the workflow a topic, and it finds the posts itself.

Why post engagers convert better than cold lists, and how to run the same pipeline from MCP or REST: see the playbook Mine LinkedIn post engagement for intent signals.

Import the template: Score LinkedIn post engagers as leads with Periodix Actions, Claude, and Google Sheets

What you need

  • A Periodix Actions account with a connected LinkedIn profile (3-day free trial)
  • The Periodix Actions node installed (listed in n8n as Periodix LinkedIn), see Installation
  • An AI provider API key: Claude by default, OpenAI or Gemini also work
  • A Google Sheet with two tabs: Hot and Cold

Workflow at a glance

Run Daily → Campaign Config → Find Topic Posts (Periodix Actions) → Extract Posts → Loop Posts → Get Post Reactions + Get Post Comments (Periodix Actions) → Normalize → Merge → Dedupe and Pre-filter by ICP → Score and Draft with AI → Parse AI Output → Hot Lead? → Save Hot Lead / Save Cold Lead

Step by step

1. Run Daily (Schedule Trigger)

Runs once a day at 9:00. Change the hour to fit your timezone.

2. Campaign Config (Set node)

All settings live in one place:

FieldExampleWhat it controls
topic_keywordsAI agents in salesThe topic used to find posts
icp_keywordsfounder, head of, growth, marketing, salesCheap pre-filter on headline and company, before any AI call
icp_descriptionRole, company type, sizePassed to AI for scoring
offerOne sentence on what you offerPassed to AI for the connection note
score_threshold7Minimum score to count as a hot lead
posts_limit20How many posts to pull per run
reactions_limit100Max reactions per post
comments_limit100Max comments per post

3. Find Topic Posts (Periodix Actions: Search)

  • Resource: Search
  • Profile: your connected LinkedIn profile
  • Search URL:
{{ "https://www.linkedin.com/search/results/content/?keywords=" + encodeURIComponent($("Campaign Config").first().json.topic_keywords) }}
  • Limit: {{ $("Campaign Config").first().json.posts_limit }}

The search runs asynchronously and can take a few minutes. Each matching post becomes one item.

4. Extract Posts (Code node)

Dedupes posts and keeps three fields: post_id, post_url, and post_text (first 500 characters). The post ID is taken from social_id when present. This is the identifier that the reactions and comments operations expect.

5. Loop Posts (Loop Over Items)

Processes one post at a time, so reactions and comments are always matched to the right post.

6. Get Post Reactions and Get Post Comments (Periodix Actions: Post)

Both run in parallel for the current post:

  • Resource: Post
  • Operation: Get Reactions / Get Comments
  • Post ID: {{ $json.post_id }}
  • Limit: reactions_limit / comments_limit from Campaign Config
  • Settings → On Error: Continue, so a post with no engagement does not stop the run

7. Normalize Reactions and Normalize Comments (Code nodes)

Both branches are mapped to the same shape:

FieldSource
sourcereaction or comment
name, headline, companyEngager's profile
provider_idLinkedIn ID, used later to send a connection request
profile_urlPublic profile URL
matched_post, post_urlThe post they engaged with

8. Merge, Collect, Dedupe and Pre-filter by ICP (Merge + Code nodes)

Engagers from all posts are merged and deduped by provider_id. Anyone whose headline or company contains none of your icp_keywords is dropped here, before any AI call. This is the main cost saver: you never pay to score someone who was never going to qualify. Leave icp_keywords empty to skip the pre-filter.

9. Score and Draft with AI (HTTP Request)

One AI call per engager does two jobs: it scores ICP fit from 1 to 10 with a short reason, and, for scores of 5 or higher, it writes a connection note under 300 characters that references the post the person engaged with. The default is Claude Haiku via the Anthropic API, one request every 1.5 seconds, with retry on failure. Swap the URL and body to use OpenAI or Gemini.

10. Parse AI Output (Code node)

Strips code fences and parses the JSON reply into score, reason, and connection_note. If parsing fails, the engager gets a score of 0 and the reason parse error, so nothing is lost silently.

11. Hot Lead? (If node) and Save to Google Sheets

Engagers with score >= score_threshold go to the Hot tab with the connection note. Everyone else goes to the Cold tab with the score and reason, which you can use to refine your ICP.

Example output (Hot tab row)

{
  "source": "comment",
  "name": "Jane Doe",
  "headline": "Head of Growth at Example SaaS",
  "company": "Example SaaS",
  "provider_id": "ACoAAExample123",
  "profile_url": "https://www.linkedin.com/in/janedoe",
  "matched_post": "We replaced our SDR research step with an AI agent...",
  "post_url": "https://www.linkedin.com/feed/update/urn:li:activity:0000000000000000000",
  "score": 8,
  "reason": "Growth leader at a B2B SaaS company actively exploring AI in outbound.",
  "connection_note": "Hi Jane, your comment on using AI agents for SDR research stood out. We work on the same problem from the LinkedIn data side, would be great to connect."
}

Next step: send the connection requests

Add a Periodix Actions node after Save Hot Lead:

  • Resource: Connection
  • Operation: Send Request
  • Recipient: {{ $json.provider_id }}
  • Note: {{ $json.connection_note }}

Add a Wait node with a randomized delay between sends, and start with low daily volumes on new or recently inactive accounts.

Troubleshooting

  • No posts found: try broader topic keywords, and check that the selected profile is connected on the Profiles page.
  • Some posts return no engagers: normal for posts with little engagement. On Error: Continue keeps the run going.
  • Almost everyone is filtered out: your icp_keywords are too narrow. Add more terms or leave the field empty.
  • Scores of 0 with reason "parse error": the AI reply was not valid JSON. Check the model name and the API key, and keep the "Respond in raw JSON only" instruction in the prompt.
  • The same person appears on different days: the workflow dedupes within one run only. To skip people already in the sheet, read the Hot and Cold tabs first and filter by provider_id, or use the Google Sheets Append or Update operation matched on provider_id.
  • The run takes a long time: each post adds two Periodix calls and one AI call per engager. Lower posts_limit, reactions_limit, or comments_limit.

Related


Did this page help you?