{
  "name": "Automated social engine - LinkedIn",
  "nodes": [
    {
      "parameters": {},
      "id": "00000000-0000-4000-8000-000000000059",
      "name": "When clicking ‘Test workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "00000000-0000-4000-8000-000000000060",
              "name": "idea",
              "value": "Our new PostSider n8n workflows are live",
              "type": "string"
            },
            {
              "id": "00000000-0000-4000-8000-000000000061",
              "name": "tone",
              "value": "confident and friendly",
              "type": "string"
            },
            {
              "id": "00000000-0000-4000-8000-000000000062",
              "name": "mode",
              "value": "approval",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "00000000-0000-4000-8000-000000000063",
      "name": "1. Post idea",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "00000000-0000-4000-8000-000000000064",
              "leftValue": "={{ ($('1. Post idea').first().json.mode || '').toLowerCase() }}",
              "rightValue": "approval",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        }
      },
      "id": "00000000-0000-4000-8000-000000000065",
      "name": "2. Mode?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        440,
        0
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://api.postsider.com/public/v1/find-slot/[YOUR POSTSIDER LINKEDIN CHANNEL ID]"
      },
      "id": "00000000-0000-4000-8000-000000000066",
      "name": "3a. Find best slot",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        -180
      ],
      "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 tone. Short paragraphs with a line break between them, a concrete takeaway, and a closing question or call to action. 2-4 relevant hashtags. Respond with the post text only.\" },\n    { \"role\": \"user\", \"content\": \"Topic: {{ $('1. Post idea').first().json.idea }}. Tone: {{ $('1. Post idea').first().json.tone }}. Write the post.\" }\n  ]\n}"
      },
      "id": "00000000-0000-4000-8000-000000000067",
      "name": "4a. Generate post (AI)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        -180
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "2",
          "name": "OpenAI API Key"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const slot = $('3a. Find best slot').first().json; // { date } UTC, append 'Z'\nconst ai = $input.first().json;\nconst media = null;\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-000000000068",
      "name": "5a. Build draft",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1100,
        -180
      ]
    },
    {
      "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-000000000069",
      "name": "6a. Create draft",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1320,
        -180
      ],
      "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-000000000070",
      "name": "7a. Request approval",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1540,
        -180
      ],
      "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 tone. Short paragraphs with a line break between them, a concrete takeaway, and a closing question or call to action. 2-4 relevant hashtags. Respond with the post text only.\" },\n    { \"role\": \"user\", \"content\": \"Topic: {{ $('1. Post idea').first().json.idea }}. Tone: {{ $('1. Post idea').first().json.tone }}. Write the post.\" }\n  ]\n}"
      },
      "id": "00000000-0000-4000-8000-000000000071",
      "name": "4b. Generate post (AI)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        180
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "2",
          "name": "OpenAI API Key"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const ai = $input.first().json;\nconst media = null;\nconst content = (ai.choices?.[0]?.message?.content || '').trim();\nreturn [{\n  json: {\n    body: {\n      type: 'now',\n      date: '',\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-000000000072",
      "name": "5b. Build post",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        180
      ]
    },
    {
      "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-000000000073",
      "name": "6b. Publish now",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1100,
        180
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "1",
          "name": "PostSider API Key"
        }
      }
    },
    {
      "parameters": {
        "content": "WHAT THIS DOES\nTurns your post idea into a professional LinkedIn post with AI and publishes it through PostSider, either immediately or via the approval queue. Enter the idea in \"1. Post idea\", pick the mode, run it.\n\nSETUP (once, about 3 minutes)\n1. PostSider API key: app.postsider.com > Settings > API > Create key. It starts with ps_ and is shown once, so save it.\n2. n8n credentials (both type Header Auth):\n   - \"PostSider API Key\": Name = Authorization, Value = your ps_ key. Select it on every node that talks to PostSider.\n   - \"OpenAI API Key\": Name = Authorization, Value = Bearer sk-... . Select it on the \"(AI)\" nodes.\n3. Channel: replace [YOUR POSTSIDER LINKEDIN CHANNEL ID] with a real channel id. Find it in the app under Settings > Channels.\n\n\nHOW TO RUN\n1. Open \"1. Post idea\" and set: idea (your topic), tone (optional), mode = \"approval\" (draft goes into the approval queue, approve in the app and PostSider schedules it) or mode = \"now\" (publishes immediately). The mode check is case-insensitive.\n2. Click \"Test workflow\".\n\nSELF-HOSTED POSTSIDER\nReplace api.postsider.com with your domain; add /api if your install serves the API under /api.",
        "height": 460,
        "width": 520,
        "color": 3
      },
      "id": "00000000-0000-4000-8000-000000000074",
      "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 (do this once, both type 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-... (your OpenAI key, platform.openai.com).\n\nSTEP 2 - \"1. Post idea\" (Set node):\n  idea = your topic (e.g. \"Our new PostSider n8n workflows are live\")\n  tone = optional style (e.g. \"confident and friendly\")\n  mode = \"approval\" (goes into the approval queue) or \"now\" (publishes immediately)\n\n\nSTEP 3 - Select the \"PostSider API Key\" credential on these nodes:\n  - \"3a. Find best slot\" (Find best slot)\n  - \"6a. Create draft\" (Create draft)\n  - \"7a. Request approval\" (Request approval)\n  - \"6b. Publish now\" (Publish now)\n\nSTEP 4 - Select the \"OpenAI API Key\" credential on these nodes:\n  - \"4a. Generate post (AI)\" (Generate post, approval)\n  - \"4b. Generate post (AI)\" (Generate post, now)\n\n\nSTEP 5 - Replace the channel id:\n  Open \"3a. Find best slot\", \"6a. Create draft\", \"5a. Build draft\" and \"5b. Build post\" and replace [YOUR POSTSIDER LINKEDIN CHANNEL ID] with your real channel id (app > Settings > Channels).\n\nSTEP 6 - Run:\n  Click \"Test workflow\" once to verify everything works before activating the workflow.",
        "height": 640,
        "width": 620,
        "color": 3
      },
      "id": "00000000-0000-4000-8000-000000000075",
      "name": "Setup step by step",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -940
      ]
    }
  ],
  "connections": {
    "1. Post idea": {
      "main": [
        [
          {
            "node": "2. Mode?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Test workflow’": {
      "main": [
        [
          {
            "node": "1. Post idea",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Mode?": {
      "main": [
        [
          {
            "node": "3a. Find best slot",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "4b. Generate post (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3a. Find best slot": {
      "main": [
        [
          {
            "node": "4a. Generate post (AI)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4a. Generate post (AI)": {
      "main": [
        [
          {
            "node": "5a. Build draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5a. Build draft": {
      "main": [
        [
          {
            "node": "6a. Create draft",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6a. Create draft": {
      "main": [
        [
          {
            "node": "7a. Request approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4b. Generate post (AI)": {
      "main": [
        [
          {
            "node": "5b. Build post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5b. Build post": {
      "main": [
        [
          {
            "node": "6b. Publish now",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "active": false,
  "tags": [
    "PostSider",
    "Automated social engine",
    "AI",
    "LinkedIn"
  ]
}