{
  "name": "RSS to PostSider",
  "nodes": [
    {
      "parameters": {
        "url": "[YOUR RSS FEED URL, e.g. https://yourblog.com/feed]",
        "options": {}
      },
      "id": "00000000-0000-4000-8000-000000000018",
      "name": "RSS Feed Trigger",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "maxItems": 1
      },
      "id": "00000000-0000-4000-8000-000000000019",
      "name": "1. Latest item",
      "type": "n8n-nodes-base.limit",
      "typeVersion": 1,
      "position": [
        220,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "00000000-0000-4000-8000-000000000020",
              "name": "idea",
              "value": "={{ $json.title }}",
              "type": "string"
            },
            {
              "id": "00000000-0000-4000-8000-000000000021",
              "name": "tone",
              "value": "confident and friendly",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "00000000-0000-4000-8000-000000000022",
      "name": "2. Post idea",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        440,
        0
      ]
    },
    {
      "parameters": {
        "content": "WHAT THIS DOES\nWatches your blog RSS feed. Every new article becomes an AI-written post for X, LinkedIn and Facebook, placed in the PostSider calendar at the next free slot and pushed into the approval queue.\n\nSETUP (once, about 4 minutes)\n1. PostSider API key: app.postsider.com > Settings > API > Create key (ps_...).\n2. n8n credentials (Header Auth): \"PostSider API Key\" (Authorization = ps_...) and \"OpenAI API Key\" (Authorization = Bearer sk-...).\n3. Open \"RSS Feed Trigger\" and set your feed URL (e.g. https://yourblog.com/feed).\n4. Replace each [YOUR POSTSIDER ... CHANNEL ID] with real channel ids (app > Settings > Channels). Delete legs you do not use.\n\nHOW TO RUN\n1. Activate the workflow. The trigger polls your feed on the default interval.\n2. Each new article becomes drafts in the calendar; approve them in the app to publish.\n\nSELF-HOSTED POSTSIDER\nReplace api.postsider.com with your domain; add /api if your install serves the API under /api.",
        "height": 640,
        "width": 620,
        "color": 3
      },
      "id": "00000000-0000-4000-8000-000000000038",
      "name": "How to use",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -440
      ]
    },
    {
      "parameters": {
        "content": "SETUP STEP BY STEP\nFollow in order. Do this once per workflow.\n\nSTEP 1 - Create the n8n credentials (Header Auth):\n  a. \"PostSider API Key\": Name = Authorization, Value = your ps_ key (app.postsider.com > Settings > API > Create key).\n  b. \"OpenAI API Key\": Name = Authorization, Value = Bearer sk-... (platform.openai.com).\n\nSTEP 2 - \"RSS Feed Trigger\":\n  Set URL to your feed, e.g. https://yourblog.com/feed. No credential needed.\n\nSTEP 3 - Select the \"PostSider API Key\" credential on every node whose name contains \"Find best slot\", \"Create draft\" or \"Request approval\" (one set per platform).\n\nSTEP 4 - Select the \"OpenAI API Key\" credential on every \"Generate post (AI)\" node.\n\nSTEP 5 - Replace the channel ids:\n  Replace [YOUR POSTSIDER X CHANNEL ID], [YOUR POSTSIDER LINKEDIN CHANNEL ID] and [YOUR POSTSIDER FACEBOOK CHANNEL ID] with your real channel ids (app > Settings > Channels). Delete the legs of platforms you do not use.\n\nSTEP 6 - Run:\n  Activate the workflow. Publish a test article on your blog; the next poll creates the posts. Approve them in the app to publish.",
        "height": 720,
        "width": 640,
        "color": 3
      },
      "id": "00000000-0000-4000-8000-000000000039",
      "name": "Setup step by step",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -1160
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://api.postsider.com/public/v1/find-slot/[YOUR POSTSIDER X CHANNEL ID]"
      },
      "id": "00000000-0000-4000-8000-000000000023",
      "name": "3.1 Find best slot",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        -220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/chat/completions",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"model\": \"gpt-4o-mini\",\n  \"temperature\": 0.8,\n  \"messages\": [\n    { \"role\": \"system\", \"content\": \"You write social media posts for X (Twitter). Rules: Max 280 characters. Sharp hook, confident tone, 1-3 relevant hashtags. Link the blog post naturally. Respond with the post text only.\" },\n    { \"role\": \"user\", \"content\": \"Topic: {{ $('2. Post idea').first().json.idea }}. Tone: {{ $('2. Post idea').first().json.tone }}. Write the post.\" }\n  ]\n}"
      },
      "id": "00000000-0000-4000-8000-000000000024",
      "name": "3.1 Generate post (AI)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        -220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "2",
          "name": "OpenAI API Key"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const slot = $('3.1 Find best slot').first().json; // { date } UTC, append 'Z'\nconst ai = $input.first().json;\nconst content = (ai.choices?.[0]?.message?.content || '').trim();\nreturn [{\n  json: {\n    body: {\n      type: 'draft',\n      date: slot.date + 'Z',\n      shortLink: false,\n      tags: [],\n      posts: [{\n        integration: { id: '[YOUR POSTSIDER X CHANNEL ID]' },\n        value: [{ content, image: [] }],\n        settings: {\"__type\":\"x\"}\n      }]\n    }\n  }\n}];"
      },
      "id": "00000000-0000-4000-8000-000000000025",
      "name": "3.1 Build draft",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1100,
        -220
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.postsider.com/public/v1/posts",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.body) }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Idempotency-Key",
              "value": "=ps-{{ $now.toISO() }}"
            }
          ]
        }
      },
      "id": "00000000-0000-4000-8000-000000000026",
      "name": "3.1 Create draft",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1320,
        -220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.postsider.com/public/v1/posts/{{ $json.postId }}/request-approval"
      },
      "id": "00000000-0000-4000-8000-000000000027",
      "name": "3.1 Request approval",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1540,
        -220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://api.postsider.com/public/v1/find-slot/[YOUR POSTSIDER LINKEDIN CHANNEL ID]"
      },
      "id": "00000000-0000-4000-8000-000000000028",
      "name": "3.2 Find best slot",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/chat/completions",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"model\": \"gpt-4o-mini\",\n  \"temperature\": 0.8,\n  \"messages\": [\n    { \"role\": \"system\", \"content\": \"You write social media posts for LinkedIn. Rules: Professional, insight-first. Short paragraphs, a concrete takeaway, a closing question or call to action. 2-4 hashtags. Respond with the post text only.\" },\n    { \"role\": \"user\", \"content\": \"Topic: {{ $('2. Post idea').first().json.idea }}. Tone: {{ $('2. Post idea').first().json.tone }}. Write the post.\" }\n  ]\n}"
      },
      "id": "00000000-0000-4000-8000-000000000029",
      "name": "3.2 Generate post (AI)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "2",
          "name": "OpenAI API Key"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const slot = $('3.2 Find best slot').first().json; // { date } UTC, append 'Z'\nconst ai = $input.first().json;\nconst content = (ai.choices?.[0]?.message?.content || '').trim();\nreturn [{\n  json: {\n    body: {\n      type: 'draft',\n      date: slot.date + 'Z',\n      shortLink: false,\n      tags: [],\n      posts: [{\n        integration: { id: '[YOUR POSTSIDER LINKEDIN CHANNEL ID]' },\n        value: [{ content, image: [] }],\n        settings: {\"__type\":\"linkedin\"}\n      }]\n    }\n  }\n}];"
      },
      "id": "00000000-0000-4000-8000-000000000030",
      "name": "3.2 Build draft",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1100,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.postsider.com/public/v1/posts",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.body) }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Idempotency-Key",
              "value": "=ps-{{ $now.toISO() }}"
            }
          ]
        }
      },
      "id": "00000000-0000-4000-8000-000000000031",
      "name": "3.2 Create draft",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1320,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.postsider.com/public/v1/posts/{{ $json.postId }}/request-approval"
      },
      "id": "00000000-0000-4000-8000-000000000032",
      "name": "3.2 Request approval",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1540,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://api.postsider.com/public/v1/find-slot/[YOUR POSTSIDER FACEBOOK CHANNEL ID]"
      },
      "id": "00000000-0000-4000-8000-000000000033",
      "name": "3.3 Find best slot",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/chat/completions",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"model\": \"gpt-4o-mini\",\n  \"temperature\": 0.8,\n  \"messages\": [\n    { \"role\": \"system\", \"content\": \"You write social media posts for Facebook. Rules: Friendly, conversational. Up to 4 short paragraphs, one clear call to action, 3-5 hashtags. Respond with the post text only.\" },\n    { \"role\": \"user\", \"content\": \"Topic: {{ $('2. Post idea').first().json.idea }}. Tone: {{ $('2. Post idea').first().json.tone }}. Write the post.\" }\n  ]\n}"
      },
      "id": "00000000-0000-4000-8000-000000000034",
      "name": "3.3 Generate post (AI)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "2",
          "name": "OpenAI API Key"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const slot = $('3.3 Find best slot').first().json; // { date } UTC, append 'Z'\nconst ai = $input.first().json;\nconst content = (ai.choices?.[0]?.message?.content || '').trim();\nreturn [{\n  json: {\n    body: {\n      type: 'draft',\n      date: slot.date + 'Z',\n      shortLink: false,\n      tags: [],\n      posts: [{\n        integration: { id: '[YOUR POSTSIDER FACEBOOK CHANNEL ID]' },\n        value: [{ content, image: [] }],\n        settings: {\"__type\":\"facebook\"}\n      }]\n    }\n  }\n}];"
      },
      "id": "00000000-0000-4000-8000-000000000035",
      "name": "3.3 Build draft",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1100,
        220
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.postsider.com/public/v1/posts",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.body) }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Idempotency-Key",
              "value": "=ps-{{ $now.toISO() }}"
            }
          ]
        }
      },
      "id": "00000000-0000-4000-8000-000000000036",
      "name": "3.3 Create draft",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1320,
        220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.postsider.com/public/v1/posts/{{ $json.postId }}/request-approval"
      },
      "id": "00000000-0000-4000-8000-000000000037",
      "name": "3.3 Request approval",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1540,
        220
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    }
  ],
  "connections": {
    "3.1 Find best slot": {
      "main": [
        [
          {
            "node": "3.1 Generate post (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.1 Generate post (AI)": {
      "main": [
        [
          {
            "node": "3.1 Build draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.1 Build draft": {
      "main": [
        [
          {
            "node": "3.1 Create draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.1 Create draft": {
      "main": [
        [
          {
            "node": "3.1 Request approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.2 Find best slot": {
      "main": [
        [
          {
            "node": "3.2 Generate post (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.2 Generate post (AI)": {
      "main": [
        [
          {
            "node": "3.2 Build draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.2 Build draft": {
      "main": [
        [
          {
            "node": "3.2 Create draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.2 Create draft": {
      "main": [
        [
          {
            "node": "3.2 Request approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.3 Find best slot": {
      "main": [
        [
          {
            "node": "3.3 Generate post (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.3 Generate post (AI)": {
      "main": [
        [
          {
            "node": "3.3 Build draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.3 Build draft": {
      "main": [
        [
          {
            "node": "3.3 Create draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3.3 Create draft": {
      "main": [
        [
          {
            "node": "3.3 Request approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RSS Feed Trigger": {
      "main": [
        [
          {
            "node": "1. Latest item",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Latest item": {
      "main": [
        [
          {
            "node": "2. Post idea",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Post idea": {
      "main": [
        [
          {
            "node": "3.1 Find best slot",
            "type": "main",
            "index": 0
          },
          {
            "node": "3.2 Find best slot",
            "type": "main",
            "index": 0
          },
          {
            "node": "3.3 Find best slot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "active": false,
  "tags": [
    "PostSider",
    "RSS",
    "AI",
    "Blog"
  ]
}