AutomationFlowsAI & RAG › Schedule Weekly Social Media Posts with Openai and Postfast

Schedule Weekly Social Media Posts with Openai and Postfast

ByPetar Georgiev @peturgeorgievv on n8n.io

This workflow runs every Monday to generate a week of social media posts with OpenAI, then schedules them at preselected high-reach time slots through PostFast for the social accounts you choose. Runs every Monday morning on a schedule trigger. Loads your brand name, voice,…

Cron / scheduled trigger★★★★☆ complexityAI-powered11 nodesN8N Nodes PostfastOpenAI
AI & RAG Trigger: Cron / scheduled Nodes: 11 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #16857 — 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 →

Download .json
{
  "name": "Generate a week of social media posts with OpenAI and schedule them via PostFast",
  "nodes": [
    {
      "id": "sticky-main",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        16
      ],
      "parameters": {
        "width": 544,
        "height": 816,
        "content": "## Generate a week of social media posts with OpenAI and schedule them at data-backed best times via PostFast\n\n### How it works\n\nRuns every Monday morning (or on demand), pulls your connected social accounts straight from PostFast so there are no IDs to copy, then OpenAI writes a week of posts in your brand voice. Each post is assigned a proven high-reach time slot based on PostFast's published analysis of 22,890 real Instagram posts and 13,758 TikTok posts (postfa.st/blog/best-time-to-post-on-instagram). Posts are scheduled through PostFast and publish automatically.\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 both PostFast nodes.\n- Connect your OpenAI credentials on the OpenAI node.\n- Update Configure brand and topics: brand name, voice, topics, posts per week and platform filter.\n- Run once manually, review the scheduled posts in your PostFast dashboard, then activate.\n\n### Customization\n\nChange the cadence, tone, post length or platform filter. The default filter targets text-friendly networks: Instagram, TikTok, Pinterest and YouTube require media, so pair them with an AI image workflow instead."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-step1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        592,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 400,
        "content": "## Start and configure\n\nTriggers every Monday morning and sets the brand, voice, topics, posts per week and platform filter for the run."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-step2",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 800,
        "height": 400,
        "content": "## Fetch accounts and write the week\n\nThe PostFast node lists your connected accounts, a filter keeps the platforms you chose, then OpenAI writes the whole week as strict JSON."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-step3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1968,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 400,
        "content": "## Best-time scheduling\n\nEach post gets next week's strongest slot from PostFast's study of 36,000+ real posts, then every selected account gets its own scheduled copy."
      },
      "typeVersion": 1
    },
    {
      "id": "trigger-monday",
      "name": "Every Monday morning",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        656,
        240
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "set-config",
      "name": "Configure brand and topics",
      "type": "n8n-nodes-base.set",
      "position": [
        864,
        240
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "brandName",
              "type": "string",
              "value": "YOUR BRAND NAME"
            },
            {
              "id": "a2",
              "name": "brandVoice",
              "type": "string",
              "value": "friendly, practical, no hype, first person"
            },
            {
              "id": "a3",
              "name": "topics",
              "type": "string",
              "value": "topic one, topic two, topic three"
            },
            {
              "id": "a4",
              "name": "postsPerWeek",
              "type": "number",
              "value": 5
            },
            {
              "id": "a5",
              "name": "platformFilter",
              "type": "string",
              "value": "X, LINKEDIN, FACEBOOK, THREADS, BLUESKY, TELEGRAM"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "pf-accounts",
      "name": "Get connected accounts (PostFast)",
      "type": "n8n-nodes-postfast.postFast",
      "position": [
        1168,
        240
      ],
      "parameters": {
        "resource": "socialAccount",
        "operation": "getAll"
      },
      "typeVersion": 1
    },
    {
      "id": "code-accounts",
      "name": "Select target accounts",
      "type": "n8n-nodes-base.code",
      "position": [
        1392,
        240
      ],
      "parameters": {
        "jsCode": "// Keep only connected accounts on the platforms chosen in the Configure node.\nconst cfg = $('Configure brand and topics').first().json;\nconst wanted = String(cfg.platformFilter || '').split(',').map(s => s.trim().toUpperCase()).filter(Boolean);\nconst accounts = $input.all().map(i => i.json);\n\nconst selected = accounts.filter(a => {\n  const status = String(a.connectionStatus || 'CONNECTED').toUpperCase();\n  const platform = String(a.platform || '').toUpperCase();\n  return status === 'CONNECTED' && (wanted.length === 0 || wanted.includes(platform));\n});\n\nif (selected.length === 0) {\n  throw new Error('No connected accounts matched the platform filter. Check the Configure node and your PostFast connections.');\n}\n\nreturn [{ json: {\n  accountIds: selected.map(a => a.id ?? a.socialMediaId),\n  accountList: selected.map(a => `${a.platform}: ${a.name ?? a.username ?? a.id}`).join(', ')\n} }];"
      },
      "typeVersion": 2
    },
    {
      "id": "openai-write",
      "name": "Write the week's posts",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1616,
        240
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are a social media copywriter for {{ $('Configure brand and topics').first().json.brandName }}. Voice: {{ $('Configure brand and topics').first().json.brandVoice }}.\n\nWrite {{ $('Configure brand and topics').first().json.postsPerWeek }} distinct social media posts about these topics: {{ $('Configure brand and topics').first().json.topics }}.\n\nRules: each post 60 to 180 words, hook in the first line, 2 to 4 relevant hashtags at the end, no emoji overload, each post must stand alone.\n\nReturn ONLY valid JSON in this exact shape: {\"posts\": [{\"text\": \"full post text with hashtags\"}]}"
            }
          ]
        },
        "jsonOutput": true
      },
      "typeVersion": 1.8
    },
    {
      "id": "code-slots",
      "name": "Assign data-backed time slots",
      "type": "n8n-nodes-base.code",
      "position": [
        2032,
        240
      ],
      "parameters": {
        "jsCode": "// Assign each post to next week's strongest slot, one item per post per account.\n// Slots (UTC) from PostFast's analysis of 22,890 IG + 13,758 TikTok real posts:\n// weekday 17:00-19:00 UTC band leads on reach; Saturday 14:00 UTC is the standout.\n// Source: postfa.st/blog/best-time-to-post-on-instagram\nconst raw = $input.first().json;\nlet parsed = raw.message?.content ?? raw.output ?? raw;\nif (typeof parsed === 'string') parsed = JSON.parse(parsed);\nconst posts = parsed.posts || [];\nif (posts.length === 0) throw new Error('OpenAI returned no posts. Check the prompt output.');\n\nconst accountIds = $('Select target accounts').first().json.accountIds;\n\n// [dayOfWeek(0=Sun..6=Sat), hourUTC]\nconst SLOTS = [[2, 17], [3, 18], [4, 19], [5, 19], [6, 14], [1, 17], [0, 17]];\n\nfunction nextSlotDate(dow, hour, after) {\n  const d = new Date(after);\n  d.setUTCHours(hour, 0, 0, 0);\n  while (d.getUTCDay() !== dow || d <= after) d.setUTCDate(d.getUTCDate() + 1);\n  return d;\n}\n\nlet cursor = new Date(Date.now() + 60 * 60 * 1000); // at least 1h ahead\nconst items = [];\nposts.forEach((p, i) => {\n  const [dow, hour] = SLOTS[i % SLOTS.length];\n  const when = nextSlotDate(dow, hour, cursor);\n  cursor = when;\n  for (const accountId of accountIds) {\n    items.push({ json: {\n      socialMediaId: accountId,\n      content: p.text,\n      scheduledAt: when.toISOString()\n    } });\n  }\n});\n\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "pf-create",
      "name": "Schedule posts via PostFast",
      "type": "n8n-nodes-postfast.postFast",
      "position": [
        2256,
        240
      ],
      "parameters": {
        "posts": {
          "post": [
            {
              "content": "={{ $json.content }}",
              "scheduledAt": "={{ $json.scheduledAt }}",
              "socialMediaId": "={{ $json.socialMediaId }}"
            }
          ]
        },
        "status": "SCHEDULED",
        "controls": {},
        "resource": "socialPost",
        "operation": "create",
        "approvalStatus": "APPROVED"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Every Monday morning": {
      "main": [
        [
          {
            "node": "Configure brand and topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select target accounts": {
      "main": [
        [
          {
            "node": "Write the week's posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write the week's posts": {
      "main": [
        [
          {
            "node": "Assign data-backed time slots",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure brand and topics": {
      "main": [
        [
          {
            "node": "Get connected accounts (PostFast)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assign data-backed time slots": {
      "main": [
        [
          {
            "node": "Schedule posts via PostFast",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get connected accounts (PostFast)": {
      "main": [
        [
          {
            "node": "Select target accounts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow runs every Monday to generate a week of social media posts with OpenAI, then schedules them at preselected high-reach time slots through PostFast for the social accounts you choose. Runs every Monday morning on a schedule trigger. Loads your brand name, voice,…

Source: https://n8n.io/workflows/16857/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This workflow runs three times a week to generate a branded social caption and AI image with OpenAI, then uploads the image via PostFast pre-signed URLs and schedules the post across selected connecte

N8N Nodes Postfast, OpenAI, HTTP Request
AI & RAG

AI Institutional Stock Valuation Engine with Risk Scoring & Scenario Targets

Google Sheets, XML, HTTP Request +3
AI & RAG

Overview This is a production-grade, fully automated stock analysis system built entirely in n8n. It combines institutional-level financial analysis, dual AI model consensus, and a self-improving back

Google Sheets, XML, HTTP Request +3
AI & RAG

This workflow enables the automatic and regular tracking of competitors' Instagram Reels, providing rich insights for each video (summary, topic, hook, angles, tags, etc) through ChatGPT, and storing

Google Sheets, Telegram, @Apify/N8N Nodes Apify +1
AI & RAG

Personalized Outreach & Follow-Up - Phase 2. Uses googleSheets, openAi, gmail, gmailTrigger. Scheduled trigger; 59 nodes.

Google Sheets, OpenAI, Gmail +2