Google Sheets + Gmail: LinkedIn posts approved fast
Your LinkedIn “content calendar” looks organized… right up until feedback arrives in five places, the post gets rewritten twice, and nobody remembers which version is approved.
This is where Sheets Gmail approvals helps. A marketing manager chasing stakeholder sign-off feels it first. But a founder posting between calls, or an agency lead managing multiple client voices, runs into the same bottleneck.
This workflow turns one Google Sheets row into a clean LinkedIn draft, emails it for approval in Gmail, and then publishes (with or without an image) while updating the sheet so your calendar stays truthful.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Google Sheets + Gmail: LinkedIn posts approved fast
flowchart LR
subgraph sg0["Schedule Flow"]
direction LR
n0["<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/>Get Image"]
n1@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger", pos: "b", h: 48 }
n2@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Chat Model", pos: "b", h: 48 }
n3@{ icon: "mdi:database", form: "rounded", label: "Get Data from Sheets", pos: "b", h: 48 }
n4@{ icon: "mdi:robot", form: "rounded", label: "Generate Post Content", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-vertical", form: "rounded", label: "Data Formatting 1", pos: "b", h: 48 }
n6@{ icon: "mdi:message-outline", form: "rounded", label: "Send Content Confirmation", pos: "b", h: 48 }
n7@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Content Confirmation Logic", pos: "b", h: 48 }
n8@{ icon: "mdi:robot", form: "rounded", label: "Regenerate Post Content", pos: "b", h: 48 }
n9@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If Image Provided", 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/linkedin.svg' width='40' height='40' /></div><br/>Post With Image"]
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/linkedin.svg' width='40' height='40' /></div><br/>Post Without Image"]
n12@{ icon: "mdi:database", form: "rounded", label: "Update Google Sheet", pos: "b", h: 48 }
n0 --> n10
n10 --> n12
n1 --> n3
n5 --> n6
n9 --> n0
n9 --> n11
n2 -.-> n4
n2 -.-> n8
n11 --> n12
n3 --> n4
n4 --> n5
n8 --> n5
n6 --> n7
n7 --> n9
n7 --> n8
n7 --> n12
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 n1 trigger
class n4,n8 ai
class n2 aiModel
class n7,n9 decision
class n3,n12 database
class n0 api
classDef customIcon fill:none,stroke:none
class n0,n10,n11 customIcon
The Problem: LinkedIn Approvals Turn Into Content Chaos
Approving LinkedIn posts sounds simple until you do it at volume. One person writes a draft, someone else tweaks tone, another person asks for “one small change,” and suddenly you’re comparing versions across email threads, docs, and Slack screenshots. Meanwhile your Google Sheet still says “Pending,” so the calendar lies to your face. You lose time, but the bigger cost is confidence. When nobody trusts the status column, posting gets inconsistent and great ideas die in limbo.
It adds up fast. Here’s where it breaks down in real life.
- Approvals happen in scattered places, so the “final” draft keeps moving.
- Copy-pasting edits back into the sheet invites mistakes, especially when you’re rushing.
- People approve vaguely (“looks good”) but you still don’t know what to post.
- Images are the worst part, because you don’t find broken URLs until you’re ready to publish.
The Solution: Google Sheets to Draft, Gmail Approval, LinkedIn Publish
This workflow creates a single path from “idea” to “approved and posted,” using tools you already live in. On a schedule you choose, n8n checks your Google Sheet for the first row marked Pending. It uses OpenAI to draft a professional LinkedIn post from your “Post Description” and “Instructions,” then packages that draft into a clean approval email in Gmail. The approver can accept, reject, or request edits through the email form. If edits are requested, the workflow revises the draft, then routes it back through the same approval logic until it’s approved. After that, it publishes to LinkedIn, optionally pulling in an image from a URL in the sheet, and finally updates the row status (so your calendar reflects reality).
The workflow starts with a scheduled run and a Google Sheets lookup. OpenAI generates (and, if needed, revises) the copy based on your instructions. Gmail collects approval, then the workflow publishes to LinkedIn and writes the outcome back to the sheet so you can see what happened without guesswork.
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 and each one needs one approval. Manually, you might spend 10 minutes drafting, 10 minutes emailing, and another 10 minutes chasing edits and updating the sheet, so roughly 30 minutes per post (about 2.5 hours weekly). With this workflow, you add the idea to Google Sheets once, then approvals happen by email and publishing is automatic. Your “time spent” becomes maybe 10 minutes per post for the initial input, plus waiting for approvals in the background.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets to store post ideas and statuses.
- Gmail to send and collect approval decisions.
- OpenAI API key (get it from the OpenAI dashboard).
Skill level: Intermediate. You’ll mostly connect accounts and map sheet fields, plus lightly adjust the AI prompt for your brand voice.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
Scheduled run checks for the next post. n8n starts on your chosen interval (every morning, every hour, weekly). It looks for the first Google Sheets row where Status is Pending.
Your draft is generated from the row. OpenAI creates a LinkedIn post using the Post Description and Instructions columns, so your guidance stays attached to the content that comes out.
Approval happens through Gmail. The workflow emails a structured approval request that routes the outcome. If the approver requests edits, the draft is revised and sent through the approval decision again.
Publishing and tracking are automatic. If an Image URL exists, n8n fetches it and publishes a LinkedIn post with media. If not, it publishes text-only, then updates Google Sheets so Status and any post link/output fields stay current.
You can easily modify the approval rules to require two reviewers, or change the schedule to run only on weekdays based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Schedule Trigger
Set the workflow to run on a schedule so it checks for new pending posts automatically.
- Add and open Scheduled Run Start.
- Set the schedule rule under Rule to your desired interval (the workflow currently uses the default schedule configuration).
- Connect Scheduled Run Start to Retrieve Sheet Entry.
Step 2: Connect Google Sheets
Retrieve the next pending LinkedIn post request from your spreadsheet and later update its status.
- Open Retrieve Sheet Entry and select the spreadsheet with Document set to
[YOUR_ID]and Sheet set togid=0. - In Retrieve Sheet Entry, confirm the filter where lookupColumn is
Statusand lookupValue isPending, and enable Return First Match. - Credential Required: Connect your
googleSheetsOAuth2Apicredentials in Retrieve Sheet Entry. - Open Update Sheet Status, set Operation to
update, and keep Document as[YOUR_ID]with Sheetgid=0. - In Update Sheet Status field mappings, set Status to
Completed, Output to{{ $json.urn }}, Post Link to{{ $json.urn }}, and row_number to{{ $('Retrieve Sheet Entry').item.json.row_number }}. - Credential Required: Connect your
googleSheetsOAuth2Apicredentials in Update Sheet Status.
Step 3: Set Up the AI Drafting and Field Formatting
Generate the initial LinkedIn post with AI, then normalize fields for approval and publishing.
- Open OpenAI Chat Engine and choose model
gpt-4o-mini. - Credential Required: Connect your
openAiApicredentials in OpenAI Chat Engine. - Open Compose Post Draft and ensure Text contains the full prompt with expressions like
{{ $json["Post Description"] }}and{{ $json["Instructions"] }}. - Note that OpenAI Chat Engine is connected as the language model for Compose Post Draft and Revise Post Draft — add credentials to OpenAI Chat Engine (not the chain nodes).
- In Format Post Fields, set Post Content to
{{ $json.text }}, Post Description to{{ $('Retrieve Sheet Entry').item.json['Post Description'] }}, and Instructions to{{ $('Retrieve Sheet Entry').item.json.Instructions }}.
Step 4: Configure Email Approval and Decision Routing
Send the AI-generated draft for approval and route the workflow based on the response.
- Open Email Approval Request and set Send To to
[YOUR_EMAIL]. - Set Subject to
Approval for LinkedIn Postand Message toGenerated Post: {{ $json['Post Content'] }} ---------- Post Description: {{ $json['Post Description'] }} ---------- Instructions: {{ $json.Instructions }}. - Keep Operation as
sendAndWaitand Response Type ascustomFormwith fieldsConfirm Content?andAny Changes?. - Credential Required: Connect your
gmailOAuth2credentials in Email Approval Request. - Open Approval Decision Router and confirm it routes based on
{{ $json.data['Confirm Content?'] }}toYes,No, andCancel. - Connect Approval Decision Router to Image Availability Check (Yes path), Revise Post Draft (No path), and Update Sheet Status (Cancel path).
Confirm Content?. Keep the label exactly as shown or the switch conditions won’t match.Step 5: Handle Revisions and Image-Based Publishing
Apply requested edits, check for an image URL, and publish to LinkedIn with or without media.
- In Revise Post Draft, keep the prompt referencing
{{ $('Format Post Fields').item.json['Post Content'] }}and{{ $('Email Approval Request').item.json.data['Any Changes?'] }}so updates reflect feedback. - In Image Availability Check, ensure the condition uses
{{ $('Retrieve Sheet Entry').item.json.Image }}with Operation set tonotEmpty. - Image Availability Check outputs to both Fetch Post Image and Publish Without Image in parallel, depending on whether the image URL exists.
- In Fetch Post Image, set URL to
{{ $('Retrieve Sheet Entry').item.json.Image }}. - In Publish With Image, set Text to
{{ $('Format Post Fields').item.json['Post Content'] }}, Person to[YOUR_ID], and Share Media Category toIMAGE. - In Publish Without Image, set Text to
{{ $('Format Post Fields').item.json['Post Content'] }}and Person to[YOUR_ID]. - Credential Required: Connect your
linkedInOAuth2Apicredentials in both Publish With Image and Publish Without Image. - Confirm both LinkedIn nodes connect to Update Sheet Status to log completion and the post URN.
Step 6: Test & Activate Your Workflow
Validate the full approval and publishing cycle before enabling the schedule.
- Click Execute Workflow and verify Retrieve Sheet Entry pulls a row with
Status=Pending. - Confirm Compose Post Draft creates
Post Contentand that Email Approval Request sends a form email with the generated content. - Submit the approval form with
Yes,No, orCanceland confirm Approval Decision Router routes to the expected path. - On approval, confirm either Publish With Image or Publish Without Image runs and Update Sheet Status writes
Completedand the URN fields. - Enable the workflow by switching Active to on for production use.
Common Gotchas
- Google Sheets credentials can expire or need specific permissions. If things break, check your Google OAuth connection inside n8n Credentials 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 30 minutes if your Google and OpenAI accounts are ready.
No. You connect accounts and map your Google Sheets columns to the email and AI 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 usage, which is usually only a few cents per batch of posts unless you generate a lot of revisions.
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, but you’ll want to adjust the Approval Decision Router logic so “Approved” from reviewer one triggers a second Gmail approval email instead of publishing. Many teams also customize the Compose Post Draft and Revise Post Draft prompts to enforce a house style, then write “Needs changes” notes back into Google Sheets for visibility. If you publish on a strict cadence, you can also change the Scheduled Run Start to only pick rows with a specific date, not just Status.
Usually it’s an expired Google OAuth token or the wrong Gmail permissions were granted. Reconnect the Gmail credential in n8n and make sure the account you authorized matches the sender you configured. If it still fails, check Google’s security alerts for blocked sign-ins and confirm the workflow is using the correct credential in the Email Approval Request node.
A lot. For most small teams, dozens of posts a week is fine, and if you self-host n8n you’re mainly limited by your server and the rate limits of Google and LinkedIn.
Often, yes, if your approvals include branching decisions and revisions. n8n handles multi-path logic cleanly, and self-hosting means you’re not paying per tiny step when the workflow loops through “revise, resend, approve.” Zapier or Make can still be fine for a simple “draft then email” flow, but they get awkward once you add conditional publishing (with or without image) and status updates back to Google Sheets. One more thing: n8n makes it easier to keep the full context (instructions, draft, edits) together as it moves through the flow. Talk to an automation expert if you want help picking the right platform.
Once this is running, your sheet becomes the source of truth again, and approvals stop derailing the week. The workflow handles the repetitive stuff. You handle the ideas.
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.