AutomationFlowsSlack & Telegram › AI News Pipeline: RSS to Telegram

AI News Pipeline: RSS to Telegram

Original n8n title: Gnca AI News Pipeline

GNCA AI News Pipeline. Uses rssFeedRead, httpRequest, telegram, errorTrigger. Scheduled trigger; 29 nodes.

Cron / scheduled trigger★★★★☆ complexity29 nodesRSS Feed ReadHTTP RequestTelegramError Trigger
Slack & Telegram Trigger: Cron / scheduled Nodes: 29 Complexity: ★★★★☆ Added:

This workflow follows the Error Trigger → HTTP Request 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 →

Download .json
{
  "updatedAt": "2026-04-02T15:15:21.611Z",
  "createdAt": "2026-04-02T15:00:48.965Z",
  "id": "rNLTPrZvDUKi2UBP",
  "name": "GNCA AI News Pipeline",
  "description": null,
  "active": true,
  "isArchived": false,
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 12
            }
          ]
        }
      },
      "id": "sched-12h",
      "name": "Her 12 Saatte",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {},
      "id": "manual",
      "name": "Manuel Test",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        200
      ]
    },
    {
      "parameters": {
        "path": "gnca-trigger",
        "httpMethod": "POST",
        "responseMode": "onReceived",
        "options": {}
      },
      "id": "webhook-trigger",
      "name": "Admin Panel Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        400
      ]
    },
    {
      "parameters": {
        "url": "https://techcrunch.com/category/artificial-intelligence/feed/",
        "options": {}
      },
      "id": "rss1",
      "name": "RSS TechCrunch",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.1,
      "position": [
        260,
        -100
      ]
    },
    {
      "parameters": {
        "url": "https://www.theverge.com/rss/ai-artificial-intelligence/index.xml",
        "options": {}
      },
      "id": "rss2",
      "name": "RSS Verge",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.1,
      "position": [
        260,
        100
      ]
    },
    {
      "parameters": {
        "url": "https://feeds.feedburner.com/venturebeat/SZYF",
        "options": {}
      },
      "id": "rss3",
      "name": "RSS VBeat",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1.1,
      "position": [
        260,
        300
      ]
    },
    {
      "parameters": {
        "mode": "append"
      },
      "id": "merge",
      "name": "Birle\u015ftir",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [
        520,
        100
      ]
    },
    {
      "parameters": {
        "jsCode": "const allItems = $input.all();\nallItems.sort((a, b) => {\n  const dateA = new Date(a.json.pubDate || a.json.isoDate || a.json.date || 0);\n  const dateB = new Date(b.json.pubDate || b.json.isoDate || b.json.date || 0);\n  return dateB - dateA;\n});\nconst top5 = allItems.slice(0, 5);\nconst newsSummary = top5.map((item, i) => {\n  const title = item.json.title || 'No title';\n  const desc = (item.json.contentSnippet || item.json.content || item.json.description || '').replace(/<[^>]*>/g, '').substring(0, 300);\n  const link = item.json.link || '';\n  return (i+1) + '. ' + title + '\\n\u00d6zet: ' + desc + '\\nLink: ' + link;\n}).join('\\n\\n');\n\nconst systemPrompt = `Sen GNCA AI News'in i\u00e7erik edit\u00f6r\u00fcs\u00fcn. GNCA AI News, yapay zeka, m\u00fchendislik ve teknoloji d\u00fcnyas\u0131ndaki en g\u00fcncel geli\u015fmeleri T\u00fcrk\u00e7e olarak aktaran bir haber ve i\u00e7erik platformudur.\n\nG\u00d6REV: Verilen haberleri GNCA AI News'in Instagram hesab\u0131 (@gnc_ai) i\u00e7in profesyonel, bilgilendirici ve ilgi \u00e7ekici T\u00fcrk\u00e7e i\u00e7eriklere d\u00f6n\u00fc\u015ft\u00fcr.\n\nTON VE \u00dcSLUP:\n- Bilgilendirici ve otoriter, ama okunmas\u0131 keyifli\n- Teknoloji merakl\u0131lar\u0131na hitap eden, sekt\u00f6r dilini bilen ama herkesin anlayaca\u011f\u0131 bir dil\n- Haberin \u00f6nemini ve etkisini vurgula\n- Emoji kullan\u0131m\u0131: ba\u015fl\u0131kta 1 adet, caption i\u00e7inde en fazla 3 adet\n\nCAPTION YAPISI:\n1. Dikkat \u00e7ekici giri\u015f c\u00fcmlesi (1 c\u00fcmle)\n2. Her haber i\u00e7in 2-3 c\u00fcmle \u00f6zet (ne oldu + neden \u00f6nemli)\n3. Genel de\u011ferlendirme: Bu geli\u015fmelerin teknoloji d\u00fcnyas\u0131 i\u00e7in anlam\u0131 (1-2 c\u00fcmle)\n4. CTA: \"Takipte kal\u0131n, teknolojinin nabz\u0131n\u0131 birlikte tutuyoruz.\" veya benzeri\n\nHASHTAG STRATEJ\u0130S\u0130:\n- Sabit: #GNCA #GNCAINews #YapayZeka #AI #Teknoloji\n- Habere \u00f6zel 3-5 hashtag se\u00e7 (\u00f6rnek: #MachineLearning #Derin\u00d6\u011frenme #Robotik #OpenAI #Google #Startup #M\u00fchendislik #Yaz\u0131l\u0131m #B\u00fcy\u00fckVeri #IoT #GPT #LLM)\n- Toplam 8-12 hashtag\n\nG\u00d6RSEL MET\u0130N (overlayText):\n- G\u00f6rsel \u00fczerine yaz\u0131lacak k\u0131sa, etkileyici T\u00fcrk\u00e7e ba\u015fl\u0131k (max 40 karakter)\n- B\u00dcY\u00dcK HARF, net ve okunakli\n- \u00d6rnekler: \"AI D\u00dcNYASINDA YEN\u0130 D\u00d6NEM\", \"YAPAY ZEKA DEVR\u0130M\u0130\", \"TEKNOLOJ\u0130DE SON GEL\u0130\u015eMELER\"\n\nTEK B\u0130R post, TEK JSON d\u00f6nd\u00fcr. Ba\u015fka hi\u00e7bir \u015fey yazma.`;\n\nconst userPrompt = `A\u015fa\u011f\u0131daki AI/teknoloji haberlerinden Instagram postu olu\u015ftur:\n\n` + newsSummary + `\n\nKURALLAR:\n1) title: Emoji ile ba\u015flayan dikkat \u00e7ekici ba\u015fl\u0131k, max 60 karakter\n2) overlayText: G\u00f6rsel \u00fczerine yaz\u0131lacak KISA T\u00fcrk\u00e7e ba\u015fl\u0131k, max 40 karakter, B\u00dcY\u00dcK HARF\n3) caption: T\u00fcrk\u00e7e profesyonel \u00f6zet, 800-1200 karakter aras\u0131, yukar\u0131daki yap\u0131y\u0131 takip et\n4) imagePrompt: DALL-E i\u00e7in \u0130ngilizce prompt - modern, teknoloji temal\u0131, kurumsal\n5) hashtags: 8-12 hashtag, string olarak bo\u015flukla ayr\u0131lm\u0131\u015f\n\nJSON format\u0131:\n{\"title\": \"...\", \"overlayText\": \"...\", \"caption\": \"...\", \"imagePrompt\": \"...\", \"hashtags\": \"...\"}\nSadece JSON d\u00f6nd\u00fcr, ba\u015fka bir \u015fey yazma.`;\n\nconst openaiBody = {\n  model: \"gpt-4o-mini\", temperature: 0.7, max_tokens: 2500,\n  messages: [\n    {role: \"system\", content: systemPrompt},\n    {role: \"user\", content: userPrompt}\n  ]\n};\nreturn [{ json: { newsCount: top5.length, newsSummary, openaiBody } }];"
      },
      "id": "sort",
      "name": "S\u0131rala & Haz\u0131rla",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        760,
        100
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/chat/completions",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_OPENAI_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.openaiBody) }}",
        "options": {
          "timeout": 60000
        }
      },
      "id": "openai",
      "name": "OpenAI",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1000,
        100
      ]
    },
    {
      "parameters": {
        "jsCode": "const response = $input.first().json;\nlet rawText = '';\nif (response.choices && response.choices[0]) {\n  rawText = response.choices[0].message.content;\n} else { throw new Error('OpenAI yan\u0131t vermedi'); }\n\n// Remove markdown code fences robustly\nlet cleaned = rawText;\nif (cleaned.indexOf('```') !== -1) {\n  const firstBrace = cleaned.indexOf('{');\n  const lastBrace = cleaned.lastIndexOf('}');\n  if (firstBrace !== -1 && lastBrace !== -1) {\n    cleaned = cleaned.substring(firstBrace, lastBrace + 1);\n  }\n}\n\n// Find first complete JSON object using brace depth\nlet depth = 0; let start = -1; let end = -1;\nfor (let i = 0; i < cleaned.length; i++) {\n  if (cleaned[i] === '{') { if (depth === 0) start = i; depth++; }\n  else if (cleaned[i] === '}') { depth--; if (depth === 0 && start !== -1) { end = i; break; } }\n}\nif (start !== -1 && end !== -1) cleaned = cleaned.substring(start, end + 1);\n\nlet content;\ntry {\n  content = JSON.parse(cleaned);\n} catch(e) {\n  throw new Error('JSON parse hatas\u0131. Temizlenen metin: ' + cleaned.substring(0, 300));\n}\n\nif (!content.title || !content.caption) throw new Error('title/caption eksik');\n\nconst overlayText = content.overlayText || content.title.replace(/[^\\w\\s\u011f\u00fc\u015f\u0131\u00f6\u00e7\u011e\u00dc\u015e\u0130\u00d6\u00c7]/g, '').substring(0, 40).toUpperCase();\n\nconst dalleBody = {\n  model: \"dall-e-3\",\n  prompt: (content.imagePrompt || \"Modern AI technology\") + \". Modern tech news illustration style. Clean geometric composition with vibrant gradients (deep purple, electric blue, cyan). Abstract digital elements like neural networks, data streams, code fragments, AI chip patterns. Futuristic and sleek aesthetic suitable for a technology news platform. Square format. Absolutely no text, letters, words, or numbers anywhere in the image.\",\n  n: 1, size: \"1024x1024\", quality: \"hd\"\n};\n\nreturn [{ json: {\n  title: content.title,\n  overlayText: overlayText,\n  caption: content.caption,\n  imagePrompt: content.imagePrompt || 'Modern AI technology social media post',\n  hashtags: content.hashtags || '#AI #YapayZeka #GNCA',\n  newsSummary: $('S\u0131rala & Haz\u0131rla').first().json.newsSummary,\n  newsCount: $('S\u0131rala & Haz\u0131rla').first().json.newsCount,\n  generatedAt: new Date().toISOString(),\n  dalleBody: dalleBody\n} }];"
      },
      "id": "parse",
      "name": "Parse Et",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1240,
        100
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/images/generations",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_OPENAI_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.dalleBody) }}",
        "options": {
          "timeout": 120000
        }
      },
      "id": "dalle",
      "name": "DALL-E",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1480,
        100
      ]
    },
    {
      "parameters": {
        "jsCode": "const imgData = $input.first().json;\n\nconst SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst headers = {\n  'apikey': SUPABASE_KEY,\n  'Authorization': 'Bearer ' + SUPABASE_KEY,\n  'Content-Type': 'application/json',\n  'Prefer': 'return=representation'\n};\n\n// Insert post with processed image URL (permanent Supabase Storage URL)\nconst postRes = await this.helpers.httpRequest({\n  method: 'POST',\n  url: SUPABASE_URL + '/rest/v1/posts',\n  headers,\n  body: JSON.stringify({\n    title: imgData.title,\n    caption: imgData.caption,\n    image_prompt: imgData.imagePrompt,\n    image_url: imgData.processedImageUrl,\n    hashtags: imgData.hashtags,\n    news_summary: imgData.newsSummary,\n    news_count: imgData.newsCount,\n    status: 'pending'\n  })\n});\n\nconst post = Array.isArray(postRes) ? postRes[0] : postRes;\n\n// Insert pipeline run\nawait this.helpers.httpRequest({\n  method: 'POST',\n  url: SUPABASE_URL + '/rest/v1/pipeline_runs',\n  headers: { ...headers, 'Prefer': 'return=minimal' },\n  body: JSON.stringify({\n    trigger_type: 'scheduled',\n    status: 'success',\n    post_id: post.id,\n    started_at: imgData.generatedAt || new Date().toISOString(),\n    finished_at: new Date().toISOString()\n  })\n});\n\nreturn [{ json: { ...post, imageUrl: imgData.processedImageUrl } }];"
      },
      "id": "save",
      "name": "Kaydet",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1840,
        100
      ]
    },
    {
      "parameters": {
        "chatId": "2099378542",
        "text": "=\ud83e\udd16 *GNCA AI Haber B\u00fclteni*\n\ud83d\udcc5 {{ $now.format('dd.MM.yyyy HH:mm') }}\n\n\ud83d\udccc *{{ $json.title }}*\n\n{{ $json.caption.substring(0, 800) }}\n\n---\n\ud83d\uddbc\ufe0f G\u00f6rsel: {{ $json.imageUrl ? '\u2705 \u00dcretildi' : '\u274c Yok' }}\n\n\u2705 /onayla \u2192 Yay\u0131nla\n\u274c /reddet \u2192 Reddet\n\ud83d\udcca /durum \u2192 Durum",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "tg-preview",
      "name": "Telegram \u00d6nizleme",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        2080,
        100
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "seconds",
              "secondsInterval": 30
            }
          ]
        }
      },
      "id": "sched-30s",
      "name": "Telegram Poll (30s)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        600
      ]
    },
    {
      "parameters": {
        "url": "https://api.telegram.org/bot8674444246:AAFWV1GrVNLSW4OxEtCXCgH1MTBgU9lpQ4U/getUpdates?timeout=5&limit=10&allowed_updates=[\"message\"]",
        "options": {
          "timeout": 10000
        }
      },
      "id": "tg-poll",
      "name": "Telegram API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        260,
        600
      ]
    },
    {
      "parameters": {
        "jsCode": "const result = $input.first().json;\n\nconst SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst headers = {\n  'apikey': SUPABASE_KEY,\n  'Authorization': 'Bearer ' + SUPABASE_KEY\n};\n\n// Read offset from settings\nlet currentOffset = 0;\ntry {\n  const offsetData = await this.helpers.httpRequest({\n    method: 'GET',\n    url: SUPABASE_URL + '/rest/v1/settings?key=eq.tg_offset&select=value',\n    headers\n  });\n  if (offsetData && offsetData.length > 0) {\n    currentOffset = parseInt(offsetData[0].value) || 0;\n  }\n} catch(e) { currentOffset = 0; }\n\nif (!result.ok || !result.result || result.result.length === 0) return [];\n\nconst messages = [];\nlet maxId = currentOffset;\n\nfor (const update of result.result) {\n  if (update.update_id < currentOffset) continue;\n  if (update.update_id >= maxId) maxId = update.update_id + 1;\n  \n  const msg = update.message;\n  if (!msg || String(msg.chat.id) !== '2099378542') continue;\n  const text = (msg.text || '').trim().toLowerCase();\n  if (text === '/onayla' || text === 'onayla') messages.push({ json: { action: 'approve' } });\n  else if (text === '/reddet' || text === 'reddet') messages.push({ json: { action: 'reject' } });\n  else if (text === '/durum' || text === 'durum') messages.push({ json: { action: 'status' } });\n}\n\n// Save new offset\nif (maxId > currentOffset) {\n  await this.helpers.httpRequest({\n    method: 'PATCH',\n    url: SUPABASE_URL + '/rest/v1/settings?key=eq.tg_offset',\n    headers: { ...headers, 'Content-Type': 'application/json' },\n    body: JSON.stringify({ value: String(maxId) })\n  });\n  \n  await this.helpers.httpRequest({\n    method: 'GET',\n    url: 'https://api.telegram.org/bot8674444246:AAFWV1GrVNLSW4OxEtCXCgH1MTBgU9lpQ4U/getUpdates?offset=' + maxId + '&limit=0'\n  });\n}\n\nreturn messages.length > 0 ? messages : [];"
      },
      "id": "tg-parse",
      "name": "Komut Ayr\u0131\u015ft\u0131r",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        520,
        600
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "conditions": [
                  {
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "approve",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Onayla"
            },
            {
              "conditions": {
                "conditions": [
                  {
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "reject",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Reddet"
            },
            {
              "conditions": {
                "conditions": [
                  {
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "status",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Durum"
            }
          ]
        }
      },
      "id": "switch",
      "name": "Aksiyon",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        760,
        600
      ]
    },
    {
      "parameters": {
        "jsCode": "const SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst headers = {\n  'apikey': SUPABASE_KEY,\n  'Authorization': 'Bearer ' + SUPABASE_KEY\n};\n\nconst posts = await this.helpers.httpRequest({\n  method: 'GET',\n  url: SUPABASE_URL + '/rest/v1/posts?status=eq.pending&order=created_at.desc&limit=1',\n  headers\n});\n\nif (!posts || posts.length === 0) throw new Error('\u0130\u00e7erik bulunamad\u0131! \u00d6nce i\u00e7erik \u00fcretin.');\nconst content = posts[0];\nif (!content.image_url) throw new Error('G\u00f6rsel URL yok!');\n\nreturn [{ json: { ...content, imageUrl: content.image_url } }];"
      },
      "id": "load",
      "name": "\u0130\u00e7erik Y\u00fckle",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1000,
        500
      ]
    },
    {
      "parameters": {
        "chatId": "2099378542",
        "text": "\u23f3 Instagram'a y\u00fckleniyor...",
        "additionalFields": {}
      },
      "id": "tg-loading",
      "name": "Y\u00fckleniyor",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1000,
        380
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://graph.facebook.com/v19.0/17841436005649126/media",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ image_url: $json.imageUrl, caption: $json.caption, access_token: \"EAAX5DGtac1kBRDCaQpcVbxHDZCjuJtwlK0qQZB0rvgQjzO5f7INg4TqDo454A9hQWZC0drlFXfR1PxUkZB4ANbBfZCHnP69rSbsfZBxdKjYDyd4x8RuDlUWR2zcjewaSIA0IZCwtb6meoeUktY70Wq35fJbIIcpJac5VxuhfSkLdXlzWZBc8tiuJL0mHDAZDZD\" }) }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "ig-create",
      "name": "IG Container",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1240,
        500
      ]
    },
    {
      "parameters": {
        "amount": 15,
        "unit": "seconds"
      },
      "id": "wait-ig",
      "name": "15s Bekle",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        1480,
        500
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://graph.facebook.com/v19.0/17841436005649126/media_publish",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ creation_id: $('IG Container').first().json.id, access_token: \"EAAX5DGtac1kBRDCaQpcVbxHDZCjuJtwlK0qQZB0rvgQjzO5f7INg4TqDo454A9hQWZC0drlFXfR1PxUkZB4ANbBfZCHnP69rSbsfZBxdKjYDyd4x8RuDlUWR2zcjewaSIA0IZCwtb6meoeUktY70Wq35fJbIIcpJac5VxuhfSkLdXlzWZBc8tiuJL0mHDAZDZD\" }) }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "ig-pub",
      "name": "IG Yay\u0131nla",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1720,
        500
      ]
    },
    {
      "parameters": {
        "jsCode": "const SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst headers = {\n  'apikey': SUPABASE_KEY,\n  'Authorization': 'Bearer ' + SUPABASE_KEY,\n  'Content-Type': 'application/json',\n  'Prefer': 'return=representation'\n};\n\nconst postId = $('\u0130\u00e7erik Y\u00fckle').first().json.id;\nconst igPostId = $input.first().json.id || 'unknown';\n\nconst updated = await this.helpers.httpRequest({\n  method: 'PATCH',\n  url: SUPABASE_URL + '/rest/v1/posts?id=eq.' + postId,\n  headers,\n  body: JSON.stringify({\n    status: 'published',\n    published_at: new Date().toISOString(),\n    instagram_post_id: igPostId\n  })\n});\n\nconst post = Array.isArray(updated) ? updated[0] : updated;\nreturn [{ json: { success: true, postId: igPostId, title: post.title } }];"
      },
      "id": "mark-pub",
      "name": "Yay\u0131n Kayd\u0131",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1960,
        500
      ]
    },
    {
      "parameters": {
        "chatId": "2099378542",
        "text": "=\u2705 *Yay\u0131nland\u0131!*\n\ud83c\udf89 Post ID: {{ $json.postId }}\n\ud83d\udccc {{ $json.title }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "tg-ok",
      "name": "Ba\u015far\u0131",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        2200,
        500
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst headers = {\n  'apikey': SUPABASE_KEY,\n  'Authorization': 'Bearer ' + SUPABASE_KEY,\n  'Content-Type': 'application/json'\n};\n\ntry {\n  // Get latest pending post\n  const posts = await this.helpers.httpRequest({\n    method: 'GET',\n    url: SUPABASE_URL + '/rest/v1/posts?status=eq.pending&order=created_at.desc&limit=1',\n    headers: { 'apikey': SUPABASE_KEY, 'Authorization': 'Bearer ' + SUPABASE_KEY }\n  });\n  if (posts && posts.length > 0) {\n    await this.helpers.httpRequest({\n      method: 'PATCH',\n      url: SUPABASE_URL + '/rest/v1/posts?id=eq.' + posts[0].id,\n      headers,\n      body: JSON.stringify({ status: 'rejected', rejected_at: new Date().toISOString() })\n    });\n  }\n} catch(e) {}\nreturn [{ json: { rejected: true } }];"
      },
      "id": "mark-rej",
      "name": "Red Kayd\u0131",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1000,
        700
      ]
    },
    {
      "parameters": {
        "chatId": "2099378542",
        "text": "\u274c *Reddedildi.* Yeni i\u00e7erik 12 saat sonra veya manuel \u00fcretilir.",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "tg-rej",
      "name": "Red Bildir",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1240,
        700
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\n\nlet s = 'Hen\u00fcz i\u00e7erik \u00fcretilmemi\u015f.';\ntry {\n  const posts = await this.helpers.httpRequest({\n    method: 'GET',\n    url: SUPABASE_URL + '/rest/v1/posts?order=created_at.desc&limit=1',\n    headers: { 'apikey': SUPABASE_KEY, 'Authorization': 'Bearer ' + SUPABASE_KEY }\n  });\n  if (posts && posts.length > 0) {\n    const c = posts[0];\n    const m = {'pending':'\u23f3 Onay bekliyor','approved':'\u2705 Onayland\u0131','published':'\u2705 Yay\u0131nland\u0131','rejected':'\u274c Reddedildi','failed':'\u26a0\ufe0f Ba\u015far\u0131s\u0131z'};\n    s = '\ud83d\udcca *Durum*\\n\ud83d\udccc ' + (c.title||'?') + '\\n\ud83d\udd04 ' + (m[c.status]||c.status) + '\\n\ud83d\udcc5 ' + (c.created_at||'?');\n  }\n} catch(e) {}\nreturn [{ json: { statusText: s } }];"
      },
      "id": "check-st",
      "name": "Durum Kontrol",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1000,
        880
      ]
    },
    {
      "parameters": {
        "chatId": "2099378542",
        "text": "={{ $json.statusText }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "tg-st",
      "name": "Durum Bildir",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        1240,
        880
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {},
      "id": "err",
      "name": "Hata Yakala",
      "type": "n8n-nodes-base.errorTrigger",
      "typeVersion": 1,
      "position": [
        0,
        1100
      ]
    },
    {
      "parameters": {
        "chatId": "2099378542",
        "text": "=\u26a0\ufe0f *Hata!*\n{{ $json.execution?.error?.message || 'Bilinmeyen hata' }}\nn8n: http://localhost:5678",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "id": "tg-err",
      "name": "Hata Bildir",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        260,
        1100
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// === G\u00f6rsel \u0130\u015fle: DALL-E g\u00f6rselini indir, metin ekle, Supabase Storage'a y\u00fckle ===\nconst { createCanvas, loadImage, GlobalFonts } = require('@napi-rs/canvas');\nconst https = require('https');\n\nconst dalleRes = $input.first().json;\nconst parsed = $('Parse Et').first().json;\n\n// DALL-E image URL\nlet dalleImageUrl = '';\nif (dalleRes.data && dalleRes.data[0]) {\n  dalleImageUrl = dalleRes.data[0].url;\n}\nif (!dalleImageUrl) throw new Error('DALL-E g\u00f6rsel URL bulunamad\u0131');\n\n// Download image as buffer using native https\nconst imageBuffer = await new Promise((resolve, reject) => {\n  https.get(dalleImageUrl, (res) => {\n    if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {\n      https.get(res.headers.location, (res2) => {\n        const chunks = [];\n        res2.on('data', chunk => chunks.push(chunk));\n        res2.on('end', () => resolve(Buffer.concat(chunks)));\n        res2.on('error', reject);\n      });\n      return;\n    }\n    const chunks = [];\n    res.on('data', chunk => chunks.push(chunk));\n    res.on('end', () => resolve(Buffer.concat(chunks)));\n    res.on('error', reject);\n  });\n});\n\n// Load into canvas\nconst img = await loadImage(imageBuffer);\nconst W = 1024;\nconst H = 1024;\nconst canvas = createCanvas(W, H);\nconst ctx = canvas.getContext('2d');\n\n// Draw original image\nctx.drawImage(img, 0, 0, W, H);\n\n// === Bottom gradient overlay ===\nconst barHeight = 180;\nconst gradientY = H - barHeight;\nconst gradient = ctx.createLinearGradient(0, gradientY, 0, H);\ngradient.addColorStop(0, 'rgba(0, 0, 0, 0)');\ngradient.addColorStop(0.3, 'rgba(0, 0, 0, 0.6)');\ngradient.addColorStop(1, 'rgba(0, 0, 0, 0.85)');\nctx.fillStyle = gradient;\nctx.fillRect(0, gradientY, W, barHeight);\n\n// === Overlay text ===\nconst overlayText = (parsed.overlayText || parsed.title || 'GNCA').substring(0, 45);\nctx.fillStyle = '#FFFFFF';\nctx.textAlign = 'left';\nctx.textBaseline = 'bottom';\n\n// Dynamic font sizing\nlet fontSize = 42;\nctx.font = `bold ${fontSize}px \"Arial\", \"Helvetica Neue\", sans-serif`;\nlet textMetrics = ctx.measureText(overlayText);\nwhile (textMetrics.width > 920 && fontSize > 24) {\n  fontSize -= 2;\n  ctx.font = `bold ${fontSize}px \"Arial\", \"Helvetica Neue\", sans-serif`;\n  textMetrics = ctx.measureText(overlayText);\n}\n\n// Text shadow\nctx.shadowColor = 'rgba(0, 0, 0, 0.7)';\nctx.shadowBlur = 8;\nctx.shadowOffsetX = 2;\nctx.shadowOffsetY = 2;\nctx.fillText(overlayText, 52, H - 70);\n\n// Reset shadow\nctx.shadowColor = 'transparent';\nctx.shadowBlur = 0;\nctx.shadowOffsetX = 0;\nctx.shadowOffsetY = 0;\n\n// === @gnc_ai watermark ===\nctx.font = 'bold 22px \"Arial\", \"Helvetica Neue\", sans-serif';\nctx.fillStyle = 'rgba(255, 255, 255, 0.75)';\nctx.textAlign = 'right';\nctx.textBaseline = 'bottom';\nctx.fillText('@gnc_ai', W - 40, H - 30);\n\n// === Blue accent line ===\nctx.strokeStyle = '#0ea5e9';\nctx.lineWidth = 3;\nctx.beginPath();\nctx.moveTo(52, H - 80 - fontSize * 0.3);\nctx.lineTo(200, H - 80 - fontSize * 0.3);\nctx.stroke();\n\n// === Encode PNG ===\nconst pngBuffer = canvas.toBuffer('image/png');\n\n// === Upload to Supabase Storage ===\nconst SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst bucketName = 'post-images';\nconst fileName = 'post_' + Date.now() + '.png';\n\nconst uploadUrl = new URL(SUPABASE_URL + '/storage/v1/object/' + bucketName + '/' + fileName);\nconst uploadRes = await new Promise((resolve, reject) => {\n  const req = https.request({\n    hostname: uploadUrl.hostname,\n    path: uploadUrl.pathname,\n    method: 'POST',\n    headers: {\n      'apikey': SUPABASE_KEY,\n      'Authorization': 'Bearer ' + SUPABASE_KEY,\n      'Content-Type': 'image/png',\n      'Content-Length': pngBuffer.length,\n      'x-upsert': 'true'\n    }\n  }, (res) => {\n    let body = '';\n    res.on('data', chunk => body += chunk);\n    res.on('end', () => {\n      if (res.statusCode >= 200 && res.statusCode < 300) {\n        resolve(JSON.parse(body));\n      } else {\n        reject(new Error('Storage upload hatas\u0131: ' + res.statusCode + ' ' + body));\n      }\n    });\n  });\n  req.on('error', reject);\n  req.write(pngBuffer);\n  req.end();\n});\n\nconst publicImageUrl = SUPABASE_URL + '/storage/v1/object/public/' + bucketName + '/' + fileName;\n\nreturn [{ json: {\n  ...parsed,\n  originalImageUrl: dalleImageUrl,\n  processedImageUrl: publicImageUrl,\n  imageFileName: fileName\n} }];"
      },
      "id": "img-process",
      "name": "G\u00f6rsel \u0130\u015fle",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1600,
        100
      ]
    }
  ],
  "connections": {
    "Her 12 Saatte": {
      "main": [
        [
          {
            "node": "RSS TechCrunch",
            "type": "main",
            "index": 0
          },
          {
            "node": "RSS Verge",
            "type": "main",
            "index": 0
          },
          {
            "node": "RSS VBeat",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manuel Test": {
      "main": [
        [
          {
            "node": "RSS TechCrunch",
            "type": "main",
            "index": 0
          },
          {
            "node": "RSS Verge",
            "type": "main",
            "index": 0
          },
          {
            "node": "RSS VBeat",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Admin Panel Trigger": {
      "main": [
        [
          {
            "node": "RSS TechCrunch",
            "type": "main",
            "index": 0
          },
          {
            "node": "RSS Verge",
            "type": "main",
            "index": 0
          },
          {
            "node": "RSS VBeat",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RSS TechCrunch": {
      "main": [
        [
          {
            "node": "Birle\u015ftir",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RSS Verge": {
      "main": [
        [
          {
            "node": "Birle\u015ftir",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "RSS VBeat": {
      "main": [
        [
          {
            "node": "Birle\u015ftir",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Birle\u015ftir": {
      "main": [
        [
          {
            "node": "S\u0131rala & Haz\u0131rla",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "S\u0131rala & Haz\u0131rla": {
      "main": [
        [
          {
            "node": "OpenAI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI": {
      "main": [
        [
          {
            "node": "Parse Et",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Et": {
      "main": [
        [
          {
            "node": "DALL-E",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "DALL-E": {
      "main": [
        [
          {
            "node": "G\u00f6rsel \u0130\u015fle",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Kaydet": {
      "main": [
        [
          {
            "node": "Telegram \u00d6nizleme",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Poll (30s)": {
      "main": [
        [
          {
            "node": "Telegram API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram API": {
      "main": [
        [
          {
            "node": "Komut Ayr\u0131\u015ft\u0131r",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Komut Ayr\u0131\u015ft\u0131r": {
      "main": [
        [
          {
            "node": "Aksiyon",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aksiyon": {
      "main": [
        [
          {
            "node": "\u0130\u00e7erik Y\u00fckle",
            "type": "main",
            "index": 0
          },
          {
            "node": "Y\u00fckleniyor",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Red Kayd\u0131",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Durum Kontrol",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u0130\u00e7erik Y\u00fckle": {
      "main": [
        [
          {
            "node": "IG Container",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IG Container": {
      "main": [
        [
          {
            "node": "15s Bekle",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "15s Bekle": {
      "main": [
        [
          {
            "node": "IG Yay\u0131nla",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IG Yay\u0131nla": {
      "main": [
        [
          {
            "node": "Yay\u0131n Kayd\u0131",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Yay\u0131n Kayd\u0131": {
      "main": [
        [
          {
            "node": "Ba\u015far\u0131",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Red Kayd\u0131": {
      "main": [
        [
          {
            "node": "Red Bildir",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Durum Kontrol": {
      "main": [
        [
          {
            "node": "Durum Bildir",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Hata Yakala": {
      "main": [
        [
          {
            "node": "Hata Bildir",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "G\u00f6rsel \u0130\u015fle": {
      "main": [
        [
          {
            "node": "Kaydet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  },
  "staticData": {
    "node:Her 12 Saatte": {
      "recurrenceRules": []
    },
    "node:Telegram Poll (30s)": {
      "recurrenceRules": []
    },
    "global": {
      "tgOffset": "294347649"
    }
  },
  "meta": null,
  "versionId": "8d6456cc-a38e-412a-990c-fe0e47b12670",
  "activeVersionId": "8d6456cc-a38e-412a-990c-fe0e47b12670",
  "versionCounter": 41,
  "triggerCount": 3,
  "shared": [
    {
      "updatedAt": "2026-04-02T15:00:48.966Z",
      "createdAt": "2026-04-02T15:00:48.966Z",
      "role": "workflow:owner",
      "workflowId": "rNLTPrZvDUKi2UBP",
      "projectId": "OaRgGzcKoxgAmXgy",
      "project": {
        "updatedAt": "2026-04-02T14:01:51.860Z",
        "createdAt": "2026-04-02T14:00:22.118Z",
        "id": "OaRgGzcKoxgAmXgy",
        "name": "Osman Baran Tekin <tekinosmanbaran@gmail.com>",
        "type": "personal",
        "icon": null,
        "description": null,
        "creatorId": "6b30529f-4650-4270-99e7-95f467bb8d04"
      }
    }
  ],
  "tags": [],
  "activeVersion": {
    "updatedAt": "2026-04-02T15:15:21.611Z",
    "createdAt": "2026-04-02T15:15:21.611Z",
    "versionId": "8d6456cc-a38e-412a-990c-fe0e47b12670",
    "workflowId": "rNLTPrZvDUKi2UBP",
    "nodes": [
      {
        "parameters": {
          "rule": {
            "interval": [
              {
                "field": "hours",
                "hoursInterval": 12
              }
            ]
          }
        },
        "id": "sched-12h",
        "name": "Her 12 Saatte",
        "type": "n8n-nodes-base.scheduleTrigger",
        "typeVersion": 1.2,
        "position": [
          0,
          0
        ]
      },
      {
        "parameters": {},
        "id": "manual",
        "name": "Manuel Test",
        "type": "n8n-nodes-base.manualTrigger",
        "typeVersion": 1,
        "position": [
          0,
          200
        ]
      },
      {
        "parameters": {
          "path": "gnca-trigger",
          "httpMethod": "POST",
          "responseMode": "onReceived",
          "options": {}
        },
        "id": "webhook-trigger",
        "name": "Admin Panel Trigger",
        "type": "n8n-nodes-base.webhook",
        "typeVersion": 2,
        "position": [
          0,
          400
        ],
        "webhookId": "gnca-trigger-id"
      },
      {
        "parameters": {
          "url": "https://techcrunch.com/category/artificial-intelligence/feed/",
          "options": {}
        },
        "id": "rss1",
        "name": "RSS TechCrunch",
        "type": "n8n-nodes-base.rssFeedRead",
        "typeVersion": 1.1,
        "position": [
          260,
          -100
        ]
      },
      {
        "parameters": {
          "url": "https://www.theverge.com/rss/ai-artificial-intelligence/index.xml",
          "options": {}
        },
        "id": "rss2",
        "name": "RSS Verge",
        "type": "n8n-nodes-base.rssFeedRead",
        "typeVersion": 1.1,
        "position": [
          260,
          100
        ]
      },
      {
        "parameters": {
          "url": "https://feeds.feedburner.com/venturebeat/SZYF",
          "options": {}
        },
        "id": "rss3",
        "name": "RSS VBeat",
        "type": "n8n-nodes-base.rssFeedRead",
        "typeVersion": 1.1,
        "position": [
          260,
          300
        ]
      },
      {
        "parameters": {
          "mode": "append"
        },
        "id": "merge",
        "name": "Birle\u015ftir",
        "type": "n8n-nodes-base.merge",
        "typeVersion": 3,
        "position": [
          520,
          100
        ]
      },
      {
        "parameters": {
          "jsCode": "const allItems = $input.all();\nallItems.sort((a, b) => {\n  const dateA = new Date(a.json.pubDate || a.json.isoDate || a.json.date || 0);\n  const dateB = new Date(b.json.pubDate || b.json.isoDate || b.json.date || 0);\n  return dateB - dateA;\n});\nconst top5 = allItems.slice(0, 5);\nconst newsSummary = top5.map((item, i) => {\n  const title = item.json.title || 'No title';\n  const desc = (item.json.contentSnippet || item.json.content || item.json.description || '').replace(/<[^>]*>/g, '').substring(0, 300);\n  const link = item.json.link || '';\n  return (i+1) + '. ' + title + '\\n\u00d6zet: ' + desc + '\\nLink: ' + link;\n}).join('\\n\\n');\n\nconst systemPrompt = `Sen GNCA AI News'in i\u00e7erik edit\u00f6r\u00fcs\u00fcn. GNCA AI News, yapay zeka, m\u00fchendislik ve teknoloji d\u00fcnyas\u0131ndaki en g\u00fcncel geli\u015fmeleri T\u00fcrk\u00e7e olarak aktaran bir haber ve i\u00e7erik platformudur.\n\nG\u00d6REV: Verilen haberleri GNCA AI News'in Instagram hesab\u0131 (@gnc_ai) i\u00e7in profesyonel, bilgilendirici ve ilgi \u00e7ekici T\u00fcrk\u00e7e i\u00e7eriklere d\u00f6n\u00fc\u015ft\u00fcr.\n\nTON VE \u00dcSLUP:\n- Bilgilendirici ve otoriter, ama okunmas\u0131 keyifli\n- Teknoloji merakl\u0131lar\u0131na hitap eden, sekt\u00f6r dilini bilen ama herkesin anlayaca\u011f\u0131 bir dil\n- Haberin \u00f6nemini ve etkisini vurgula\n- Emoji kullan\u0131m\u0131: ba\u015fl\u0131kta 1 adet, caption i\u00e7inde en fazla 3 adet\n\nCAPTION YAPISI:\n1. Dikkat \u00e7ekici giri\u015f c\u00fcmlesi (1 c\u00fcmle)\n2. Her haber i\u00e7in 2-3 c\u00fcmle \u00f6zet (ne oldu + neden \u00f6nemli)\n3. Genel de\u011ferlendirme: Bu geli\u015fmelerin teknoloji d\u00fcnyas\u0131 i\u00e7in anlam\u0131 (1-2 c\u00fcmle)\n4. CTA: \"Takipte kal\u0131n, teknolojinin nabz\u0131n\u0131 birlikte tutuyoruz.\" veya benzeri\n\nHASHTAG STRATEJ\u0130S\u0130:\n- Sabit: #GNCA #GNCAINews #YapayZeka #AI #Teknoloji\n- Habere \u00f6zel 3-5 hashtag se\u00e7 (\u00f6rnek: #MachineLearning #Derin\u00d6\u011frenme #Robotik #OpenAI #Google #Startup #M\u00fchendislik #Yaz\u0131l\u0131m #B\u00fcy\u00fckVeri #IoT #GPT #LLM)\n- Toplam 8-12 hashtag\n\nG\u00d6RSEL MET\u0130N (overlayText):\n- G\u00f6rsel \u00fczerine yaz\u0131lacak k\u0131sa, etkileyici T\u00fcrk\u00e7e ba\u015fl\u0131k (max 40 karakter)\n- B\u00dcY\u00dcK HARF, net ve okunakli\n- \u00d6rnekler: \"AI D\u00dcNYASINDA YEN\u0130 D\u00d6NEM\", \"YAPAY ZEKA DEVR\u0130M\u0130\", \"TEKNOLOJ\u0130DE SON GEL\u0130\u015eMELER\"\n\nTEK B\u0130R post, TEK JSON d\u00f6nd\u00fcr. Ba\u015fka hi\u00e7bir \u015fey yazma.`;\n\nconst userPrompt = `A\u015fa\u011f\u0131daki AI/teknoloji haberlerinden Instagram postu olu\u015ftur:\n\n` + newsSummary + `\n\nKURALLAR:\n1) title: Emoji ile ba\u015flayan dikkat \u00e7ekici ba\u015fl\u0131k, max 60 karakter\n2) overlayText: G\u00f6rsel \u00fczerine yaz\u0131lacak KISA T\u00fcrk\u00e7e ba\u015fl\u0131k, max 40 karakter, B\u00dcY\u00dcK HARF\n3) caption: T\u00fcrk\u00e7e profesyonel \u00f6zet, 800-1200 karakter aras\u0131, yukar\u0131daki yap\u0131y\u0131 takip et\n4) imagePrompt: DALL-E i\u00e7in \u0130ngilizce prompt - modern, teknoloji temal\u0131, kurumsal\n5) hashtags: 8-12 hashtag, string olarak bo\u015flukla ayr\u0131lm\u0131\u015f\n\nJSON format\u0131:\n{\"title\": \"...\", \"overlayText\": \"...\", \"caption\": \"...\", \"imagePrompt\": \"...\", \"hashtags\": \"...\"}\nSadece JSON d\u00f6nd\u00fcr, ba\u015fka bir \u015fey yazma.`;\n\nconst openaiBody = {\n  model: \"gpt-4o-mini\", temperature: 0.7, max_tokens: 2500,\n  messages: [\n    {role: \"system\", content: systemPrompt},\n    {role: \"user\", content: userPrompt}\n  ]\n};\nreturn [{ json: { newsCount: top5.length, newsSummary, openaiBody } }];"
        },
        "id": "sort",
        "name": "S\u0131rala & Haz\u0131rla",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          760,
          100
        ]
      },
      {
        "parameters": {
          "method": "POST",
          "url": "https://api.openai.com/v1/chat/completions",
          "sendHeaders": true,
          "headerParameters": {
            "parameters": [
              {
                "name": "Authorization",
                "value": "Bearer YOUR_OPENAI_API_KEY"
              },
              {
                "name": "Content-Type",
                "value": "application/json"
              }
            ]
          },
          "sendBody": true,
          "specifyBody": "json",
          "jsonBody": "={{ JSON.stringify($json.openaiBody) }}",
          "options": {
            "timeout": 60000
          }
        },
        "id": "openai",
        "name": "OpenAI",
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4.2,
        "position": [
          1000,
          100
        ]
      },
      {
        "parameters": {
          "jsCode": "const response = $input.first().json;\nlet rawText = '';\nif (response.choices && response.choices[0]) {\n  rawText = response.choices[0].message.content;\n} else { throw new Error('OpenAI yan\u0131t vermedi'); }\n\n// Remove markdown code fences robustly\nlet cleaned = rawText;\nif (cleaned.indexOf('```') !== -1) {\n  const firstBrace = cleaned.indexOf('{');\n  const lastBrace = cleaned.lastIndexOf('}');\n  if (firstBrace !== -1 && lastBrace !== -1) {\n    cleaned = cleaned.substring(firstBrace, lastBrace + 1);\n  }\n}\n\n// Find first complete JSON object using brace depth\nlet depth = 0; let start = -1; let end = -1;\nfor (let i = 0; i < cleaned.length; i++) {\n  if (cleaned[i] === '{') { if (depth === 0) start = i; depth++; }\n  else if (cleaned[i] === '}') { depth--; if (depth === 0 && start !== -1) { end = i; break; } }\n}\nif (start !== -1 && end !== -1) cleaned = cleaned.substring(start, end + 1);\n\nlet content;\ntry {\n  content = JSON.parse(cleaned);\n} catch(e) {\n  throw new Error('JSON parse hatas\u0131. Temizlenen metin: ' + cleaned.substring(0, 300));\n}\n\nif (!content.title || !content.caption) throw new Error('title/caption eksik');\n\nconst overlayText = content.overlayText || content.title.replace(/[^\\w\\s\u011f\u00fc\u015f\u0131\u00f6\u00e7\u011e\u00dc\u015e\u0130\u00d6\u00c7]/g, '').substring(0, 40).toUpperCase();\n\nconst dalleBody = {\n  model: \"dall-e-3\",\n  prompt: (content.imagePrompt || \"Modern AI technology\") + \". Modern tech news illustration style. Clean geometric composition with vibrant gradients (deep purple, electric blue, cyan). Abstract digital elements like neural networks, data streams, code fragments, AI chip patterns. Futuristic and sleek aesthetic suitable for a technology news platform. Square format. Absolutely no text, letters, words, or numbers anywhere in the image.\",\n  n: 1, size: \"1024x1024\", quality: \"hd\"\n};\n\nreturn [{ json: {\n  title: content.title,\n  overlayText: overlayText,\n  caption: content.caption,\n  imagePrompt: content.imagePrompt || 'Modern AI technology social media post',\n  hashtags: content.hashtags || '#AI #YapayZeka #GNCA',\n  newsSummary: $('S\u0131rala & Haz\u0131rla').first().json.newsSummary,\n  newsCount: $('S\u0131rala & Haz\u0131rla').first().json.newsCount,\n  generatedAt: new Date().toISOString(),\n  dalleBody: dalleBody\n} }];"
        },
        "id": "parse",
        "name": "Parse Et",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          1240,
          100
        ]
      },
      {
        "parameters": {
          "method": "POST",
          "url": "https://api.openai.com/v1/images/generations",
          "sendHeaders": true,
          "headerParameters": {
            "parameters": [
              {
                "name": "Authorization",
                "value": "Bearer YOUR_OPENAI_API_KEY"
              },
              {
                "name": "Content-Type",
                "value": "application/json"
              }
            ]
          },
          "sendBody": true,
          "specifyBody": "json",
          "jsonBody": "={{ JSON.stringify($json.dalleBody) }}",
          "options": {
            "timeout": 120000
          }
        },
        "id": "dalle",
        "name": "DALL-E",
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4.2,
        "position": [
          1480,
          100
        ]
      },
      {
        "parameters": {
          "jsCode": "const imgData = $input.first().json;\n\nconst SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst headers = {\n  'apikey': SUPABASE_KEY,\n  'Authorization': 'Bearer ' + SUPABASE_KEY,\n  'Content-Type': 'application/json',\n  'Prefer': 'return=representation'\n};\n\n// Insert post with processed image URL (permanent Supabase Storage URL)\nconst postRes = await this.helpers.httpRequest({\n  method: 'POST',\n  url: SUPABASE_URL + '/rest/v1/posts',\n  headers,\n  body: JSON.stringify({\n    title: imgData.title,\n    caption: imgData.caption,\n    image_prompt: imgData.imagePrompt,\n    image_url: imgData.processedImageUrl,\n    hashtags: imgData.hashtags,\n    news_summary: imgData.newsSummary,\n    news_count: imgData.newsCount,\n    status: 'pending'\n  })\n});\n\nconst post = Array.isArray(postRes) ? postRes[0] : postRes;\n\n// Insert pipeline run\nawait this.helpers.httpRequest({\n  method: 'POST',\n  url: SUPABASE_URL + '/rest/v1/pipeline_runs',\n  headers: { ...headers, 'Prefer': 'return=minimal' },\n  body: JSON.stringify({\n    trigger_type: 'scheduled',\n    status: 'success',\n    post_id: post.id,\n    started_at: imgData.generatedAt || new Date().toISOString(),\n    finished_at: new Date().toISOString()\n  })\n});\n\nreturn [{ json: { ...post, imageUrl: imgData.processedImageUrl } }];"
        },
        "id": "save",
        "name": "Kaydet",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          1840,
          100
        ]
      },
      {
        "parameters": {
          "chatId": "2099378542",
          "text": "=\ud83e\udd16 *GNCA AI Haber B\u00fclteni*\n\ud83d\udcc5 {{ $now.format('dd.MM.yyyy HH:mm') }}\n\n\ud83d\udccc *{{ $json.title }}*\n\n{{ $json.caption.substring(0, 800) }}\n\n---\n\ud83d\uddbc\ufe0f G\u00f6rsel: {{ $json.imageUrl ? '\u2705 \u00dcretildi' : '\u274c Yok' }}\n\n\u2705 /onayla \u2192 Yay\u0131nla\n\u274c /reddet \u2192 Reddet\n\ud83d\udcca /durum \u2192 Durum",
          "additionalFields": {
            "parse_mode": "Markdown"
          }
        },
        "id": "tg-preview",
        "name": "Telegram \u00d6nizleme",
        "type": "n8n-nodes-base.telegram",
        "typeVersion": 1.2,
        "position": [
          2080,
          100
        ],
        "credentials": {
          "telegramApi": {
            "id": "9VDqFtkbrcHS1LG9",
            "name": "Telegram Bot - GNCA"
          }
        },
        "webhookId": "90d72b9c-e848-4ab9-9a8a-1d961223a94d"
      },
      {
        "parameters": {
          "rule": {
            "interval": [
              {
                "field": "seconds",
                "secondsInterval": 30
              }
            ]
          }
        },
        "id": "sched-30s",
        "name": "Telegram Poll (30s)",
        "type": "n8n-nodes-base.scheduleTrigger",
        "typeVersion": 1.2,
        "position": [
          0,
          600
        ]
      },
      {
        "parameters": {
          "url": "https://api.telegram.org/bot8674444246:AAFWV1GrVNLSW4OxEtCXCgH1MTBgU9lpQ4U/getUpdates?timeout=5&limit=10&allowed_updates=[\"message\"]",
          "options": {
            "timeout": 10000
          }
        },
        "id": "tg-poll",
        "name": "Telegram API",
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4.2,
        "position": [
          260,
          600
        ]
      },
      {
        "parameters": {
          "jsCode": "const result = $input.first().json;\n\nconst SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst headers = {\n  'apikey': SUPABASE_KEY,\n  'Authorization': 'Bearer ' + SUPABASE_KEY\n};\n\n// Read offset from settings\nlet currentOffset = 0;\ntry {\n  const offsetData = await this.helpers.httpRequest({\n    method: 'GET',\n    url: SUPABASE_URL + '/rest/v1/settings?key=eq.tg_offset&select=value',\n    headers\n  });\n  if (offsetData && offsetData.length > 0) {\n    currentOffset = parseInt(offsetData[0].value) || 0;\n  }\n} catch(e) { currentOffset = 0; }\n\nif (!result.ok || !result.result || result.result.length === 0) return [];\n\nconst messages = [];\nlet maxId = currentOffset;\n\nfor (const update of result.result) {\n  if (update.update_id < currentOffset) continue;\n  if (update.update_id >= maxId) maxId = update.update_id + 1;\n  \n  const msg = update.message;\n  if (!msg || String(msg.chat.id) !== '2099378542') continue;\n  const text = (msg.text || '').trim().toLowerCase();\n  if (text === '/onayla' || text === 'onayla') messages.push({ json: { action: 'approve' } });\n  else if (text === '/reddet' || text === 'reddet') messages.push({ json: { action: 'reject' } });\n  else if (text === '/durum' || text === 'durum') messages.push({ json: { action: 'status' } });\n}\n\n// Save new offset\nif (maxId > currentOffset) {\n  await this.helpers.httpRequest({\n    method: 'PATCH',\n    url: SUPABASE_URL + '/rest/v1/settings?key=eq.tg_offset',\n    headers: { ...headers, 'Content-Type': 'application/json' },\n    body: JSON.stringify({ value: String(maxId) })\n  });\n  \n  await this.helpers.httpRequest({\n    method: 'GET',\n    url: 'https://api.telegram.org/bot8674444246:AAFWV1GrVNLSW4OxEtCXCgH1MTBgU9lpQ4U/getUpdates?offset=' + maxId + '&limit=0'\n  });\n}\n\nreturn messages.length > 0 ? messages : [];"
        },
        "id": "tg-parse",
        "name": "Komut Ayr\u0131\u015ft\u0131r",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          520,
          600
        ]
      },
      {
        "parameters": {
          "rules": {
            "values": [
              {
                "conditions": {
                  "conditions": [
                    {
                      "leftValue": "={{ $json.action }}",
                      "rightValue": "approve",
                      "operator": {
                        "type": "string",
                        "operation": "equals"
                      }
                    }
                  ]
                },
                "renameOutput": true,
                "outputKey": "Onayla"
              },
              {
                "conditions": {
                  "conditions": [
                    {
                      "leftValue": "={{ $json.action }}",
                      "rightValue": "reject",
                      "operator": {
                        "type": "string",
                        "operation": "equals"
                      }
                    }
                  ]
                },
                "renameOutput": true,
                "outputKey": "Reddet"
              },
              {
                "conditions": {
                  "conditions": [
                    {
                      "leftValue": "={{ $json.action }}",
                      "rightValue": "status",
                      "operator": {
                        "type": "string",
                        "operation": "equals"
                      }
                    }
                  ]
                },
                "renameOutput": true,
                "outputKey": "Durum"
              }
            ]
          }
        },
        "id": "switch",
        "name": "Aksiyon",
        "type": "n8n-nodes-base.switch",
        "typeVersion": 3.2,
        "position": [
          760,
          600
        ]
      },
      {
        "parameters": {
          "jsCode": "const SUPABASE_URL = 'https://gcjllksbgtstbzatvwat.supabase.co';\nconst SUPABASE_KEY = 'YOUR_SUPABASE_SERVICE_ROLE_KEY';\nconst headers = {\n  'apikey': SUPABASE_KEY,\n  'Authorization': 'Bearer ' + SUPABASE_KEY\n};\n\nconst posts = await this.helpers.httpRequest({\n  method: 'GET',\n  url: SUPABASE_URL + '/rest/v1/posts?status=eq.pending&order=created_at.desc&limit=1',\n  headers\n});\n\nif (!posts || posts.length === 0) throw new Error('\u0130\u00e7erik bulunamad\u0131! \u00d6nce i\u00e7erik \u00fcretin.');\nconst content = posts[0];\nif (!content.image_url) throw new Error('G\u00f6rsel URL yok!');\n\nreturn [{ json: { ...content, imageUrl: content.image_url } }];"
        },
        "id": "load",
        "name": "\u0130\u00e7erik Y\u00fckle",
        "type": "n8n-nodes-base.code",
        "typeVersion": 2,
        "position": [
          1000,
          500
        ]
      },
      {
        "parameters": {
          "chatId": "2099378542",
          "text": "\u23f3 Instagram'a y\u00fckleniyor...",
          "additionalFields": {}
        },
        "id": "tg-loading",
        "name": "Y\u00fckleniyor",
        "type": "n8n-nodes-base.telegram",
        "typeVersion": 1.2,
        "position": [
          1000,
          380
        ],
        "credentials": {
          "telegramApi": {
            "id": "9VDqFtkbrcHS1LG9",
            "name": "Telegram Bot - GNCA"
          }
        },
        "webhookId": "a2857179-58f1-4c10-a607-2defcf845353"
      },
      {
        "parameters": {
          "method": "POST",
          "url": "https://graph.facebook.com/v19.0/17841436005649126/media",
          "sendBody": true,
          "specifyBody": "json",
          "jsonBody": "={{ JSON.stringify({ image_url: $json.imageUrl, caption: $json.caption, access_token: \"EAAX5DGtac1kBRDCaQpcVbxHDZCjuJtwlK0qQZB0rvgQjzO5f7INg4TqDo454A9hQWZC0drlFXfR1PxUkZB4ANbBfZCHnP69rSbsfZBxdKjYDyd4x8RuDlUWR2zcjewaSIA0IZCwtb6meoeUktY70Wq35fJbIIcpJac5VxuhfSkLdXlzWZBc8tiuJL0mHDAZDZD\" }) }}",
          "options": {
            "timeout": 30000
          }
        },
        "id": "ig-create",
        "name": "IG Container",
        "type": "n8n-nodes-base.httpRequest",
        "typeVersion": 4.2,
        "position": [
          1240,
          500
        ]
      },
      {
        "parameters": {
          "amount": 15,
          "unit": "seconds"
        },
        "id": "wait-ig",
        "name": "15s Bekle",
        "type": "n8n-nodes-base.wait",
        "typeVersion": 1.1,
        "position": [
          1480,
          500
        ],
        "webhookId": "341a7fff-ee08-434b-9d9a-9a1533edc34b"
      },
      {
        "parameters": {
          "method": "POST",
          "url": "https://graph.facebook.com/v19.0/17841436005649126/media_publish",
          "sendBody": true,
          "specifyBody": "json",
          "jsonBody": "={{ JSON.stringify({ creation_id: $('IG Container').first().json.id, access_token: \"EAAX5DGtac1kBRDCaQpcVbxHDZCjuJtwlK0qQZB0rvgQjzO5f7INg4TqDo454A9hQWZC0drlFXfR1PxUkZB4ANbBfZCHnP69rSbsfZBxdKjYDyd4x8RuDlUWR2zcjewaSIA0IZCwtb6meoeUktY70Wq35fJbIIcpJac5VxuhfSkLdXlzWZBc8tiuJL0mHDAZDZD\" }) }}",
          "options": {
            "timeout": 30000
          }
        },
        "id": "ig-pub",
        "name": "IG Yay\u0131nla",
        "type": "n8n-

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

GNCA AI News Pipeline. Uses rssFeedRead, httpRequest, telegram, errorTrigger. Scheduled trigger; 29 nodes.

Source: https://github.com/obtein/gnca/blob/36498f183770ccc025f0bb3ca4d87c2c48fa813e/n8n/workflow-original.json — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

GNCA AI News Pipeline. Uses rssFeedRead, httpRequest, telegram, errorTrigger. Scheduled trigger; 31 nodes.

RSS Feed Read, HTTP Request, Telegram +1
Slack & Telegram

Auto Hunt. Uses httpRequest, googleSheets, rssFeedRead, telegram. Scheduled trigger; 78 nodes.

HTTP Request, Google Sheets, RSS Feed Read +1
Slack & Telegram

. Uses googleSheets, telegram, httpRequest, wise. Scheduled trigger; 36 nodes.

Google Sheets, Telegram, HTTP Request +2
Slack & Telegram

Apollo Data Enrichment Using Company Id to automatically finds contacts for companies listed in your Google Sheet, enriches each person with emails and phone numbers via Apollo’s API, and writes verif

Google Sheets, HTTP Request, Error Trigger +1
Slack & Telegram

Graceful Content Sparks — RSS → Notion (n8n)

RSS Feed Read, Notion, Email Send +2