Skip to content

Instantly share code, notes, and snippets.

@waptik
Created September 1, 2025 06:05
Show Gist options
  • Save waptik/2685d1f4863f6b4c6dff4d14d0c7948b to your computer and use it in GitHub Desktop.
Save waptik/2685d1f4863f6b4c6dff4d14d0c7948b to your computer and use it in GitHub Desktop.
Dev.to Real-Time AI Agents powered by n8n and Bright Data: Youtube & Tiktok video catchup digest
{
"name": "Catch up on your bookmarked Youtube & Tiktok videos",
"nodes": [
{
"parameters": {
"options": {
"reset": false
}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
464,
-272
],
"id": "68e688ea-9ebc-4fb4-8fea-7e08aab15464",
"name": "Loop Over Items",
"executeOnce": false
},
{
"parameters": {
"jsCode": "\n$input.item.json.platform = null;\n\nconst possibleYTChannelLinks = [\n /youtu\\.be\\/[A-Za-z0-9]+/,\n /^https?:\\/\\/(?:www\\.)?youtube\\.com\\/shorts\\/[A-Za-z0-9]+/,\n /^https?:\\/\\/(?:m\\.)?youtube\\.com\\/shorts\\/[A-Za-z0-9]+/,\n /^https?:\\/\\/(?:m\\.)?youtube\\.com\\/watch\\?v=[A-Za-z0-9]+/,\n /^https?:\\/\\/(?:www\\.)?youtube\\.com\\/watch\\?v=[A-Za-z0-9]+/,\n /^https?:\\/\\/(?:www\\.)?youtube\\.com\\/embed\\/[A-Za-z0-9]+/,\n /^https?:\\/\\/(?:www\\.)?youtube\\.com\\/live\\/[A-Za-z0-9]+/,\n /^https?:\\/\\/(?:m\\.)?youtube\\.com\\/watch\\?v=[A-Za-z0-9]+/,\n]\n\n\nconst possibleTikTokVideoLinks=[\n /^https?:\\/\\/(www\\.)?tiktok\\.com\\/@[^/]+\\/video\\/\\d+/,\n /^https?:\\/\\/m\\.tiktok\\.com\\/@[^/]+\\/video\\/\\d+/,\n /^https?:\\/\\/[a-z]{2}\\.tiktok\\.com\\/@[^/]+\\/video\\/\\d+/,\n /^https?:\\/\\/vm\\.tiktok\\.com\\/[A-Za-z0-9]+/,\n /^https?:\\/\\/(www\\.)?tiktok\\.com\\/v\\/\\d+/,\n /^https?:\\/\\/(www\\.)?tiktok\\.com\\/video\\/\\d+/,\n /^https?:\\/\\/(www\\.)?tiktok\\.com\\/t\\/[A-Za-z0-9]+/\n]\n\n\nfunction isValidTikTokUrl(url) {\n return possibleTikTokVideoLinks.some((domain) => domain.test(url));\n}\n\nconst isValidYoutubeUrl = (url) => {\n return possibleYTChannelLinks.some((domain) => domain.test(url));\n};\n\n\nconst items = $input.all();\nconst urls = [];\nfor (let i = 0; i < items.length; i++) {\n const chatInput = items[i]?.json?.chatInput || \"\";\n const urlArr = chatInput\n .split(\",\")\n .map((str) => str.trim())\n .filter(url => url.length > 0)\n console.log({urlArr})\n\n const urlArrWithPlatform=urlArr\n .map(url => {\n\n let platform = null\n\n if (isValidTikTokUrl(url)) {\n platform = \"tiktok\"\n } else if (isValidYoutubeUrl(url)){\n platform = \"youtube\"\n }\n\n return { json: { url, platform }}\n })\n\n console.log({urlArrWithPlatform})\n \n urls.push(...urlArrWithPlatform);\n}\nreturn urls;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
240,
-272
],
"id": "e41d5c70-d8cf-4bf5-b04b-706460be648d",
"name": "Split text into array of urls"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"name": "Go to next url object",
"typeVersion": 1,
"position": [
1328,
-464
],
"id": "61cd774f-bbde-4345-b308-1f1d67c2146e"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $json.platform }}",
"rightValue": "youtube",
"operator": {
"type": "string",
"operation": "equals"
},
"id": "13162c00-56f4-438b-8c85-93e07e4fdab3"
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "youtube channel"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "372ab8ff-a2f5-4dea-add9-1620068bdf04",
"leftValue": "={{ $json.platform }}",
"rightValue": "tiktok",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "tiktok profile"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "54db8eb3-0014-463b-a521-cb7c5b009a5b",
"leftValue": "={{ $json.platform }}",
"rightValue": "null",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "platform is null"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
688,
-672
],
"id": "760819b7-8c77-43c8-9c83-ad39d507baae",
"name": "Check url platform"
},
{
"parameters": {
"resource": "webScrapper",
"dataset_id": {
"__rl": true,
"value": "gd_lu702nij2f790tmv9h",
"mode": "list",
"cachedResultName": "TikTok - Posts"
},
"urls": "=[{\"url\": \"{{ $('Loop Over Items').item.json.url }}\"}]",
"requestOptions": {}
},
"type": "@brightdata/n8n-nodes-brightdata.brightData",
"typeVersion": 1,
"position": [
912,
-656
],
"id": "4deea833-a94b-4ece-bb64-4f76f19887da",
"name": "Tiktok user info",
"credentials": {
"brightdataApi": {
"id": "",
"name": "BrightData account"
}
}
},
{
"parameters": {
"resource": "webScrapper",
"dataset_id": {
"__rl": true,
"value": "gd_lk56epmy2i5g7lzu0k",
"mode": "list",
"cachedResultName": "Youtube - Videos posts"
},
"urls": "=[{\"url\":\"{{ $json.url }}\"}]",
"include_errors": true,
"requestOptions": {}
},
"type": "@brightdata/n8n-nodes-brightdata.brightData",
"typeVersion": 1,
"position": [
1328,
-848
],
"id": "1ad2dfd4-8618-426d-ad29-681411711fe7",
"name": "Extract structured data from a single URL",
"credentials": {
"brightdataApi": {
"id": "",
"name": "BrightData account"
}
}
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
2512,
-448
],
"id": "8915a294-2503-4ab3-894a-ea7a9a8e498f",
"name": "Google Gemini Chat Model",
"credentials": {
"googlePalmApi": {
"id": "",
"name": "Google Gemini(PaLM) Api account"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "7293f891-89fc-4fe7-9047-0630515430af",
"leftValue": "={{ $json.transcript }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1760,
-848
],
"id": "c221ae66-25c5-4cd4-9f76-b6bc234f0380",
"name": "Does youtube video have a transcript?"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "8fa6ec67-065e-4808-9244-ace8cf53bd2b",
"name": "url",
"value": "=https://www.youtube.com/watch?v={{ $json.video_id }}",
"type": "string"
},
{
"id": "dc546035-edb8-4459-b492-809a1ac888b4",
"name": "title",
"value": "={{ $json.title }}",
"type": "string"
},
{
"id": "4fcdc06d-b981-44b5-aceb-41f25465ca83",
"name": "youtuber",
"value": "={{ $json.youtuber }}",
"type": "string"
},
{
"id": "b6e6e8d0-4538-48e2-9d9d-af088e8654af",
"name": "channel_url",
"value": "={{ $json.channel_url }}",
"type": "string"
},
{
"id": "65201b0d-0800-4b0f-a67f-872a3cdea145",
"name": "date_posted",
"value": "={{ $json.date_posted }}",
"type": "string"
},
{
"id": "6ca5e683-2ebc-40d6-a7bd-ead98ff8ad58",
"name": "video_length",
"value": "={{ $json.video_length }}",
"type": "number"
},
{
"id": "7b847a2a-0a13-4769-ac23-17f4ba095b95",
"name": "likes",
"value": "={{ $json.likes }}",
"type": "number"
},
{
"id": "9d16bf80-deda-462c-a71a-fa5baf46fbdf",
"name": "subscribers",
"value": "={{ $json.subscribers }}",
"type": "number"
},
{
"id": "14fe71e7-b0ca-4cd1-90df-6e5646497726",
"name": "num_comments",
"value": "={{ $json.num_comments }}",
"type": "number"
},
{
"id": "afabffaf-5e0a-4c4c-9edb-47ecdda1370a",
"name": "description",
"value": "={{ $json.description }}",
"type": "string"
},
{
"id": "01d18083-2f26-4d78-8c7c-c791c1665139",
"name": "transcript",
"value": "={{ $json.transcript }}",
"type": "string"
},
{
"id": "16a3fb64-ab1a-4d0e-9ec5-5e0dd130decc",
"name": "tags",
"value": "={{ $json.tags }}",
"type": "array"
},
{
"id": "abc562aa-36cd-402a-acf3-27ae6e702abc",
"name": "language",
"value": "={{ $json.transcript_language[0].language }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1984,
-848
],
"id": "1e288700-0a0c-45fe-a2f9-40dd6b64feb6",
"name": "Extract essential data"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "9cc57541-cad3-4b5f-b67d-ff9c7d9ab5a6",
"name": "postdata",
"value": "=Youtuber: {{ $json.youtuber }}\nURL: {{ $json.url }}\nTitle: {{ $json.title }}\nDescription: {{ $json.description }}\nUploaded on: {{ $json.date_posted }}\nDuration: {{ $json.video_length }}s\nTranscript: {{ $json.transcript }}\nLanguage: {{ $json.language }}\nComments: {{ $json.num_comments }}\nLikes: {{ $json.likes }}\nSubscribers: {{ $json.subscribers }}\nTags: {{ $json.tags.join(\", \") }}\n",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2208,
-848
],
"id": "1e3e1b0e-04de-4025-9768-0cc135161d99",
"name": "Reduce Objects to 1"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.postdata }}",
"options": {
"systemMessage": "You are an AI Agent whose role is to act as a Daily Video Digest Newsletter Generator.\n\n**Role:**\nYou are an AI Agent specialising in summarising YouTube and TikTok video content and generating daily catch-up newsletters.\n\n**Task:**\nYour primary task is to process given YouTube and TikTok video data, including URLs and transcripts, to create personalised daily newsletters for users and send it to their emails.\nYou must transform video transcripts into three distinct sections: a section for the full transcript and its language, another one about summary of the video and finally one in a Morning Brew style email newsletter format for deeper insights. It's crucial to utilize both the video link and the full transcript to ensure comprehensive and accurate context for content generation, as transcripts alone may lack detail.\nAlso, include engagement stats of the video and that of the channel right before the sections previously mentioned.\nFor each video, you must users receive their email digest, summarizing all relevant videos from their favorite creators.\nIF NO TITLE IS PROVIDED IN THE INPUT, KINDLY GENERATE ONE BASED ON THE TRANSCRIPT AND/OR DESCRIPTION.\nDO NOT INCLUDE ANYTHING ABOUT STORYTELLING OR MORNING-BREW. SIMPLY STATE \"SUMMARY\" OR \"INSIGHTS\" OR SOMETHING ALONG THAT LINE.\nONLY SEND ONE EMAIL PER VIDEO.\n\n**Tools:**\nYou have access to the following tool:\n- `sendNewsletter`: This tool allows you to send an email. It requires a `subject` (string) and a `message` (string, in HTML format) for the email body. The email will be sent to the user's registered email address.\n\n**Output:**\nUpon completion of the task, in your final output, you must return a JSON object summarizing the email sending activity. \nUse the following format:\n```json\n{\n \"video_title\": <user_provided_or_autogenerated_title>, // \"YouTube Video Title\" or “Title generated by agent”\n \"video_url\": \"https://www.youtube.com/watch?v=some-id\",\n \"short_summary\": \"A brief, concise summary of the video content.\",\n \"email_subject\": \"Your Daily Catch-Up on [Youtuber/Tiktoker Name] Videos!\",\n \"email_body_html\": \"<html>...</html>\"\n // ... additional emails\n}\n```\n\n**Input Example (for your reference):**\n```json\n{\n \"title\": \"Automate a Viral Newsletter Using n8n + Real-Time Web Data\", (optional for tiktok)\n \"url\": \"https://www.youtube.com/watch?v=SoDip-tvZ0Y\",\n \"description\": \"Join us for a free, live demo with our partner n8n, where we’ll show you how to automate a viral newsletter using Bright Data’s verified node in n8n’s powerful workflows.\",\n \"upvotes\": 104,\n \"comment_count\": 3,\n \"comments\": \"[{\\\"comment\\\":\\\"Great demo! Learned a lot about Bright Data.\\\"}, {\\\"comment\\\":\\\"Is there a way to integrate this with email marketing platforms?\\\"}, {\\\"comment\\\":\\\"This is brilliant for daily content curation.\\\"}]\"\n// … additional video metadata\n}\n// Note: If multiple videos are processed, they will be joined like this:\n// {video1_data}\\n\\n{video2_data}\\n\\n{video3_data}\n```"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2.2,
"position": [
2576,
-672
],
"id": "45f42098-6aab-4a76-94f4-5603e7c68af2",
"name": "Summary & Insights Agent"
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.3,
"position": [
16,
-272
],
"id": "bff51394-f3ad-4e25-b090-9227301b5139",
"name": "When chat message received",
"webhookId": "2a30d2b4-c135-4c6b-93c2-0e73a0e7091b"
},
{
"parameters": {},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
2640,
-448
],
"id": "eee1fc71-df19-45d2-91db-de8660e2b348",
"name": "Simple Memory for Summary Agent"
},
{
"parameters": {
"url": "=https://api.supadata.ai/v1/transcript?url={{ $json.url }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1840,
-672
],
"id": "2f60cb19-a5b3-4a3e-9412-4e0a1ed45129",
"name": "Tiktok video transcription from supadata.ai",
"credentials": {
"httpHeaderAuth": {
"id": "",
"name": "Supabdata.io Auth"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "2700b419-ce5c-42d7-958d-aefd60521611",
"name": "url",
"value": "={{ $('Tiktok user info').item.json.url }}",
"type": "string"
},
{
"id": "0bbc72b6-c4e1-4f51-8938-05b583717092",
"name": "tiktoker",
"value": "={{ $('Tiktok user info').item.json.profile_username }}",
"type": "string"
},
{
"id": "aa1d62fc-372e-4993-9d7b-f8dc23a52b82",
"name": "duration",
"value": "={{ $('Tiktok user info').item.json.video_duration }}",
"type": "number"
},
{
"id": "da818b2e-abc7-4939-9eab-529896bca0f6",
"name": "view_count",
"value": "={{ $('Tiktok user info').item.json.play_count }}",
"type": "number"
},
{
"id": "eeb99ed4-13df-449f-80ea-8569afefa623",
"name": "comment_count",
"value": "={{ $('Tiktok user info').item.json.comment_count }}",
"type": "number"
},
{
"id": "d7307cc9-024d-421e-b40e-bd31e95c46e1",
"name": "bookmark_count",
"value": "={{ $('Tiktok user info').item.json.collect_count }}",
"type": "number"
},
{
"id": "fd7f13cc-2b5d-4147-81ff-fc94542e1b23",
"name": "share_count",
"value": "={{ $('Tiktok user info').item.json.share_count }}",
"type": "string"
},
{
"id": "f828bf36-4415-4682-95e6-0e56379a9d11",
"name": "digg_count",
"value": "={{ $('Tiktok user info').item.json.digg_count }}",
"type": "number"
},
{
"id": "a2d43205-bc3e-4435-8fa9-b99f8092d3d2",
"name": "create_time",
"value": "={{ $('Tiktok user info').item.json.create_time }}",
"type": "string"
},
{
"id": "322272ba-674f-4f00-bdc7-c64360933716",
"name": "description",
"value": "={{ $('Tiktok user info').item.json.description }}",
"type": "string"
},
{
"id": "268ee142-ac50-41da-b72b-17be14551761",
"name": "transcript",
"value": "={{ $json.content.map(c=>c.text).join('\\n') }}",
"type": "string"
},
{
"id": "23b8fca4-1987-4a3b-a9ea-416f733ca440",
"name": "language",
"value": "={{ $json.lang }}",
"type": "string"
},
{
"id": "e7bd5ce6-60f2-40fd-a9b8-db8ff28f64d8",
"name": "hashtags",
"value": "={{ $('Tiktok user info').item.json.hashtags.join(', ') }}",
"type": "string"
},
{
"id": "4b3e5da3-a98f-4923-959b-587338d80b0d",
"name": "followers",
"value": "={{ $('Tiktok user info').item.json.profile_followers }}",
"type": "number"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2064,
-672
],
"id": "c7719be3-bc0c-466d-9b6d-e99abfd38518",
"name": "Structure tiktok video data"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "a40a5e2b-f998-410f-9710-599f18db028a",
"name": "postdata",
"value": "=Tiktoker: {{ $json.tiktoker }}\nURL: {{ $json.url }}\nDescription: {{ $json.description }}\nUploaded on: {{ $json.create_time }} \nDuration: {{ $json.duration }}s \nTranscript: {{ $json.transcript }} \nLanguage: {{ $json.language }} \nComments: {{ $json.comment_count }}\nLikes: {{ $json.digg_count }}\nShare: {{ $json.share_count }}\nViews: {{ $json.view_count }}\nBookmarks: {{ $json.bookmark_count }} \nFollowers: {{ $json.followers }} \nTags: {{ $json.hashtags }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2288,
-672
],
"id": "5e07ea49-4ab7-4601-8361-c1a45d843a94",
"name": "Reduce Objects to "
},
{
"parameters": {
"sendTo": "[email protected]",
"subject": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Subject', ``, 'string') }}",
"message": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message', ``, 'string') }}",
"options": {}
},
"type": "n8n-nodes-base.gmailTool",
"typeVersion": 2.1,
"position": [
2768,
-448
],
"id": "5af7c6bd-c169-4de6-8bc4-4a35f5b80e46",
"name": "sendNewsletter",
"webhookId": "aab0ff1d-bc1b-473b-98c4-ffb603a64aca",
"credentials": {
"gmailOAuth2": {
"id": "",
"name": "Gmail account"
}
}
}
],
"pinData": {},
"connections": {
"Loop Over Items": {
"main": [
[],
[
{
"node": "Check url platform",
"type": "main",
"index": 0
}
]
]
},
"Split text into array of urls": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Go to next url object": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Check url platform": {
"main": [
[
{
"node": "Extract structured data from a single URL",
"type": "main",
"index": 0
}
],
[
{
"node": "Tiktok user info",
"type": "main",
"index": 0
}
],
[
{
"node": "Go to next url object",
"type": "main",
"index": 0
}
]
]
},
"Tiktok user info": {
"main": [
[
{
"node": "Tiktok video transcription from supadata.ai",
"type": "main",
"index": 0
}
]
]
},
"Extract structured data from a single URL": {
"main": [
[
{
"node": "Does youtube video have a transcript?",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Summary & Insights Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Does youtube video have a transcript?": {
"main": [
[
{
"node": "Extract essential data",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Extract essential data": {
"main": [
[
{
"node": "Reduce Objects to 1",
"type": "main",
"index": 0
}
]
]
},
"Reduce Objects to 1": {
"main": [
[
{
"node": "Summary & Insights Agent",
"type": "main",
"index": 0
}
]
]
},
"Summary & Insights Agent": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Split text into array of urls",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory for Summary Agent": {
"ai_memory": [
[
{
"node": "Summary & Insights Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Tiktok video transcription from supadata.ai": {
"main": [
[
{
"node": "Structure tiktok video data",
"type": "main",
"index": 0
}
]
]
},
"Structure tiktok video data": {
"main": [
[
{
"node": "Reduce Objects to ",
"type": "main",
"index": 0
}
]
]
},
"Reduce Objects to ": {
"main": [
[
{
"node": "Summary & Insights Agent",
"type": "main",
"index": 0
}
]
]
},
"sendNewsletter": {
"ai_tool": [
[
{
"node": "Summary & Insights Agent",
"type": "ai_tool",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "97b1a604-8e94-4483-9253-9a8fcd487e8f",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "419ee57538b9e7591da262f8ad7cad263ef014d587b7f964d02d381044b06e06"
},
"id": "YOkco5Yzof2gJcnH",
"tags": []
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment