{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "79aab463-97ea-4107-bfd9-1ba264a1ec48",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4528,
        -304
      ],
      "parameters": {
        "color": 4,
        "width": 588,
        "height": 1172,
        "content": "## TikTok Trend Tracker to Telegram Bot Daily Digest \u2014 WayinVideo Summarization + GPT-4o-mini + Telegram + Sheets\n\nFor social media teams, content agencies, and brand managers who want to track what is trending on TikTok in their niche every morning without manually watching hours of videos. Every day at 8AM this workflow reads pending TikTok video URLs from your Google Sheet, checks if there are any to process, submits each to WayinVideo Summarization API, and stores per-video summaries. Once all videos are processed, a Code node aggregates all summaries into one combined string and GPT-4o-mini writes a clean daily digest \u2014 trend overview, per-video bullet points, top 3 content patterns, action recommendations, and trending tags. A Code node formats everything into a Telegram Markdown message with auto-truncation at 4000 characters. Telegram Bot sends the digest to your team channel. Google Sheets logs the digest and marks all processed videos.\n\n## How it works\n- **1. Schedule \u2014 Every Day 8AM** triggers the pipeline daily\n- **2. Google Sheets \u2014 Read Pending Videos** reads all rows from the Video Queue tab\n- **3. IF \u2014 Any Pending Videos Today?** stops the workflow cleanly if the queue is empty\n- **4\u20136. WayinVideo Summarization** submits each URL, waits 60 seconds, polls until SUCCEEDED\n- **7. IF \u2014 Summary Complete?** checks status \u2014 retries via 30-second wait if not ready\n- **9. Code \u2014 Extract Summary Per Video** extracts summary, highlights array, and tags per video\n- **10. Code \u2014 Aggregate All Summaries** collects all per-video items into one combined text string for GPT \u2014 this node sits above the main flow as it waits for all items\n- **11. AI Agent \u2014 Write Daily Digest** uses GPT-4o-mini to write a 5-section digest with trend overview, video summaries, top patterns, action recommendations, and top tags\n- **13. Code \u2014 Format Telegram Message** builds a Markdown-formatted Telegram message with section headers and auto-truncates at 4000 characters\n- **14. Telegram \u2014 Send Daily Digest** sends the message to your team channel via Bot API\n- **15. Google Sheets \u2014 Log Digest** appends the digest summary to the Digest Log tab\n- **16. Google Sheets \u2014 Mark Videos Processed** updates each Video Queue row with Processed status\n\n## Set up steps\n1. In **4. WayinVideo \u2014 Submit Summarization** and **6. WayinVideo \u2014 Get Summary Results** \u2014 replace `YOUR_WAYINVIDEO_API_KEY`\n2. In **12. OpenAI \u2014 GPT-4o-mini Model** \u2014 connect your OpenAI credential\n3. In **2** and **15** and **16** \u2014 connect Google Sheets OAuth2 and replace `YOUR_TREND_SHEET_ID`\n4. In **14. Telegram \u2014 Send Daily Digest** \u2014 replace `YOUR_TELEGRAM_CHAT_ID` and connect your Telegram Bot credential (create bot via @BotFather, get chat ID via getUpdates)\n5. Create a Google Sheet named TikTok Trend Tracker with two tabs: Video Queue (columns: Video URL, Video Title, Niche / Category, Date Added, Status, Processed Date) and Digest Log (columns: Digest Date, Niche, Videos Processed, Overview, Top Patterns, Action Recommendations, Top Tags, Telegram Sent, Sent On)"
      },
      "typeVersion": 1
    },
    {
      "id": "91cd6804-d1fa-458f-9c57-92f8e366ce36",
      "name": "Section \u2014 Schedule Trigger",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3872,
        64
      ],
      "parameters": {
        "color": 5,
        "width": 260,
        "height": 324,
        "content": "## Schedule Trigger\nFires every day at 8AM automatically. Can also be triggered manually to process today's queue on demand."
      },
      "typeVersion": 1
    },
    {
      "id": "e3a98d35-e293-4258-a650-8ee1ea91ebc8",
      "name": "Section \u2014 Sheet Read and Empty Queue Check",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3584,
        -16
      ],
      "parameters": {
        "color": 5,
        "width": 420,
        "height": 500,
        "content": "## Sheet Read and Empty Queue Check\nReads all rows from the Video Queue tab. IF no pending videos exist the workflow stops cleanly \u2014 no error. IF videos are found each one is processed sequentially."
      },
      "typeVersion": 1
    },
    {
      "id": "7e03c8e5-3496-404b-b432-9f9d9a0ab08b",
      "name": "Section \u2014 WayinVideo Summarization Submit and Poll",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3104,
        96
      ],
      "parameters": {
        "color": 6,
        "width": 708,
        "height": 356,
        "content": "## WayinVideo Summarization Submit and Poll\nSubmits each TikTok video URL to the Summarization API. Waits 60 seconds for initial processing. Polls the results endpoint until status equals SUCCEEDED."
      },
      "typeVersion": 1
    },
    {
      "id": "054c799c-2530-49a5-bcbf-70469bdddc3c",
      "name": "Section \u2014 Summary Status Check and Retry Loop",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2368,
        -16
      ],
      "parameters": {
        "color": 6,
        "width": 324,
        "height": 852,
        "content": "## Summary Status Check and Retry Loop\nIF checks for SUCCEEDED status. TRUE proceeds to per-video extraction. FALSE waits 30 seconds and polls again. Loop continues until summary is ready."
      },
      "typeVersion": 1
    },
    {
      "id": "29fddeac-d8af-42f0-b6d0-1b70ada7bd37",
      "name": "Section \u2014 Per-Video Extract, Aggregate, and AI Digest Writing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1904,
        32
      ],
      "parameters": {
        "color": 6,
        "width": 876,
        "height": 560,
        "content": "## Per-Video Extract, Aggregate, and AI Digest Writing\nCode node extracts summary, highlights, and tags per video. The Aggregate node (10) sits above to collect ALL processed items into one combined string before passing to GPT. GPT-4o-mini writes a 5-section daily digest. Note: node 10 receives all items at once after the last video is processed."
      },
      "typeVersion": 1
    },
    {
      "id": "198191dd-0f32-4002-bcd5-40485fdadedc",
      "name": "Section \u2014 Telegram Format, Send, and Sheet Logs",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -880,
        80
      ],
      "parameters": {
        "color": 4,
        "width": 900,
        "height": 372,
        "content": "## Telegram Format, Send, and Sheet Logs\nBuilds a Markdown-formatted Telegram message with auto-truncation at 4000 chars. Telegram Bot sends the digest. Google Sheets logs the digest to the Digest Log tab and marks all Video Queue rows as Processed."
      },
      "typeVersion": 1
    },
    {
      "id": "9b9c73e3-3a85-4a3d-b81e-90fbf79409b1",
      "name": "1. Schedule \u2014 Every Day 8AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -3792,
        208
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7aafbc3f-c274-4895-a0fd-e1fedaff5010",
      "name": "2. Google Sheets \u2014 Read Pending Videos",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -3552,
        208
      ],
      "parameters": {
        "operation": "getAll",
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_TREND_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "cbc9a2b5-d612-4c55-8fe0-252265721817",
      "name": "3. IF \u2014 Any Pending Videos Today?",
      "type": "n8n-nodes-base.if",
      "position": [
        -3312,
        208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "has-videos",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $items().length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "821e5bc1-27de-43c5-93ed-db92ae00e794",
      "name": "4. WayinVideo \u2014 Submit Summarization",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -3056,
        208
      ],
      "parameters": {
        "url": "https://wayinvideo-api.wayin.ai/api/v2/summaries",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"video_url\": \"{{ $json['Video URL'] }}\",\n  \"target_lang\": \"en\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "x-wayinvideo-api-version",
              "value": "v2"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "3fe5139e-f61d-4d4f-8513-42f15dde91bc",
      "name": "5. Wait \u2014 60 Seconds",
      "type": "n8n-nodes-base.wait",
      "position": [
        -2816,
        208
      ],
      "parameters": {
        "amount": 60
      },
      "typeVersion": 1.1
    },
    {
      "id": "3b9c7e11-fca6-443a-9117-3f7330d10600",
      "name": "6. WayinVideo \u2014 Get Summary Results",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2576,
        208
      ],
      "parameters": {
        "url": "=https://wayinvideo-api.wayin.ai/api/v2/summaries/results/{{ $('4. WayinVideo \u2014 Submit Summarization').item.json.data.id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "x-wayinvideo-api-version",
              "value": "v2"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f5bc7e59-a754-41aa-86ff-047159fff420",
      "name": "7. IF \u2014 Summary Complete?",
      "type": "n8n-nodes-base.if",
      "position": [
        -2288,
        208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "summary-status",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.data.status }}",
              "rightValue": "SUCCEEDED"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "ed5d04c7-24da-4dab-ace6-91d28dfd4489",
      "name": "8. Wait \u2014 30 Seconds Retry",
      "type": "n8n-nodes-base.wait",
      "position": [
        -2288,
        416
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "69ff2ced-94fa-4388-9374-fd0b09ca801a",
      "name": "9. Code \u2014 Extract Summary Per Video",
      "type": "n8n-nodes-base.code",
      "position": [
        -1840,
        192
      ],
      "parameters": {
        "jsCode": "// Extract summary data and store per video\nconst summaryData = $('6. WayinVideo \u2014 Get Summary Results').item.json.data;\nconst videoUrl = $('2. Google Sheets \u2014 Read Pending Videos').item.json['Video URL'];\nconst videoTitle = $('2. Google Sheets \u2014 Read Pending Videos').item.json['Video Title'] || 'Untitled';\nconst niche = $('2. Google Sheets \u2014 Read Pending Videos').item.json['Niche / Category'] || 'General';\nconst dateAdded = $('2. Google Sheets \u2014 Read Pending Videos').item.json['Date Added'] || new Date().toISOString().split('T')[0];\n\n// Extract summary fields\nconst summary = summaryData.summary || '';\nconst highlights = Array.isArray(summaryData.highlights)\n  ? summaryData.highlights.map(h => h.desc).filter(Boolean)\n  : [];\nconst tags = Array.isArray(summaryData.tags)\n  ? summaryData.tags\n  : [];\n\nreturn [{\n  json: {\n    videoUrl,\n    videoTitle,\n    niche,\n    dateAdded,\n    summary,\n    highlights,\n    tags,\n    highlightsText: highlights.join(' | '),\n    tagsText: tags.join(', ')\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "92f692cd-e8da-4b13-ba10-ea60161e7ffa",
      "name": "10. Code \u2014 Aggregate All Summaries",
      "type": "n8n-nodes-base.code",
      "position": [
        -1584,
        192
      ],
      "parameters": {
        "jsCode": "// Aggregate all video summaries into one item for the AI digest\n// This node collects all items processed so far\nconst allItems = $input.all();\n\nif (allItems.length === 0) {\n  throw new Error('No video summaries to compile into digest.');\n}\n\n// Build combined text for GPT\nconst allVideoSummaries = allItems.map((item, index) => {\n  const data = item.json;\n  return [\n    `VIDEO ${index + 1}: ${data.videoTitle}`,\n    `URL: ${data.videoUrl}`,\n    `Summary: ${data.summary}`,\n    `Key Highlights: ${data.highlightsText}`,\n    `Tags: ${data.tagsText}`,\n    `---`\n  ].join('\\n');\n}).join('\\n');\n\nconst niche = allItems[0].json.niche || 'General';\nconst videoUrls = allItems.map(item => item.json.videoUrl);\n\nreturn [{\n  json: {\n    allVideoSummaries,\n    totalVideos: allItems.length,\n    niche,\n    videoUrls\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "6a84e948-1a79-4f83-b58d-d5066755381f",
      "name": "11. AI Agent \u2014 Write Daily Digest",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1344,
        192
      ],
      "parameters": {
        "text": "=You are a social media trend analyst who writes sharp, actionable daily digests for marketing teams.\n\nYour team tracks trending TikTok videos in their niche every day. Today's batch of videos has been summarized by AI. Your job is to compile all these summaries into one clean, scannable daily digest that the team can read in under 2 minutes on Telegram.\n\n---\n\n## TODAY'S TRENDING VIDEOS\n\n{{ $json.allVideoSummaries }}\n\n---\n\n## DIGEST WRITING RULES\n1. Write for a fast-moving social media team \u2014 bullet points and short sentences only\n2. Start with a 1-2 sentence overview of today's overall trend patterns\n3. Cover each video briefly \u2014 what it was about and why it is trending\n4. Extract the top 3 content patterns or hooks being used across these videos\n5. End with 2-3 specific action recommendations for the team\n6. Total length: 300-400 words maximum \u2014 Telegram readers skim\n7. Use emojis sparingly \u2014 only for section headers\n8. No generic filler \u2014 every sentence must add value\n\n---\n\n## OUTPUT FORMAT\nReturn in this exact structure:\n\nDIGEST_OVERVIEW:\n[1-2 sentence overview of today's trends]\n\nVIDEO_SUMMARIES:\n[For each video \u2014 one bullet point: Video title/topic \u2014 what it covers \u2014 why it is trending]\n\nTOP_PATTERNS:\n[3 bullet points \u2014 content patterns or hooks being used today]\n\nACTION_RECOMMENDATIONS:\n[2-3 bullet points \u2014 specific things the team should do or create today]\n\nTOP_TAGS:\n[Top 8 tags from today's videos \u2014 comma separated]",
        "options": {
          "systemMessage": "=You are an expert social media trend analyst. Date: {{ $now.toFormat('dd MMMM yyyy') }}. Niche being tracked: {{ $json.niche }}. Total videos today: {{ $json.totalVideos }}."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "6afe74e2-fcb0-49d7-aa5b-f92244fbe859",
      "name": "12. OpenAI \u2014 GPT-4o-mini Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1344,
        432
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "09f927c3-ad67-4ce0-86b9-b59340be3689",
      "name": "13. Code \u2014 Format Telegram Message",
      "type": "n8n-nodes-base.code",
      "position": [
        -800,
        208
      ],
      "parameters": {
        "jsCode": "// Parse AI digest output and format for Telegram\nconst output = $input.first().json.output || '';\nconst niche = $input.first().json.niche || 'General';\nconst totalVideos = $input.first().json.totalVideos || 0;\nconst videoUrls = $input.first().json.videoUrls || [];\n\n// Extract sections\nconst overviewMatch = output.match(/DIGEST_OVERVIEW:\\s*([\\s\\S]*?)(?=\\nVIDEO_SUMMARIES:|$)/);\nconst summariesMatch = output.match(/VIDEO_SUMMARIES:\\s*([\\s\\S]*?)(?=\\nTOP_PATTERNS:|$)/);\nconst patternsMatch = output.match(/TOP_PATTERNS:\\s*([\\s\\S]*?)(?=\\nACTION_RECOMMENDATIONS:|$)/);\nconst actionsMatch = output.match(/ACTION_RECOMMENDATIONS:\\s*([\\s\\S]*?)(?=\\nTOP_TAGS:|$)/);\nconst tagsMatch = output.match(/TOP_TAGS:\\s*([\\s\\S]*)$/);\n\nconst overview = overviewMatch ? overviewMatch[1].trim() : '';\nconst videoSummaries = summariesMatch ? summariesMatch[1].trim() : '';\nconst topPatterns = patternsMatch ? patternsMatch[1].trim() : '';\nconst actionRecs = actionsMatch ? actionsMatch[1].trim() : '';\nconst topTags = tagsMatch ? tagsMatch[1].trim() : '';\n\n// Build Telegram message\nconst today = new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' });\n\nconst telegramMessage = [\n  `\ud83d\udcf1 *TikTok Trend Digest \u2014 ${today}*`,\n  `_Niche: ${niche} | Videos Tracked: ${totalVideos}_`,\n  ``,\n  `\ud83d\udcca *Overview*`,\n  overview,\n  ``,\n  `\ud83c\udfac *Today's Videos*`,\n  videoSummaries,\n  ``,\n  `\ud83d\udd25 *Top Content Patterns*`,\n  topPatterns,\n  ``,\n  `\u2705 *Action Recommendations*`,\n  actionRecs,\n  ``,\n  `\ud83c\udff7\ufe0f *Trending Tags*`,\n  topTags,\n  ``,\n  `_Powered by WayinVideo + GPT-4o-mini_`\n].join('\\n');\n\n// Truncate if over Telegram limit\nconst truncated = telegramMessage.length > 4000\n  ? telegramMessage.substring(0, 3900) + '...\\n\\n_Message truncated \u2014 check digest log for full version_'\n  : telegramMessage;\n\nreturn [{\n  json: {\n    telegramMessage: truncated,\n    overview,\n    videoSummaries,\n    topPatterns,\n    actionRecs,\n    topTags,\n    niche,\n    totalVideos,\n    digestDate: today\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "d0a230e9-f30c-436f-945d-644a82abc059",
      "name": "14. Telegram \u2014 Send Daily Digest",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -624,
        208
      ],
      "parameters": {
        "text": "={{ $json.telegramMessage }}",
        "chatId": "YOUR_TELEGRAM_CHAT_ID",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "36429d2b-03a0-4715-911a-8860a224af5a",
      "name": "15. Google Sheets \u2014 Log Digest",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -416,
        208
      ],
      "parameters": {
        "columns": {
          "value": {
            "Niche": "={{ $('13. Code \u2014 Format Telegram Message').item.json.niche }}",
            "Sent On": "={{ $now.toFormat('dd MMMM yyyy HH:mm') }}",
            "Overview": "={{ $('13. Code \u2014 Format Telegram Message').item.json.overview }}",
            "Top Tags": "={{ $('13. Code \u2014 Format Telegram Message').item.json.topTags }}",
            "Digest Date": "={{ $('13. Code \u2014 Format Telegram Message').item.json.digestDate }}",
            "Top Patterns": "={{ $('13. Code \u2014 Format Telegram Message').item.json.topPatterns }}",
            "Telegram Sent": "Yes",
            "Videos Processed": "={{ $('13. Code \u2014 Format Telegram Message').item.json.totalVideos }}",
            "Action Recommendations": "={{ $('13. Code \u2014 Format Telegram Message').item.json.actionRecs }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Digest Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_TREND_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "cd3bf9a2-5255-4087-90d3-61513e038f27",
      "name": "16. Google Sheets \u2014 Mark Videos Processed",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -192,
        208
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Processed",
            "Video URL": "={{ $('9. Code \u2014 Extract Summary Per Video').item.json.videoUrl }}",
            "Processed Date": "={{ $now.toFormat('dd MMMM yyyy') }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Video URL"
          ]
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Video Queue"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_TREND_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    }
  ],
  "connections": {
    "5. Wait \u2014 60 Seconds": {
      "main": [
        [
          {
            "node": "6. WayinVideo \u2014 Get Summary Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7. IF \u2014 Summary Complete?": {
      "main": [
        [
          {
            "node": "9. Code \u2014 Extract Summary Per Video",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "8. Wait \u2014 30 Seconds Retry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8. Wait \u2014 30 Seconds Retry": {
      "main": [
        [
          {
            "node": "6. WayinVideo \u2014 Get Summary Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Schedule \u2014 Every Day 8AM": {
      "main": [
        [
          {
            "node": "2. Google Sheets \u2014 Read Pending Videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "12. OpenAI \u2014 GPT-4o-mini Model": {
      "ai_languageModel": [
        [
          {
            "node": "11. AI Agent \u2014 Write Daily Digest",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "15. Google Sheets \u2014 Log Digest": {
      "main": [
        [
          {
            "node": "16. Google Sheets \u2014 Mark Videos Processed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "14. Telegram \u2014 Send Daily Digest": {
      "main": [
        [
          {
            "node": "15. Google Sheets \u2014 Log Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "11. AI Agent \u2014 Write Daily Digest": {
      "main": [
        [
          {
            "node": "13. Code \u2014 Format Telegram Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3. IF \u2014 Any Pending Videos Today?": {
      "main": [
        [
          {
            "node": "4. WayinVideo \u2014 Submit Summarization",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "10. Code \u2014 Aggregate All Summaries": {
      "main": [
        [
          {
            "node": "11. AI Agent \u2014 Write Daily Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "13. Code \u2014 Format Telegram Message": {
      "main": [
        [
          {
            "node": "14. Telegram \u2014 Send Daily Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6. WayinVideo \u2014 Get Summary Results": {
      "main": [
        [
          {
            "node": "7. IF \u2014 Summary Complete?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9. Code \u2014 Extract Summary Per Video": {
      "main": [
        [
          {
            "node": "10. Code \u2014 Aggregate All Summaries",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. WayinVideo \u2014 Submit Summarization": {
      "main": [
        [
          {
            "node": "5. Wait \u2014 60 Seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Google Sheets \u2014 Read Pending Videos": {
      "main": [
        [
          {
            "node": "3. IF \u2014 Any Pending Videos Today?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}