Google Sheets + Slack: approved LinkedIn posts
Your LinkedIn content process usually breaks in the boring places. Drafts live in a doc, images sit in a folder, approvals happen in DMs, and “final” somehow means “we’ll fix it right before posting.” Then someone posts the wrong version.
This Sheets Slack approval automation hits social media managers first, but founders and agency teams feel it too. You get a clean approval loop, fewer last‑minute edits, and a repeatable way to publish without hovering over LinkedIn all day.
Below you’ll see exactly how the workflow turns a Google Sheets row into an AI-written draft, routes it to Slack for human review, then publishes to your profile (and optionally to groups) while updating status back in the sheet.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Google Sheets + Slack: approved LinkedIn posts
flowchart LR
subgraph sg0["Flow 1"]
direction LR
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/webhook.dark.svg' width='40' height='40' /></div><br/>Inbound Webhook Receiver"]
n9["<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/>Parse Slack Response"]
n10@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Response Validation", pos: "b", h: 48 }
n11@{ icon: "mdi:swap-vertical", form: "rounded", label: "Assemble Final Message", pos: "b", h: 48 }
n12["<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 LinkedIn Profile"]
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/httprequest.dark.svg' width='40' height='40' /></div><br/>Publish LinkedIn Update"]
n14@{ icon: "mdi:database", form: "rounded", label: "Retrieve Group Identifiers", pos: "b", h: 48 }
n15@{ icon: "mdi:swap-vertical", form: "rounded", label: "Iterate Groups", pos: "b", h: 48 }
n16["<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 to LinkedIn Groups"]
n17@{ icon: "mdi:database", form: "rounded", label: "Mark Posting Status", pos: "b", h: 48 }
n18["<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/>Initialize Media Upload"]
n19@{ icon: "mdi:swap-vertical", form: "rounded", label: "Prepare Upload Details", pos: "b", h: 48 }
n20["<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/>Download Image Binary"]
n21["<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/>Send Image Payload"]
n23["<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/>Extract Topics and Media"]
n3 --> n23
n15 --> n17
n15 --> n16
n14 --> n15
n21 --> n13
n13 --> n14
n18 --> n19
n9 --> n10
n20 --> n21
n11 --> n12
n19 --> n20
n10 --> n11
n12 --> n18
n16 --> n15
n23 --> n9
end
subgraph sg1["Retrieve Post Topics Flow"]
direction LR
n0@{ icon: "mdi:cog", form: "rounded", label: "Throttle Items", pos: "b", h: 48 }
n1@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Decoder", pos: "b", h: 48 }
n2@{ icon: "mdi:brain", form: "rounded", label: "OpenAI Dialog Model", pos: "b", h: 48 }
n4@{ icon: "mdi:play-circle", form: "rounded", label: "Retrieve Post Topics", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Status Check Gate", pos: "b", h: 48 }
n6@{ icon: "mdi:robot", form: "rounded", label: "LinkedIn Post Generator", pos: "b", h: 48 }
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/code.svg' width='40' height='40' /></div><br/>Content Formatter"]
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/slack.svg' width='40' height='40' /></div><br/>Slack Review Request"]
n22@{ icon: "mdi:swap-vertical", form: "rounded", label: "Map Post Fields", pos: "b", h: 48 }
n0 --> n22
n22 --> n6
n7 --> n8
n5 --> n0
n2 -.-> n6
n4 --> n5
n6 --> n7
n1 -.-> n6
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 n4 trigger
class n1,n6 ai
class n2 aiModel
class n10,n5 decision
class n14,n17 database
class n3,n12,n13,n16,n18,n20,n21 api
class n9,n23,n7 code
classDef customIcon fill:none,stroke:none
class n3,n9,n12,n13,n16,n18,n20,n21,n23,n7,n8 customIcon
The Problem: LinkedIn posts get stuck in approval limbo
Most teams don’t struggle with “writing a post.” They struggle with everything around it. Someone collects topics in a spreadsheet, another person drafts in a doc, approvals happen in Slack with screenshots, and the image link is buried in a thread from three days ago. By the time you’re ready to publish, you’re hunting for the latest version and hoping nobody edited the wrong copy. That’s how good ideas die: in friction, waiting, and avoidable mistakes.
It adds up fast. And it’s rarely just one thing.
- Posts sit as “Pending” because nobody knows where to approve them.
- Copy-paste publishing invites tiny errors that look unprofessional on a public feed.
- Images get skipped because the upload step is annoying and easy to forget.
- Status tracking turns into a mess, so you can’t tell what’s drafted, approved, or already posted.
The Solution: Google Sheets → AI draft → Slack approval → LinkedIn posting
This workflow uses Google Sheets as your content “source of truth,” then handles the heavy lifting automatically. Every minute, it checks for new rows marked Pending. When it finds one, OpenAI (GPT‑4 class model) generates a full LinkedIn post based on your topic and any fields you’ve mapped (title, notes, and image URL). The draft is formatted for review, then sent to Slack with interactive buttons so a human can approve or edit. Once approved, the workflow uploads the image to LinkedIn, publishes the post to your profile, optionally distributes it to selected LinkedIn groups, and finally updates the original Google Sheets row to Posted so it won’t run twice.
The workflow starts in Google Sheets with a simple status change. Slack acts as the “gate” where you keep brand control. LinkedIn only sees the final, approved content, and your spreadsheet stays current automatically.
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 three manual steps: draft, send for approval, then upload text and an image. Even if each step is “only” about 10 minutes, that’s roughly 30 minutes per post, or about 2.5 hours a week. With this workflow, you drop a topic into Google Sheets (maybe 2 minutes), approve or tweak it in Slack (another 2–5 minutes), then the posting happens automatically while you move on. Honestly, the biggest win is that nothing gets lost between tools.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets to store topics, image URLs, and statuses
- Slack to review, approve, and edit drafts
- OpenAI API Key (get it from your OpenAI dashboard)
Skill level: Intermediate. You’ll connect accounts, paste API keys, and confirm a Slack interactive webhook URL.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A “Pending” row triggers everything. The workflow checks your “Linkedin Post” spreadsheet on a schedule (every minute) and pulls in new topics that are marked Pending, which prevents accidental re-posting.
AI drafts the post and formats it for review. Using an OpenAI chat model plus a structured output parser, the workflow generates a LinkedIn-ready draft, then cleans it up so it displays nicely in Slack (spacing, sections, hashtags, the works).
Slack becomes the approval gate. A Slack message is sent with interactive controls. When someone approves or edits, a webhook receives that response, validates it, and assembles the final message text that will actually be published.
LinkedIn posting and status updates happen automatically. The workflow fetches your LinkedIn profile details, registers and uploads the image using HTTP requests, publishes to your profile, then loops through group IDs from a “Groups” sheet to post to selected groups. Finally, Google Sheets is updated to Posted.
You can easily modify the approver in Slack or the groups list in Sheets based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Webhook Trigger
This workflow starts from inbound requests and sheet updates, then filters items before generating content.
- Add and open Inbound Webhook Receiver, and copy the webhook URL generated for your environment (the workflow shows
webhookIdset toYOUR_WEBHOOK_IDas a placeholder). - Configure Retrieve Post Topics to listen for new rows or updates that should trigger posting.
- Open Status Check Gate and set your approval logic so only eligible posts continue to Throttle Items.
- Keep Throttle Items connected to Map Post Fields to control the number of posts processed per run.
- Ensure Inbound Webhook Receiver connects to Extract Topics and Media for downstream parsing.
Step 2: Connect Google Sheets
Google Sheets provides topic input and group identifiers, and stores posting status.
- In Retrieve Group Identifiers, select the spreadsheet and sheet that contains LinkedIn group IDs.
- In Mark Posting Status, choose the spreadsheet and range to update after successful posting.
- Verify Retrieve Post Topics points to the sheet that holds topic/media rows.
- Confirm the flow from Retrieve Group Identifiers to Iterate Groups is intact.
Step 3: Set Up AI Content Generation
These nodes map fields, generate a LinkedIn post, and format the content for review.
- In Map Post Fields, map incoming topic and media fields to the structure expected by the generator.
- Open LinkedIn Post Generator and confirm it is connected to OpenAI Dialog Model as the language model.
- Ensure Structured Output Decoder is attached to LinkedIn Post Generator for structured outputs.
- Use Content Formatter to format the generated post before it is sent to review.
Step 4: Configure Review and Approval Logic
This section routes the formatted post to Slack for review and validates the response.
- Set up Slack Review Request to post the formatted content to your review channel (the workflow shows
YOUR_SLACK_WEBHOOK_IDas a placeholder). - Use Parse Slack Response to extract approval or rejection signals from the Slack reply.
- Configure Response Validation to route only approved content forward.
- In Assemble Final Message, build the final payload that will be posted to LinkedIn.
- Confirm the flow from Extract Topics and Media to Parse Slack Response remains connected.
Step 5: Configure LinkedIn Publishing and Group Distribution
These nodes retrieve the profile, upload media, publish updates, and distribute posts to groups.
- In Retrieve LinkedIn Profile, configure the LinkedIn API request to fetch the account profile used for posting.
- Ensure the media upload flow is connected: Initialize Media Upload → Prepare Upload Details → Download Image Binary → Send Image Payload → Publish LinkedIn Update.
- Confirm Publish LinkedIn Update passes to Retrieve Group Identifiers for group distribution.
- Iterate Groups outputs to both Mark Posting Status and Post to LinkedIn Groups in parallel for each group item.
- Leave Throttle Items in place to prevent API rate-limit issues during bursts.
Step 6: Test and Activate Your Workflow
Run a controlled test to confirm approvals, LinkedIn posting, and status updates work end-to-end.
- Click Execute Workflow and send a sample request to Inbound Webhook Receiver or add a new row to Retrieve Post Topics.
- Verify that LinkedIn Post Generator produces content and Slack Review Request posts it to your review channel.
- Approve the message in Slack and confirm Response Validation routes the item to Assemble Final Message.
- Check that Publish LinkedIn Update succeeds and that group distribution reaches Post to LinkedIn Groups and Mark Posting Status.
- Once successful, toggle the workflow to Active for production use.
Common Gotchas
- Slack interactive messages need the correct Request URL in your Slack app settings. If approvals aren’t coming back, check Interactive Components and your n8n webhook URL 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.
- LinkedIn tokens and permissions are picky, especially for group posting. If profile posting works but group posting fails, re-check the app scopes and confirm the group allows posts from your account.
Frequently Asked Questions
About 30–60 minutes if you already have your Slack and LinkedIn apps ready.
No. You’ll mostly connect accounts and paste credentials. The only “technical” part is confirming the Slack interactive webhook URL points to your n8n webhook.
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 (often just a few dollars a month for light posting).
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 plan it intentionally. You can route the Slack Review Request to a channel instead of a DM, then update the Inbound Webhook Receiver handling so it accepts approvals from a specific user list. Common customizations include adding a second approval step for compliance, changing the AI prompt to match brand voice, and restricting which LinkedIn groups can be posted to by filtering the GroupIds sheet.
Usually it’s an app configuration issue, not n8n. Confirm your Slack OAuth token is still valid, and double-check that Interactive Components are enabled with the correct request URL pointing to your n8n webhook. If the buttons show up but nothing happens after clicking, it’s almost always the webhook URL or missing Slack permissions.
Plenty for a typical small team: dozens per day is realistic if your LinkedIn limits and OpenAI usage stay reasonable, and n8n can queue items one at a time to keep things stable.
Often, yes, because this workflow isn’t just a 2-step “send message then post.” You’ve got branching logic (Pending checks, validation gates), interactive Slack responses coming back through a webhook, and multiple HTTP calls to LinkedIn for image registration and upload. n8n handles that kind of logic cleanly, and self-hosting can keep costs predictable if you run lots of approvals. Zapier or Make can still work if you keep it simple, but the moment you want edits, group posting, or more control, you’ll feel the limits. Talk to an automation expert if you want help choosing.
Once this is running, your spreadsheet becomes a calm, reliable pipeline instead of a graveyard of half-finished drafts. The workflow handles the repetitive parts so you can focus on what actually moves the needle.
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.