AutomationFlowsAI & RAG › Create Linkedin Content with Gpt-4 via Telegram Bot & Approval Loop

Create Linkedin Content with Gpt-4 via Telegram Bot & Approval Loop

ByFeras Dabour @ferasdabour on n8n.io

AI LinkedIn Content Bot with Approval Loop

Event trigger★★★★☆ complexityAI-powered24 nodesOpenAI ChatOpenAITelegramMemory Buffer WindowTelegram TriggerAgent@Blotato/N8N Nodes Blotato
AI & RAG Trigger: Event Nodes: 24 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #10737 — we link there as the canonical source.

This workflow follows the Agent → OpenAI Chat recipe pattern — see all workflows that pair these two integrations.

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
{
  "id": "h53azcTZL2gEfUGc",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI LinkedIn Content Bot with Approval Loop",
  "tags": [],
  "nodes": [
    {
      "id": "256ac265-a798-4a3e-b8f8-347114668aea",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        3296,
        1424
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6f2d024b-ecde-448e-bb27-bedaa70ba05d",
      "name": "Speech to Text",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        3088,
        1088
      ],
      "parameters": {
        "options": {},
        "resource": "audio",
        "operation": "transcribe"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "5cfb6cd4-ed6e-40b5-bda0-d640f655ffa7",
      "name": "Get Voice File",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2864,
        1088
      ],
      "parameters": {
        "fileId": "={{ $('Start: Telegram Message').item.json.message.voice.file_id }}",
        "resource": "file",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "a1c71dc5-1ab6-4269-b92c-c91aa84f2c04",
      "name": "Check if Approved",
      "type": "n8n-nodes-base.if",
      "position": [
        3664,
        1200
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.output }}",
              "rightValue": "videoPrompt"
            },
            {
              "id": "id-2",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.output }}",
              "rightValue": "socialMediaText"
            },
            {
              "id": "id-3",
              "operator": {
                "type": "string",
                "operation": "startsWith"
              },
              "leftValue": "={{ $json.output }}",
              "rightValue": "{"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "0e275874-9f2e-48c7-8fad-254e2d385e40",
      "name": "Window Buffer Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        3440,
        1424
      ],
      "parameters": {
        "sessionKey": "={{ $('Start: Telegram Message').first().json.message.from.id }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "83ff364f-acf2-4c8e-b38f-cded14a99222",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        816
      ],
      "parameters": {
        "width": 1120,
        "height": 752,
        "content": "## AI LinkedIn Content Bot with Approval Loop\n\nTransform your Telegram into a LinkedIn content assistant. Send ideas via text or voice, collaborate with AI to refine posts, and publish directly to LinkedIn with a simple \"ok\".\n\n### How it works\n\n1. **Send your idea** - Message your Telegram bot with text or voice notes\n2. **AI drafts content** - GPT analyzes your input and creates a LinkedIn-optimized post with hashtags\n3. **Iterative refinement** - Request changes (tone, length, style) until satisfied\n4. **Approve & publish** - Say \"ok\" or \"approved\" to trigger automatic LinkedIn posting via Blotato\n5. **Get confirmation** - Receive a direct link once your post is live\n\n### Setup steps\n\n1. **Telegram Bot** - Create a bot via @BotFather and add the API token to credentials\n2. **OpenAI API** - Add your OpenAI key for AI generation and voice transcription\n3. **Blotato Account** - Connect your LinkedIn profile at [Blotato] and add API credentials\n4. **Customize the AI** - Edit the system prompt in \"AI: Draft & Revise Post\" to match your brand voice and content style\n\n### Customization tips\n\n- **Adjust tone & style** - Modify the system prompt to change formality, emoji usage, or hashtag count\n- **Switch AI models** - Swap GPT-4o-mini for more powerful models in the OpenAI Chat Model node\n- **Schedule posts** - Change Blotato operation from \"create\" to \"schedule\" for delayed publishing"
      },
      "typeVersion": 1
    },
    {
      "id": "3acd0bb7-da29-4248-b1ae-14ea2a69f92a",
      "name": "Start: Telegram Message",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        2192,
        1184
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f468b5ea-2ca7-4595-9c61-8da6e4ced2e1",
      "name": "Prepare Input",
      "type": "n8n-nodes-base.set",
      "position": [
        2416,
        1184
      ],
      "parameters": {
        "fields": {
          "values": [
            {
              "name": "text",
              "stringValue": "={{ $json?.message?.text || \"\" }}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "5a18e9f7-14e5-4c51-832a-3a43dd4bc588",
      "name": "Check: ist it a Voice?",
      "type": "n8n-nodes-base.if",
      "position": [
        2640,
        1184
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a0bf9719-4272-46f6-ab3b-eda6f7b44fd8",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.message.text }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6173bca9-d5cb-443c-8de6-616f02c7875a",
      "name": "AI: Draft & Revise Post",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3312,
        1200
      ],
      "parameters": {
        "text": "={{ $json.text }}",
        "options": {
          "systemMessage": "You are a LinkedIn Content Creator Agent for Telegram.\nKeep the confirmation process, but change the output format as follows:\n\nYour Task\n\n\nAnalyze the user's message:\n\n\nTopic\n\n\nGoal (e.g., reach, show expertise, recruiting, personal branding, leads)\n\n\nTarget Audience\n\n\nTonality (e.g., factual, personal, bold, inspiring)\n\n\n\n\nCreate a LinkedIn post as ONE continuous text:\n\n\nStrong hook in the first 1\u20132 lines.\n\n\nClear main part with added value, story, example, or insight.\n\n\nOptional Call-to-Action (e.g., question to the community, invitation to exchange).\n\n\nIntegrate hashtags at the end of the post (5\u201312 suitable hashtags, mix of niche + somewhat broader).\n\n\nReadable on LinkedIn: short paragraphs, emojis only sparingly.\n\n\n\n\nPresent the suggestion to the user in the following format:\n\n\nHeadline: Vorschlag Post:\n\n\nBelow that, the complete LinkedIn post (incl. hashtags at the end in the same text).\n\n\n\n\nAsk for feedback:\n\n\nFor example:\n\u201c\u00c4nderungsw\u00fcnsche? (Ton, L\u00e4nge, Du/Sie, mehr/weniger pers\u00f6nlich, mehr Fachinhalt, andere Hashtags?)\u201d\n(Translation note: \"\u00c4nderungsw\u00fcnsche?\" means \"Request for changes?\". \"Du/Sie\" refers to the German formal/informal 'you' distinction.)\n\n\n\n\nIf the user requests changes:\n\n\nAdjust the post specifically based on the feedback.\n\n\nAgain, output only:\n\n\nVorschlag Post:\n\n\nthe revised complete post.\n\n\n\n\n\n\nIf the user says \u201capproved\u201d, \u201cok\u201d, \u201cpasst\u201d, \u201cfreigeben\u201d or similar:\n\n\nReturn exclusively this JSON, without additional text, without Markdown:\n\n\n\n\n{\n\"Post\": \"The final LinkedIn post as one text, including hashtags at the end\"\n}\n\n\nImportant:\n\n\nNever output JSON before approval, only normal suggestion text.\n\n\nThe final output after approval consists of only one field: Post."
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "7ad66bc0-633b-4082-b38e-1b68a46f2b28",
      "name": "Approval: Extract Final Post Text",
      "type": "n8n-nodes-base.code",
      "position": [
        3888,
        1104
      ],
      "parameters": {
        "jsCode": "// Get the output from AI Agent\nconst aiOutput = $input.item.json.output;\n\nif (!aiOutput) {\n  throw new Error('No output found from AI Agent');\n}\n\n// The AI should only return pure JSON on approval.\n// But we still defensively versuchen, JSON aus gemischtem Text zu extrahieren.\nlet jsonString = aiOutput;\n\n// Remove markdown code fences if present\njsonString = jsonString\n  .replace(/```json\\s*/gi, '')\n  .replace(/```\\s*/g, '');\n\n// Try to find a JSON object in the text\nconst jsonMatch = jsonString.match(/\\{[\\s\\S]*\\}/);\nif (jsonMatch) {\n  jsonString = jsonMatch[0];\n}\n\ntry {\n  const parsed = JSON.parse(jsonString);\n\n  // Validate required field\n  if (!parsed.Post) {\n    throw new Error('Missing required field: Post');\n  }\n\n  // Return normalized structure\n  return {\n    Post: parsed.Post\n  };\n\n} catch (error) {\n  // Fallback: try to extract Post via regex if JSON parsing failed\n  const postMatch = aiOutput.match(/\"Post\"\\s*:\\s*\"([\\s\\S]*?)\"/);\n\n  if (postMatch && postMatch[1]) {\n    return {\n      Post: postMatch[1]\n    };\n  }\n\n  throw new Error(`Failed to parse AI output: ${error.message}. Output was: ${aiOutput}`);\n}\n"
      },
      "typeVersion": 2
    },
    {
      "id": "702cc34b-ac50-4f72-a8f9-c469302a2136",
      "name": "Create post with Blotato",
      "type": "@blotato/n8n-nodes-blotato.blotato",
      "position": [
        4112,
        1104
      ],
      "parameters": {
        "options": {},
        "platform": "linkedin",
        "accountId": {
          "__rl": true,
          "mode": "list",
          "value": "8621",
          "cachedResultUrl": "https://backend.blotato.com/v2/accounts/8621",
          "cachedResultName": "Feras Dabour"
        },
        "postContentText": "={{ $json.Post }}"
      },
      "credentials": {
        "blotatoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "3da38ca3-9cca-4e20-90ec-bbeb2d1cb6b4",
      "name": "Give Blotat 5s :)",
      "type": "n8n-nodes-base.wait",
      "position": [
        4336,
        1104
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "1839679c-9aab-4f66-8d6a-566f46d0c1cd",
      "name": "Check post status",
      "type": "@blotato/n8n-nodes-blotato.blotato",
      "position": [
        4560,
        1104
      ],
      "parameters": {
        "operation": "get",
        "postSubmissionId": "={{ $json.postSubmissionId }}"
      },
      "credentials": {
        "blotatoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "379e44ac-e094-4996-893f-f39d1133d28a",
      "name": "Published?",
      "type": "n8n-nodes-base.if",
      "position": [
        4784,
        1104
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "1bc619f0-b64a-4487-bbc7-21be7c30f1f1",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "published"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c8bcb473-e162-4219-ae63-4848aef7a7a4",
      "name": "Send a confirmation message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        5232,
        944
      ],
      "parameters": {
        "text": "=Your post is online!\n\nClick here to go to the post:\n{{ $json.publicUrl }}",
        "chatId": "={{ $('Start: Telegram Message').item.json.message.chat.id }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c9b3847e-2fce-4f2a-a8ae-fa9543e7a4e9",
      "name": "In Progress?",
      "type": "n8n-nodes-base.if",
      "position": [
        5008,
        1120
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e6c403be-3a03-4365-ac18-69d9ffc1770b",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Check post status').item.json.status }}",
              "rightValue": "in-progress"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c46d71c6-43a2-4a51-84fe-28895a47c6b2",
      "name": "Give Blotat other 5s :)",
      "type": "n8n-nodes-base.wait",
      "position": [
        5008,
        1328
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "cb8bb39a-9a07-4157-af23-d078d722a3f3",
      "name": "Send an error message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        5248,
        1136
      ],
      "parameters": {
        "text": "There was an error uploading your post.",
        "chatId": "={{ $('Start: Telegram Message').item.json.message.chat.id }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6eb7505b-ccf5-4293-ae02-ad771773de1f",
      "name": "Post Suggestion Or Ask For Approval",
      "type": "n8n-nodes-base.telegram",
      "position": [
        3888,
        1296
      ],
      "parameters": {
        "text": "={{ $('AI: Draft & Revise Post').item.json.output }}",
        "chatId": "={{ $('Start: Telegram Message').first().json.message.chat.id }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7df3aedd-07ad-48aa-a59b-d3ae8a66fb18",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 1104,
        "height": 752,
        "content": "## 1. Capture Input\n\nReceives Telegram messages and converts voice notes to text using OpenAI Whisper"
      },
      "typeVersion": 1
    },
    {
      "id": "35d08d82-7491-439b-b4ba-cafeb6c7cc3b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3248,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 752,
        "content": "## 2. AI Content Creation\n\nGenerates LinkedIn posts and handles revision requests through conversational memory"
      },
      "typeVersion": 1
    },
    {
      "id": "b9d9208f-728a-4c66-a1ad-70661a6724a4",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3616,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 752,
        "content": "## 3. Approval & Publishing\n\nDetects approval keywords, extracts final content, and posts to LinkedIn via Blotato"
      },
      "typeVersion": 1
    },
    {
      "id": "5663605d-4dae-4208-bc9f-61b60d2242c8",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4288,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 1168,
        "height": 752,
        "content": "## 4. Status Monitoring\n\nPolls Blotato API to verify publication and sends confirmation with post link to Telegram"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "66e55dce-2117-4fde-84cb-bcc137464fd8",
  "connections": {
    "Published?": {
      "main": [
        [
          {
            "node": "Send a confirmation message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "In Progress?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "In Progress?": {
      "main": [
        [
          {
            "node": "Give Blotat other 5s :)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send an error message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Input": {
      "main": [
        [
          {
            "node": "Check: ist it a Voice?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Voice File": {
      "main": [
        [
          {
            "node": "Speech to Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Speech to Text": {
      "main": [
        [
          {
            "node": "AI: Draft & Revise Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if Approved": {
      "main": [
        [
          {
            "node": "Approval: Extract Final Post Text",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Post Suggestion Or Ask For Approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check post status": {
      "main": [
        [
          {
            "node": "Published?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Give Blotat 5s :)": {
      "main": [
        [
          {
            "node": "Check post status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI: Draft & Revise Post",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Window Buffer Memory": {
      "ai_memory": [
        [
          {
            "node": "AI: Draft & Revise Post",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Check: ist it a Voice?": {
      "main": [
        [
          {
            "node": "Get Voice File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI: Draft & Revise Post",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI: Draft & Revise Post": {
      "main": [
        [
          {
            "node": "Check if Approved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Give Blotat other 5s :)": {
      "main": [
        [
          {
            "node": "Check post status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start: Telegram Message": {
      "main": [
        [
          {
            "node": "Prepare Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create post with Blotato": {
      "main": [
        [
          {
            "node": "Give Blotat 5s :)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Approval: Extract Final Post Text": {
      "main": [
        [
          {
            "node": "Create post with Blotato",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Suggestion Or Ask For Approval": {
      "main": [
        []
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

AI LinkedIn Content Bot with Approval Loop

Source: https://n8n.io/workflows/10737/ — 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

Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.

@Blotato/N8N Nodes Blotato, Google Sheets, OpenAI Chat +9
AI & RAG

Digital marketers, content creators, social media managers, and businesses who want to use AI marketing automation for YouTube Shorts without spending hours on production. This AI workflow helps anyon

OpenAI, HTTP Request, OpenAI Chat +7
AI & RAG

Jarvis is a powerful multi-agent productivity assistant built in n8n. It works directly from Telegram and can understand both text messages and voice notes.

Telegram Trigger, Telegram, OpenAI +10
AI & RAG

This template is designed for marketers, content creators, and e-commerce brands who want to automate the creation of professional ad videos at scale. It’s ideal for teams looking to generate consiste

Telegram, Telegram Trigger, Google Drive +8
AI & RAG

Unlock the Power of Language with Personalized AI Learning! MOTION TUTOR is a revolutionary AI-powered language learning platform that adapts to your progress and guides you from basic vocabulary to c

Agent, Airtable Tool, OpenAI Chat +6