This workflow corresponds to n8n.io template #8410 — we link there as the canonical source.
This workflow follows the Chainllm → Execute Workflow Trigger 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 →
{
"nodes": [
{
"id": "ecc6cdb5-59f7-4bfc-83c6-40d87f48502e",
"name": "When clicking \u2018Execute workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
576,
672
],
"parameters": {},
"typeVersion": 1
},
{
"id": "cf48f485-1f2b-45ca-951b-29b6fce58c78",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
2768,
576
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b436d79c-8106-4b3c-b422-3580962d8db5",
"operator": {
"type": "object",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{$json}}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "ee3adcb5-d57b-46a2-a1b4-71ea08f44c1e",
"name": "Find documents",
"type": "n8n-nodes-base.mongoDb",
"position": [
1232,
672
],
"parameters": {
"options": {
"projection": "{\n \"tweet_id\": 1,\n \"_id\": 0\n }"
},
"collection": "collection_name"
},
"credentials": {
"mongoDb": {
"name": "<your credential>"
}
},
"retryOnFail": false,
"typeVersion": 1.2,
"alwaysOutputData": true
},
{
"id": "3730bc4b-bb19-4c26-9acc-28f07466283d",
"name": "Aggregate1",
"type": "n8n-nodes-base.aggregate",
"position": [
1408,
672
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "tweet_id"
}
]
}
},
"typeVersion": 1
},
{
"id": "1ffd6d06-62c9-4034-8bae-f9818436c256",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
576,
832
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 20
}
]
}
},
"typeVersion": 1.2
},
{
"id": "edd31538-108b-48c8-9a6e-90f27fd247d2",
"name": "Code",
"type": "n8n-nodes-base.code",
"position": [
736,
928
],
"parameters": {
"jsCode": "// Force to Kyiv timezone\nconst now = new Date();\n\n// Format to Kyiv and extract hour\nconst formatter = new Intl.DateTimeFormat('en-GB', {\n timeZone: 'Europe/Kyiv',\n hour: 'numeric',\n hour12: false\n});\n\nconst hour = parseInt(formatter.format(now), 10);\n\n// Active hours: 07:00\u201323:59\nif (hour < 7 || hour >= 24) {\n return [{ json: { value: false } }];\n}\n\n// Probability (~28%)\nif (Math.random() < 1) {\n return [{ json: { value: true } }];\n} else {\n return [{ json: { value: false } }];\n}\n"
},
"typeVersion": 2
},
{
"id": "ddfd32d3-e428-4cd9-bfe7-fbbc8110b89d",
"name": "If1",
"type": "n8n-nodes-base.if",
"position": [
880,
832
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7b85bd0c-3413-402f-8e6b-85235023fd46",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.value }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "a49b0899-268c-4e4e-a676-b396d924b461",
"name": "No Operation, do nothing",
"type": "n8n-nodes-base.noOp",
"position": [
1024,
928
],
"parameters": {},
"typeVersion": 1
},
{
"id": "18784d65-ee93-4245-86e5-640f352a3ca0",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
3184,
752
],
"parameters": {
"amount": 3
},
"typeVersion": 1.1
},
{
"id": "36ec187d-64dc-437e-b3d1-884fbade96f1",
"name": "If5",
"type": "n8n-nodes-base.if",
"position": [
2960,
800
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8310c6d9-2fa2-492b-8d9a-472ba8139197",
"operator": {
"type": "number",
"operation": "lt"
},
"leftValue": "={{ $('Keyword/Community List').item.json.failure }}",
"rightValue": 3
}
]
}
},
"typeVersion": 2.2
},
{
"id": "6c0d2132-f538-4f9b-bf40-d717fc957fae",
"name": "When Executed by Another Workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
928,
1632
],
"parameters": {
"inputSource": "passthrough"
},
"typeVersion": 1.1
},
{
"id": "9b5f56a2-12fc-48e2-91b6-e5a2657c273f",
"name": "If2",
"type": "n8n-nodes-base.if",
"position": [
2432,
656
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b436d79c-8106-4b3c-b422-3580962d8db5",
"operator": {
"type": "object",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{$json}}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "2157f455-c935-40a5-85e4-02e99ce5c6ef",
"name": "Execute Workflow",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
3328,
368
],
"parameters": {
"options": {},
"workflowId": {
"__rl": true,
"mode": "list",
"value": "d2ab3cFnoWqP7E49",
"cachedResultName": "Reply posting on X"
},
"workflowInputs": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "9e4ea923-1d37-4680-b4e3-1954ac63f018",
"name": "Get dataset items",
"type": "@apify/n8n-nodes-apify.apify",
"position": [
2256,
656
],
"parameters": {
"resource": "Datasets",
"datasetId": "={{ $json.defaultDatasetId }}"
},
"credentials": {
"apifyApi": {
"name": "<your credential>"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "67fe82eb-3108-430b-872f-b80e6bb8a9a8",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
816
],
"parameters": {
"color": 5,
"width": 832,
"height": 256,
"content": "## Schedule trigger\nEdit timezone!!\n\nRuns from 7am to midnight\nbased on your time zone. \n\nThe code allows to mimic \nyour natural posting time"
},
"typeVersion": 1
},
{
"id": "e52c138a-46d9-4aee-97ac-1e941702645f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1552,
416
],
"parameters": {
"color": 6,
"width": 192,
"height": 432,
"content": "## \ud83d\udc47A list of keywords/communities to search\n\nYou have to specify them in the node\n"
},
"typeVersion": 1
},
{
"id": "8b97e7fb-9775-46c9-8c0e-7d28fd40b3d5",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2064,
176
],
"parameters": {
"color": 4,
"width": 352,
"height": 848,
"content": "## Apify X (Twitter) scrapping\n\n\n### Its very important that you must have Apify community node installed befor pasting the JSON\n\nApify scrappers that extract tweets based on keywords or search within specific communities\n\nYou can only have one actor active.\nEither Community search actor or Search actor based on where you want to search for posts. \n\nYou have to turn on depended filters\n\n\n\n\n\n\n\n\n\n\n"
},
"typeVersion": 1
},
{
"id": "9d638975-a8fc-4ad3-923f-d2e529965a42",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
416
],
"parameters": {
"color": 3,
"width": 192,
"height": 432,
"content": "## Mongo DB\n\nYou have to connect your mongo DB account to store already replied tweets.\n\nThe node fetches already replied tweets\n"
},
"typeVersion": 1
},
{
"id": "703597d7-9b77-4099-b9a0-577970d3c2f1",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2576,
176
],
"parameters": {
"color": 2,
"width": 166,
"height": 848,
"content": "## Filters tweets\n\nFeel free to edit filters\n\nNote: same filter works for both, community and search Apify actors. But since you can filter search actor output by providing some parameters to the API call some filters can be duplicated. So just make sure they match"
},
"typeVersion": 1
},
{
"id": "435f2399-99d8-47ca-8972-418a07afee3d",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2864,
672
],
"parameters": {
"color": 3,
"width": 800,
"height": 432,
"content": "## Retry section\nIf no tweets meet our criteria, try the loop again, selection of another random keyword from the list. If 4 retries with no results, then send a message to telegram that it was unsuccessful. You have to specify telegram chat ID to send messages to"
},
"typeVersion": 1
},
{
"id": "485a4674-0edb-4199-b304-4a197c5010aa",
"name": "Basic LLM Chain",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
1344,
1632
],
"parameters": {
"text": "={{ $json.data }}",
"batching": {},
"messages": {
"messageValues": [
{
"message": "You are an X (formerly Twitter) reply specialist. Your job is to analyze a list of posts and generate intelligent, engaging replies that maximize engagement potential.\nInput Format\nYou will be given a JSON object containing the current time and a list of posts:\n{\n\"time_now\": \"YYYY-MM-DDTHH:MM:SS.sssZ\", // ISO 8601 format, e.g., \"2025-09-01T06:46:53.131+01:00\"\n\"data\": [\n{\n\"post_id\": \"1234567890\",\n\"screen_name\": \"example_user\",\n\"tweet_text\": \"Post content here\",\n\"created_at\": \"Wed Jun 18 17:15:39 +0000 2025\", // Twitter date format\n\"tweet_likes\": 500,\n\"tweet_retweets\": 100,\n\"tweet_replies\": 50,\n\"tweet_views\": \"9062\",\n\"user_followers_count\": 10000\n},\n// More posts...\n]\n}\nIf any fields are missing, use reasonable defaults (e.g., 0 for engagement metrics).\nYour Task\nGiven the input, you must:\nFilter out ineligible posts first (see below).\nSelect the post with the highest engagement potential from the remaining ones.\nGenerate an optimized reply for that post.\nOutput: Post ID + Generated Reply in JSON.\nPost Filtering (Before Scoring)\nIgnore and exclude posts that:\n- Are giveaways, contests, or promotions requiring specific actions like liking, reposting, or commenting a keyword/phrase to enter or receive something (e.g., \"Comment 'Vault' to win\" or \"Like + RT for free access\"). These are spammy and low-value for engagement.\n- Are purely promotional ads without substantive discussion (e.g., just product plugs with no insight or question).\n- Have no meaningful content for reply (e.g., empty or emoji-only posts).\nIf all posts are filtered out, output the \"No high-potential posts\" error.\nPost Selection Criteria\nPriority ranking (most important first):\nEngagement Potential - High like-to-follower ratio, growing momentum, active replies.\nUser Authority - High follower count, quality engagement.\nTiming Balance - Recent posts (relative to time_now, prefer <6 hours) or older with exceptional metrics.\nDecision Process\nScore each post after filtering:\nEngagement Velocity: (tweet_likes + tweet_retweets + tweet_replies * 2) / max(1, hours_since_posted), where hours_since_posted is calculated as the difference between time_now and created_at in hours.\nAuthority: log10(user_followers_count) * (total_engagement / user_followers_count), where total_engagement = tweet_likes + tweet_retweets + tweet_replies.\nTiming: +3 if hours_since_posted < 6; +2 if velocity > 10/hour; +1 if hours_since_posted < 24.\nOpportunity: 1-5 based on value-add potential (e.g., 5 for questions or posts inviting discussion, 4 for controversial or relatable takes that allow witty twists, 1 for closed statements).\nTotal: (Velocity * 0.4) + (Authority * 0.3) + (Timing * 0.2) + (Opportunity * 0.1)\nSelect the highest-scoring post (>3.0 threshold, else error).\nCraft reply.\nReply Style Guide\nPrioritize a human, casual voice: Sarcastic, witty, dry humor, or self-deprecating where it fits\u2014avoid generic positivity or spam-like enthusiasm. Mix styles based on the post, but lean toward edge for better engagement.\nChoose/mix the most effective:\nWitty/Sarcastic - For controversial or bold statements. Example: \"Subscriptions cost more than owning stuff outright. Wild plot twist. Who saw that coming?\"\nHumorous/Exaggerated - For relatable or fun posts. Example: \"$350M for no Mac? I\u2019d take the cash and type on a banana if I had to.\"\nInformational/Educational - For advice-seeking posts. Example: \"SaaS isn\u2019t just revenue\u2014it\u2019s low inventory risk. But good luck explaining that to your accountant.\"\nThought-Provoking - For shallow observations. Example: \"Subscriptions swap financial anxiety for predictable costs. Until the price hikes hit, anyway.\"\nEmpathetic/Supportive - For emotional content. Example: \"Been there\u2014tough spot. X worked for me, but honestly, it was a grind.\"\nReply Quality Standards\nIntelligent and nuanced.\nAuthentic human voice: Conversational, natural, with a touch of personality\u2014like sarcasm, irony, or understatement. Avoid sounding like a bot or marketer (no exclamation overload, no forced hype).\nAdd meaningful value (insight, humor, or perspective) with a unique twist that surprises or amuses.\n<100 characters. The shorter, the better!!!!\nStandalone replies in 95% of cases: Deliver a complete, engaging point without expecting a response. Avoid questions unless strictly necessary.\nQuestions only in 5% of cases: Include a question only if the original post is a direct question (e.g., \u201cWhat\u2019s your top red flag?\u201d) or explicitly invites discussion (e.g., \u201cCan you do this for 30 days?\u201d), and the question adds unique, specific value likely to spark meaningful replies. Do not mirror the original question or add redundant questions. For the most part, avoid questions in the replies!!!!\nYou can use 1 emoji, but try to avoid it, only use it when necessary.\nAvoid hashtags.\nThink step-by-step: Analyze the post\u2019s intent and tone. Select style that matches but adds edge (e.g., sarcasm for boastful posts, humor for absurd ones). Craft reply as a punchy, standalone zinger. Verify it's natural, question-free unless essential, and feels like a clever friend's quip\u2014not generic praise.\nOutput Format\nValid JSON only:\n{\n\"selected_tweet_id\": \"id_here\",\n\"screen_name\": \"name_here\",\n\"reply\": \"reply_here\"\n}\nEdge Cases\nEmpty data list: {\"error\": \"No posts provided.\"}\nNo post scores >3.0 or all filtered out: {\"error\": \"No high-potential posts.\"}\nRemember: Focus on one brilliant, value-adding reply that feels natural, standalone, and conversational with a human edge."
}
]
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "3e265172-5389-4249-91f6-c82fde2e5557",
"name": "OpenRouter Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
1328,
1824
],
"parameters": {
"model": "x-ai/grok-3",
"options": {
"responseFormat": "json_object"
}
},
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "d666ab13-f11d-4eba-bd3f-f92ef54fa085",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1440,
1808
],
"parameters": {
"autoFix": true,
"jsonSchemaExample": "{ \n \"selected_tweet_id\": \"tweet_id_here\",\n \"screen_name\": \"author_screen_name\",\n \"reply\": \"your_generated_reply_here\"\n}"
},
"typeVersion": 1.3
},
{
"id": "0b0f7f12-2b65-4df3-a292-a05f25477960",
"name": "Create Tweet",
"type": "n8n-nodes-base.twitter",
"onError": "continueErrorOutput",
"position": [
1696,
1632
],
"parameters": {
"text": "={{ $json.output.reply }}",
"additionalFields": {
"inReplyToStatusId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.output.selected_tweet_id }}"
}
}
},
"credentials": {
"twitterOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "e27abf81-aa67-4f21-aafd-ec1aa4a62f80",
"name": "OpenRouter Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
"position": [
1424,
1936
],
"parameters": {
"options": {}
},
"credentials": {
"openRouterApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "b34cf3c1-5998-4e1b-a7d6-941d2d64fefa",
"name": "Send a success reply",
"type": "n8n-nodes-base.telegram",
"position": [
1920,
1536
],
"parameters": {
"text": "=\ud83d\udfe2 Posted a reply successfully\n\nhttps://x.com/{{ $('Basic LLM Chain').item.json.output.screen_name }}/status/{{ $('Basic LLM Chain').item.json.output.selected_tweet_id }}\n\n<code>{{ $('Basic LLM Chain').item.json.output.reply }}</code>\n",
"chatId": "11111111111111",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false,
"disable_notification": true
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "bdd0ff4f-733f-4ca8-8f64-64dd2c8b1ca1",
"name": "Send a failed reply",
"type": "n8n-nodes-base.telegram",
"position": [
1920,
1744
],
"parameters": {
"text": "=\ud83d\udd34 Posted a reply unsuccessfully due to X (Twitter) API limitation, (17 posts a day for free tier)\n\nhttps://x.com/{{ $('Basic LLM Chain').item.json.output.screen_name }}/status/{{ $('Basic LLM Chain').item.json.output.selected_tweet_id }}\n\n<code>{{ $('Basic LLM Chain').item.json.output.reply }}</code>\n",
"chatId": "11111111111111",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false,
"disable_notification": true
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "0465ce22-961e-485c-87fc-bfaf414fe160",
"name": "parse reply",
"type": "n8n-nodes-base.set",
"position": [
2144,
1632
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0c5f816e-b877-4fd6-8503-bdef0343079d",
"name": "tweet_id",
"type": "string",
"value": "={{ $('Basic LLM Chain').item.json.output.selected_tweet_id }}"
},
{
"id": "94ae6af6-9e8c-44e1-b53e-eea2a133cc8e",
"name": "screen_name",
"type": "string",
"value": "={{ $('Basic LLM Chain').item.json.output.screen_name }}"
},
{
"id": "6da73fce-869a-4c13-b3c3-3602d7ba55c9",
"name": "reply",
"type": "string",
"value": "={{ $('Basic LLM Chain').item.json.output.reply }}"
},
{
"id": "11bd3d58-f53d-410c-bfe0-b1259d41a1fb",
"name": "tweet_url",
"type": "string",
"value": "=https://x.com/{{ $('Basic LLM Chain').item.json.output.screen_name }}/status/{{ $('Basic LLM Chain').item.json.output.selected_tweet_id }}"
},
{
"id": "c5241ce8-609b-46f1-9360-cbf5d779953b",
"name": "date",
"type": "string",
"value": "={{ $now.format('HH:mm; dd.MM.yyyy')}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "45246617-5c18-467b-a4d2-5416fd822ae0",
"name": "Insert documents",
"type": "n8n-nodes-base.mongoDb",
"position": [
2320,
1632
],
"parameters": {
"fields": "=tweet_id, screen_name, reply, tweet_url, date",
"options": {
"dateFields": ""
},
"operation": "insert",
"collection": "collection_name"
},
"credentials": {
"mongoDb": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "66b0ce1c-eb96-4034-a184-66ff71e6a823",
"name": "modify tweet data",
"type": "n8n-nodes-base.set",
"position": [
1168,
1632
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "310097a1-1356-4c9c-b5d5-1c4e944aba61",
"name": "time_now",
"type": "string",
"value": "={{ $now }}"
},
{
"id": "2d7f2ada-72ef-4bad-936d-5eeb90bd4e38",
"name": "data",
"type": "array",
"value": "={{ $json.data }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "2f0a83c2-67da-47c5-92f4-1785963783ea",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
592,
528
],
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "1154db08-9329-4c58-bf8f-2713ac8b6d49",
"name": "If3",
"type": "n8n-nodes-base.if",
"position": [
816,
528
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "d837eb25-886e-450c-9145-7a1e483d630e",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.message.text }}",
"rightValue": "/reply"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "63dde44f-4f97-463b-9a84-799b7c34be97",
"name": "No Operation, do nothing1",
"type": "n8n-nodes-base.noOp",
"position": [
960,
352
],
"parameters": {},
"typeVersion": 1
},
{
"id": "18537add-f26a-464b-b887-72c002908422",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
352
],
"parameters": {
"color": 4,
"width": 576,
"height": 336,
"content": "## Telegram trigger\n\nYou can trigger the workflow manually via /reply\nYou need to setup bot credential for this"
},
"typeVersion": 1
},
{
"id": "1251926c-16ad-42e7-a998-ec2744ca0449",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
1424
],
"parameters": {
"color": 3,
"width": 192,
"height": 384,
"content": "## Add current date\n\nso the LLM better understand the trending tweets"
},
"typeVersion": 1
},
{
"id": "feaa97ff-885d-4e8e-8d45-882981153b36",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
1312,
1424
],
"parameters": {
"width": 368,
"height": 656,
"content": "## LLM tweets processing "
},
"typeVersion": 1
},
{
"id": "f14dfad5-89e9-41a5-9f26-72b6eb933160",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1840,
1424
],
"parameters": {
"color": 6,
"height": 560,
"content": "## Provide status message to telegram\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nYou have to specify telegram chat ID"
},
"typeVersion": 1
},
{
"id": "857e08df-a675-4274-a7e6-38552f5df5f6",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1680,
1424
],
"parameters": {
"color": 4,
"width": 150,
"height": 560,
"content": "## Reply to the post\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nNote: official twitter API has limitations. You cna post about 17 times a day before limits apply"
},
"typeVersion": 1
},
{
"id": "606e31d4-5d39-4018-ba0f-39fae1095fd6",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
2080,
1424
],
"parameters": {
"width": 480,
"height": 384,
"content": "## Saving reply to databse to avoid duplications"
},
"typeVersion": 1
},
{
"id": "7ddb2983-ac6e-408b-8296-d3eca2d65ba6",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
2416,
416
],
"parameters": {
"color": 3,
"width": 150,
"height": 432,
"content": "## Check if there are results\n\nBased on your query and parameters the APIs may return no results"
},
"typeVersion": 1
},
{
"id": "8c505aee-c842-4849-b231-05f1f8204a0c",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"position": [
2912,
288
],
"parameters": {
"color": 5,
"width": 608,
"height": 256,
"content": "## Send tweet data to Sub workflow\nDouble check it triggers the execution workflow"
},
"typeVersion": 1
},
{
"id": "26ab8845-7d5f-4431-9ac9-a28f0c4d1039",
"name": "Sticky Note16",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
0
],
"parameters": {
"width": 3936,
"height": 1216,
"content": "# \ud83d\udc47\ud83d\udc47\ud83d\udc47\n# You have to specify your own data/create credentials to use the workflow properly:\n\n### Find the newest version at https://dziura.online/automation\n### Documentation and usage guide https://docs.google.com/document/d/13okk16lkUOgpbeahMcdmd7BuWkAp_Lx6kQ8BwScbqZk/edit?usp=sharing\n\n\n### * Telegram bot https://t.me/BotFather\n### * Telegram chat id to send status messages to\n### * Mongo DB database to save replies (connection tutorial link https://youtu.be/gB76VdlpX7Y?si=bw_LHLTkXEk8LFO0)\n### * Its very important that you must have Apify community node installed before pasting the JSON. Just paste it over\n### Apify Account. I use:\n### https://apify.com/api-ninja/x-twitter-advanced-search actor for scrapping X (Twitter) posts and\n### https://apify.com/api-ninja/x-twitter-community-search-post-scraper for community posts scraping\n### * Open Router, or any LLM to process tweets https://openrouter.ai/. Grok3 proven to be working well\n### * X (twitter) API for automatic posting https://developer.x.com\n"
},
"typeVersion": 1
},
{
"id": "d891c53f-54d9-49f2-bd30-8fc61f8f95b5",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
800,
1280
],
"parameters": {
"color": 5,
"width": 1872,
"height": 912,
"content": "# Execution workflow\n\n\nGenerating a reply and posting on X, send status to telegram chat, save reply to mongo db"
},
"typeVersion": 1
},
{
"id": "07aa12a2-1ccc-4f7e-acf2-e824a446a1fc",
"name": "Get tweet data",
"type": "n8n-nodes-base.set",
"position": [
2960,
368
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a2b5edfc-0e25-4492-bc6f-69e12e42cddb",
"name": "id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "2d24a106-0404-4dc3-977e-97281311af0d",
"name": "screen_name",
"type": "string",
"value": "={{ $json.author.userName }}"
},
{
"id": "0e403383-bddf-4739-bc6a-9cf5cf299236",
"name": "user_followers_count",
"type": "number",
"value": "={{ $json.author.followers }}"
},
{
"id": "bfe1a4a3-5b37-4bc0-a174-2262393c50ba",
"name": "created_at",
"type": "string",
"value": "={{ $json.createdAt }}"
},
{
"id": "6434ee6b-7e9b-4a82-b2a0-a504e61767ae",
"name": "tweet_text",
"type": "string",
"value": "={{ $json.text.replace(/\\s*https?:\\/\\/\\S+$/, '') }}\n"
},
{
"id": "2e43111a-7963-4f20-b6e1-2d0986ac2551",
"name": "tweet_likes",
"type": "number",
"value": "={{ $json.likeCount }}"
},
{
"id": "1b856625-d214-4700-b37b-8d56649af3b9",
"name": "tweet_retweets",
"type": "number",
"value": "={{ $json.retweetCount }}"
},
{
"id": "afb5df07-042f-4b51-880c-201061cae0be",
"name": "tweet_views",
"type": "string",
"value": "={{ $json.viewCount }}"
},
{
"id": "490aa9a3-65ff-4f33-bfe7-97c8bf6b8436",
"name": "tweet_replies",
"type": "number",
"value": "={{ $json.replyCount }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f339aa30-a798-4fb1-8d26-d7c79fece3b7",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
3136,
368
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "d6bfb139-0065-48cd-8075-f1d9a205c6e2",
"name": "Community filter",
"type": "n8n-nodes-base.filter",
"position": [
2608,
592
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "abda82ba-a65f-4af9-b5dc-c91a27d7c993",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.text.length }}",
"rightValue": 60
},
{
"id": "e269fa10-d9e1-4398-95a9-18f393408bad",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.author.followers }}",
"rightValue": 100
},
{
"id": "f2d57a64-ad49-453b-ad04-8d4b7d03c5be",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ !$('Aggregate1').item.json.tweet_id.includes($json.id) }}",
"rightValue": "="
},
{
"id": "bb6e7ed7-c9e5-4454-8f7c-6fea447a9f9b",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.replyCount }}",
"rightValue": 3
},
{
"id": "6681f28a-8904-4869-84e7-5b479b092ec2",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.likeCount }}",
"rightValue": 10
},
{
"id": "38e16cbc-2ec1-4087-95a3-af0ccee0a005",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.lang }}",
"rightValue": "en"
},
{
"id": "70719339-978b-472b-b3fc-98620fd42c28",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.viewCount }}",
"rightValue": 100
}
]
}
},
"typeVersion": 2.2,
"alwaysOutputData": true
},
{
"id": "0600faa2-8e57-4461-b389-47da9a977ae0",
"name": "Community search actor",
"type": "@apify/n8n-nodes-apify.apify",
"position": [
2112,
512
],
"parameters": {
"actorId": {
"__rl": true,
"mode": "id",
"value": "upbwCMnBATzmzcaNu"
},
"timeout": {},
"customBody": "={\n \"communityIds\": [\n \"{{ $json.randomized_item }}\"\n ],\n \"numberOfTweets\": 40\n}"
},
"credentials": {
"apifyApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "9a6fecf4-16a9-42f1-9c04-a21e911e27f0",
"name": "Keyword/Community List",
"type": "n8n-nodes-base.set",
"position": [
1600,
672
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"keyword_community_list\": [\n \"BuildInPublic\",\n \"Automation\",\n \"n8n\",\n \"cats OR dogs\",\n \"AI\",\n \"#devtools\",\n \"#Networking OR #TechCommunity\",\n \"1699807431709041070\",\n \"1472105760389668865\",\n \"1699807431709041070\",\n \"1808786876314026197\",\n \"1488952693443997701\"\n ],\n \"failure\": {{ $runIndex === 0 ? 0 : ($json.failure || 0) }}\n}"
},
"typeVersion": 3.4
},
{
"id": "8f1d16fe-2d34-4bd5-b674-6745c4c3b4f5",
"name": "Randomized community, keyword",
"type": "n8n-nodes-base.set",
"position": [
1792,
672
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "1c216d43-8f92-4a73-bd6e-b85368fb1b84",
"name": "randomized_item",
"type": "string",
"value": "={{ $json.keyword_community_list.randomItem() }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "c00ce586-7400-4130-9259-38bd88505230",
"name": "If4",
"type": "n8n-nodes-base.if",
"position": [
1952,
672
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6f1f27b9-5a72-42b3-bee1-e23e30c648f6",
"operator": {
"type": "string",
"operation": "regex"
},
"leftValue": "={{ $json.randomized_item }}",
"rightValue": "\\d{19}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "cbfaea8c-a107-492b-873f-4f829532c091",
"name": "Sticky Note15",
"type": "n8n-nodes-base.stickyNote",
"position": [
1744,
416
],
"parameters": {
"color": 5,
"width": 320,
"height": 432,
"content": "## Get randomized items, route to the right API\n\n\nSet and check random item from user input list of keywords or communities. Check if it matches community ID regex, route to the right either to community search, or to search by keyword actor"
},
"typeVersion": 1
},
{
"id": "4baacafe-5a2b-45b6-83fc-6ada987c2466",
"name": "Sticky Note17",
"type": "n8n-nodes-base.stickyNote",
"position": [
1376,
416
],
"parameters": {
"color": 2,
"width": 166,
"height": 432,
"content": "## Aggregate posted reply to a unified list "
},
"typeVersion": 1
},
{
"id": "62c7cd3b-8ada-472f-b77e-b3c99a39927c",
"name": "Send a scraping failure message",
"type": "n8n-nodes-base.telegram",
"position": [
3184,
896
],
"parameters": {
"text": "=\ud83d\udd34 Parsed search unsuccessfully. Failed after 4 retries\n\nclick /reply to try again\n",
"chatId": "11111111111111",
"additionalFields": {
"parse_mode": "HTML",
"appendAttribution": false,
"disable_notification": true
}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "8fc09efc-025f-4911-8bef-64b9260800fc",
"name": "Increment Failure Counter",
"type": "n8n-nodes-base.set",
"position": [
3456,
912
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "increment-failure-counter",
"name": "failure",
"type": "number",
"value": "={{ $('Keyword/Community List').item.json.failure +1 }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "e92c86cf-a55f-426b-a64f-befd8ac0fb91",
"name": "Search keyword actor",
"type": "@apify/n8n-nodes-apify.apify",
"position": [
2112,
800
],
"parameters": {
"actorId": {
"__rl": true,
"mode": "id",
"value": "0oVSlMlAX47R2EyoP"
},
"customBody": "={\n \"contentLanguage\": \"en\",\n \"contentQuestionMarks\": false,\n \"engagementHasEngagement\": false,\n \"engagementMinLikes\": 10,\n \"engagementMinReplies\": 5,\n \"engagementMinRetweets\": 0,\n \"mediaHasHashtags\": false,\n \"mediaHasLinks\": false,\n \"mediaHasMentions\": false,\n \"mediaNewsOnly\": false,\n \"mediaSafeContentOnly\": false,\n \"numberOfTweets\": 20,\n \"query\": \"{{ $json.randomized_item }}\",\n \"timeWithinTime\": \"2d\",\n \"tweetTypes\": [\n \"original\"\n ],\n \"usersBlueVerifiedOnly\": true,\n \"usersVerifiedOnly\": false\n}"
},
"credentials": {
"apifyApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
}
],
"connections": {
"If": {
"main": [
[
{
"node": "Get tweet data",
"type": "main",
"index": 0
}
],
[
{
"node": "If5",
"type": "main",
"index": 0
}
]
]
},
"If1": {
"main": [
[
{
"node": "Find documents",
"type": "main",
"index": 0
}
],
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"If2": {
"main": [
[
{
"node": "Community filter",
"type": "main",
"index": 0
}
],
[
{
"node": "If5",
"type": "main",
"index": 0
}
]
]
},
"If3": {
"main": [
[
{
"node": "Find documents",
"type": "main",
"index": 0
}
],
[
{
"node": "No Operation, do nothing1",
"type": "main",
"index": 0
}
]
]
},
"If4": {
"main": [
[
{
"node": "Community search actor",
"type": "main",
"index": 0
}
],
[
{
"node": "Search keyword actor",
"type": "main",
"index": 0
}
]
]
},
"If5": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
],
[
{
"node": "Send a scraping failure message",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Increment Failure Counter",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "Execute Workflow",
"type": "main",
"index": 0
}
]
]
},
"Aggregate1": {
"main": [
[
{
"node": "Keyword/Community List",
"type": "main",
"index": 0
}
]
]
},
"parse reply": {
"main": [
[
{
"node": "Insert documents",
"type": "main",
"index": 0
}
]
]
},
"Create Tweet": {
"main": [
[
{
"node": "Send a success reply",
"type": "main",
"index": 0
}
],
[
{
"node": "Send a failed reply",
"type": "main",
"index": 0
}
]
]
},
"Find documents": {
"main": [
[
{
"node": "Aggregate1",
"type": "main",
"index": 0
}
]
]
},
"Get tweet data": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Basic LLM Chain": {
"main": [
[
{
"node": "Create Tweet",
"type": "main",
"index": 0
}
]
]
},
"Community filter": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "If3",
"type": "main",
"index": 0
}
]
]
},
"Get dataset items": {
"main": [
[
{
"node": "If2",
"type": "main",
"index": 0
}
]
]
},
"modify tweet data": {
"main": [
[
{
"node": "Basic LLM Chain",
"type": "main",
"index": 0
}
]
]
},
"Send a failed reply": {
"main": [
[
{
"node": "parse reply",
"type": "main",
"index": 0
}
]
]
},
"Search keyword actor": {
"main": [
[
{
"node": "Get dataset items",
"type": "main",
"index": 0
}
]
]
},
"Send a success reply": {
"main": [
[
{
"node": "parse reply",
"type": "main",
"index": 0
}
]
]
},
"OpenRouter Chat Model": {
"ai_languageModel": [
[
{
"node": "Structured Output Parser",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Community search actor": {
"main": [
[
{
"node": "Get dataset items",
"type": "main",
"index": 0
}
]
]
},
"Keyword/Community List": {
"main": [
[
{
"node": "Randomized community, keyword",
"type": "main",
"index": 0
}
]
]
},
"OpenRouter Chat Model1": {
"ai_languageModel": [
[
{
"node": "Basic LLM Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Basic LLM Chain",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Increment Failure Counter": {
"main": [
[
{
"node": "Keyword/Community List",
"type": "main",
"index": 0
}
]
]
},
"Randomized community, keyword": {
"main": [
[
{
"node": "If4",
"type": "main",
"index": 0
}
]
]
},
"When Executed by Another Workflow": {
"main": [
[
{
"node": "modify tweet data",
"type": "main",
"index": 0
}
]
]
},
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Find documents",
"type": "main",
"index": 0
}
]
]
}
}
}
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.
apifyApimongoDbopenRouterApitelegramApitwitterOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
N8N Automated Twitter Reply Bot Workflow
Source: https://n8n.io/workflows/8410/ — 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 n8n workflow lets you effortlessly tailor your resume for any job using Telegram and LinkedIn. Simply send a LinkedIn job URL or paste a job description to the Telegram bot, and the workflow will
This workflow is ideal for individuals, marketers, agencies, and brands who want to effortlessly automate the entire blogging and social media process—from idea generation to promotion. Its primary go
This workflow is built for creators, solopreneurs, SaaS founders, and agencies looking to automate their social media content process from idea to publication. It combines the power of OpenAI, Google
Automatically scrape LinkedIn posts with Apify, transform them into optimized tweets and threads using Claude AI, store them in Airtable for approval, and publish to X on a daily schedule.
AI Social Media Publisher from WordPress. Uses manualTrigger, googleSheets, lmChatOpenRouter, outputParserStructured. Event-driven trigger; 20 nodes.