{
  "id": "yt-liked-full-05",
  "meta": {
    "instanceId": "vorlux-hub"
  },
  "name": "Vorlux AI | YouTube Liked Full Pipeline (6h)",
  "active": true,
  "nodes": [
    {
      "id": "e5f6a7b8-0005-4eee-8005-000000000001",
      "name": "Every 6 Hours",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [220, 300],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      }
    },
    {
      "id": "e5f6a7b8-0005-4eee-8005-000000000002",
      "name": "Sync Liked Videos",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [460, 300],
      "parameters": {
        "method": "GET",
        "url": "={{$env.VORLUX_HUB_URL}}/api/integrations/youtube/liked-pipeline?action=sync&status=new&limit=5",
        "options": {
          "timeout": 30000
        }
      },
      "notes": "Syncs new liked videos that haven't been processed yet"
    },
    {
      "id": "e5f6a7b8-0005-4eee-8005-000000000003",
      "name": "Has New Likes?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [700, 300],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ ($json.data || []).length > 0 }}",
              "rightValue": "true",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "e5f6a7b8-0005-4eee-8005-000000000004",
      "name": "Full Pipeline Process",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [940, 200],
      "notes": "Complete pipeline: transcript -> rewrite -> SEO -> content project -> thumbnail -> social",
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const videos = $input.first().json.data || [];\nconst hubUrl = $env.VORLUX_HUB_URL || 'http://localhost:3010';\nconst ollamaUrl = $env.OLLAMA_BASE_URL || 'http://localhost:11434';\nconst results = [];\n\nfor (const video of videos.slice(0, 3)) {\n  const videoId = video.video_id || video.videoId;\n  const pipeline = { videoId, title: video.title, steps: {} };\n  \n  try {\n    // Step 1: Pull transcript (4 fallback methods)\n    let transcript = '';\n    const methods = ['hub_api', 'supadata', 'local_proxy', 'innertube'];\n    for (const method of methods) {\n      if (transcript) break;\n      try {\n        if (method === 'hub_api') {\n          const r = await fetch(hubUrl + '/api/integrations/youtube/liked-pipeline', {\n            method: 'POST', headers: {'Content-Type':'application/json'},\n            body: JSON.stringify({videoId, action:'fetch_transcript'}),\n            signal: AbortSignal.timeout(30000)\n          });\n          const d = await r.json();\n          if (d.data?.transcript?.length > 200) transcript = d.data.transcript;\n        } else if (method === 'supadata') {\n          const r = await fetch(`https://api.supadata.ai/v1/youtube/transcript?videoId=${videoId}&text=true`, {signal: AbortSignal.timeout(15000)});\n          const d = await r.json();\n          if (d.content?.length > 200) transcript = d.content;\n        } else if (method === 'local_proxy') {\n          const r = await fetch(hubUrl + '/api/integrations/youtube/transcript?videoId=' + videoId, {signal: AbortSignal.timeout(20000)});\n          const d = await r.json();\n          if (d.data?.transcript?.length > 200) transcript = d.data.transcript;\n        } else {\n          const r = await fetch(`https://www.youtube.com/watch?v=${videoId}`, {signal: AbortSignal.timeout(10000)});\n          const html = await r.text();\n          const m = html.match(/\"captionTracks\":\\[\\{\"baseUrl\":\"([^\"]+)\"/);\n          if (m) { const cr = await fetch(m[1].replace(/\\\\u0026/g,'&'), {signal: AbortSignal.timeout(10000)}); transcript = (await cr.text()).replace(/<[^>]+>/g,' ').replace(/\\s+/g,' ').trim(); }\n        }\n      } catch {}\n    }\n    pipeline.steps.transcript = { success: transcript.length > 200, length: transcript.length };\n    if (transcript.length < 200) { pipeline.status = 'no_transcript'; results.push(pipeline); continue; }\n    \n    // Step 2: Rewrite as original bilingual script\n    let rewritten = '';\n    try {\n      const rw = await fetch(hubUrl + '/api/orchestrator/execute', {\n        method: 'POST', headers: {'Content-Type':'application/json'},\n        body: JSON.stringify({ agentId: 'content-writer', action: 'rewrite_video_script',\n          params: { originalTitle: video.title, originalTranscript: transcript.substring(0, 8000),\n            instructions: 'Rewrite as a new Vorlux AI HUB article. Keep core insights. Brand voice: tech-savvy, approachable. 1500-2500 words. Include both English and Spanish versions separated by ---ES--- marker.' }\n        }), signal: AbortSignal.timeout(120000)\n      });\n      const rwd = await rw.json();\n      rewritten = rwd.data?.result || '';\n    } catch {}\n    pipeline.steps.rewrite = { success: rewritten.length > 800, length: rewritten.length };\n    \n    // Step 3: Generate SEO metadata\n    let seo = {};\n    try {\n      const seoR = await fetch(ollamaUrl + '/api/generate', {\n        method: 'POST', headers: {'Content-Type':'application/json'},\n        body: JSON.stringify({ model: 'qwen2.5:7b', stream: false,\n          prompt: `Generate SEO metadata as JSON for this article. Include: title, description (150 chars), keywords (array of 5-10), og_description, slug. Article: ${rewritten.substring(0, 2000)}` }),\n        signal: AbortSignal.timeout(60000)\n      });\n      const seoD = await seoR.json();\n      try { seo = JSON.parse(seoD.response); } catch { seo = { title: video.title, description: video.title }; }\n    } catch {}\n    pipeline.steps.seo = { success: !!seo.title };\n    \n    // Step 4: Create content project\n    let projectId = null;\n    try {\n      const pr = await fetch(hubUrl + '/api/content/pipeline', {\n        method: 'POST', headers: {'Content-Type':'application/json'},\n        body: JSON.stringify({ action: 'create_from_liked', title: seo.title || 'Inspired by: ' + video.title,\n          content: rewritten, source: 'youtube_liked_full', sourceVideoId: videoId,\n          sourceChannel: video.channel_title, seo, bilingual: true }),\n        signal: AbortSignal.timeout(15000)\n      });\n      const prd = await pr.json();\n      projectId = prd.data?.id;\n    } catch {}\n    pipeline.steps.project = { success: !!projectId, id: projectId };\n    \n    // Step 5: Queue thumbnail generation via ComfyUI\n    try {\n      await fetch(hubUrl + '/api/comfyui/queue', {\n        method: 'POST', headers: {'Content-Type':'application/json'},\n        body: JSON.stringify({ workflow: 'blog_thumbnail', params: { title: seo.title || video.title, style: 'tech_modern' }, projectId }),\n        signal: AbortSignal.timeout(10000)\n      });\n      pipeline.steps.thumbnail = { success: true, queued: true };\n    } catch { pipeline.steps.thumbnail = { success: false }; }\n    \n    // Step 6: Queue social posts\n    try {\n      await fetch(hubUrl + '/api/social/queue', {\n        method: 'POST', headers: {'Content-Type':'application/json'},\n        body: JSON.stringify({ projectId, platforms: ['twitter', 'discord'], scheduledFor: new Date(Date.now() + 86400000).toISOString() }),\n        signal: AbortSignal.timeout(10000)\n      });\n      pipeline.steps.social = { success: true, queued: true };\n    } catch { pipeline.steps.social = { success: false }; }\n    \n    // Step 7: Mark as processed\n    try {\n      await fetch(hubUrl + '/api/integrations/youtube/liked-pipeline', {\n        method: 'POST', headers: {'Content-Type':'application/json'},\n        body: JSON.stringify({ videoId, action: 'mark_processed', projectId, steps: pipeline.steps }),\n        signal: AbortSignal.timeout(10000)\n      });\n    } catch {}\n    \n    pipeline.status = 'complete';\n  } catch (err) {\n    pipeline.status = 'error';\n    pipeline.error = String(err).substring(0, 200);\n  }\n  results.push(pipeline);\n}\n\nreturn [{ json: { results, processed: results.filter(r => r.status === 'complete').length, total: results.length } }];"
      }
    },
    {
      "id": "e5f6a7b8-0005-4eee-8005-000000000005",
      "name": "Update Pipeline Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1200, 100],
      "parameters": {
        "method": "POST",
        "url": "={{$env.VORLUX_HUB_URL}}/api/integrations/youtube/liked-pipeline",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ action: 'batch_status_update', results: $json.results }) }}",
        "options": {
          "timeout": 15000
        }
      }
    },
    {
      "id": "e5f6a7b8-0005-4eee-8005-000000000006",
      "name": "Discord Summary",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1200, 300],
      "parameters": {
        "method": "POST",
        "url": "={{$env.DISCORD_CONTENT_WEBHOOK}}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"embeds\":[{\"title\":\"YouTube Liked Full Pipeline\",\"description\":\"Processed: {{ $json.processed }}/{{ $json.total }} videos\\n\\n{{ $json.results.map(r => (r.status === 'complete' ? '\\u2705' : '\\u274c') + ' ' + r.title + ' (' + r.status + ')\\nSteps: ' + Object.entries(r.steps || {}).map(([k,v]) => k + ':' + (v.success ? 'OK' : 'FAIL')).join(', ')).join('\\\\n\\\\n') }}\",\"color\":16711680,\"footer\":{\"text\":\"Full pipeline: transcript -> rewrite -> SEO -> project -> thumbnail -> social\"}}]}",
        "options": {
          "timeout": 10000
        }
      }
    },
    {
      "id": "e5f6a7b8-0005-4eee-8005-000000000007",
      "name": "Log Activity",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1200, 500],
      "parameters": {
        "method": "POST",
        "url": "={{$env.VORLUX_HUB_URL}}/api/activity",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ type: 'youtube_liked_full_pipeline', action: 'batch_process', metadata: { processed: $json.processed, total: $json.total } }) }}",
        "options": {
          "timeout": 10000
        }
      }
    }
  ],
  "connections": {
    "Every 6 Hours": {
      "main": [
        [
          {
            "node": "Sync Liked Videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sync Liked Videos": {
      "main": [
        [
          {
            "node": "Has New Likes?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has New Likes?": {
      "main": [
        [
          {
            "node": "Full Pipeline Process",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Full Pipeline Process": {
      "main": [
        [
          {
            "node": "Update Pipeline Status",
            "type": "main",
            "index": 0
          },
          {
            "node": "Discord Summary",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Activity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveManualExecutions": true,
    "saveExecutionProgress": true
  },
  "tags": [
    { "name": "youtube" },
    { "name": "liked" },
    { "name": "content" },
    { "name": "pipeline" },
    { "name": "full" }
  ],
  "versionId": "2"
}