Google Sheets + LinkedIn: posts published without repeats
Posting on LinkedIn sounds simple until you’re staring at a blank box, digging for old drafts, and wondering if you already posted that exact idea last month.
This hits marketing managers and agency owners hardest, honestly. But founders running their own personal brand feel it too. With Sheets LinkedIn automation, your Google Sheet becomes a queue that writes, posts, and marks items as done so nothing repeats.
You’ll see how the workflow turns “pending topics” into published posts on your profile and in groups, without you babysitting every step.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: Google Sheets + LinkedIn: posts published without repeats
flowchart LR
subgraph sg0["Linkedin-Post-Topic Flow"]
direction LR
n0@{ icon: "mdi:cog", form: "rounded", label: "Limit", pos: "b", h: 48 }
n1@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser", pos: "b", h: 48 }
n2@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model", pos: "b", h: 48 }
n3@{ icon: "mdi:play-circle", form: "rounded", label: "Linkedin-Post-Topic", pos: "b", h: 48 }
n4@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Validate-Status", pos: "b", h: 48 }
n5@{ icon: "mdi:robot", form: "rounded", label: "Linedin-Post-Creator", pos: "b", h: 48 }
n6["<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/code.svg' width='40' height='40' /></div><br/>Format-Content"]
n7["<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/>Linkedin-User-Detail"]
n8["<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/>Linkedin-post"]
n9@{ icon: "mdi:database", form: "rounded", label: "Get-Group-id", pos: "b", h: 48 }
n10@{ icon: "mdi:swap-vertical", form: "rounded", label: "Pick 1 by 1", pos: "b", h: 48 }
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/>Post-Linkedin-Groups"]
n12@{ icon: "mdi:database", form: "rounded", label: "Update-Status", pos: "b", h: 48 }
n0 --> n5
n10 --> n12
n10 --> n11
n9 --> n10
n8 --> n9
n6 --> n7
n4 --> n0
n2 -.-> n5
n3 --> n4
n5 --> n6
n7 --> n8
n11 --> n10
n1 -.-> n5
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 n3 trigger
class n1,n5 ai
class n2 aiModel
class n4 decision
class n9,n12 database
class n7,n8,n11 api
class n6 code
classDef customIcon fill:none,stroke:none
class n6,n7,n8,n11 customIcon
The Challenge: Posting consistently without repeating yourself
Most LinkedIn “consistency” advice skips the messy part: you still have to come up with topics, write the post, publish it, then track what ran and where it went. When you’re busy, you post whatever is top-of-mind. That’s how duplicates happen. Even worse, groups add another layer because you’re re-copying the same post into multiple places, and one missed paste can turn into a half-finished distribution run that you don’t notice until later.
It adds up fast. Here’s where it breaks down in real life.
- You lose about 30 minutes per post just switching tabs, copying text, and double-checking what you posted last.
- Group posting becomes a mini-project because each group needs a manual post, and mistakes don’t show up until someone replies.
- Your idea list turns into a graveyard since there’s no clean “Pending vs Posted” workflow you trust.
- When you hand posting to someone else, the handoff is brittle because your only “system” is a spreadsheet and good intentions.
The Fix: Google Sheets becomes your LinkedIn publishing queue
This workflow treats your Google Sheet like a lightweight content calendar that actually executes. A schedule trigger checks your “Linkedin Post” sheet for rows marked Pending, then grabs one topic title to work on. GPT-4o turns that title into a polished LinkedIn post in your chosen style, and the workflow formats it into the exact payload LinkedIn expects. Next, it fetches your LinkedIn profile details (so the post goes out under the right identity), publishes the post to your profile, then pulls your group IDs from a second “Groups” sheet and loops through them to publish the same post into each group feed. Finally, it writes back to the original sheet and flips the Status to Posted, which prevents repeats the next time the schedule runs.
The workflow starts on a timed schedule and only proceeds if the status check sees Pending content. From there, Google Sheets supplies the topic, GPT-4o drafts the copy, LinkedIn publishing happens via HTTP requests, then the sheet gets updated as the source of truth.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you publish 3 times a week and share each post to 5 groups. Manually, that’s roughly 20 minutes to write and format, plus maybe 5 minutes per group to post and sanity-check, so you’re near 45 minutes per publish (about 2+ hours a week). With this workflow, you spend about 10 minutes loading topics into Google Sheets, then the schedule run drafts and posts automatically while you do other work. The repeat-prevention piece is the quiet win: no more “didn’t we already say this?” moments.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets to store topics, statuses, and group IDs.
- LinkedIn to publish on your profile and in groups.
- OpenAI API key (get it from your OpenAI dashboard).
Skill level: Intermediate. You’ll connect accounts, paste an API key, and edit a prompt, but you won’t be writing an app.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A scheduled check scans your sheet. The workflow runs on a schedule trigger and looks at “Sheet1” for a row where Status is Pending. It also limits how many items it processes so you don’t accidentally blast out ten posts at once.
A quick gate prevents bad runs. An “If” check acts like a bouncer: if there’s nothing pending, nothing else happens. Simple, but it saves you from weird edge cases.
GPT-4o writes the post from the title. The LinkedIn Post Composer takes your “Linkedin Post Title” and generates a full post, then a formatting step turns it into the correct structure for LinkedIn’s publishing endpoint.
Publishing happens to your profile, then groups. The workflow fetches your LinkedIn profile details, publishes the post to your profile, retrieves all GroupIds from the “Groups” sheet, then loops through those groups and posts to each feed.
Status is written back to Sheets. Once posting is done, it updates the original row to Posted, which means the topic won’t be selected again.
You can easily modify the posting cadence to match your content calendar based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Google Sheets Trigger
This workflow starts when a new or updated row appears in your Google Sheet.
- Add and configure Sheet Topic Trigger.
- Set Document to
[YOUR_ID](Linkedin Post spreadsheet). - Set Sheet Name to
gid=[YOUR_ID](Sheet1). - Set the polling schedule to Every Minute under Poll Times.
- Credential Required: Connect your googleSheetsTriggerOAuth2Api credentials.
Pending for rows to pass Status Gate Check.Step 2: Connect Google Sheets
The workflow reads group IDs and updates posting status back to the spreadsheet.
- Configure Retrieve Group IDs with Document set to
[YOUR_ID]and Sheet Name set to[YOUR_ID](Groups). - Credential Required: Connect your googleSheetsOAuth2Api credentials for Retrieve Group IDs.
- Configure Update Posting Status with Document set to
[YOUR_ID]and Sheet Name set togid=[YOUR_ID](Sheet1). - In Update Posting Status, set Operation to
updateand map ID to{{ $('Cap Items').item.json.ID }}and Status toPosted. - Credential Required: Connect your googleSheetsOAuth2Api credentials for Update Posting Status.
Step 3: Set Up the AI Post Composer
This stage limits incoming items, generates a post, and formats it for the LinkedIn API.
- In Status Gate Check, configure the condition to check leftValue
{{ $json.Status }}equalsPending. - Use Cap Items to limit items (default configuration is acceptable for a single-row test).
- Configure LinkedIn Post Composer with the provided prompt and ensure the title reference remains
{{ $('Sheet Topic Trigger').item.json['Linkedin Post Title'] }}. - Ensure Structured Parse Engine is attached to LinkedIn Post Composer as the output parser with the JSON schema shown in the node settings.
- Open OpenAI Conversation Model and select the model
gpt-4o. - Credential Required: Connect your openAiApi credentials in OpenAI Conversation Model. Structured Parse Engine uses the parent node’s credentials.
- In Format Post Payload, keep the JavaScript that stringifies the post:
item.json.output.post = JSON.stringify(item.json.output.post);.
Step 4: Configure Output Actions (LinkedIn API)
These nodes fetch your LinkedIn profile and publish the post to your feed.
- Configure Fetch LinkedIn Profile with URL set to
https://api.linkedin.com/v2/userinfoand Authentication set tohttpHeaderAuth. - Credential Required: Connect your httpHeaderAuth credentials in Fetch LinkedIn Profile.
- Configure Publish LinkedIn Post with URL
https://api.linkedin.com/v2/ugcPosts, MethodPOST, and JSON Body set to the expression: { "author": "urn:li:person:{{ $('Fetch LinkedIn Profile').item.json.sub }}", "lifecycleState": "PUBLISHED", "specificContent": { "com.linkedin.ugc.ShareContent": { "shareCommentary": { "text": {{ $('Format Post Payload').item.json.output.post }} }, "shareMediaCategory": "NONE" } }, "visibility": { "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC" } }- Credential Required: Connect your httpHeaderAuth credentials in Publish LinkedIn Post.
Step 5: Configure Group Posting and Status Updates
After the main post publishes, the workflow posts to each group ID and updates the original row.
- Ensure Retrieve Group IDs feeds into Iterate Groups to batch group IDs.
- Configure Post to Group Feed with URL
https://api.linkedin.com/v2/ugcPosts, MethodPOST, and the JSON body expression: { "author": "urn:li:person:{{ $('Fetch LinkedIn Profile').item.json.sub }}", "containerEntity": "urn:li:group:{{ $json.GroupIds }}", "lifecycleState": "PUBLISHED", "specificContent": { "com.linkedin.ugc.ShareContent": { "shareCommentary": { "text": {{ $('Format Post Payload').item.json.output.post }} }, "shareMediaCategory": "NONE" } }, "visibility": { "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC" } }- Credential Required: Connect your httpHeaderAuth credentials in Post to Group Feed.
- Verify Iterate Groups connects to Update Posting Status after the loop completes.
Step 6: Test and Activate Your Workflow
Run a manual test to ensure each LinkedIn API call and sheet update completes successfully.
- In your sheet, add a new row with Status set to
Pendingand a valid Linkedin Post Title. - Click Execute Workflow to run from Sheet Topic Trigger.
- Confirm Publish LinkedIn Post returns a successful response and that groups are posted via Post to Group Feed.
- Verify Update Posting Status changes the row’s Status to
Posted. - When everything looks correct, toggle the workflow to Active for production use.
Watch Out For
- Google Sheets credentials can expire or need specific permissions. If things break, check the n8n credential connection test and the Google account’s access to the target spreadsheet 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.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Common Questions
About 30 minutes if your accounts are ready.
Yes, but you will need someone comfortable connecting accounts and copying API keys. The actual setup is mostly filling in credentials, checking the sheet columns, and adjusting the GPT-4o prompt.
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 costs (often just a few cents per post, depending on length).
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.
You can adjust the “LinkedIn Post Composer” prompt to match your voice, your offer, and your formatting rules (hooks, line breaks, CTA style). If you want approvals, add a manual checkpoint before “Publish LinkedIn Post” (many teams route the draft to email or chat, then only continue when approved). You can also swap the schedule cadence so it runs daily, weekdays only, or at specific times. And if you only want to post to your profile, disable the group loop that reads GroupIds and posts to group feeds.
Usually it’s an expired Google authorization or the wrong Google account connected to the node. Reconnect the Google Sheets credential in n8n, then confirm the spreadsheet name and sheet tabs (“Sheet1” and “Groups”) match what the nodes reference. If it still fails, check that the account has edit access, because the workflow needs to write “Posted” back into the Status column.
It scales to dozens of posts per week easily, and the main limiter is how many group posts you try to publish in a single run.
Often, yes, because this workflow leans on conditional logic (the status gate), looping through group IDs, and a more custom HTTP publishing flow. In Zapier or Make, that usually means extra paid steps and more fragile “glue” between modules. n8n also gives you a self-host option, which matters when you’re running frequent schedules or higher volume. The tradeoff is that you may spend a bit more time on first setup, especially around LinkedIn permissions and payload formatting. Talk to an automation expert if you want a quick recommendation for your exact setup.
Once this is live, your spreadsheet stops being a to-do list and starts acting like a publishing system. The workflow handles the repetitive parts, and you get your time (and consistency) back.
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.