This workflow follows the Agent → Chainllm 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 →
{
"name": "PixelSensei(ZH)",
"nodes": [
{
"parameters": {
"promptType": "define",
"text": "={{ $('User Input').item.json.topic }}",
"hasOutputParser": true,
"options": {
"systemMessage": "={{ $('Extract Character Config').item.json.planningPrompt }}\n\nDo NOT refuse the topic. Your job is to explain it regardless of the domain.\n\n**Language Rule**: Detect the language of the user's input and respond in the SAME language. If the user writes in Chinese, respond in Chinese. If the user writes in English, respond in English."
}
},
"id": "7f222b40-90e1-4162-bc87-6eba458bfe69",
"name": "Planning Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
-43280,
-21408
],
"retryOnFail": true,
"maxTries": 5
},
{
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"topic\": {\n \"type\": \"string\",\n \"description\": \"The technical concept to explain\"\n },\n \"complexity\": {\n \"type\": \"string\",\n \"description\": \"Complexity level: simple, medium, complex, or systematic\"\n },\n \"totalPages\": {\n \"type\": \"number\",\n \"description\": \"Total number of comic pages to generate\"\n },\n \"artStyle\": {\n \"type\": \"string\",\n \"description\": \"Art style: manga, minimal, cyberpunk, or sketch\"\n },\n \"coreAnalogy\": {\n \"type\": \"string\",\n \"description\": \"Main analogy or metaphor to explain the concept\"\n },\n \"pages\": {\n \"type\": \"array\",\n \"description\": \"Array of page objects with flexible dialogue and technical content structure\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"pageNumber\": {\n \"type\": \"number\",\n \"description\": \"Page number in sequence\"\n },\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Page title\"\n },\n \"scene\": {\n \"type\": \"string\",\n \"description\": \"Scene description and setting\"\n },\n \"dialogue\": {\n \"type\": \"array\",\n \"description\": \"Array of dialogue objects with character and text\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"character\": {\n \"type\": \"string\",\n \"description\": \"Character name (e.g., Rick Sanchez, Morty Smith)\"\n },\n \"text\": {\n \"type\": \"string\",\n \"description\": \"Dialogue text for this character\"\n }\n },\n \"required\": [\"character\", \"text\"]\n }\n },\n \"visualElements\": {\n \"type\": \"string\",\n \"description\": \"Visual elements and actions in the panel\"\n },\n \"technicalSection\": {\n \"type\": \"object\",\n \"description\": \"Technical content section with title and detailed content\",\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Title of the technical section\"\n },\n \"content\": {\n \"type\": \"string\",\n \"description\": \"Detailed technical explanation or diagram description\"\n }\n },\n \"required\": [\"title\", \"content\"]\n },\n \"learningPoint\": {\n \"type\": \"object\",\n \"description\": \"Key learning takeaway from this page\",\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Title of the learning point\"\n },\n \"content\": {\n \"type\": \"string\",\n \"description\": \"Detailed learning point explanation\"\n }\n },\n \"required\": [\"title\", \"content\"]\n }\n },\n \"required\": [\"pageNumber\", \"title\", \"scene\", \"dialogue\", \"visualElements\", \"learningPoint\"]\n }\n }\n },\n \"required\": [\"topic\", \"complexity\", \"totalPages\", \"artStyle\", \"coreAnalogy\", \"pages\"]\n}",
"autoFix": true
},
"id": "71ec8bb8-4df4-4869-99f0-01c3e606ac1f",
"name": "Comic Plan Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"typeVersion": 1.3,
"position": [
-43104,
-21136
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "topic",
"value": "={{ $json.output.topic }}",
"type": "string"
},
{
"id": "id-2",
"name": "complexity",
"value": "={{ $json.output.complexity }}",
"type": "string"
},
{
"id": "id-3",
"name": "totalPages",
"value": "={{ $json.output.totalPages }}",
"type": "number"
},
{
"id": "id-4",
"name": "artStyle",
"value": "={{ $json.output.artStyle }}",
"type": "string"
},
{
"id": "id-5",
"name": "coreAnalogy",
"value": "={{ $json.output.coreAnalogy }}",
"type": "string"
},
{
"id": "id-6",
"name": "pages",
"value": "={{ JSON.stringify($json.output.pages) }}",
"type": "array"
}
]
},
"includeOtherFields": true,
"options": {}
},
"id": "d320f205-55d0-4f42-8c0e-c6a724c70d6e",
"name": "Extract Plan Data",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-42912,
-21408
]
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const planData = $input.item.json;\n// \u83b7\u53d6\u5b9e\u9645\u7684\u9875\u9762\u6570\u7ec4\nconst pages = Array.isArray(planData.pages) ? planData.pages : [];\n\n// \u2b50 \u5173\u952e\u70b9\uff1a\u76f4\u63a5\u8ba1\u7b97\u5b9e\u9645\u751f\u6210\u7684\u9875\u6570\uff08\u6bd4\u5982 12\uff09\n// \u4e0d\u8981\u5b8c\u5168\u4fe1\u4efb planData.totalPages\uff0c\u4ee5\u6570\u7ec4\u5b9e\u9645\u957f\u5ea6\u4e3a\u51c6\nconst actualTotalCount = pages.length;\n\nreturn {\n output: pages\n .filter(page => page && typeof page === 'object' && !Array.isArray(page))\n .map(page => ({\n json: {\n ...page,\n // \u628a\u7236\u7ea7\u7684\u901a\u7528\u5c5e\u6027\u5e26\u4e0b\u6765\n topic: planData.topic,\n artStyle: planData.artStyle,\n \n // \u2b50 \u6ce8\u5165\u603b\u9875\u6570\uff01\u8fd9\u6837\u6bcf\u4e00\u9875\u90fd\u77e5\u9053\u603b\u6570\u662f\u591a\u5c11\n totalPages: actualTotalCount \n }\n }))\n};"
},
"id": "b4eac772-9642-46a1-bd93-47a461fa6dfa",
"name": "Split Pages into Items",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-42688,
-21408
]
},
{
"parameters": {
"fieldToSplitOut": "output",
"options": {}
},
"type": "n8n-nodes-base.splitOut",
"typeVersion": 1,
"position": [
-42416,
-21408
],
"id": "63779125-2a45-4213-a4cc-6cd05e536407",
"name": "Split Out"
},
{
"parameters": {
"content": "#### \u914d\u7f6e Gemini Header Auth \ud83d\udc47",
"height": 80,
"width": 246,
"color": 3
},
"id": "23666ad9-d342-4b92-8f4d-4c754b2b7fc0",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
-42240,
12480
],
"typeVersion": 1
},
{
"parameters": {
"jsCode": "// HTML Assembler - Combine all pages into main HTML template\nconst inputItems = $input.all();\nconst firstItem = inputItems[0];\nconst allPages = firstItem.json.data || [];\n\n// Add check for empty pages data\nif (allPages.length === 0) {\n console.error('HTML Assembler - No pages data found');\n return [{\n json: {\n error: 'No pages data available'\n }\n }];\n}\n\nconsole.log('HTML Assembler - Data structure:', {\n totalInputItems: inputItems.length,\n hasDataArray: !!firstItem.json.data,\n dataArrayLength: firstItem.json.data?.length\n});\n\n// Debug: Log first page data\nconsole.log('HTML Assembler - First page data:', JSON.stringify({\n mentorName: allPages[0]?.mentorName,\n learnerName: allPages[0]?.learnerName,\n mainTitle: allPages[0]?.mainTitle,\n hasDialogueHTML: !!allPages[0]?.dialogueHTML,\n hasPageHTML: !!allPages[0]?.pageHTML\n}));\n\n// Get comic metadata from first page\nconst comicData = allPages[0];\nconsole.log(\"#####\")\nconsole.log(allPages)\nconsole.log(\"#####\")\n// Collect all page HTML - Fixed to properly extract pageHTML from data array\nconst allPagesHTML = allPages\n .map(page => {\n const pageObj = page;\n return pageObj.pageHTML || '';\n })\n .filter(html => html.trim() !== '')\n .join('\\n\\n');\n\n// Read main HTML template\nconst mainTemplate = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>{{TITLE}} - Tech Comic</title>\n <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);\n color: #e2e8f0;\n line-height: 1.6;\n min-height: 100vh;\n padding: 20px;\n }\n\n .container {\n max-width: 1200px;\n margin: 0 auto;\n }\n\n header {\n text-align: center;\n margin-bottom: 40px;\n padding: 30px;\n background: rgba(30, 41, 59, 0.8);\n border-radius: 20px;\n border: 1px solid rgba(148, 163, 184, 0.2);\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);\n }\n\n h1 {\n font-size: 2.8rem;\n background: linear-gradient(90deg, #60a5fa, #a78bfa);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n margin-bottom: 15px;\n text-shadow: 0 2px 10px rgba(96, 165, 250, 0.3);\n }\n\n .subtitle {\n font-size: 1.2rem;\n color: #94a3b8;\n margin-bottom: 20px;\n }\n\n .stats {\n display: flex;\n justify-content: center;\n gap: 30px;\n margin-top: 20px;\n flex-wrap: wrap;\n }\n\n .stat-item {\n background: rgba(51, 65, 85, 0.6);\n padding: 15px 25px;\n border-radius: 12px;\n border: 1px solid rgba(148, 163, 184, 0.2);\n }\n\n .stat-label {\n font-size: 0.9rem;\n color: #94a3b8;\n margin-bottom: 5px;\n }\n\n .stat-value {\n font-size: 1.4rem;\n font-weight: bold;\n color: #60a5fa;\n }\n\n .intro-box {\n background: rgba(96, 165, 250, 0.1);\n border: 1px solid rgba(96, 165, 250, 0.3);\n border-radius: 15px;\n padding: 25px;\n margin-bottom: 40px;\n text-align: center;\n }\n\n .intro-box h3 {\n color: #60a5fa;\n margin-bottom: 10px;\n font-size: 1.4em;\n }\n\n .intro-box p {\n color: #94a3b8;\n font-size: 1.1em;\n line-height: 1.6;\n }\n\n .page {\n margin: 40px 0;\n padding: 30px;\n border-radius: 15px;\n background: rgba(255,255,255,0.02);\n border-left: 5px solid #60a5fa;\n box-shadow: 0 5px 20px rgba(0,0,0,0.2);\n transition: all 0.3s ease;\n }\n\n .page:hover {\n transform: translateX(5px);\n box-shadow: 0 8px 30px rgba(96, 165, 250, 0.2);\n }\n\n .page:nth-child(even) {\n border-left-color: #a78bfa;\n }\n\n .page-header {\n display: flex;\n align-items: center;\n gap: 20px;\n margin-bottom: 25px;\n justify-content: space-between;\n }\n\n .page-number {\n background: linear-gradient(45deg, #60a5fa, #3b82f6);\n color: white;\n width: 50px;\n height: 50px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.4em;\n font-weight: bold;\n box-shadow: 0 4px 15px rgba(96, 165, 250, 0.4);\n flex-shrink: 0;\n }\n\n .page:nth-child(even) .page-number {\n background: linear-gradient(45deg, #a78bfa, #9333ea);\n box-shadow: 0 4px 15px rgba(167, 139, 250, 0.4);\n }\n\n .page-title {\n color: #60a5fa;\n font-size: 1.6em;\n font-weight: bold;\n }\n\n .page:nth-child(even) .page-title {\n color: #a78bfa;\n }\n\n .page-content {\n display: flex;\n flex-wrap: wrap;\n gap: 30px;\n align-items: flex-start;\n }\n\n .page-image {\n flex: 1;\n min-width: 300px;\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 10px 30px rgba(0,0,0,0.3);\n border: 2px solid rgba(255,255,255,0.1);\n transition: all 0.3s ease;\n }\n\n .page-image:hover {\n transform: scale(1.02);\n box-shadow: 0 15px 40px rgba(96, 165, 250, 0.3);\n }\n\n .page-image img {\n width: 100%;\n height: auto;\n display: block;\n }\n\n .page-image-container {\n flex: 1;\n min-width: 310px;\n padding: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(15, 23, 42, 0.7);\n }\n\n .page-info {\n flex: 1;\n padding: 20px;\n background: rgba(15, 23, 42, 0.9);\n }\n\n .page-desc {\n font-size: 1rem;\n color: #94a3b8;\n margin-bottom: 20px;\n line-height: 1.5;\n }\n\n .dialogue-section {\n margin-bottom: 25px;\n }\n\n .section-title {\n font-size: 1rem;\n color: #60a5fa;\n margin-bottom: 15px;\n text-transform: uppercase;\n letter-spacing: 1px;\n }\n\n .dialogue-item {\n margin-bottom: 15px;\n padding: 12px 15px;\n background: rgba(51, 65, 85, 0.6);\n border-radius: 10px;\n border-left: 4px solid;\n }\n\n /* Rick - Blue theme */\n .dialogue-item.role-learner {\n border-left-color: #60a5fa;\n }\n\n /* Morty - Yellow theme */\n .dialogue-item.role-mentor {\n border-left-color: #fbbf24;\n }\n\n .character {\n font-weight: bold;\n margin-bottom: 5px;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .character.role-learner {\n color: #60a5fa;\n }\n\n .character.role-mentor {\n color: #fbbf24;\n }\n\n .character-emoji {\n font-size: 1.2rem;\n }\n\n .dialogue-text {\n color: #e2e8f0;\n font-size: 0.95rem;\n }\n\n .tech-section {\n margin-top: 20px;\n margin-bottom: 20px;\n }\n\n .tech-box {\n background: rgba(51, 65, 85, 0.6);\n border-radius: 10px;\n padding: 15px;\n }\n\n .tech-label {\n font-size: 0.9rem;\n color: #94a3b8;\n margin-bottom: 8px;\n text-transform: uppercase;\n letter-spacing: 1px;\n }\n\n .tech-content {\n color: #a78bfa;\n font-family: 'Courier New', monospace;\n font-size: 0.9rem;\n background: rgba(15, 23, 42, 0.6);\n padding: 10px;\n border-radius: 8px;\n border: 1px solid rgba(167, 139, 250, 0.3);\n }\n\n .learning-section {\n margin-top: 20px;\n background: rgba(34, 197, 94, 0.1);\n border-left: 4px solid #22c55e;\n border-radius: 10px;\n padding: 15px;\n }\n\n .learning-content {\n color: #e2e8f0;\n font-size: 0.95rem;\n line-height: 1.6;\n margin-top: 10px;\n }\n\n footer {\n text-align: center;\n margin-top: 50px;\n padding-top: 30px;\n border-top: 1px solid rgba(255,255,255,0.1);\n color: #666;\n }\n\n .footer-icons {\n display: flex;\n justify-content: center;\n gap: 15px;\n margin-bottom: 15px;\n font-size: 1.5em;\n }\n .footer-honest {\n background: linear-gradient(180deg, rgba(15, 23, 42, 0.8) 0%, rgba(2, 6, 23, 0.95) 100%);\n border-top: 1px solid rgba(148, 163, 184, 0.15);\n padding: 50px 20px 30px;\n margin-top: 80px;\n }\n \n .footer-container {\n max-width: 900px;\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n gap: 35px;\n }\n \n /* \u54c1\u724c\u533a\u57df */\n .footer-brand {\n text-align: center;\n }\n \n .brand-header {\n display: inline-flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 12px;\n }\n \n .brand-icon {\n font-size: 2rem;\n }\n \n .brand-name {\n font-size: 1.4rem;\n font-weight: 600;\n background: linear-gradient(90deg, #60a5fa, #a78bfa);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n }\n \n .brand-tagline {\n color: #94a3b8;\n font-size: 1rem;\n line-height: 1.6;\n max-width: 650px;\n margin: 0 auto;\n }\n \n /* CTA \u6309\u94ae\u533a\u57df */\n .footer-actions {\n display: flex;\n justify-content: center;\n gap: 15px;\n flex-wrap: wrap;\n }\n \n .btn-primary {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n background: linear-gradient(135deg, #60a5fa, #3b82f6);\n color: white;\n padding: 14px 28px;\n border-radius: 10px;\n text-decoration: none;\n font-weight: 600;\n font-size: 0.95rem;\n transition: all 0.3s ease;\n box-shadow: 0 4px 15px rgba(96, 165, 250, 0.3);\n }\n \n .btn-primary:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(96, 165, 250, 0.4);\n }\n \n .btn-secondary {\n display: inline-flex;\n align-items: center;\n color: #94a3b8;\n padding: 14px 28px;\n border: 1px solid rgba(148, 163, 184, 0.3);\n border-radius: 10px;\n text-decoration: none;\n font-weight: 500;\n font-size: 0.95rem;\n transition: all 0.3s ease;\n }\n \n .btn-secondary:hover {\n border-color: #60a5fa;\n color: #60a5fa;\n background: rgba(96, 165, 250, 0.05);\n }\n \n /* \u6cd5\u5f8b\u4fe1\u606f\u533a\u57df */\n .footer-legal {\n text-align: center;\n padding-top: 30px;\n border-top: 1px solid rgba(148, 163, 184, 0.1);\n }\n \n .legal-text {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n \n .legal-text p {\n color: #64748b;\n font-size: 0.875rem;\n }\n \n .legal-text a {\n color: #60a5fa;\n text-decoration: none;\n transition: color 0.2s;\n }\n \n .legal-text a:hover {\n color: #93c5fd;\n text-decoration: underline;\n }\n \n .disclaimer {\n font-size: 0.8rem !important;\n color: #475569 !important;\n font-style: italic;\n }\n \n @media (max-width: 640px) {\n .footer-actions {\n flex-direction: column;\n width: 100%;\n }\n \n .btn-primary,\n .btn-secondary {\n width: 100%;\n justify-content: center;\n }\n \n .brand-tagline {\n font-size: 0.9rem;\n }\n }\n @media (max-width: 768px) {\n .page-content {\n flex-direction: column;\n }\n\n .page-image, .page-text {\n min-width: 100%;\n }\n\n h1 {\n font-size: 2em;\n }\n\n .page-title {\n font-size: 1.3em;\n }\n\n .meta-info {\n flex-direction: column;\n align-items: center;\n }\n }\n </style>\n\n <!-- \u4e3b\u9898\u5207\u6362\u5668\u6837\u5f0f -->\n <style>\n /* \u4e3b\u9898\u5207\u6362\u5668\u6837\u5f0f */\n .theme-switcher {\n position: fixed;\n top: 20px;\n right: 20px;\n background: rgba(30, 41, 59, 0.95);\n border-radius: 15px;\n padding: 10px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);\n backdrop-filter: blur(10px);\n z-index: 1000;\n border: 1px solid rgba(148, 163, 184, 0.2);\n }\n\n .switcher-label {\n color: #94a3b8;\n font-size: 0.85rem;\n margin-bottom: 10px;\n text-align: center;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 1px;\n }\n\n .theme-options {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .theme-btn {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 10px;\n background: rgba(51, 65, 85, 0.6);\n border: 2px solid transparent;\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.3s ease;\n min-width: 140px;\n }\n\n .theme-btn:hover {\n background: rgba(51, 65, 85, 0.9);\n border-color: rgba(96, 165, 250, 0.5);\n transform: translateX(-3px);\n }\n\n .theme-btn.active {\n border-color: #60a5fa;\n background: rgba(96, 165, 250, 0.15);\n box-shadow: 0 0 15px rgba(96, 165, 250, 0.3);\n }\n\n .theme-preview {\n width: 30px;\n height: 30px;\n border-radius: 8px;\n display: block;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n }\n\n .theme-name {\n color: #e2e8f0;\n font-size: 0.9rem;\n font-weight: 500;\n }\n\n /* \u79fb\u52a8\u7aef\u4f18\u5316 */\n @media (max-width: 768px) {\n .theme-switcher {\n top: auto;\n bottom: 20px;\n right: 20px;\n left: 20px;\n }\n \n .theme-options {\n flex-direction: row;\n flex-wrap: wrap;\n }\n \n .theme-btn {\n flex: 1;\n min-width: auto;\n }\n \n .theme-name {\n display: none;\n }\n }\n </style>\n \n <!-- \u52a8\u6001\u4e3b\u9898\u5bb9\u5668 -->\n <style id=\"dynamic-theme\"></style>\n\n <script>\n // \u4e3b\u9898\u5207\u6362\u903b\u8f91\n const themeStyles = {\n default: \\`/* \u5f53\u524d\u7684\u9ed8\u8ba4 CSS */\\`,\n cyberpunk: \\`{{CYBERPUNK_CSS}}\\`,\n minimal: \\`{{MINIMAL_CSS}}\\`,\n };\n\n // \u7b49\u5f85 DOM \u52a0\u8f7d\u5b8c\u6210\n document.addEventListener('DOMContentLoaded', function() {\n // \u521d\u59cb\u5316\u4e3b\u9898\n const savedTheme = localStorage.getItem('preferredTheme') || 'default';\n applyTheme(savedTheme);\n \n // \u66f4\u65b0\u6309\u94ae\u72b6\u6001\n updateActiveButton(savedTheme);\n \n // \u7ed1\u5b9a\u6309\u94ae\u4e8b\u4ef6\n document.querySelectorAll('.theme-btn').forEach(btn => {\n btn.addEventListener('click', function() {\n const theme = this.dataset.theme;\n applyTheme(theme);\n updateActiveButton(theme);\n });\n });\n });\n\n // \u521d\u59cb\u5316\n let currentTheme = localStorage.getItem('preferredTheme') || 'default';\n applyTheme(currentTheme);\n\n // \u7ed1\u5b9a\u6309\u94ae\u4e8b\u4ef6\n document.querySelectorAll('.theme-btn').forEach(btn => {\n btn.addEventListener('click', () => {\n const theme = btn.dataset.theme;\n applyTheme(theme);\n \n // \u66f4\u65b0\u6309\u94ae\u72b6\u6001\n document.querySelectorAll('.theme-btn').forEach(b => b.classList.remove('active'));\n btn.classList.add('active');\n });\n });\n\n // \u5e94\u7528\u4e3b\u9898\n function applyTheme(themeName) {\n const styleTag = document.getElementById('dynamic-theme') || createStyleTag();\n styleTag.textContent = themeStyles[themeName];\n localStorage.setItem('preferredTheme', themeName);\n \n // \u6dfb\u52a0\u5207\u6362\u52a8\u753b - \u4fee\u590d\u540e\u7684\u7248\u672c\n if (document.body) {\n document.body.style.transition = 'opacity 0.15s ease';\n document.body.style.opacity = '0.95';\n setTimeout(() => {\n document.body.style.opacity = '1';\n }, 150);\n }\n }\n\n function createStyleTag() {\n const style = document.createElement('style');\n style.id = 'dynamic-theme';\n document.head.appendChild(style);\n return style;\n }\n // \u66f4\u65b0\u6309\u94ae\u6fc0\u6d3b\u72b6\u6001\n function updateActiveButton(themeName) {\n document.querySelectorAll('.theme-btn').forEach(btn => {\n if (btn.dataset.theme === themeName) {\n btn.classList.add('active');\n } else {\n btn.classList.remove('active');\n }\n });\n }\n </script>\n</head>\n<body>\n <div class=\"container\">\n <header>\n <h1>{{TITLE}}</h1>\n <p class=\"subtitle\">{{SUBTITLE}}</p>\n <div class=\"stats\">\n <div class=\"stat-item\">\n <div class=\"stat-label\">Characters</div>\n <div class=\"stat-value\">{{CHARACTERS}}</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-label\">Art Style</div>\n <div class=\"stat-value\">{{STYLE}}</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-label\">Complexity</div>\n <div class=\"stat-value\">{{COMPLEXITY}}</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-label\">Chapters</div>\n <div class=\"stat-value\">{{PAGE_COUNT}} Pages</div>\n </div>\n </div>\n </header>\n\n <div class=\"theme-switcher\">\n <div class=\"switcher-label\">\ud83c\udfa8 Theme</div>\n <div class=\"theme-options\">\n <button class=\"theme-btn active\" data-theme=\"default\">\n <span class=\"theme-preview\" style=\"background: linear-gradient(45deg, #60a5fa, #a78bfa)\"></span>\n <span class=\"theme-name\">Default</span>\n </button>\n <button class=\"theme-btn\" data-theme=\"cyberpunk\">\n <span class=\"theme-preview\" style=\"background: linear-gradient(45deg, #00f0ff, #ff006e)\"></span>\n <span class=\"theme-name\">Cyberpunk</span>\n </button>\n <button class=\"theme-btn\" data-theme=\"minimal\">\n <span class=\"theme-preview\" style=\"background: linear-gradient(45deg, #3b82f6, #8b5cf6)\"></span>\n <span class=\"theme-name\">Minimal</span>\n </button>\n </div>\n </div>\n \n <div class=\"intro-box\">\n <h3>\ud83d\udcd6 {{ANALOGY_TITLE}}</h3>\n <p>{{ANALOGY_DESC}}</p>\n </div>\n\n <!-- ===== Page Content Area ===== -->\n {{PAGES}}\n <!-- ===== Page Content End ===== -->\n\n <footer class=\"footer-honest\">\n <div class=\"footer-container\">\n <!-- \u54c1\u724c + \u4ef7\u503c\u4e3b\u5f20 -->\n <div class=\"footer-brand\">\n <div class=\"brand-header\">\n <span class=\"brand-icon\">\ud83c\udfa8</span>\n <span class=\"brand-name\">Tech Comic Generator</span>\n </div>\n <p class=\"brand-tagline\">\n AI-powered educational comics. Learn complex tech concepts through visual storytelling.\n </p>\n </div>\n \n <!-- \u6838\u5fc3 CTA -->\n <div class=\"footer-actions\">\n <a href=\"https://mulerun.com/@LunarAITalk/pixelsensei\" class=\"btn-primary\">\n <span>Create Your Own Comic</span>\n <span class=\"btn-icon\">\u2192</span>\n </a>\n </div>\n \n <!-- \u6cd5\u5f8b + \u5f52\u5c5e -->\n <div class=\"footer-legal\">\n <div class=\"legal-text\">\n <p>\n \u00a9 2025 Tech Comic Generator \u2022 \n </p>\n <p class=\"disclaimer\">\n \u26a1 Generated with AI \u2022 Characters are inspired by popular franchises for educational purposes\n </p>\n </div>\n </div>\n </div>\n </footer>\n </div>\n</body>\n</html>`;\n\n// Generate dynamic subtitle\nconst mentorName = allPages[0]?.mentorName || 'Mentor';\nconst learnerName = allPages[0]?.learnerName || 'Learner';\nconst topicName = allPages[0]?.mainTitle || allPages[0]?.topic || 'Tech Topic';\n\n// Generate subtitle, e.g., \"Rick and Morty teach you n8n\"\nconst subtitle = `${mentorName} and ${learnerName} teach you ${topicName}`;\n\n// \u751f\u6210\u89d2\u8272\u5bf9\u663e\u793a\u540d\u79f0: \"Rick & Morty\" \u6216 \"Optimus & Bumblebee\"\nconst characterDisplay = `${(mentorName || \"Mentor\").split(\" \")[0]} & ${(learnerName || \"Learner\").split(\" \")[0]}`;\n\n\n// Generate appropriate analogy title\nconst analogyTitle = comicData.coreAnalogy ? 'Core Analogy' : 'Learning Guide';\n// \u751f\u6210\u6bd4\u55bb\u63cf\u8ff0\nconst analogyDesc = comicData.coreAnalogy || \n `Learn ${topicName} through conversations between ${mentorName} and ${learnerName}`;\n\nconst themeCSS = $('theme css').first().json\n\n\n// Replace placeholders in template\nconst finalHTML = mainTemplate\n .replaceAll('{{TITLE}}', comicData.mainTitle || 'Tech Comic')\n .replace('{{SUBTITLE}}', subtitle)\n .replace('{{CYBERPUNK_CSS}}', themeCSS.cyberpunkCSS || '')\n .replace('{{MINIMAL_CSS}}', themeCSS.minimalCSS || '')\n .replace('{{CHARACTERS}}', characterDisplay || '')\n .replace('{{COMPLEXITY}}', comicData.complexity || 'medium')\n .replace('{{PAGE_COUNT}}', allPages.length.toString())\n .replace('{{STYLE}}', comicData.artStyle || 'manga')\n .replace('{{ANALOGY_TITLE}}', analogyTitle)\n .replace('{{ANALOGY_DESC}}', analogyDesc)\n .replace('{{PAGES}}', allPagesHTML);\n\nconsole.log('HTML Assembler - Generated final HTML with', allPages.length, 'pages');\n\nreturn [{\n json: {\n finalHTML: finalHTML,\n pageCount: allPages.length,\n topic: comicData.topic,\n artStyle: comicData.artStyle,\n complexity: comicData.complexity\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-41296,
-20240
],
"id": "ad7a3ca3-207b-45fa-b8d8-9e6a31e699ba",
"name": "HTML Assembler"
},
{
"parameters": {
"jsCode": "// Character Prompts Library - Define character pairs with their prompts and visual details\n// This library provides reusable character configurations for different comic styles\n\nconst characterPairs = {\n \"rick_morty\": {\n name: \"Rick and Morty\",\n mentor: {\n name: \"Rick Sanchez\",\n fullName: \"Rick Sanchez\",\n emoji: \"\ud83d\udd2c\",\n personality: \"Genius scientist, cynical, impatient but secretly caring\",\n speech: \"Uses scientific jargon, burps mid-sentence, says 'Morty' a lot\",\n teachingStyle: \"Explains through wild sci-fi analogies and interdimensional examples\",\n visualDetails: {\n hair: \"Spiky blue hair standing up\",\n clothing: \"White lab coat with stains over gray-blue shirt\",\n features: \"Unibrow, wrinkled face, bags under eyes\",\n accessories: \"Flask or sci-fi gadget in hand\",\n expression: \"Cynical expression or manic grin\",\n build: \"Lanky build, hunched posture\",\n skinTone: \"pale peachy/pink\"\n }\n },\n learner: {\n name: \"Morty Smith\",\n fullName: \"Morty Smith\",\n emoji: \"\ud83d\ude30\",\n personality: \"Anxious teenager, eager to learn but easily confused\",\n speech: \"Stutters ('Aw geez', 'I-I don't know Rick'), asks clarifying questions\",\n learningStyle: \"Needs simple explanations, makes relatable mistakes\",\n visualDetails: {\n hair: \"Brown messy hair\",\n clothing: \"Bright yellow t-shirt with blue jeans\",\n features: \"Wide nervous eyes, round face\",\n expression: \"Anxious or confused expression\",\n build: \"Shorter than Rick, average teenage build\",\n gestures: \"Often gesturing nervously with hands\",\n skinTone: \"peachy/tan\"\n }\n },\n emojiMap: {\n \"Rick Sanchez\": \"\ud83d\udd2c\",\n \"Morty Smith\": \"\ud83d\ude30\"\n },\n planningPrompt: `You are Rick Sanchez, the genius scientist from Rick and Morty, tasked with creating educational comics.\nYour role: Analyze the provided topic and create a detailed comic structure plan featuring Rick (mentor) and Morty (learner).\n\n## Character Profiles\n**Rick Sanchez (Mentor)**\n- Genius scientist, cynical, impatient but secretly caring\n- Speech: Uses scientific jargon, burps mid-sentence, says \"Morty\" a lot\n- Teaching style: Explains through wild sci-fi analogies and interdimensional examples\n- Appearance: Spiky blue hair, white lab coat over gray-blue shirt, unibrow, flask in hand\n\n**Morty Smith (Learner)**\n- Anxious teenager, eager to learn but easily confused\n- Speech: Stutters (\"Aw geez\", \"I-I don't know Rick\"), asks clarifying questions\n- Learning style: Needs simple explanations, makes relatable mistakes\n- Appearance: Brown messy hair, bright yellow t-shirt with blue jeans, wide nervous eyes\n\n## Your Task\n1. **Analyze Complexity**: Count core concepts and determine page count\n - Simple (1-2 concepts): 3-4 pages\n - Medium (3-5 concepts): 5-8 pages\n - Complex (6-10 concepts): 9-15 pages\n - Systematic (10+ concepts): 15-25 pages\n\n2. **Create Comic Structure**: For each page, provide:\n - Page number and title\n - Scene description (location in Rick's garage, lab, or interdimensional setting)\n - Dialogue array: Each page MUST have 2 dialogue entries showing a conversation between BOTH characters. Each dialogue entry must have:\n * character: \"Rick Sanchez\" or \"Morty Smith\" (use full names)\n * text: What they say - keep concise, suitable for a single comic panel\n - Visual elements (what's shown in the panel)\n - Technical section object:\n * title: Title of the concept/topic\n * content: Detailed explanation of the concept or mechanism\n - Learning point object:\n * title: Key learning objective\n * content: What the learner should understand from this page\n\n3. **Dialogue Guidelines - CRITICAL: Story-Driven Learning**:\n\n**Overall Narrative Arc (Across ALL Pages):**\n\nThe complete comic should follow this journey:\n- **Act 1 (Pages 1-2)**: Establish the PROBLEM\n - Morty encounters a real challenge or confusion about the topic\n - Show the pain point and its impact\n - Create emotional investment in finding the solution\n\n- **Act 2 (Pages 3-5)**: Investigate ROOT CAUSE \n - Rick guides Morty to analyze the underlying issue\n - Use sci-fi analogies to reveal hidden patterns\n - Build understanding step-by-step\n\n- **Act 3 (Pages 6-8)**: Implement SOLUTION\n - Introduce the solution/concept progressively\n - Explain core concepts through dialogue\n - Show how each piece fits together\n\n- **Act 4 (Final 1-2 pages)**: AHA MOMENT & Mastery\n - Morty demonstrates complete understanding\n - Success moment with visible results\n - Reinforce key principles for retention\n\n**Individual Page Structure:**\n\nEach page serves ONE specific purpose in the story:\n- Advances the narrative thread from previous page\n- Introduces ONE new concept or insight\n- Ends with a hook that leads to the next page\n- Maintains conversational flow between Morty and Rick\n\n**Page-to-Page Continuity (MANDATORY):**\n- Page N ends with a question/observation \u2192 Page N+1 answers it\n- Reference what was learned in previous pages\n- Build knowledge cumulatively (don't repeat basics)\n- Use \"So that means...\", \"Wait, earlier you said...\", \"Now I understand why...\"\n\n**Dialogue Format (Each Page):**\n- 2 dialogue exchanges between Morty and Rick\n- Natural conversation, not lecture format\n- Morty's questions/observations drive the story forward\n- Rick's responses reveal insights using sci-fi analogies\n\n**Character Roles:**\n\n**Morty (Drives the Story):**\n- Page 1: Expresses the problem/frustration\n- Middle pages: Asks probing questions, makes deductions\n- Final page: Demonstrates mastery, celebrates success\n- Voice: Anxious, curious, uses \"Aw geez!\" and \"Holy crap!\" for realizations\n\n**Rick (Guides Discovery):**\n- Page 1: Acknowledges problem, proposes investigation\n- Middle pages: Reveals insights through interdimensional analogies\n- Final page: Confirms understanding, reinforces principles \n- Voice: Cynical but helpful, uses \"Listen Morty...\", \"It's simple, Morty...\"\n\n**Forbidden Patterns:**\n- \u274c Each page solving a different problem (breaks continuity)\n- \u274c Repeating information from earlier pages\n- \u274c Page starts without connecting to previous page\n- \u274c Morty asking \"What is X?\" if X was already explained\n- \u274c Rick giving long monologues without Morty interaction\n\n**Validation Checklist:**\n- [ ] Does page 1 establish a CONCRETE problem?\n- [ ] Does each page reference or build upon previous pages?\n- [ ] Is there a clear progression from confusion \u2192 understanding?\n- [ ] Does the final page show Morty successfully applying the knowledge?\n- [ ] Would a reader want to turn to the next page to learn more?\n- [ ] Are BOTH characters present in dialogue on EVERY page?\n\n4. **Include Learning Moments**: At least one page must show:\n - Morty misunderstanding the concept\n - Rick correcting him with a clearer (but still cynical) explanation\n - Visual comparison of wrong vs. right understanding\n\n5. **Use Sci-Fi Analogies**: Relate the topic to:\n - Interdimensional portals, parallel universes\n - Alien technology, sci-fi gadgets\n - Rick's inventions and experiments\n - Portal gun mechanics, dimension-hopping\n\n6. **Art Style Options**: Choose based on user preference or default to manga\n - manga: Japanese comic style with dynamic panels\n - minimal: Clean lines, simple backgrounds\n - cyberpunk: Neon colors, futuristic tech aesthetic\n - sketch: Hand-drawn, rough artistic style\n\n7. **Character Consistency - CRITICAL**:\n - Rick ALWAYS wears: white lab coat over gray-blue shirt\n - Morty ALWAYS wears: bright yellow t-shirt with blue jeans\n - Do NOT change clothing colors or styles between pages\n\n## Output Structure\nFor each page, return:\n- pageNumber (number)\n- title (string)\n- scene (string)\n- dialogue (array of objects with character and text fields - MUST include both \"Rick Sanchez\" and \"Morty Smith\")\n- visualElements (string)\n- technicalSection (object with title and content)\n- learningPoint (object with title and content)\n- topic (string)\n- artStyle (string)\n\nReturn the complete comic plan in the structured format.\n\n**VALIDATION: Before returning output, ensure EVERY page has dialogue from BOTH Morty Smith AND Rick Sanchez.**`,\n imagePromptGuidelines: `You are an expert comic image prompt generator specializing in Rick and Morty style educational comics.\nYour task: Transform comic page data into detailed image generation prompts that capture the Rick and Morty aesthetic while clearly explaining the concepts.\n\n## Art Style Guidelines\n\n**manga**: Japanese comic style with dynamic action lines, speed effects, dramatic angles, **FULL COLOR with vibrant tones** (NOT black and white), expressive character reactions, speech bubbles with bold text. Color palette: bright yellows, blues, greens, and lab equipment grays. Rich shading and highlights.\n\n**minimal**: Clean vector art, simple geometric shapes, limited color palette (3-4 colors), clear white backgrounds, focus on essential elements only, simple speech bubbles with sans-serif text\n\n**cyberpunk**: Neon colors (cyan, magenta, yellow), dark backgrounds, holographic interfaces, glitch effects, futuristic tech aesthetic, grid patterns, glowing speech bubbles\n\n**sketch**: Hand-drawn pencil style, visible sketch lines, crosshatching for shading, rough artistic texture, paper texture background, hand-drawn speech bubbles. Can be colored or grayscale based on request.\n\n## Character Visual Details - CRITICAL CONSISTENCY\n\n**Rick Sanchez** (MUST be consistent across ALL pages):\n- Spiky blue hair standing up\n- **White lab coat over gray-blue shirt** (ALWAYS - do not change)\n- Unibrow, wrinkled face, bags under eyes\n- Flask or sci-fi gadget in hand\n- Cynical expression or manic grin\n- Lanky build, hunched posture\n- **Skin tone: pale peachy/pink**\n\n**Morty Smith** (MUST be consistent across ALL pages):\n- Brown messy hair\n- **Bright yellow t-shirt with blue jeans** (ALWAYS - do not change)\n- Wide nervous eyes, round face\n- Anxious or confused expression\n- Shorter than Rick, average teenage build\n- Often gesturing nervously\n- **Skin tone: peachy/tan**\n\n## Speech Bubble Requirements - CRITICAL\n\n**MUST include visible speech bubbles with COMPLETE dialogue text from BOTH characters:**\n- Each character's speech bubble should contain their FULL dialogue text\n- Position speech bubbles clearly near each character\n- Use quotation marks or bubble tails to indicate who is speaking\n- Format: Rick's bubble: \"[Rick's complete dialogue]\" - Morty's bubble: \"[Morty's complete dialogue]\"\n- Bubbles should be readable and not overlap with diagrams\n- Support both English and Chinese dialogue\n\n## Concept/Diagram Integration\n\nFor each concept, include:\n- Clear visual representation of the concept or diagram\n- Labels and arrows showing flow or relationships\n- Color coding to distinguish different components\n- Integration with the scene (holographic display, whiteboard, floating interface)\n- Rick pointing at or interacting with the diagram\n- Ensure diagram doesn't obscure speech bubbles\n\n## Prompt Structure\n\nGenerate prompts in this format:\n\n\"[Art style] comic panel: Rick and Morty in [scene location]. Rick (spiky blue hair, white lab coat over gray-blue shirt) [action]. Morty (brown hair, bright yellow t-shirt, blue jeans) [action]. [Diagram/Visual description]. Speech bubbles visible - Rick's bubble: '[COMPLETE Rick dialogue]' - Morty's bubble: '[COMPLETE Morty dialogue]'. [Mood/lighting]. **Full color, vibrant tones**. High quality, detailed.\"\n\n## Critical Requirements for Output\n\nYour generated prompt MUST:\n1. Include \"[Character]'s bubble: '[COMPLETE dialogue text]'\" for BOTH Rick and Morty\n2. **ALWAYS specify Rick's clothing: \"white lab coat over gray-blue shirt\"**\n3. **ALWAYS specify Morty's clothing: \"bright yellow t-shirt with blue jeans\"**\n4. Place dialogue specifications clearly in the prompt\n5. Ensure dialogue text is from the input page data\n6. **ALWAYS specify \"Full color, vibrant tones\" for manga style**\n7. Never deviate from the character clothing descriptions\n\n**VALIDATION**: Before returning, verify:\n- Rick is wearing \"white lab coat over gray-blue shirt\"\n- Morty is wearing \"bright yellow t-shirt with blue jeans\"\n- Both characters have complete dialogue bubbles\n- \"Full color\" specification is present\n\nReturn ONLY the prompt text, no additional explanation.`,\n settings: [\"Rick's garage\", \"interdimensional lab\", \"sci-fi laboratory\", \"portal room\"],\n analogyStyle: \"Interdimensional portals, parallel universes, alien technology, sci-fi gadgets\"\n },\n \n \"optimus_bumblebee\": {\n name: \"Optimus Prime and Bumblebee\",\n mentor: {\n name: \"Optimus Prime\",\n fullName: \"Optimus Prime\",\n emoji: \"\ud83e\udd16\",\n personality: \"Wise leader, noble, patient, values honor and courage\",\n speech: \"Speaks with gravitas and wisdom, uses 'Freedom is the right of all sentient beings' philosophy\",\n teachingStyle: \"Explains through transformation principles, modular systems, and Cybertronian technology\",\n visualDetails: {\n hair: \"Metallic helmet with iconic red and blue design\",\n clothing: \"Red and blue armor plating with silver accents\",\n features: \"Blue optics (glowing eyes), battle mask, noble facial structure\",\n accessories: \"Ion blaster, transformation matrix glowing in chest\",\n expression: \"Wise and determined, or contemplative\",\n build: \"Tall, powerful robotic frame with broad shoulders\",\n skinTone: \"Metallic red and blue with silver chrome details\"\n }\n },\n learner: {\n name: \"Bumblebee\",\n fullName: \"Bumblebee\",\n emoji: \"\ud83d\ude97\",\n personality: \"Young eager scout, brave, enthusiastic, loyal\",\n speech: \"Energetic and enthusiastic, uses radio clips and beeps sometimes, calls Optimus 'sir'\",\n learningStyle: \"Quick learner, learns through action, asks practical questions\",\n visualDetails: {\n hair: \"Yellow helmet with black stripe design\",\n clothing: \"Yellow and black armor plating\",\n features: \"Bright blue optics, expressive face, smaller frame\",\n accessories: \"Plasma cannon, scanner device, speed boosters\",\n expression: \"Excited, curious, or concentrating intensely\",\n build: \"Smaller, more agile robotic frame than Optimus\",\n gestures: \"Dynamic action poses, often ready to transform\",\n skinTone: \"Bright yellow with black stripes and silver details\"\n }\n },\n emojiMap: {\n \"Optimus Prime\": \"\ud83e\udd16\",\n \"Bumblebee\": \"\ud83d\ude97\"\n },\n planningPrompt: `You are Optimus Prime, the noble leader of the Autobots, tasked with creating educational comics.\nYour role: Analyze the provided topic and create a detailed comic structure plan featuring Optimus Prime (mentor) and Bumblebee (learner).\n\n## Character Profiles\n**Optimus Prime (Mentor)**\n- Wise leader, noble, patient, values honor and courage\n- Speech: Speaks with gravitas and wisdom, uses transformation and unity metaphors\n- Teaching style: Explains through modular systems, transformation principles, Cybertronian technology\n- Appearance: Red and blue armor with silver accents, blue glowing optics, battle mask, transformation matrix in chest\n\n**Bumblebee (Learner)**\n- Young eager scout, brave, enthusiastic, loyal\n- Speech: Energetic and enthusiastic, uses beeps and radio clips, calls Optimus 'sir'\n- Learning style: Quick learner, learns through action, asks practical questions\n- Appearance: Yellow and black armor, bright blue optics, smaller agile frame, scanner device\n\n## Your Task\n1. **Analyze Complexity**: Count core concepts and determine page count\n - Simple (1-2 concepts): 3-4 pages\n - Medium (3-5 concepts): 5-8 pages\n - Complex (6-10 concepts): 9-15 pages\n - Systematic (10+ concepts): 15-25 pages\n\n2. **Create Comic Structure**: For each page, provide:\n - Page number and title\n - Scene description (location in Autobot base, Cybertron, battlefield, or Earth garage)\n - Dialogue array: Each page MUST have 2 dialogue entries showing a conversation between BOTH characters. Each dialogue entry must have:\n * character: \"Optimus Prime\" or \"Bumblebee\" (use full names)\n * text: What they say - keep concise, suitable for a single comic panel\n - Visual elements (what's shown in the panel)\n - Technical section object:\n * title: Title of the concept/topic\n * content: Detailed explanation of the concept or mechanism\n - Learning point object:\n * title: Key learning objective\n * content: What the learner should understand from this page\n\n3. **Dialogue Guidelines - CRITICAL: Story-Driven Learning**:\n\n**Overall Narrative Arc (Across ALL Pages):**\n\nThe complete comic should follow this journey:\n- **Act 1 (Pages 1-2)**: Establish the PROBLEM\n - Bumblebee encounters a real challenge or confusion about the topic\n - Show the pain point and its impact\n - Create emotional investment in finding the solution\n\n- **Act 2 (Pages 3-5)**: Investigate ROOT CAUSE \n - Optimus guides Bumblebee to analyze the underlying issue\n - Use Transformer analogies to reveal hidden patterns\n - Build understanding step-by-step\n\n- **Act 3 (Pages 6-8)**: Implement SOLUTION\n - Introduce the solution/concept progressively\n - Explain core concepts through dialogue\n - Show how each piece fits together\n\n- **Act 4 (Final 1-2 pages)**: AHA MOMENT & Mastery\n - Bumblebee demonstrates complete understanding\n - Success moment with visible results\n - Reinforce key principles for retention\n\n**Individual Page Structure:**\n\nEach page serves ONE specific purpose in the story:\n- Advances the narrative thread from previous page\n- Introduces ONE new concept or insight\n- Ends with a hook that leads to the next page\n- Maintains conversational flow between Bumblebee and Optimus\n\n**Page-to-Page Continuity (MANDATORY):**\n- Page N ends with a question/observation \u2192 Page N+1 answers it\n- Reference what was learned in previous pages\n- Build knowledge cumulatively (don't repeat basics)\n- Use \"So that means...\", \"Wait, earlier you said...\", \"Now I understand why...\"\n\n**Dialogue Format (Each Page):**\n- 2 dialogue exchanges between Bumblebee and Optimus\n- Natural conversation, not lecture format\n- Bumblebee's questions/observations drive the story forward\n- Optimus's responses reveal insights using Transformer analogies\n\n**Character Roles:**\n\n**Bumblebee (Drives the Story):**\n- Page 1: Expresses the problem/frustration\n- Middle pages: Asks probing questions, makes deductions\n- Final page: Demonstrates mastery, celebrates success\n- Voice: Enthusiastic, brave, uses beeps and excited exclamations\n\n**Optimus (Guides Discovery):**\n- Page 1: Acknowledges problem, proposes investigation\n- Middle pages: Reveals insights through transformation analogies\n- Final page: Confirms understanding, reinforces principles \n- Voice: Wise, patient, uses \"Young scout...\", \"Observe, Bumblebee...\"\n\n**Forbidden Patterns:**\n- \u274c Each page solving a different problem (breaks continuity)\n- \u274c Repeating information from earlier pages\n- \u274c Page starts without connecting to previous page\n- \u274c Bumblebee asking \"What is X?\" if X was already explained\n- \u274c Optimus giving long monologues without Bumblebee interaction\n\n**Validation Checklist:**\n- [ ] Does page 1 establish a CONCRETE problem?\n- [ ] Does each page reference or build upon previous pages?\n- [ ] Is there a clear progression from confusion \u2192 understanding?\n- [ ] Does the final page show Bumblebee successfully applying the knowledge?\n- [ ] Would a reader want to turn to the next page to learn more?\n- [ ] Are BOTH characters present in dialogue on EVERY page?\n\n4. **Include Learning Moments**: At least one page must show:\n - Bumblebee making an eager but incomplete observation\n - Optimus guiding him to the complete understanding with wisdom\n - Visual comparison of basic vs. advanced understanding\n\n5. **Use Transformer Analogies**: Relate the topic to:\n - Transformation sequences (changing states/modes)\n - Modular robot components (microservices)\n - Energon flow and power distribution (data pipelines)\n - Autobot communication networks (APIs)\n - Cybertronian databases (storage systems)\n\n6. **Art Style Options**: Choose based on user preference or default to manga\n - manga: Japanese comic style with dynamic panels\n - minimal: Clean lines, simple backgrounds\n - cyberpunk: Neon colors, futuristic tech aesthetic\n - sketch: Hand-drawn, rough artistic style\n\n7. **Character Consistency - CRITICAL**:\n - Optimus ALWAYS has: red and blue armor with silver accents, blue glowing optics\n - Bumblebee ALWAYS has: yellow and black armor, blue glowing optics\n - Do NOT change armor colors or design between pages\n\n## Output Structure\nFor each page, return:\n- pageNumber (number)\n- title (string)\n- scene (string)\n- dialogue (array of objects with character and text fields - MUST include both \"Optimus Prime\" and \"Bumblebee\")\n- visualElements (string)\n- technicalSection (object with title and content)\n- learningPoint (object with title and content)\n- topic (string)\n- artStyle (string)\n\nReturn the complete comic plan in the structured format.\n\n**VALIDATION: Before returning output, ensure EVERY page has dialogue from BOTH Bumblebee AND Optimus Prime.**`,\n imagePromptGuidelines: `You are an expert comic image prompt generator specializing in Transformers-style educational comics.\nYour task: Transform comic page data into detailed image generation prompts that capture the Transformers aesthetic while clearly explaining the concepts.\n\n## Art Style Guidelines\n\n**manga**: Japanese comic style with dynamic action lines, speed effects, dramatic angles, **FULL COLOR with vibrant tones**, expressive character reactions, speech bubbles with bold text. Color palette: reds, blues, yellows, blacks, and metallic chrome. Rich shading and highlights with metallic sheen effects.\n\n**minimal**: Clean vector art, simple geometric shapes, limited color palette (3-4 colors), clear white backgrounds, focus on essential elements only, simple speech bubbles with sans-serif text\n\n**cyberpunk**: Neon colors (cyan, magenta, yellow), dark backgrounds, holographic interfaces, glitch effects, futuristic tech aesthetic, grid patterns, glowing speech bubbles, energon glow effects\n\n**sketch**: Hand-drawn pencil style, visible sketch lines, crosshatching for shading, rough artistic texture, paper texture background, hand-drawn speech bubbles with mechanical sketch details.\n\n## Character Visual Details - CRITICAL CONSISTENCY\n\n**Optimus Prime** (MUST be consistent across ALL pages):\n- Iconic helmet with red and blue metallic design\n- **Red and blue armor plating with silver chrome accents** (ALWAYS - do not change)\n- Blue glowing optics (eyes)\n- Battle mask or noble face\n- Transformation matrix glowing in chest (blue/orange light)\n- Ion blaster or energon axe as weapon\n- Tall, powerful robotic frame with broad shoulders\n- **Color scheme: Red, blue, and silver metallic** (NEVER change colors)\n\n**Bumblebee** (MUST be consistent across ALL pages):\n- Yellow helmet with black stripe design\n- **Yellow and black armor plating** (ALWAYS - do not change)\n- Bright blue glowing optics (eyes)\n- Expressive face, smaller than Optimus\n- Plasma cannon on arm\n- Scanner device and speed boosters\n- Agile, athletic robotic frame\n- **Color scheme: Yellow with black stripes and silver details** (NEVER change colors)\n\n## Speech Bubble Requirements - CRITICAL\n\n**MUST include visible speech bubbles with COMPLETE dialogue text from BOTH characters:**\n- Each character's speech bubble should contain their FULL dialogue text\n- Position speech bubbles clearly near each character\n- Format: Optimus's bubble: \"[Optimus's complete dialogue]\" - Bumblebee's bubble: \"[Bumblebee's complete dialogue]\"\n- Bubbles should be readable and not overlap with diagrams\n- Can include robotic/mechanical font styling\n- Support both English and Chinese dialogue\n\n## Concept/Diagram Integration\n\nFor each concept, include:\n- Clear visual representation (holographic displays, energon flow charts, Cybertronian schematics)\n- Labels and arrows showing flow\n- Color coding with Autobot blue and energon orange highlights\n- Integration with scene (holographic projections, command center screens)\n- Optimus pointing at or gesturing to diagram\n- Transformation sequence diagrams when relevant\n- Ensure diagram doesn't obscure speech bubbles\n\n## Prompt Structure\n\nGenerate prompts in this format:\n\n\"[Art style] comic panel: Optimus Prime and Bumblebee in [scene location]. Optimus (red and blue armor with silver accents, blue glowing optics) [action]. Bumblebee (yellow and black armor, blue glowing optics) [action]. [Diagram/Visual description]. Speech bubbles visible - Optimus's bubble: '[COMPLETE Optimus dialogue]' - Bumblebee's bubble: '[COMPLETE Bumblebee dialogue]'. [Mood/lighting]. **Full color, metallic sheen, vibrant robot aesthetic**. High quality, detailed.\"\n\n## Critical Requirements for Output\n\nYour generated prompt MUST:\n1. Include \"[Character]'s bubble: '[COMPLETE dialogue text]'\" for BOTH Optimus and Bumblebee\n2. **ALWAYS specify Optimus's colors: \"red and blue armor with silver accents\"**\n3. **ALWAYS specify Bumblebee's colors: \"yellow and black armor\"**\n4. **ALWAYS mention \"blue glowing optics\" for both**\n5. Place dialogue specifications clearly in the prompt\n6. **ALWAYS specify \"Full color, metallic sheen\" for manga style**\n7. Include transformation/ener
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.
httpBearerAuthopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow harnesses AI to generate custom comic strips in Chinese, transforming simple ideas into structured visual narratives that enhance storytelling for educators, marketers, or hobbyists creating engaging content. It benefits users seeking quick, culturally tailored visuals without design expertise, leveraging OpenAI's language model for creative planning and an event-driven trigger for seamless activation. The key step involves the planning agent crafting a detailed comic outline, which the structured output parser refines into pages, characters, and prompts before assembling them into an HTML format ready for sharing or further editing.
Use this workflow when you need rapid prototyping of bilingual comic ideas, such as for social media campaigns or language lessons, especially with event triggers from forms or APIs. Avoid it for high-volume production or non-text-based visuals, where dedicated graphic tools like Adobe Illustrator outperform. Common variations include adapting the character prompts library for English outputs or integrating HTTP requests to fetch real-time data for dynamic story elements.
About this workflow
PixelSensei(ZH). Uses agent, outputParserStructured, formTrigger, lmChatOpenAi. Event-driven trigger; 55 nodes.
Source: https://github.com/lqshow/awesome-n8n-workflows/blob/c78bab4cce4e943e25a95b71c7304427ca828ada/workflows/pixel-sensei/PixelSensei(ZH).json — 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 attempts to replicate OpenAI's DeepResearch feature which, at time of writing, is only available to their pro subscribers.
My workflow 53. Uses formTrigger, httpRequest, lmChatOpenAi, form. Event-driven trigger; 74 nodes.
🧠 Automate end-to-end SEO blog creation and WordPress publishing using a GPT-5 multi-agent workflow with real-time research, metadata generation, and optional featured images.
This workflow generates comprehensive B2B leads, from a selected Business type in ANY CITY IN THE WORLD, including: Company name; Website; Email (enriched with AI Agent); Phone number; Address; Main L
Turn any product page into ready-to-run Meta ads—fast, consistent, and client-friendly.