{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "f7e6d361-1844-48dc-8329-9ff2f7b0e648",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3008,
        400
      ],
      "parameters": {
        "width": 400,
        "height": 664,
        "content": "## \ud83c\udf19 Dream Journal Suite - AI Video Generator\n\n**Transform dream descriptions into cinematic AI videos with psychological analysis**\n\nThis workflow creates a Telegram bot that:\n1. Accepts dream descriptions from users\n2. Offers 8 visual styles (cinematic, ghibli, surreal, etc.)\n3. Generates AI video with native audio using Google Veo3\n4. Provides psychological dream analysis\n5. Logs everything to Google Sheets as a dream journal\n\n### Commands\n- `/dream [description]` - Generate video in cinematic style\n- `/dream [style] [description]` - Generate with specific style\n- `/styles` - Show available styles\n\n### Requirements\n- Telegram Bot (via @BotFather)\n- fal.ai API Key (for Veo3)\n- OpenRouter API Key (for LLM)\n- Google Sheets (optional, for dream journal)\n\n### Setup Time: ~15 minutes\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d45833e7-b294-48a4-a209-af49775c7bdb",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2576,
        448
      ],
      "parameters": {
        "color": 7,
        "height": 216,
        "content": "### 1\ufe0f\u20e3 Telegram Input\n\nReceives messages from Telegram bot.\n\n**Setup:**\n1. Create bot via @BotFather\n2. Copy API token\n3. Add to Telegram credentials"
      },
      "typeVersion": 1
    },
    {
      "id": "5d49f0de-bc6b-43dd-9450-05af6c198715",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2320,
        448
      ],
      "parameters": {
        "color": 7,
        "width": 280,
        "height": 216,
        "content": "### 2\ufe0f\u20e3 Command Parser\n\nExtracts style and dream content from user message.\n\n**Supported Styles:**\n- cinematic, ghibli, surreal\n- vintage, horror, abstract\n- watercolor, cyberpunk"
      },
      "typeVersion": 1
    },
    {
      "id": "ca54fc50-8425-4caf-80dd-565fcd8d81ae",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1488,
        448
      ],
      "parameters": {
        "color": 7,
        "width": 280,
        "height": 204,
        "content": "### 3\ufe0f\u20e3 AI Dream Analysis\n\nLLM analyzes the dream and creates:\n- Optimized video prompt for Veo3\n- Psychological interpretation\n- Theme & symbol analysis\n\n**Customize:** Edit system prompt to change analysis style"
      },
      "typeVersion": 1
    },
    {
      "id": "e4321c6d-d70b-4fba-803e-48267c67cb57",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        352
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "height": 308,
        "content": "### 4\ufe0f\u20e3 Veo3 Video Generation\n\nGoogle Veo3 generates video WITH native audio from single prompt.\n\n**Note:** Prompt includes sound descriptions for audio generation.\n\n**Setup:**\n1. Get fal.ai API key\n2. Create Header Auth credential:\n   - Name: `Authorization`\n   - Value: `Key YOUR_API_KEY`"
      },
      "typeVersion": 1
    },
    {
      "id": "8d869a26-d6d6-46c7-a239-deb9b5223c6b",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        64,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 260,
        "height": 344,
        "content": "### 5\ufe0f\u20e3 Dream Journal (Optional)\n\nLogs all dreams to Google Sheets.\n\n**Columns:**\n- Timestamp, Username, Style\n- Dream, Theme, Emotion\n- Type, Meaning, Video URL\n\n**Setup:**\n1. Create spreadsheet with columns above\n2. Connect Google Sheets credential\n3. Select document & sheet"
      },
      "typeVersion": 1
    },
    {
      "id": "933b1e41-d839-4e31-991b-eba28947546d",
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -2528,
        672
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "8cc8e741-50b6-4b25-a27a-e0d7b2558ca8",
      "name": "Parse Dream Command",
      "type": "n8n-nodes-base.code",
      "position": [
        -2288,
        672
      ],
      "parameters": {
        "jsCode": "// Parse command and extract style + dream content\nconst message = $input.first().json.message.text || '';\n\nconst STYLES = {\n  'cinematic': 'Cinematic film style with professional cinematography, dramatic lighting, smooth camera movements',\n  'ghibli': 'Studio Ghibli anime style with soft watercolor backgrounds, magical realism, warm colors, whimsical atmosphere',\n  'surreal': 'Surrealist art style inspired by Dal\u00ed and Magritte - impossible geometry, melting forms, dreamlike distortions',\n  'vintage': 'Vintage 8mm film style with grain, light leaks, sepia tones, nostalgic imperfection',\n  'horror': 'Dark horror style with high contrast shadows, unsettling angles, fog, tension-building atmosphere',\n  'abstract': 'Abstract experimental style with geometric shapes, flowing colors, morphing forms',\n  'watercolor': 'Soft watercolor painting style with bleeding colors, soft edges, pastel palette',\n  'cyberpunk': 'Neon-lit cyberpunk style with electric blues/pinks, rain-slicked surfaces, futuristic urban aesthetics'\n};\n\nlet style = 'cinematic';\nlet styleDescription = STYLES['cinematic'];\nlet dreamContent = message;\n\nif (message.startsWith('/dream')) {\n  const parts = message.replace('/dream', '').trim().split(' ');\n  const potentialStyle = parts[0]?.toLowerCase();\n  \n  if (STYLES[potentialStyle]) {\n    style = potentialStyle;\n    styleDescription = STYLES[potentialStyle];\n    dreamContent = parts.slice(1).join(' ');\n  } else {\n    dreamContent = parts.join(' ');\n  }\n}\n\nconst hasDreamContent = dreamContent && dreamContent.trim().length > 5;\nconst isStylesRequest = message.startsWith('/styles');\n\nreturn {\n  json: {\n    originalMessage: message,\n    style,\n    styleDescription,\n    dreamContent: dreamContent.trim(),\n    hasDreamContent,\n    isStylesRequest,\n    chatId: $input.first().json.message.chat.id,\n    userId: $input.first().json.message.from.id,\n    username: $input.first().json.message.from.username || 'anonymous',\n    timestamp: new Date().toISOString()\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "c1b4bb72-f3eb-4ec1-83ce-1f37177aca23",
      "name": "Route: Style Help Request",
      "type": "n8n-nodes-base.if",
      "position": [
        -2048,
        672
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "styles-check",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.isStylesRequest }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f688987d-0b67-49a8-b3ce-c7663d207bab",
      "name": "Send Available Styles",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1808,
        528
      ],
      "parameters": {
        "text": "\ud83c\udfa8 **Available Dream Styles**\n\nUse: `/dream [style] [your dream]`\n\n\u2022 `cinematic` - \ud83c\udfac Film-like cinematography\n\u2022 `ghibli` - \ud83c\udf38 Studio Ghibli anime\n\u2022 `surreal` - \ud83c\udfad Dal\u00ed/Magritte surrealism\n\u2022 `vintage` - \ud83d\udcf7 8mm film nostalgia\n\u2022 `horror` - \ud83d\udc7b Dark & unsettling\n\u2022 `abstract` - \ud83c\udf00 Experimental visuals\n\u2022 `watercolor` - \ud83d\uddbc\ufe0f Soft painting style\n\u2022 `cyberpunk` - \ud83c\udf03 Neon futurism\n\n**Example:**\n`/dream ghibli I was flying over a magical forest`",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "34ce9e70-a020-4e0f-a645-d026448f15d4",
      "name": "Route: Valid Dream Input",
      "type": "n8n-nodes-base.if",
      "position": [
        -1808,
        768
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "content-check",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.hasDreamContent }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1f45c9f2-3b54-471e-aa6c-e97bb5010452",
      "name": "Send Usage Instructions",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1568,
        896
      ],
      "parameters": {
        "text": "\ud83d\udcad Please describe your dream!\n\n**Usage:** `/dream [your dream]`\nor: `/dream ghibli [your dream]`\n\nType `/styles` for all styles.",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a4d84001-474a-482f-9ede-8143fa295233",
      "name": "Send Processing Status",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -1568,
        672
      ],
      "parameters": {
        "text": "\ud83c\udf19 Analyzing your dream in **{{ $json.style }}** style...\n\n\u23f3 This may take 2-3 minutes.",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "f2984f4a-d0f3-4d1e-8308-a629982e4ae7",
      "name": "Set API Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -1328,
        672
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "veo3-url",
              "name": "veo3ApiUrl",
              "type": "string",
              "value": "https://queue.fal.run/fal-ai/veo3"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "5bd379b9-3f8a-461e-b508-ff89f7db16d6",
      "name": "AI Dream Analyzer Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1088,
        672
      ],
      "parameters": {
        "text": "=DREAM: {{ $json.dreamContent }}\nSTYLE: {{ $json.style }} - {{ $json.styleDescription }}",
        "options": {
          "systemMessage": "You are a dream interpreter and cinematic prompt engineer. Analyze dreams and output JSON.\n\n## STYLE APPLICATION\n\n**cinematic**: Film cinematography, dramatic lighting, smooth camera, lens flares, depth of field\n**ghibli**: Studio Ghibli anime - soft watercolors, magical realism, warm palette, whimsical, hand-drawn feel\n**surreal**: Dal\u00ed/Magritte - impossible geometry, melting forms, dreamlike distortions, symbolic imagery\n**vintage**: 8mm film - grain, light leaks, sepia/faded tones, vignette, nostalgic imperfection\n**horror**: Dark atmosphere - high contrast shadows, unsettling angles, fog, tension, desaturated with vivid accents\n**abstract**: Non-representational - geometric shapes, flowing colors, morphing forms, emotional expression\n**watercolor**: Painting in motion - bleeding colors, soft edges, brush texture, pastel palette, ethereal\n**cyberpunk**: Neon futurism - electric blues/pinks, rain-slicked surfaces, holograms, urban density\n\n## OUTPUT FORMAT (JSON ONLY)\n\n{\n  \"videoPrompt\": \"[150-200 words. Cinematic description in requested style. Include: camera movement, lighting, colors, atmosphere, sound elements for Veo3. Present tense. Single paragraph.]\",\n  \"analysis\": {\n    \"theme\": \"[2-3 words]\",\n    \"emotionalTone\": \"[emotion]\",\n    \"symbols\": [{\"symbol\": \"[name]\", \"interpretation\": \"[meaning]\"}],\n    \"possibleMeaning\": \"[2-3 sentences]\",\n    \"dreamType\": \"[Anxiety/Wish-fulfillment/Processing/Nightmare/Peaceful/Adventure/Transformation]\"\n  }\n}\n\n## RULES\n1. Output ONLY valid JSON - no markdown, no explanation\n2. Video prompt MUST include audio/sound descriptions (Veo3 generates audio)\n3. Match the requested style precisely\n4. Embrace dream logic - impossible elements are features"
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "1852dbef-4641-4327-b275-5b5fd45e9d57",
      "name": "OpenRouter LLM",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -1088,
        896
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "3eb580b8-6a0c-4840-8bd0-263ee5319b71",
      "name": "Extract Video Prompt & Analysis",
      "type": "n8n-nodes-base.code",
      "position": [
        -800,
        672
      ],
      "parameters": {
        "jsCode": "const agentOutput = $input.first().json.output;\nconst prevData = $('Set API Configuration').first().json;\n\nlet parsed;\ntry {\n  const clean = agentOutput.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n  parsed = JSON.parse(clean);\n} catch (e) {\n  parsed = {\n    videoPrompt: agentOutput,\n    analysis: {\n      theme: \"Unknown\",\n      emotionalTone: \"Mysterious\",\n      symbols: [{symbol: \"Dream\", interpretation: \"Personal significance\"}],\n      possibleMeaning: \"This dream reflects your subconscious thoughts.\",\n      dreamType: \"Processing\"\n    }\n  };\n}\n\nreturn {\n  json: {\n    ...prevData,\n    videoPrompt: parsed.videoPrompt,\n    analysis: parsed.analysis\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "6229ad0e-3df0-439a-a98c-3bb062026f03",
      "name": "Generate Dream Video (Veo3)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -560,
        672
      ],
      "parameters": {
        "url": "={{ $json.veo3ApiUrl }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"prompt\": \"{{ $json.videoPrompt }}\",\n  \"aspect_ratio\": \"16:9\",\n  \"duration\": \"8s\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.3
    },
    {
      "id": "f2593ea4-ffe3-401f-9e84-bdb7093cbff3",
      "name": "Wait for Video Generation",
      "type": "n8n-nodes-base.wait",
      "position": [
        -336,
        672
      ],
      "parameters": {
        "unit": "minutes",
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "ec89d8c1-37e7-40fe-9438-76cb9fa82a34",
      "name": "Poll Generation Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -128,
        672
      ],
      "parameters": {
        "url": "={{ $('Generate Dream Video (Veo3)').first().json.status_url }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.3
    },
    {
      "id": "d6e25fff-569f-4308-aa20-f39ee43c696e",
      "name": "Route: Generation Complete",
      "type": "n8n-nodes-base.if",
      "position": [
        96,
        672
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "complete-check",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "COMPLETED"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "945b53d9-813f-4705-b249-ffc6b1a86ff7",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        336,
        656
      ],
      "parameters": {
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": ""
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "03a52cba-15de-4d01-936e-22c373d776e9",
      "name": "Send Dream Video to User",
      "type": "n8n-nodes-base.telegram",
      "position": [
        576,
        656
      ],
      "parameters": {
        "file": "={{ $('Poll Generation Status').first().json.response?.video?.url || $('Poll Generation Status').first().json.video?.url }}",
        "chatId": "={{ $('Extract Video Prompt & Analysis').first().json.chatId }}",
        "operation": "sendVideo",
        "additionalFields": {
          "caption": "=\u2728 **Your Dream Video**\n\n\ud83c\udfa8 Style: {{ $('Extract Video Prompt & Analysis').first().json.style }}\n\n\ud83d\udcca **Analysis:**\n\u2022 Theme: {{ $('Extract Video Prompt & Analysis').first().json.analysis.theme }}\n\u2022 Mood: {{ $('Extract Video Prompt & Analysis').first().json.analysis.emotionalTone }}\n\u2022 Type: {{ $('Extract Video Prompt & Analysis').first().json.analysis.dreamType }}\n\n\ud83d\udcad {{ $('Extract Video Prompt & Analysis').first().json.analysis.possibleMeaning }}",
          "parse_mode": "Markdown"
        }
      },
      "typeVersion": 1.2
    }
  ],
  "connections": {
    "OpenRouter LLM": {
      "ai_languageModel": [
        [
          {
            "node": "AI Dream Analyzer Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Parse Dream Command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Dream Command": {
      "main": [
        [
          {
            "node": "Route: Style Help Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheets": {
      "main": [
        [
          {
            "node": "Send Dream Video to User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set API Configuration": {
      "main": [
        [
          {
            "node": "AI Dream Analyzer Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Poll Generation Status": {
      "main": [
        [
          {
            "node": "Route: Generation Complete",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Processing Status": {
      "main": [
        [
          {
            "node": "Set API Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Dream Analyzer Agent": {
      "main": [
        [
          {
            "node": "Extract Video Prompt & Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Valid Dream Input": {
      "main": [
        [
          {
            "node": "Send Processing Status",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Usage Instructions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Style Help Request": {
      "main": [
        [
          {
            "node": "Send Available Styles",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Route: Valid Dream Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Video Generation": {
      "main": [
        [
          {
            "node": "Poll Generation Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Generation Complete": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait for Video Generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Dream Video (Veo3)": {
      "main": [
        [
          {
            "node": "Wait for Video Generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Video Prompt & Analysis": {
      "main": [
        [
          {
            "node": "Generate Dream Video (Veo3)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}