This workflow follows the HTTP Request → Telegram 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 →
{
"_meta": {
"notes": "All credentials replaced with ${ENV_VAR} placeholders. Configure via Doppler or .env. Original had hardcoded receiver secret, ngrok URL, Supabase URL, internal n8n IP, Telegram chat ID, public TG channel handle \u2014 all replaced. Replace n8n credential IDs with your own after import."
},
"name": "YT Shorts Pilot v0.3 (zero-touch publish)",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 14 * * 1,2,4,5"
}
]
},
"triggerAtStartup": false,
"timezone": "Europe/Berlin"
},
"id": "cron-1400-berlin",
"name": "Schedule 14:00 Berlin Mon/Tue/Thu/Fri",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
240,
300
]
},
{
"parameters": {
"httpMethod": "POST",
"path": "yt-publish-now",
"responseMode": "lastNode",
"options": {}
},
"id": "webhook-manual",
"name": "Webhook manual yt-publish-now",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1.1,
"position": [
240,
500
]
},
{
"parameters": {
"method": "GET",
"url": "=${RECEIVER_BASE_URL}/queue/list",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Receiver-Secret",
"value": "=${RECEIVER_SECRET}"
}
]
},
"options": {
"timeout": 15000
}
},
"id": "get-queue-list",
"name": "GET /queue/list",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
460,
400
]
},
{
"parameters": {
"jsCode": "// Filter today's items from queue\nconst today = new Date().toISOString().slice(0,10);\nconst data = $input.first().json;\nconst items = Array.isArray(data.items) ? data.items : [];\nconst todaysItems = items.filter(it => it.publish_date === today);\nreturn todaysItems.length\n ? todaysItems.map(it => ({ json: { ...it, today } }))\n : [{ json: { empty: true, today } }];"
},
"id": "filter-today",
"name": "Filter today's items",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
400
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict"
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json.empty }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
}
},
"id": "if-empty",
"name": "Is today queue empty?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
900,
400
]
},
{
"parameters": {
"chatId": "=${TELEGRAM_TARGET_CHAT}",
"text": "={{ 'Queue empty for ' + $json.today + ' \u2014 no YouTube publish today.' }}",
"additionalFields": {
"parse_mode": "HTML"
}
},
"id": "tg-empty",
"name": "TG empty queue",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1120,
250
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "GET",
"url": "=${SUPABASE_GENESIS_URL}/rest/v1/yt_published?slug=eq.{{ $json.slug }}&select=slug,video_id,youtube_url",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/vnd.pgrst.object+json"
}
]
},
"options": {
"timeout": 15000,
"response": {
"response": {
"neverError": true,
"fullResponse": false
}
}
}
},
"id": "check-published",
"name": "Supabase: check yt_published",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1120,
550
],
"alwaysOutputData": true,
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Accept: pgrst.object returns either {slug, video_id, ...} if found, or {code:'PGRST116', ...} for 0 rows (with neverError=true).\n// Sometimes n8n wraps the response in {data: '<stringified json>'} if mime type is unknown \u2014 parse that case.\nlet r = $input.first().json || {};\nif (r.data && typeof r.data === 'string') {\n try { r = JSON.parse(r.data); } catch(e) { r = {}; }\n}\nconst alreadyPublished = !!(r && r.slug && r.video_id) && !r.code;\nconst items = $('Filter today\\'s items').all().map(x => x.json);\nconst firstItem = items.find(i => !i.empty) || {};\nreturn [{ json: { ...firstItem, already_published: alreadyPublished, existing: alreadyPublished ? r : null } }];"
},
"id": "merge-status",
"name": "Merge item + published status",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
550
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict"
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json.already_published }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
}
},
"id": "if-already",
"name": "Already published?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1560,
550
]
},
{
"parameters": {
"chatId": "=${TELEGRAM_TARGET_CHAT}",
"text": "={{ '<b>' + $json.slug + '</b> already published.\\n' + $json.existing.youtube_url }}",
"additionalFields": {
"parse_mode": "HTML",
"disable_web_page_preview": false
}
},
"id": "tg-already",
"name": "TG already published",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1780,
400
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict"
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json.rendered }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
}
},
"id": "if-rendered",
"name": "Already rendered?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1780,
700
]
},
{
"parameters": {
"chatId": "=${TELEGRAM_TARGET_CHAT}",
"text": "={{ '<b>' + $json.slug + '</b> \u2014 \"' + $json.title + '\"\\n\\nNot rendered. Trigger manually:\\n<code>curl -X POST ${RECEIVER_BASE_URL}/render_queued -H \"X-Receiver-Secret: $SECRET\" -H \"Content-Type: application/json\" -d ' + \"'\" + '{\"slug\":\"' + $json.slug + '\"}' + \"'\" + '</code>' }}",
"additionalFields": {
"parse_mode": "HTML"
}
},
"id": "tg-need-render",
"name": "TG need render",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2000,
800
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Build payload for /youtube/upload from queue item\nconst it = $input.first().json;\nconst mp4 = it.mp4_path || `${$env.CONTENT_MACHINE_RUNS_DIR || '/tmp/runs'}/${it.run_id || ''}/final.mp4`;\nconst titleBase = it.title || it.slug;\nconst title = (titleBase + ' #shorts').slice(0, 100);\nreturn [{ json: {\n slug: it.slug,\n mp4_path: mp4,\n title: title,\n description: ($env.AUTHOR_NAME || 'Author') + ' \u00b7 ' + ($env.AUTHOR_URL || 'https://example.com') + '\\n\\n#AI #ClaudeCode #Anthropic #shorts',\n tags: ['AI','Claude Code','Anthropic','Shorts','AI agents'],\n lang: it.lang || 'ru',\n privacy: 'public'\n}}];"
},
"id": "prepare-upload",
"name": "Prepare YT upload payload",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2000,
600
]
},
{
"parameters": {
"method": "POST",
"url": "=${RECEIVER_BASE_URL}/youtube/upload",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "X-Receiver-Secret",
"value": "=${RECEIVER_SECRET}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ mp4_path: $json.mp4_path, title: $json.title, description: $json.description, tags: $json.tags, lang: $json.lang, privacy: $json.privacy }) }}",
"options": {
"timeout": 300000
}
},
"id": "post-yt-upload",
"name": "POST /youtube/upload",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2220,
600
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict"
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $json.ok }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
}
},
"id": "if-upload-ok",
"name": "Upload ok?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
2440,
600
]
},
{
"parameters": {
"chatId": "=${TELEGRAM_TARGET_CHAT}",
"text": "={{ '<b>YT upload FAIL</b>\\n\\nslug=' + $('Prepare YT upload payload').first().json.slug + '\\nexit=' + ($json.exit_code ?? '?') + '\\n\\n<code>' + ($json.log || $json.error || 'no log').toString().slice(0, 300) + '</code>' }}",
"additionalFields": {
"parse_mode": "HTML"
}
},
"id": "tg-upload-fail",
"name": "TG upload FAIL",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
2660,
750
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "=${N8N_BASE_URL}/webhook/cm-publish",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ caption: '<b>' + $('Prepare YT upload payload').first().json.title.replace(' #shorts','') + '</b>\\n\\n' + $('Prepare YT upload payload').first().json.description.split('\\n')[0] + '\\n\\n' + $json.url + '\\n\\n#claude #ai #shorts' }) }}",
"options": {
"timeout": 15000
}
},
"id": "post-tg-channel",
"name": "POST cm-publish (TG channel)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2660,
500
]
},
{
"parameters": {
"method": "POST",
"url": "=${SUPABASE_GENESIS_URL}/rest/v1/yt_published",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=minimal"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ slug: $('Prepare YT upload payload').first().json.slug, video_id: $('POST /youtube/upload').first().json.video_id, youtube_url: $('POST /youtube/upload').first().json.url, tg_message_id: $json.message_id || null, privacy: $('Prepare YT upload payload').first().json.privacy, title: $('Prepare YT upload payload').first().json.title, notes: 'Auto-published by YT Shorts Pilot v0.3 cron' }) }}",
"options": {
"timeout": 15000
}
},
"id": "supabase-mark",
"name": "Supabase: mark yt_published",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2880,
500
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "=${TELEGRAM_TARGET_CHAT}",
"text": "={{ '<b>YouTube + TG published</b>\\n\\nslug: ' + $('Prepare YT upload payload').first().json.slug + '\\nyoutube: ' + $('POST /youtube/upload').first().json.url + '\\ntg msg_id: ' + ($('POST cm-publish (TG channel)').first().json.message_id ?? '?') + '\\nupload: ' + $('POST /youtube/upload').first().json.duration_s + 's' }}",
"additionalFields": {
"parse_mode": "HTML",
"disable_web_page_preview": false
}
},
"id": "tg-success",
"name": "TG success",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
3100,
500
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Schedule 14:00 Berlin Mon/Tue/Thu/Fri": {
"main": [
[
{
"node": "GET /queue/list",
"type": "main",
"index": 0
}
]
]
},
"Webhook manual yt-publish-now": {
"main": [
[
{
"node": "GET /queue/list",
"type": "main",
"index": 0
}
]
]
},
"GET /queue/list": {
"main": [
[
{
"node": "Filter today's items",
"type": "main",
"index": 0
}
]
]
},
"Filter today's items": {
"main": [
[
{
"node": "Is today queue empty?",
"type": "main",
"index": 0
}
]
]
},
"Is today queue empty?": {
"main": [
[
{
"node": "TG empty queue",
"type": "main",
"index": 0
}
],
[
{
"node": "Supabase: check yt_published",
"type": "main",
"index": 0
}
]
]
},
"Supabase: check yt_published": {
"main": [
[
{
"node": "Merge item + published status",
"type": "main",
"index": 0
}
]
]
},
"Merge item + published status": {
"main": [
[
{
"node": "Already published?",
"type": "main",
"index": 0
}
]
]
},
"Already published?": {
"main": [
[
{
"node": "TG already published",
"type": "main",
"index": 0
}
],
[
{
"node": "Already rendered?",
"type": "main",
"index": 0
}
]
]
},
"Already rendered?": {
"main": [
[
{
"node": "Prepare YT upload payload",
"type": "main",
"index": 0
}
],
[
{
"node": "TG need render",
"type": "main",
"index": 0
}
]
]
},
"Prepare YT upload payload": {
"main": [
[
{
"node": "POST /youtube/upload",
"type": "main",
"index": 0
}
]
]
},
"POST /youtube/upload": {
"main": [
[
{
"node": "Upload ok?",
"type": "main",
"index": 0
}
]
]
},
"Upload ok?": {
"main": [
[
{
"node": "POST cm-publish (TG channel)",
"type": "main",
"index": 0
}
],
[
{
"node": "TG upload FAIL",
"type": "main",
"index": 0
}
]
]
},
"POST cm-publish (TG channel)": {
"main": [
[
{
"node": "Supabase: mark yt_published",
"type": "main",
"index": 0
}
]
]
},
"Supabase: mark yt_published": {
"main": [
[
{
"node": "TG success",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"saveManualExecutions": true,
"saveExecutionProgress": true,
"timezone": "Europe/Berlin"
}
}
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.
httpHeaderAuthtelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
YT Shorts Pilot v0.3 (zero-touch publish). Uses httpRequest, telegram. Scheduled trigger; 19 nodes.
Source: https://github.com/DenisShokhirev041279/genesis-content-os/blob/main/workflows/YT_Shorts_Pilot_v0_3.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.
Auto Hunt. Uses httpRequest, googleSheets, rssFeedRead, telegram. Scheduled trigger; 78 nodes.
Auto-Hunt. Uses httpRequest, googleSheets, rssFeedRead, telegram. Scheduled trigger; 78 nodes.
This workflow runs daily at 9 AM, uses Perplexity to compile vaping industry news, optionally captures article screenshots via Browserless, and generates a HeyGen avatar video from a template. It then
. Uses googleSheets, telegram, httpRequest, wise. Scheduled trigger; 36 nodes.
GNCA AI News Pipeline. Uses rssFeedRead, httpRequest, telegram, errorTrigger. Scheduled trigger; 31 nodes.