Google Sheets + Gmail: approved LinkedIn posts
LinkedIn content “systems” usually break in the same place. Drafts get scattered, approvals happen in DMs, and by the time someone replies, the post feels stale or you’ve lost the latest edit.
This hits marketers first, but agency owners and solo operators feel it too. With Sheets Gmail approvals, you can turn a simple spreadsheet row into a LinkedIn-ready draft, get a clean approval request in email, and ship posts without the back-and-forth chaos.
Below, you’ll see how the automation works, what you’ll need, and what kind of time you get back when approvals and publishing stop being manual chores.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Google Sheets + Gmail: approved LinkedIn posts
flowchart LR
subgraph sg0["Google Sheets Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "Google Sheets Trigger", pos: "b", h: 48 }
n1@{ icon: "mdi:cog", form: "rounded", label: "Search", pos: "b", h: 48 }
n2["<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/>chat input"]
n3["<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/>Code in JavaScript"]
n4@{ icon: "mdi:database", form: "rounded", label: "Add the post to the sheet", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Filter", pos: "b", h: 48 }
n6@{ icon: "mdi:robot", form: "rounded", label: "Content Generator", pos: "b", h: 48 }
n7@{ icon: "mdi:wrench", form: "rounded", label: "Message a model in Ollama", pos: "b", h: 48 }
n8@{ icon: "mdi:brain", form: "rounded", label: "Ollama Chat Model", pos: "b", h: 48 }
n9@{ icon: "mdi:message-outline", form: "rounded", label: "Approval Email", pos: "b", h: 48 }
n10@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Approved?", pos: "b", h: 48 }
n11@{ icon: "mdi:robot", form: "rounded", label: "Image Prompt", pos: "b", h: 48 }
n12@{ icon: "mdi:robot", form: "rounded", label: "Generate image", pos: "b", h: 48 }
n13["<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/linkedin.svg' width='40' height='40' /></div><br/>Create a post"]
n5 --> n3
n1 --> n2
n10 --> n11
n10 --> n6
n2 --> n6
n11 --> n12
n9 --> n10
n12 --> n13
n6 --> n4
n8 -.-> n6
n3 --> n1
n0 --> n5
n4 --> n9
n7 -.-> n11
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 trigger
class n6,n11,n12 ai
class n8 aiModel
class n7 ai
class n5,n10 decision
class n4 database
class n2,n3 code
classDef customIcon fill:none,stroke:none
class n2,n3,n13 customIcon
The Problem: LinkedIn posts get stuck in approval limbo
You start with good intentions: a content calendar in Google Sheets, a few campaign notes, and a plan to post consistently. Then reality shows up. Someone wants “a quick tweak,” feedback comes in late, and the draft lives in three places at once. Meanwhile, you’re still hunting for a visual, rewriting hooks, and checking trends manually. The worst part is the mental load. You spend more energy managing the process than writing the actual post.
None of these alone is the problem. Together, they are.
- Copying campaign details from a sheet into prompts and drafts eats about 20 minutes per post.
- Approvals happen in scattered replies, which means edits get missed or overwritten.
- Trend research turns into a rabbit hole, and posting slips by a day (or a week).
- Visuals become a last-minute scramble, so posts go out text-only or not at all.
The Solution: Google Sheets to Gmail approval to published LinkedIn post
This workflow treats your Google Sheet like the source of truth. When you add a new row for a campaign entry, n8n picks it up, cleans the data, and maps the fields into a structured prompt. It then pulls fresh context by looking up LinkedIn trends via Tavily, so your draft isn’t written in a vacuum. Next, an AI agent generates a LinkedIn post draft and writes it back into the same sheet, so everyone reviews the same version. A Gmail approval request goes out automatically, and once the post is approved, the workflow creates an image prompt, generates a visual asset with OpenAI Images, and publishes the final post to LinkedIn.
The workflow starts with a new Google Sheets row. Then it enriches your campaign details with trend research and generates the draft. Finally, Gmail handles the approval step and LinkedIn receives the finished post with a visual attached.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you publish 5 LinkedIn posts a week. Manually, a typical cycle looks like 30 minutes to draft, about 20 minutes to research what’s trending, another 15 minutes to chase approval, and 15 minutes to find or make a visual, which is roughly 1.5 hours per post (so about 7 hours a week). With this workflow, you add one row in Sheets (2 minutes), review the AI draft in the sheet, and approve from Gmail. The automation handles trend lookup, drafting, image generation, and publishing, so your “hands-on” time often drops to about 10 minutes per post.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets for campaign rows and draft storage.
- Gmail to send and track approvals in email.
- Tavily API key (get it from your Tavily dashboard).
- LinkedIn OAuth app (create it in the LinkedIn developer portal).
- OpenAI API key (get it from your OpenAI API settings) for image generation, or keep text-only.
- Ollama (optional) to run a local model for drafting.
Skill level: Intermediate. You’ll connect a few accounts, paste API keys, and update IDs (like your LinkedIn person/account ID) inside the workflow.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A new row in Google Sheets kicks it off. When a campaign entry is added, the workflow monitors the sheet and filters out blank or incomplete records so you don’t generate garbage drafts.
Your campaign fields get cleaned and shaped. n8n maps the row into consistent fields (offer, audience, angle, CTA, etc.), so the AI prompt stays reliable even when different people fill in the sheet.
Trend context gets pulled in before drafting. Tavily searches for relevant LinkedIn trends, and the workflow merges that context into the prompt. Then the AI agent generates the post draft and writes it back into the sheet for review.
Approval happens via Gmail, then publishing follows. The workflow emails an approval request. If approved, it generates an image prompt, creates the visual asset with OpenAI Images, and publishes the update to LinkedIn.
You can easily modify the approval rule to auto-approve certain campaigns or route approvals to a different inbox based on client, product line, or budget. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Google Sheets Trigger
Set up the trigger so the workflow starts when a new row is added to your content planning sheet.
- Add the Sheet Row Monitor node and set Event to
rowAdded. - Set Poll Times to
everyMinuteto check for new rows frequently. - Select the Google Sheet using Document ID (URL mode) and choose the Sheet Name from the list.
- Credential Required: Connect your
googleSheetsTriggerOAuth2Apicredentials in Sheet Row Monitor.
Step 2: Connect Google Sheets
Filter new rows, map the fields needed for content generation, and prepare the update back into the sheet.
- In Filter Empty Records, keep the condition that checks Left Value as
={{ $json.LinkedIn_Post }}with the empty operator so only rows without a draft are processed. - In Map Row Fields, keep the JS code that maps
Campaign,Subject,Audience, androwNumberfrom the trigger data. - Configure Update Sheet Post with Operation set to
updateand Matching Columns set toID. - In Update Sheet Post mapping, set ID to
={{ $('Sheet Row Monitor').item.json.ID }}and LinkedIn_Post to={{ $json.output }}. - Credential Required: Update Sheet Post needs Google Sheets credentials, but none are configured—add your Google Sheets OAuth2 credentials before running.
⚠️ Common Pitfall: The column name is LinkedIn_Post (with a trailing space). Keep the exact name in both the sheet and node mapping to avoid failed updates.
Step 3: Set Up Trend Enrichment and Prompt Preparation
Enrich the post topic with trending LinkedIn results and format the AI prompt input.
- In Trend Lookup, set Query to
={{$json["Campaign"] + " " + $json["Subject"] + " for " + $json["Audience"] + " site:linkedin.com"}}. - Credential Required: Connect your
tavilyApicredentials in Trend Lookup. - In Compose Prompt Input, keep the JS code that creates
chatInputusing the Sheet fields and Tavily results. - Verify the execution flow: Map Row Fields → Trend Lookup → Compose Prompt Input.
Step 4: Set Up AI Drafting and Approval Logic
Generate the LinkedIn draft using the agent, route for approval, and handle revisions.
- In Generate LinkedIn Draft, keep the Text prompt as defined, including the expressions like
{{ $('Sheet Row Monitor').item.json.Campaign }}and{{ $json.chatInput }}. - Ensure Ollama Chat Engine is connected as the language model for Generate LinkedIn Draft. Add credentials to Ollama Chat Engine if your Ollama setup requires them.
- In Send Approval Request, keep Operation as
sendAndWait, Subject asApproval for LinkedIn Post Content, and the message body containing{{ $json['LinkedIn_Post '] }}. - Credential Required: Connect your
gmailOAuth2credentials in Send Approval Request. - In Approval Decision, keep the condition Left Value as
={{ $json.data['Do you approve this text?'][0] }}and Right Value as={{"Yes"}}. - Confirm the branching behavior: Send Approval Request → Approval Decision, and if “Yes” it goes to Draft Image Prompt; if “No” it loops back to Generate LinkedIn Draft for revisions.
Step 5: Configure Publishing Outputs
Create the image prompt, generate the visual asset, and publish the LinkedIn update.
- In Draft Image Prompt, set Model to
llama3.2:latestand keep the message content={{ $('Update Sheet Post').item.json['LinkedIn_Post '] }}. - Note that Ollama Tool Message is an AI tool sub-node connected to Draft Image Prompt; if tool credentials are needed, add them to Draft Image Prompt, not the sub-node.
- In Create Visual Asset, set Resource to
imageand Prompt to=Generate an image for a linkedin post this is the description:{{ $json.content }} .The images should be realistic for linkedin.. - Credential Required: Connect your
openAiApicredentials in Create Visual Asset. - In Publish LinkedIn Update, set Authentication to
communityManagementand Share Media Category toIMAGE. - Credential Required: Connect your
linkedInCommunityManagementOAuth2Apicredentials in Publish LinkedIn Update.
Step 6: Test and Activate Your Workflow
Run a full test to validate the data flow from the sheet to LinkedIn publishing, then activate for production.
- Manually add a new row in the target Google Sheet with Campaign, Subject, and Audience populated, leaving LinkedIn_Post empty.
- Use Execute Workflow in n8n to test the run and confirm Generate LinkedIn Draft creates a post and Update Sheet Post writes it back to the sheet.
- Approve the draft via the email from Send Approval Request and verify Draft Image Prompt → Create Visual Asset → Publish LinkedIn Update completes successfully.
- When the test is successful, switch the workflow to Active to run continuously.
Common Gotchas
- Google Sheets credentials can expire or lack access to the right spreadsheet. If things break, check the n8n credential connection and the sheet sharing settings 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.
Frequently Asked Questions
About an hour if your accounts and API keys are ready.
No. You’ll mostly connect accounts and paste a few keys and IDs. The only “technical” part is matching your Google Sheet columns to the workflow fields.
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 image generation costs (often just a few cents per image) and any Tavily usage.
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 it’s one of the best reasons to use n8n. You can keep the Google Sheets “single source of truth,” then swap the Gmail approval step for Slack approvals, a webhook from your internal tool, or even a simple “Approved” checkbox column in Sheets. Most customizations happen around the Approval Decision logic and the message-sending node. You can also change the AI model (Ollama vs. another LLM), adjust the trend search query, and lock in a stronger brand voice in the prompt so the drafts need fewer edits.
Usually it’s permission-related: the Google account used in n8n can’t see the sheet, or the spreadsheet was moved. Reconnect your Google Sheets credentials in n8n, confirm the sheet is shared with that account, then verify the Sheet URL or ID in the trigger and update nodes.
Plenty for a small team. On n8n Cloud, your limit is based on monthly executions, and each post usually counts as one execution. If you self-host, there’s no platform execution cap; your server and API rate limits become the bottleneck.
Often, yes. This workflow has branching logic (approval or not), data shaping, and multiple AI steps, which can get expensive or awkward in Zapier/Make once you add paths and retries. n8n also gives you a self-host option, which is handy when you want more volume without surprise bills. Zapier or Make can still win if you only need a very simple “row added → send email” flow. Talk to an automation expert if you want a quick recommendation based on your posting volume.
Once this is running, your spreadsheet stops being a graveyard of half-finished ideas. It becomes a simple pipeline that reliably turns rows into approved, published LinkedIn posts.
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.