Google Sheets + LinkedIn: outreach tracked, invites sent
Your LinkedIn outreach usually breaks in the same place. You start with a clean list, you send a few invites, then the tabs multiply, the notes get messy, and you’re never 100% sure who you already contacted. That’s how duplicates happen. Or worse, silence because you forgot to follow up.
LinkedIn outreach automation is a lifesaver for recruiters managing candidate pipelines, but growth marketers and small agency owners feel the same pain. The outcome is simple: invites go out only when they should, messages go out only once, and your tracking stays reliable in Google Sheets.
This workflow runs outreach straight from a spreadsheet, checks connection status, sends a connection request, then generates an AI icebreaker based on real LinkedIn activity. You’ll see what it does, what you need, and where teams usually trip up.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Google Sheets + LinkedIn: outreach tracked, invites sent
flowchart LR
subgraph sg0["Manual Run Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "Manual Run Trigger", pos: "b", h: 48 }
n1@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Connection Status Check", pos: "b", h: 48 }
n2@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Message Sent Check", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Invite Sent Check", pos: "b", h: 48 }
n4@{ icon: "mdi:database", form: "rounded", label: "Modify Message Flag", pos: "b", h: 48 }
n5@{ icon: "mdi:database", form: "rounded", label: "Modify Invite Flag", pos: "b", h: 48 }
n6@{ icon: "mdi:play-circle", form: "rounded", label: "Scheduled Automation Trigger", pos: "b", h: 48 }
n7@{ icon: "mdi:database", form: "rounded", label: "Update Relation Flag", pos: "b", h: 48 }
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Relation Condition Check", pos: "b", h: 48 }
n9@{ icon: "mdi:cog", form: "rounded", label: "Run Sub-Workflow (Configure ..", pos: "b", h: 48 }
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Lookup User Profile"]
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Retrieve Profile Posts"]
n12@{ icon: "mdi:swap-vertical", form: "rounded", label: "Separate Items", pos: "b", h: 48 }
n13@{ icon: "mdi:cog", form: "rounded", label: "Restrict Count", pos: "b", h: 48 }
n14@{ icon: "mdi:cog", form: "rounded", label: "Aggregate Records", pos: "b", h: 48 }
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Retrieve Company Posts"]
n16@{ icon: "mdi:swap-vertical", form: "rounded", label: "Separate Items B", pos: "b", h: 48 }
n17@{ icon: "mdi:cog", form: "rounded", label: "Restrict Count B", pos: "b", h: 48 }
n18@{ icon: "mdi:cog", form: "rounded", label: "Aggregate Records B", pos: "b", h: 48 }
n19@{ icon: "mdi:swap-vertical", form: "rounded", label: "Assign Input Data", pos: "b", h: 48 }
n20@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Validate Username Present", pos: "b", h: 48 }
n21@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Validate Company ID", pos: "b", h: 48 }
n26@{ icon: "mdi:swap-vertical", form: "rounded", label: "Map Response Range 0-2", pos: "b", h: 48 }
n27@{ icon: "mdi:swap-vertical", form: "rounded", label: "Map Response Range 0-1", pos: "b", h: 48 }
n28@{ icon: "mdi:database", form: "rounded", label: "Retrieve Sheet Data", pos: "b", h: 48 }
n29@{ icon: "mdi:database", form: "rounded", label: "Modify Sheet Data", pos: "b", h: 48 }
n30@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set Connection Flag", pos: "b", h: 48 }
n31@{ icon: "mdi:cog", form: "rounded", label: "Detect Connection State", pos: "b", h: 48 }
n32@{ icon: "mdi:cog", form: "rounded", label: "Dispatch LinkedIn Message", pos: "b", h: 48 }
n33@{ icon: "mdi:cog", form: "rounded", label: "Dispatch Connection Invite", pos: "b", h: 48 }
n34@{ icon: "mdi:swap-vertical", form: "rounded", label: "Process Next Batch", pos: "b", h: 48 }
n35@{ icon: "mdi:cog", form: "rounded", label: "Sort Records", pos: "b", h: 48 }
n36@{ icon: "mdi:cog", form: "rounded", label: "Sort Records B", pos: "b", h: 48 }
n35 --> n17
n13 --> n14
n36 --> n13
n17 --> n18
n14 --> n21
n34 --> n10
n12 --> n36
n18 --> n9
n28 --> n34
n16 --> n35
n29 --> n8
n1 --> n2
n1 --> n3
n8 --> n30
n8 --> n31
n9 --> n29
n6 --> n19
n15 --> n16
n11 --> n12
n30 --> n1
n3 --> n33
n19 --> n28
n5 --> n34
n2 --> n32
n2 --> n7
n31 --> n1
n4 --> n34
n20 --> n27
n20 --> n11
n27 --> n21
n26 --> n9
n21 --> n26
n21 --> n15
n10 --> n20
n33 --> n5
n32 --> n4
n0 --> n19
end
subgraph sg1["Triggered by Parent Flow Flow"]
direction LR
n22@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Engine", pos: "b", h: 48 }
n23@{ icon: "mdi:robot", form: "rounded", label: "Structured Result Parser", pos: "b", h: 48 }
n24@{ icon: "mdi:robot", form: "rounded", label: "Compose Subject and Letter", pos: "b", h: 48 }
n25@{ icon: "mdi:play-circle", form: "rounded", label: "Triggered by Parent Flow", pos: "b", h: 48 }
n22 -.-> n24
n23 -.-> n24
n25 --> n24
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0,n6,n25 trigger
class n23,n24 ai
class n22 aiModel
class n1,n2,n3,n8,n20,n21 decision
class n4,n5,n7,n28,n29 database
class n10,n11,n15 api
classDef customIcon fill:none,stroke:none
class n10,n11,n15 customIcon
The Problem: LinkedIn Outreach Gets Messy Fast
Running outreach from LinkedIn manually looks manageable… until you do it every day. You copy profile links from a sheet, open them one by one, check if you’re already connected, send an invite, then try to craft a message that doesn’t sound like a template. Then you do it again tomorrow, except you can’t remember if you already invited “Jordan P.” last week, and your notes are split across LinkedIn, a CRM, and someone’s half-updated spreadsheet. The mental load is real, and mistakes are awkward (duplicate invites, repeated messages, or missing follow-ups).
It adds up fast. And the friction compounds once you scale beyond a handful of profiles.
- Checking connection status profile-by-profile eats about 5 minutes per lead, and it’s pure context switching.
- Your tracking drifts because “I’ll update the sheet later” turns into “I forgot which ones I sent.”
- Generic first messages get ignored, so you spend your best energy rewriting the same opener all week.
- Without a consistent process, outreach volume stays capped by your calendar, not your pipeline goals.
The Solution: Google Sheets-Driven Outreach With Built-In Safeguards
This n8n workflow turns your Google Sheet into the control center for LinkedIn outreach. It starts by pulling LinkedIn profile addresses from your sheet, then checks what’s already been done so you don’t resend invites or messages. Next, it looks up the person’s profile details and recent posts (plus company posts when available) using API calls, which gives the AI enough context to write a real icebreaker. Finally, Browserflow sends the connection invite or the follow-up message on LinkedIn, and the workflow writes the outcome back to Google Sheets. Your sheet stays current, your outreach stays consistent, and you can run it on a schedule instead of “when you have time.”
The workflow can be triggered manually for a quick batch, or run automatically on a schedule. In the middle, it enriches each lead with profile and post data, generates a tailored message with OpenAI, then uses Browserflow to send the invite and message. After that, it updates flags in Google Sheets (invite sent, message sent, relation/connection state), so the next run knows exactly what to do.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you reach out to 50 LinkedIn profiles each week. Manually, you’ll spend about 5 minutes per person to open the profile, confirm connection state, send an invite, and note it somewhere, which is roughly 4 hours. Then you’ll spend another 2 hours writing “not-too-salesy” openers. With this workflow, you update one Google Sheet, run a batch (or let the schedule handle it), and you mainly review the generated icebreakers. Most teams get back about 4 hours a week, sometimes more.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets to store leads, flags, and status.
- Browserflow to send LinkedIn invites and messages.
- RapidAPI key (get it from your RapidAPI dashboard).
- OpenAI API key (get it from the OpenAI API settings page).
Skill level: Intermediate. You’ll connect accounts, add credentials, and self-host n8n if you want the Browserflow community node.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A scheduled run (or manual run) kicks things off. You can run it on demand when you add fresh leads, or set the schedule trigger so it checks your sheet regularly and processes the next batch.
Your sheet becomes the single source of truth. n8n retrieves the rows, sorts them, then works through them in batches. It uses flags like “invite sent” and “message sent” so the workflow can safely run again tomorrow without repeating itself.
Profile and company context gets pulled in. HTTP requests fetch the user profile plus a limited number of personal and company posts (based on your MaxItems setting). The workflow aggregates that content so the AI has enough material to work with, without downloading endless feeds.
Invites and icebreakers go out, then tracking updates. If you are not connected, Browserflow sends the invite. If it’s time to message (or a connection is detected), OpenAI generates a tailored opener and Browserflow sends it, then Google Sheets is updated so you can see exactly what happened.
You can easily modify the message prompt to match your brand voice based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Manual Trigger
This workflow can be started manually or on a schedule. Configure both triggers so you can test manually and then automate.
- Open Manual Run Trigger and leave the default settings (manual execution trigger).
- Open Scheduled Automation Trigger and set your preferred schedule for recurring runs.
- Ensure both Manual Run Trigger and Scheduled Automation Trigger connect into Assign Input Data.
Step 2: Connect Google Sheets
Five Google Sheets nodes read and update flags for outreach status. Connect credentials and set sheet details consistently across them.
- Open Retrieve Sheet Data and select your spreadsheet and range for input records.
- Open Modify Sheet Data and map fields for updating profile details returned by the sub-workflow.
- Open Modify Invite Flag, Modify Message Flag, and Update Relation Flag to update the correct columns for invite, message, and relation status.
- Credential Required: Connect your Google Sheets credentials to Retrieve Sheet Data, Modify Sheet Data, Modify Invite Flag, Modify Message Flag, and Update Relation Flag.
Step 3: Set Up Data Preparation and Profile Lookup
This path loads batch data, enriches it with profile data, and decides which downstream branch to use.
- In Assign Input Data, map any fixed or derived fields needed by downstream nodes.
- Confirm Retrieve Sheet Data flows into Process Next Batch and then into Lookup User Profile.
- Credential Required: Connect your HTTP Request credentials (or API auth headers) in Lookup User Profile, Retrieve Profile Posts, and Retrieve Company Posts to access external data.
- Verify the decision logic in the IF nodes (Validate Username Present and Validate Company ID) matches your API response fields.
Step 4: Configure AI Message Generation
The AI chain generates the outreach subject and letter using a language model and structured parser.
- Open Compose Subject and Letter and confirm it is connected to Triggered by Parent Flow for inbound executions.
- Ensure OpenAI Chat Engine is attached to Compose Subject and Letter as the language model input.
- Ensure Structured Result Parser is attached to Compose Subject and Letter as the output parser.
- Credential Required: Connect your OpenAI credentials in OpenAI Chat Engine. The Structured Result Parser is a sub-node—add credentials to OpenAI Chat Engine, not the parser.
Step 5: Configure Outreach Routing and Browser Automation
IF branches route contacts through invite, message, and connection status paths, with Browserflow nodes performing LinkedIn actions.
- Review the branch chain from Set Connection Flag → Connection Status Check → Message Sent Check and Invite Sent Check to match your business rules.
- Confirm Dispatch Connection Invite outputs to Modify Invite Flag, and Dispatch LinkedIn Message outputs to Modify Message Flag.
- Credential Required: Connect your Browserflow credentials in Dispatch Connection Invite, Dispatch LinkedIn Message, and Detect Connection State.
- Validate the loopback from Modify Invite Flag and Modify Message Flag into Process Next Batch to continue batch processing.
Step 6: Configure the Sub-Workflow Execution
The workflow calls a child workflow for additional processing before writing back to the sheet.
- Open Run Sub-Workflow (Configure Required) and select the target workflow to execute.
- Verify the flow from Aggregate Records B to Run Sub-Workflow (Configure Required) and back to Modify Sheet Data.
Step 7: Configure Sorting, Limiting, and Aggregation
These nodes control the volume and ordering of content used for personalization.
- Review Separate Items → Sort Records B → Restrict Count → Aggregate Records for profile post selection.
- Review Separate Items B → Sort Records → Restrict Count B → Aggregate Records B for company post selection.
Step 8: Test and Activate Your Workflow
Run a manual test to confirm the full flow, then enable the schedule for production.
- Click Execute Workflow to run from Manual Run Trigger and inspect data through Retrieve Sheet Data and Process Next Batch.
- Confirm successful branches: HTTP requests return profile data, AI outputs from Compose Subject and Letter are structured, and Google Sheets flags update via Modify Invite Flag and Modify Message Flag.
- Verify Browserflow actions execute and the status checks (Connection Status Check, Message Sent Check, Invite Sent Check) route correctly.
- Enable the workflow and activate Scheduled Automation Trigger for ongoing execution.
Common Gotchas
- Google Sheets credentials can expire or lose access if the sheet is moved. If things break, check the n8n credential connection test and the sheet sharing permissions first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Browserflow can fail if your LinkedIn session changes or the API key is wrong. Re-check the Browserflow credential in n8n and confirm your Browserflow plan still has invite/message capacity.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Frequently Asked Questions
About 45 minutes if you already have your keys and accounts.
No. You will mostly copy credentials, map a few fields, and test with a small batch.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenAI API usage and RapidAPI credits (you can contact up to 50 people on the free tier mentioned in the workflow notes).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and you should. Update the prompt in the OpenAI Chat Engine node so it matches your tone, your offer, and what you consider “personalized.” Common tweaks include changing the length, adding a soft CTA, and telling it to reference a recent post only when it’s actually relevant (otherwise it can feel forced).
Usually it’s an invalid API key, a plan limit (no remaining invites/messages), or a LinkedIn session change on the Browserflow side. Recreate the Browserflow credential in n8n, then verify your Browserflow account is active and has capacity. If it fails only on some profiles, LinkedIn restrictions or unusual profile formats can also cause intermittent errors.
Practically, it can handle as many rows as your n8n and API limits allow, but most people start with batches of 20–50 and scale up once results look good.
For LinkedIn outreach specifically, n8n tends to be the better fit because you can self-host (important here), handle branching logic without paying per “path,” and stitch together enrichment plus AI generation in one flow. Zapier and Make are great for simple “new row → send email” automations, but LinkedIn sending usually needs more careful checks and state tracking. Also, this workflow uses a community node (Browserflow), which is a big deal if you want LinkedIn actions inside the automation. If you want help choosing, Talk to an automation expert.
Once this is running, your spreadsheet stays clean and your outreach stays consistent. Honestly, it’s nice to stop thinking about “did I already send that?” and just move on.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.