This workflow corresponds to n8n.io template #16979 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Schedule social media posts from a Google Sheets content calendar via PostFast",
"nodes": [
{
"id": "t3-sticky-main",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
16,
16
],
"parameters": {
"width": 544,
"height": 960,
"content": "## Schedule social media posts from a Google Sheets content calendar via PostFast\n\n### How it works\n\nThis workflow runs every morning, reads your Google Sheets content calendar, picks the rows marked ready whose publish time is still in the future, schedules each one through PostFast, and writes scheduled back to the row so nothing is ever sent twice. PostFast publishes each post automatically at the row's date and time.\n\n### Your sheet needs 4 columns\n\n- content: the full post text\n- scheduledAt: ISO date-time, e.g. 2026-07-15T17:00:00Z\n- accountId: the PostFast social account ID to post to\n- status: ready for rows to schedule (the workflow sets scheduled after)\n\n### Setup steps\n\n- Install the verified PostFast community node (n8n Cloud: enable Verified Community Nodes in the Admin Panel; self-hosted: install n8n-nodes-postfast).\n- Connect your PostFast credentials (API key from Settings > API) on the PostFast Scheduler node.\n- Connect your Google Sheets credentials and select your spreadsheet and sheet in both Sheets nodes.\n- Find your account IDs with the PostFast node's Get All Social Accounts operation, or in your PostFast dashboard.\n- Add one test row with status ready, run manually, and check the post in your PostFast dashboard before activating.\n\n### Customization\n\nAdd columns for platform-specific captions, change the run time, or extend rows with media keys for image posts."
},
"typeVersion": 1
},
{
"id": "t3-sticky-1",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
592,
32
],
"parameters": {
"color": 7,
"width": 464,
"height": 400,
"content": "## Read the calendar\n\nRuns every morning and loads all rows from your content calendar sheet."
},
"typeVersion": 1
},
{
"id": "t3-sticky-2",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1136,
32
],
"parameters": {
"color": 7,
"width": 336,
"height": 400,
"content": "## Keep ready future rows\n\nOnly rows with status ready and a publish time at least 10 minutes in the future move on. Everything else is skipped."
},
"typeVersion": 1
},
{
"id": "t3-sticky-3",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1504,
32
],
"parameters": {
"color": 7,
"width": 480,
"height": 400,
"content": "## Schedule and mark done\n\nEach row becomes a scheduled PostFast post, then the row's status is set to scheduled so it is never sent twice."
},
"typeVersion": 1
},
{
"id": "t3-trigger",
"name": "Every Morning at 7am",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
656,
240
],
"parameters": {
"rule": {
"interval": [
{
"field": "days",
"triggerAtHour": 7
}
]
}
},
"typeVersion": 1.2
},
{
"id": "t3-read",
"name": "Read Content Calendar",
"type": "n8n-nodes-base.googleSheets",
"position": [
880,
240
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"typeVersion": 4.5
},
{
"id": "t3-filter",
"name": "Keep Ready Future Rows",
"type": "n8n-nodes-base.filter",
"position": [
1200,
240
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "c1",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "ready"
},
{
"id": "c2",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ new Date($json.scheduledAt).getTime() }}",
"rightValue": "={{ Date.now() + 10 * 60 * 1000 }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "t3-create",
"name": "PostFast Scheduler",
"type": "n8n-nodes-postfast.postFast",
"position": [
1568,
240
],
"parameters": {
"posts": {
"post": [
{
"content": "={{ $json.content }}",
"scheduledAt": "={{ new Date($json.scheduledAt).toISOString() }}",
"socialMediaId": "={{ String($json.accountId).trim() }}"
}
]
},
"controls": {}
},
"typeVersion": 1
},
{
"id": "t3-update",
"name": "Mark Row as Scheduled",
"type": "n8n-nodes-base.googleSheets",
"position": [
1792,
240
],
"parameters": {
"columns": {
"value": {
"status": "scheduled"
},
"mappingMode": "defineBelow",
"matchingColumns": [
"content"
]
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": ""
},
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"typeVersion": 4.5
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"connections": {
"PostFast Scheduler": {
"main": [
[
{
"node": "Mark Row as Scheduled",
"type": "main",
"index": 0
}
]
]
},
"Every Morning at 7am": {
"main": [
[
{
"node": "Read Content Calendar",
"type": "main",
"index": 0
}
]
]
},
"Read Content Calendar": {
"main": [
[
{
"node": "Keep Ready Future Rows",
"type": "main",
"index": 0
}
]
]
},
"Keep Ready Future Rows": {
"main": [
[
{
"node": "PostFast Scheduler",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow runs every morning to read a Google Sheets content calendar, filter for posts marked ready and scheduled in the future, schedule them in PostFast, and then update the sheet to mark each row as scheduled. Runs every day at 7:00 AM using a schedule trigger. Reads all…
Source: https://n8n.io/workflows/16979/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates video distribution to 9 social platforms simultaneously using Blotato's API. It includes both a scheduled publisher (checks Google Sheets for videos marked "Ready") and a subwo
YogiAI. Uses googleSheets, googleSheetsTool, httpRequest, stopAndError. Scheduled trigger; 61 nodes.
This workflow monitors Google Calendar for events indicating that a customer will visit the company today or the next day, retrieves the required details, and sends reminder notifications to the relev
Useful if a team is working within a single instance and you want to be notified of what workflows have changed since you last visited them. Another use-case might be monitoring your managed instances
ofn hook v0.24.0 beta. Uses start, httpRequest, functionItem, itemLists. Scheduled trigger; 42 nodes.