This workflow corresponds to n8n.io template #10322 — we link there as the canonical source.
This workflow follows the Agent → Form 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 →
{
"id": "0cppyRyk426a9Syl",
"name": "AI-Powered Twitter Automation with Content Generation and Engagement",
"tags": [],
"nodes": [
{
"id": "8e1cf93a-2686-4255-a52c-c587d1009c08",
"name": "Twitter Content Form",
"type": "n8n-nodes-base.formTrigger",
"position": [
528,
544
],
"parameters": {
"options": {
"path": "twitter-content-form",
"buttonLabel": "Generate Content"
},
"formTitle": "Twitter Content Generator",
"formFields": {
"values": [
{
"fieldLabel": "Topic/Niche",
"placeholder": "What topic or niche should the tweet be about?",
"requiredField": true
},
{
"fieldType": "dropdown",
"fieldLabel": "Tone",
"fieldOptions": {
"values": [
{
"option": "Casual"
},
{
"option": "Professional"
},
{
"option": "Normal"
},
{
"option": "Humorous"
}
]
},
"requiredField": true
},
{
"fieldType": "dropdown",
"fieldLabel": "Action Type",
"fieldOptions": {
"values": [
{
"option": "Post Tweet"
},
{
"option": "Engage with Posts"
},
{
"option": "Send Direct Message"
}
]
}
},
{
"fieldLabel": "Additional Instructions For Image(Prompt)",
"placeholder": "Any specific instructions for the AI?"
}
]
},
"formDescription": "Submit your content preferences for AI-powered Twitter automation"
},
"typeVersion": 2.3
},
{
"id": "0da7cb0f-a12a-46e6-9d19-30cc58df4da0",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
752,
544
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "imageGenerationChance",
"type": "number",
"value": 0.3
},
{
"id": "id-2",
"name": "maxTweetLength",
"type": "number",
"value": 280
},
{
"id": "id-3",
"name": "imageModelUrl",
"type": "string",
"value": "https://openrouter.ai/api/v1/images/generations"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "25a1ccc6-d24e-4bc0-a6e6-289d44ac2064",
"name": "Twitter Post Tool",
"type": "n8n-nodes-base.twitterTool",
"position": [
2496,
816
],
"parameters": {
"text": "={{ $fromAI('tweet_text', 'The tweet content to post', 'string') }}",
"additionalFields": {
"attachments": "binary:imageData"
}
},
"typeVersion": 2
},
{
"id": "dab13c9d-a7e2-48ba-8179-d75d82372fcc",
"name": "Twitter DM Tool",
"type": "n8n-nodes-base.twitterTool",
"position": [
2608,
816
],
"parameters": {
"text": "={{ $fromAI('dm_message', 'The direct message content', 'string') }}",
"user": {
"__rl": true,
"mode": "username",
"value": "={{ $fromAI('recipient_username', 'The username to send the DM to', 'string') }}"
},
"resource": "directMessage",
"additionalFields": {}
},
"typeVersion": 2
},
{
"id": "c32402c6-0a70-4988-9673-4952f30158eb",
"name": "Twitter AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2432,
576
],
"parameters": {
"text": "=Topic: {{ $json['Topic/Niche'] }}\nTone: {{ $json.Tone }}\nAction: {{ $json['Action Type'] }}\nAdditional Instructions: {{ $json['Additional Instructions'] }}\nMax Tweet Length: {{ $json.maxTweetLength }} characters",
"options": {
"systemMessage": "=You are a Twitter automation assistant that helps create engaging content and manage Twitter interactions.\n\nYour capabilities:\n1. **Post Tweets**: Create compelling tweets based on the given topic, niche, and tone. Keep tweets under the specified character limit. You can include an image that is provided as input when posting the tweet. You do not create or generate images yourself."
},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "2d3f7d79-844f-4642-940c-6c64ffb6094f",
"name": "Process AI Response",
"type": "n8n-nodes-base.code",
"position": [
2736,
576
],
"parameters": {
"jsCode": "// Extract and format the AI agent's response\nconst items = $input.all();\n\nconst processedResults = items.map((item, index) => {\n const agentResponse = item.json;\n \n return {\n json: {\n timestamp: new Date().toISOString(),\n itemIndex: index,\n agentOutput: agentResponse.output || agentResponse.text || '',\n fullResponse: agentResponse,\n status: 'processed'\n }\n };\n});\n\nreturn processedResults;"
},
"typeVersion": 2
},
{
"id": "0559c71c-7a6a-44a5-93a0-b7d148d07811",
"name": "Fields - Set Values",
"type": "n8n-nodes-base.set",
"position": [
992,
400
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "4e04fec4-441e-45f7-acea-0017a4b5c104",
"name": "model",
"type": "string",
"value": "flux"
},
{
"id": "aa80cd68-1c82-4032-b1d7-e098856eec38",
"name": "width",
"type": "string",
"value": "1080"
},
{
"id": "da6d305f-aece-49bd-ae02-52df59915c60",
"name": "height",
"type": "string",
"value": "1920"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a2e8982a-b501-435b-84b9-c2c86cda7cba",
"name": "Code - Clean Json",
"type": "n8n-nodes-base.code",
"position": [
1552,
400
],
"parameters": {
"jsCode": "function cleanAndExtractJSON(response) {\n try {\n const result = {\n image_prompt: []\n };\n\n const lines = response.split('\\n');\n let currentPrompt = '';\n\n for (const line of lines) {\n if (line.includes('\"prompt\":')) {\n if (currentPrompt) {\n result.image_prompt.push(currentPrompt.trim());\n }\n currentPrompt = line.split('\"prompt\":')[1].trim();\n }\n }\n\n if (currentPrompt) {\n result.image_prompt.push(currentPrompt.trim());\n }\n\n return { json: result };\n \n } catch (error) {\n return { \n json: {\n image_prompt: []\n }\n };\n }\n}\n\nconst response = $input.first().json.output;\nreturn cleanAndExtractJSON(response);"
},
"executeOnce": false,
"typeVersion": 2,
"alwaysOutputData": true
},
{
"id": "15ce60b3-2822-49b7-8a80-e9709d33f9a4",
"name": "Code - Get Prompt",
"type": "n8n-nodes-base.code",
"position": [
1744,
400
],
"parameters": {
"jsCode": "return $input.first().json.image_prompt.map(prompt => ({\n json: {\n body: {\n prompt: prompt,\n \"image_size\": {\n \"width\": $('Fields - Set Values').first().json.width,\n \"height\": $('Fields - Set Values').first().json.height\n },\n \"num_inference_steps\": 12,\n \"guidance_scale\": 3.5,\n \"num_images\": 1,\n \"enable_safety_checker\": true,\n}\n }\n }\n));"
},
"typeVersion": 2,
"alwaysOutputData": true
},
{
"id": "df0bd8e3-bab9-401a-a611-dea217d059d0",
"name": "HTTP Request - Create Image",
"type": "n8n-nodes-base.httpRequest",
"position": [
2128,
400
],
"parameters": {
"url": "=https://image.pollinations.ai/prompt/ {{ $('Code - Get Prompt').item.json.body.prompt }}",
"options": {
"response": {
"response": {
"responseFormat": "file",
"outputPropertyName": "imageData"
}
}
},
"jsonQuery": "={\n \"width\": {{ $('Fields - Set Values').item.json.width }},\n \"height\": {{ $('Fields - Set Values').item.json.height }},\n \"model\": \"{{ $('Fields - Set Values').item.json.model }}\",\n \"seed\": 42,\n \"nologo\": true\n}",
"sendQuery": true,
"sendHeaders": true,
"specifyQuery": "json",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Accept",
"value": "application/json"
}
]
}
},
"retryOnFail": true,
"typeVersion": 4.2,
"alwaysOutputData": true,
"waitBetweenTries": 5000
},
{
"id": "7e832f3a-b2fa-4d36-9eab-399480545267",
"name": "Code - Set Filename",
"type": "n8n-nodes-base.code",
"position": [
1904,
400
],
"parameters": {
"jsCode": "for (let i = 0; i < items.length; i++) {\n items[i].json.fileName = `images_${(i + 1).toString().padStart(3, '0')}.png`;\n}\nreturn items;"
},
"typeVersion": 2
},
{
"id": "4932d5ff-7acc-4129-b376-cb8061042bf8",
"name": "AI Agent - Create Image From Prompt",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1232,
400
],
"parameters": {
"text": "={{ $('Workflow Configuration').item.json['Additional Instructions'] }}",
"options": {
"systemMessage": "=You are an AI image-prompt creation expert. Please create a post using the following JSON format:\nAI Image Generation Prompt Guidelines:\nObjective\nCreate highly realistic, high\u2010quality images\nEnsure the image content faithfully conveys the spirit of the original text\nIntegrate short text (10\u201320 characters) naturally into the image\nMaintain consistency and professionalism\n\nStandard Prompt Structure\n[Main Scene] | [Key Elements] | [Text Integration] | [Lighting & Atmosphere] | [Technical Parameters] | [Style Parameters]\n\nComponent Breakdown\n1. Main Scene (Weight ::8)\nDescribe the primary setting in line with the content.\nExamples:\nTech news: \u201cmodern tech office setting, minimalist workspace\u201d\nEconomy news: \u201cprofessional financial district, corporate environment\u201d\nEducation news: \u201cmodern classroom, advanced learning environment\u201d\n\n2. Key Elements (Weight ::8)\nList the main visual elements required.\nExamples:\n\u201clarge HD display showing text \u2018AI Ethics\u2019 in modern typography\u201d\n\u201cprofessional people in business attire discussing around interactive screen\u201d\n\u201cdetailed infographic elements floating in augmented reality style\u201d\n\n3. Text Integration (Weight ::7)\nHow to display text within the image:\ntext elements | elegant typography, clear readable text, integrated naturally into scene ::7\n\n4. Lighting & Atmosphere (Weight ::7)\nlighting | cinematic dramatic lighting, natural ambient light, professional studio setup ::7\nbackground | depth of field blur, clean professional environment ::6\n\n5. Technical Parameters\nparameters | 8k resolution, hyperrealistic, photorealistic quality, octane render, cinematic composition --ar 16:9\nsettings | sharp focus, high detail, professional photography --s 1000 --q 2\nComplete Examples\nExample 1: AI Ethics News\nprofessional tech conference room | large display showing \"AI Ethics Now\" in modern typography, group of diverse executives in discussion ::8 | clean modern workspace, glass walls, tech atmosphere ::7 | cinematic lighting, natural window light ::7 | 8k resolution, hyperrealistic quality, octane render --ar 16:9 --s 1000 --q 2\nExample 2: Financial Market News\nmodern stock exchange environment | giant LED wall showing \"Market Alert\" in bold typography, professional traders in action ::8 | dynamic financial data visualization, sleek modern interior ::7 | dramatic lighting, blue-tinted atmosphere ::7 | 8k resolution, photorealistic quality --ar 16:9 --s 1000 --q 2\n\nAdditional Parameters\n--chaos [0\u2013100]: Adjust randomness\n--stylize [0\u20131000]: Degree of stylization\n--seed [number]: Ensure consistency across generations\n--niji: Optimized for Asian\u2010style aesthetics\n--v 5.2: Use the latest model version\n\nImportant Notes\nText in Image\nKeep it short and legible\nUse professional fonts\nIntegrate naturally into the scene\n\nComposition\nFollow the rule of thirds\nEnsure a clear focal point\nBalance text and imagery\n\nColor\nMatch a professional tone\nProvide sufficient contrast for readability\nMaintain visual consistency\n\nTechnical Details\nAlways use high resolution (8k)\nEnsure professional lighting\nOptimize for sharpness and detail\n\nCommon Pitfalls to Avoid\nOverly generic prompts\nMissing text\u2010integration guidance\nFailing to specify composition rules\nOmitting key technical parameters\n\nThe structure is:\n{\n prompt_image {prompt : \"\" , ...}\n}"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "2153e1ab-de35-4e2f-a5e5-1ff44443a6ba",
"name": "Google Gemini Chat Model2",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1232,
560
],
"parameters": {
"options": {
"topK": 40,
"topP": 1,
"temperature": 0.5,
"safetySettings": {
"values": [
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_NONE"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_NONE"
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_NONE"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_NONE"
}
]
},
"maxOutputTokens": 65536
},
"modelName": "models/gemini-2.0-flash"
},
"typeVersion": 1
},
{
"id": "d4020d18-38e6-46d6-b253-b4305e25bf52",
"name": "Twitter Engagement Tool",
"type": "n8n-nodes-base.twitterTool",
"position": [
2720,
816
],
"parameters": {
"tweetId": {
"__rl": true,
"mode": "id",
"value": "={{ $fromAI('tweet_id', 'The ID of the tweet to like, retweet, or reply to', 'string') }}"
},
"operation": "like"
},
"typeVersion": 2
},
{
"id": "9485ce18-f55e-461a-b49f-c20f5e0b2f8a",
"name": "Create Tweet",
"type": "n8n-nodes-base.twitter",
"position": [
3136,
400
],
"parameters": {
"text": "={{ $('Twitter AI Agent').first().json.output }}",
"additionalFields": {}
},
"typeVersion": 2
},
{
"id": "b2d84a23-05ee-4642-a3be-9b8821ebfa81",
"name": "Merge Tweet Text and Image",
"type": "n8n-nodes-base.merge",
"position": [
2496,
384
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "2637e5e1-f6a1-4780-ad62-70c5591d6a79",
"name": "Google Gemini Chat Model3",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
2400,
816
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash"
},
"typeVersion": 1
},
{
"id": "c3c7a659-1423-4d54-82d6-d69e427d5a84",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1872,
128
],
"parameters": {
"color": 6,
"width": 420,
"height": 604,
"content": "## **Image Generated Output**\nThis HTTP node returns the generated image as a binary (property: **imageData**). In the execution output, click **Binary > imageData > View** to preview.\n\n**Heads-up:** Images are created via an external API (Pollinations). Check the service terms and ensure usage complies with your policies."
},
"typeVersion": 1
},
{
"id": "b06e67ba-79c7-465e-8059-b47fa7e0c650",
"name": "Sticky \u2013 Twitter Form",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
128
],
"parameters": {
"color": 5,
"width": 492,
"height": 600,
"content": "## Twitter Form & Config\n**Trigger:** *Twitter Content Form* (public webhook path `twitter-content-form`)\n**Config:** *Workflow Configuration* sets shared constants like `maxTweetLength` and image defaults.\n\n**What to fill:**\n- Choose **Tone** & **Action Type** (Post, Engage, DM)\n- Add optional **Additional Instructions For Image(Prompt)**\n\n**Security tip:** Protect the webhook (IP allow-list, secret path) for production."
},
"typeVersion": 1
},
{
"id": "149b85fd-1623-4819-8cfd-968d5bf3a18a",
"name": "Sticky \u2013 Twitter AI",
"type": "n8n-nodes-base.stickyNote",
"position": [
2304,
560
],
"parameters": {
"color": 7,
"width": 600,
"height": 608,
"content": "\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\n\n## Twitter Content AI\n**Nodes:** *Twitter AI Agent* \u2192 *Process AI Response*\n\n**Purpose:** Generates tweet text (and parameters for tools) from the form input. The AI output is passed forward; `Process AI Response` wraps it with metadata.\n\n**Note:** The `twitterTool` nodes (Post/DM/Engage) are exposed to the AI via tool connectors. Ensure they are authorized before enabling in prod."
},
"typeVersion": 1
},
{
"id": "d9e44007-bc90-4b4c-a117-803562a10afa",
"name": "Sticky \u2013 Image Gen Flow",
"type": "n8n-nodes-base.stickyNote",
"position": [
960,
128
],
"parameters": {
"color": 6,
"width": 892,
"height": 596,
"content": "## Optional Image Generation Path\n**Nodes:** *Fields - Set Values* \u2192 *AI Agent - Create Image From Prompt* \u2192 *Code - Clean Json* \u2192 *Code - Get Prompt* \u2192 *Code - Set Filename* \u2192 *HTTP Request - Create Image*\n\n**What it does:** Converts user \"Additional Instructions\" into **image prompts**, then calls an image API and attaches binary `imageData`.\n\n**Usage in Tweets:** *Merge Tweet Text and Image* combines text + image. *Create Tweet* can then include the binary as an attachment.\n\n**Tip:** Swap the image API URL or parameters to your preferred service."
},
"typeVersion": 1
},
{
"id": "aa00fd60-272a-40fd-8d28-95dd4bfa5832",
"name": "Sticky \u2013 Twitter Actions",
"type": "n8n-nodes-base.stickyNote",
"position": [
2800,
128
],
"parameters": {
"color": 6,
"width": 464,
"height": 408,
"content": "## Posting/DM/Engagement\n**Nodes:** *Twitter Post Tool*, *Twitter DM Tool*, *Twitter Engagement Tool*, *Create Tweet*\n\n- **Create Tweet:** Posts the generated tweet text (and image when merged).\n- **Post/DM/Engage Tools:** Can be invoked by the AI with structured arguments.\n\n**Before publishing:**\n- Connect your **Twitter/X credentials**.\n- Test in a sandbox account.\n- Respect rate limits and platform policies."
},
"typeVersion": 1
},
{
"id": "0e1dfb5b-22bb-4de8-b308-63c34b3f3e86",
"name": "Sticky \u2013 Credentials",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
752
],
"parameters": {
"color": 4,
"width": 488,
"height": 284,
"content": "## Credentials & Environment\n**Required:**\n- **Reddit OAuth2** \u2013 for search & commenting\n- **Google Sheets OAuth2** \u2013 for saving results\n- **Google Gemini** \u2013 for AI agents\n- **Twitter/X** \u2013 for posting/DM/engagement (if you enable those nodes)\n\n**Set these in n8n Credentials** and test each connection.\n\n**Note:** External image API (Pollinations) requires outbound HTTP; replace with your own if needed."
},
"typeVersion": 1
},
{
"id": "dc096eb0-7f37-4dfc-8c24-bef1e1dc2acf",
"name": "Sticky \u2013 Merge & Tweet",
"type": "n8n-nodes-base.stickyNote",
"position": [
2320,
128
],
"parameters": {
"color": 2,
"width": 468,
"height": 412,
"content": "## Merge & Publish (Twitter)\n**Node:** *Merge Tweet Text and Image*\nCombines text from the AI with optional `imageData` from the image flow. Downstream *Create Tweet* will post the composed content.\n\n**Tip:** If you want image-optional posting, add an IF check for `imageData` before Merge."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "a6591255-d7b1-4591-8683-4bc3e546b199",
"connections": {
"Twitter DM Tool": {
"ai_tool": [
[
{
"node": "Twitter AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Twitter AI Agent": {
"main": [
[
{
"node": "Process AI Response",
"type": "main",
"index": 0
},
{
"node": "Merge Tweet Text and Image",
"type": "main",
"index": 0
}
]
]
},
"Code - Clean Json": {
"main": [
[
{
"node": "Code - Get Prompt",
"type": "main",
"index": 0
}
]
]
},
"Code - Get Prompt": {
"main": [
[
{
"node": "Code - Set Filename",
"type": "main",
"index": 0
}
]
]
},
"Twitter Post Tool": {
"ai_tool": [
[
{
"node": "Twitter AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Code - Set Filename": {
"main": [
[
{
"node": "HTTP Request - Create Image",
"type": "main",
"index": 0
}
]
]
},
"Fields - Set Values": {
"main": [
[
{
"node": "AI Agent - Create Image From Prompt",
"type": "main",
"index": 0
}
]
]
},
"Process AI Response": {
"main": [
[
{
"node": "Create Tweet",
"type": "main",
"index": 0
}
]
]
},
"Twitter Content Form": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "Twitter AI Agent",
"type": "main",
"index": 0
},
{
"node": "Fields - Set Values",
"type": "main",
"index": 0
}
]
]
},
"Twitter Engagement Tool": {
"ai_tool": [
[
{
"node": "Twitter AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Google Gemini Chat Model2": {
"ai_languageModel": [
[
{
"node": "AI Agent - Create Image From Prompt",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Google Gemini Chat Model3": {
"ai_languageModel": [
[
{
"node": "Twitter AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Merge Tweet Text and Image": {
"main": [
[
{
"node": "Create Tweet",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request - Create Image": {
"main": [
[
{
"node": "Merge Tweet Text and Image",
"type": "main",
"index": 1
}
]
]
},
"AI Agent - Create Image From Prompt": {
"main": [
[
{
"node": "Code - Clean Json",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n template automates Twitter (X) activity — from generating tweet content with AI to engaging with posts and even sending DMs — all powered by Google Gemini or OpenRouter AI.
Source: https://n8n.io/workflows/10322/ — 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 template is perfect for content creators, marketers, solopreneurs, agencies, and social media strategists who want to understand what audiences are talking about online. It helps teams quickly tu
How it works: This end-to-end workflow automates your personal or brand content strategy by: 🧠 Using Google Gemini or OpenAI to generate engaging LinkedIn/X content from a title or trending posts. 🗓️
How it Works
This automated workflow template transforms a single product image into a complete professional advertisement video with dynamic motion and custom soundtrack. Perfect for e-commerce businesses, market
This workflow is designed for marketers, content creators, agencies, and solo founders who want to publish long‑form posts with visuals on autopilot using n8n and AI agents.