{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "7e0f3434-7e68-4c33-a2ea-c1ac03aa37a5",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        -304
      ],
      "parameters": {
        "color": 4,
        "width": 572,
        "height": 1124,
        "content": "## LinkedIn Carousel PDF Generator \u2014 GPT-4o-mini + html-pdf-node + Google Drive + Sheets + Gmail\n\nFor LinkedIn creators who want to automatically generate a fully branded carousel PDF from a single topic \u2014 ready to upload directly to LinkedIn as a document post. Submit the topic, brand name, target audience, tone, and slide count via the form. GPT-4o-mini returns a pure JSON array of structured slides \u2014 title slide, content slides, and a CTA slide \u2014 each with headline, emoji, subtitle, and bullet points. A Code node parses the JSON array with error handling. A second Code node builds a complete multi-page HTML document with branded inline styles, background decorations, slide number badges, and a swipe prompt. A third Code node uses html-pdf-node to convert the HTML into a square-format PDF binary (1080x1080px per slide). The PDF is uploaded to Google Drive. Google Sheets logs the run with Drive file ID and link. Gmail emails the PDF to you with posting instructions.\n\n## How it works\n- **1. Form \u2014 Carousel Topic + Details** collects topic, brand name, target audience, tone, and number of content slides\n- **2. AI Agent \u2014 Generate Slide Content** uses GPT-4o-mini to return a pure JSON array of slides \u2014 title, content, and CTA types\n- **OpenAI \u2014 GPT-4o-mini Model** language model attached to the AI Agent\n- **3. Code \u2014 Parse Slides JSON** strips markdown fences, finds the JSON array, validates it, and extracts form metadata\n- **4. Code \u2014 Build HTML Slides** reads brand settings (color, font, size), loops slides to build one HTML div per slide with inline styles, background circles, brand tag, and swipe prompt \u2014 wraps in a full HTML document\n- **5. Code \u2014 Generate PDF** uses html-pdf-node to convert HTML to PDF binary (requires npm install html-pdf-node on your n8n server), returns binary data and metadata\n- **6. Google Drive \u2014 Upload PDF** uploads the PDF binary to your target Drive folder\n- **7. Google Sheets \u2014 Log Carousel** appends 9 columns including Drive file ID and constructed Drive link\n- **8. Gmail \u2014 Email PDF to You** sends an HTML email with the Drive link and LinkedIn posting instructions\n\n## Set up steps\n1. Install html-pdf-node on your n8n server: `npm install html-pdf-node` (Docker: `docker exec -it n8n npm install html-pdf-node`)\n2. In **OpenAI \u2014 GPT-4o-mini Model** \u2014 connect your OpenAI credential\n3. In **6. Google Drive \u2014 Upload PDF** \u2014 connect your Google Drive OAuth2 credential and replace `YOUR_GDRIVE_FOLDER_ID`\n4. In **7. Google Sheets \u2014 Log Carousel** \u2014 connect your Google Sheets OAuth2 credential and replace `YOUR_GOOGLE_SHEET_ID`. Create a tab named Carousel Log with columns: Date, Topic, Brand Name, Slide Count, File Name, Drive Link, Drive File ID, PDF Size (bytes), Generated On\n5. In **8. Gmail \u2014 Email PDF to You** \u2014 connect your Gmail OAuth2 credential and replace `YOUR_EMAIL_ADDRESS`\n6. In **4. Code \u2014 Build HTML Slides** \u2014 update the BRAND SETTINGS section: replace BRAND_COLOR with your hex color, update FONT if needed"
      },
      "typeVersion": 1
    },
    {
      "id": "71235a9c-06ba-4ba8-801c-1f59e7626f61",
      "name": "Section \u2014 Form Input",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -272,
        -128
      ],
      "parameters": {
        "color": 5,
        "width": 260,
        "height": 516,
        "content": "## Form Input\nUser enters carousel topic, brand name, target audience, tone, and number of content slides. All five fields feed into the AI prompt and HTML brand settings."
      },
      "typeVersion": 1
    },
    {
      "id": "90afc31f-c62c-4950-b3b6-f1f44d81c17c",
      "name": "Section \u2014 AI Slide Content Generation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        -160
      ],
      "parameters": {
        "color": 6,
        "width": 276,
        "height": 772,
        "content": "## AI Slide Content Generation\nGPT-4o-mini generates a pure JSON array of slides \u2014 title, content (one key point each), and CTA type. Each slide has headline, emoji, subtitle, and bullet points."
      },
      "typeVersion": 1
    },
    {
      "id": "a0768ba5-b64d-4a4b-9cb0-b1e99d99bfc0",
      "name": "Section \u2014 JSON Parse and HTML Slide Build",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        352,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 420,
        "height": 340,
        "content": "## JSON Parse and HTML Slide Build\nCode node parses the JSON array with error handling. Second Code node builds a multi-page HTML document with branded inline styles, background decorations, slide badges, and swipe prompt."
      },
      "typeVersion": 1
    },
    {
      "id": "9f5a9c14-3689-4247-8c97-6b32e4e5ff82",
      "name": "Section \u2014 PDF Generation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 340,
        "height": 340,
        "content": "## PDF Generation\nCode node uses html-pdf-node to convert the HTML into a square-format PDF (1080x1080px per slide). Requires npm install html-pdf-node on your n8n server."
      },
      "typeVersion": 1
    },
    {
      "id": "efd788bc-1cbc-4abf-aadf-88524d9ee0bc",
      "name": "Section \u2014 Drive Upload, Sheet Log, and Gmail Send",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1200,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 692,
        "height": 340,
        "content": "## Drive Upload, Sheet Log, and Gmail Send\nPDF uploaded to Google Drive. Sheets logs 9 columns with Drive file ID and link. Gmail sends the PDF with LinkedIn posting instructions."
      },
      "typeVersion": 1
    },
    {
      "id": "6205806d-ba7b-41f3-a35e-becc1fb9ce0c",
      "name": "1. Form \u2014 Carousel Topic + Details",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -208,
        64
      ],
      "parameters": {
        "options": {},
        "formTitle": "LinkedIn Carousel Generator",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Carousel Topic",
              "placeholder": "e.g. 5 SEO mistakes beginners make / How to grow on LinkedIn / Morning routine habits",
              "requiredField": true
            },
            {
              "fieldLabel": "Your Name or Brand",
              "placeholder": "e.g. Rahul Sharma | Incrementors",
              "requiredField": true
            },
            {
              "fieldLabel": "Target Audience",
              "placeholder": "e.g. Startup founders, Digital marketers, Freelancers",
              "requiredField": true
            },
            {
              "fieldLabel": "Tone",
              "placeholder": "e.g. Professional / Motivational / Educational / Casual",
              "requiredField": true
            },
            {
              "fieldLabel": "Number of Content Slides",
              "placeholder": "e.g. 5 (recommended: 4 to 7)",
              "requiredField": true
            }
          ]
        },
        "formDescription": "Enter your carousel topic and AI will generate a complete 7-slide LinkedIn carousel PDF \u2014 ready to post in minutes."
      },
      "typeVersion": 2.2
    },
    {
      "id": "8e970dcd-f572-4c93-889d-85c0065ed5d4",
      "name": "2. AI Agent \u2014 Generate Slide Content",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        96,
        64
      ],
      "parameters": {
        "text": "=Create a LinkedIn carousel for this topic: {{ $json['Carousel Topic'] }}\n\nTarget Audience: {{ $json['Target Audience'] }}\nTone: {{ $json['Tone'] }}\nNumber of content slides: {{ $json['Number of Content Slides'] }}\nBrand: {{ $json['Your Name or Brand'] }}",
        "options": {
          "systemMessage": "You are an expert LinkedIn content strategist who creates high-engagement carousel posts.\n\nCreate a LinkedIn carousel with this exact structure:\n- Slide 1: Title slide (hook that stops the scroll)\n- Slides 2 to N: Content slides (one key point per slide)\n- Last slide: CTA slide (follow + engage prompt)\n\nRules for each slide:\n1. Headline: Short and punchy \u2014 max 8 words \u2014 no fluff\n2. Points: Exactly 3 bullet points per content slide \u2014 each point max 12 words\n3. Emoji: One relevant emoji for each slide\n4. Title slide: Just a powerful headline + subtitle + emoji \u2014 no bullet points\n5. CTA slide: Follow prompt + question to boost comments \u2014 no bullet points\n\nReturn ONLY a valid JSON array \u2014 no text before or after, no markdown backticks.\n\nFormat:\n[\n  {\n    \"slide_number\": 1,\n    \"type\": \"title\",\n    \"emoji\": \"\ud83d\ude80\",\n    \"headline\": \"Your powerful hook headline here\",\n    \"subtitle\": \"A one-line supporting statement\",\n    \"points\": []\n  },\n  {\n    \"slide_number\": 2,\n    \"type\": \"content\",\n    \"emoji\": \"\ud83d\udca1\",\n    \"headline\": \"Point headline here\",\n    \"subtitle\": \"\",\n    \"points\": [\n      \"First bullet point \u2014 specific and actionable\",\n      \"Second bullet point \u2014 concrete advice\",\n      \"Third bullet point \u2014 clear takeaway\"\n    ]\n  },\n  {\n    \"slide_number\": 99,\n    \"type\": \"cta\",\n    \"emoji\": \"\ud83d\udd14\",\n    \"headline\": \"Follow for more tips like this\",\n    \"subtitle\": \"What part resonated with you most? Comment below!\",\n    \"points\": []\n  }\n]\n\nReturn ONLY the JSON array. Nothing else."
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "2d2be17c-c921-4bbc-8521-132096b2f176",
      "name": "OpenAI \u2014 GPT-4o-mini Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        96,
        272
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "0c5b5de2-b248-4b2b-a206-c32ad415a72e",
      "name": "3. Code \u2014 Parse Slides JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        400,
        64
      ],
      "parameters": {
        "jsCode": "// Parse the AI JSON output into slides array\nconst output = $input.first().json.output || '';\n\nlet slides = [];\ntry {\n  const cleaned = output\n    .replace(/```json/gi, '')\n    .replace(/```/g, '')\n    .trim();\n\n  const match = cleaned.match(/\\[\\s*\\{[\\s\\S]*\\}\\s*\\]/);\n  if (match) {\n    slides = JSON.parse(match[0]);\n  } else {\n    slides = JSON.parse(cleaned);\n  }\n} catch (e) {\n  throw new Error('Could not parse slide JSON from AI output. Output was: ' + output.substring(0, 300));\n}\n\nif (!Array.isArray(slides) || slides.length === 0) {\n  throw new Error('No slides returned from AI. Check the prompt.');\n}\n\nconst topic = $('1. Form \u2014 Carousel Topic + Details').item.json['Carousel Topic'];\nconst brandName = $('1. Form \u2014 Carousel Topic + Details').item.json['Your Name or Brand'];\nconst targetAudience = $('1. Form \u2014 Carousel Topic + Details').item.json['Target Audience'];\nconst tone = $('1. Form \u2014 Carousel Topic + Details').item.json['Tone'];\n\nreturn [{\n  json: {\n    slides,\n    slideCount: slides.length,\n    topic,\n    brandName,\n    targetAudience,\n    tone\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "8a56823c-5be4-486e-a3e3-a9a908599ae2",
      "name": "4. Code \u2014 Build HTML Slides",
      "type": "n8n-nodes-base.code",
      "position": [
        640,
        64
      ],
      "parameters": {
        "jsCode": "// =============================================\n// BRAND SETTINGS \u2014 CUSTOMIZE THESE\n// =============================================\nconst BRAND_NAME = $('1. Form \u2014 Carousel Topic + Details').item.json['Your Name or Brand'] || 'YOUR_BRAND_NAME';\nconst BRAND_COLOR = '#0A66C2'; // LinkedIn blue \u2014 change to your brand color\nconst ACCENT_COLOR = '#ffffff';\nconst BG_COLOR = '#ffffff';\nconst TEXT_COLOR = '#1a1a1a';\nconst SLIDE_SIZE = '1080px';\nconst FONT = 'Arial, sans-serif';\n// =============================================\n\nconst slides = $json.slides;\nconst topic = $json.topic;\n\nlet slidesHtml = '';\n\nfor (const slide of slides) {\n  const isTitle = slide.type === 'title';\n  const isCta = slide.type === 'cta';\n\n  const slideBadge = (!isTitle && !isCta)\n    ? `<div style=\"position:absolute;top:32px;right:32px;background:rgba(255,255,255,0.2);color:${ACCENT_COLOR};border-radius:50%;width:44px;height:44px;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700;\">${slide.slide_number}</div>`\n    : '';\n\n  let pointsHtml = '';\n  if (slide.points && slide.points.length > 0) {\n    pointsHtml = `\n      <ul style=\"list-style:none;padding:0;margin:20px 0 0;\">\n        ${slide.points.map(point => `\n          <li style=\"display:flex;align-items:flex-start;margin-bottom:18px;\">\n            <span style=\"min-width:28px;height:28px;background:rgba(255,255,255,0.25);border-radius:50%;display:flex;align-items:center;justify-content:center;margin-right:14px;margin-top:2px;font-size:13px;font-weight:700;color:${ACCENT_COLOR};\">\u2713</span>\n            <span style=\"font-size:20px;line-height:1.5;color:${ACCENT_COLOR};font-weight:400;\">${point}</span>\n          </li>`).join('')}\n      </ul>`;\n  }\n\n  const subtitleHtml = slide.subtitle\n    ? `<p style=\"font-size:${isTitle ? '22px' : '18px'};color:rgba(255,255,255,0.8);margin:12px 0 0;font-weight:300;line-height:1.4;\">${slide.subtitle}</p>`\n    : '';\n\n  const swipePrompt = isTitle\n    ? `<div style=\"position:absolute;bottom:32px;right:32px;background:rgba(255,255,255,0.2);border-radius:24px;padding:10px 20px;\">\n         <span style=\"color:${ACCENT_COLOR};font-size:15px;font-weight:500;\">Swipe \u2192 </span>\n       </div>`\n    : '';\n\n  const brandTag = `<div style=\"position:absolute;bottom:${isTitle ? '32px' : '28px'};left:32px;\">\n    <span style=\"color:rgba(255,255,255,0.7);font-size:14px;font-weight:500;\">${BRAND_NAME}</span>\n  </div>`;\n\n  slidesHtml += `\n    <div style=\"width:${SLIDE_SIZE};height:${SLIDE_SIZE};background:linear-gradient(135deg, ${BRAND_COLOR} 0%, #083f7a 100%);position:relative;display:flex;flex-direction:column;justify-content:center;padding:56px;box-sizing:border-box;page-break-after:always;overflow:hidden;\">\n      <div style=\"position:absolute;top:-80px;right:-80px;width:300px;height:300px;border-radius:50%;background:rgba(255,255,255,0.05);\"></div>\n      <div style=\"position:absolute;bottom:-60px;left:-60px;width:220px;height:220px;border-radius:50%;background:rgba(255,255,255,0.04);\"></div>\n      ${slideBadge}\n      ${brandTag}\n      ${swipePrompt}\n      <div style=\"position:relative;z-index:2;\">\n        <div style=\"font-size:${isTitle ? '72px' : '56px'};margin-bottom:16px;\">${slide.emoji}</div>\n        <h1 style=\"font-size:${isTitle ? '48px' : '36px'};font-weight:800;color:${ACCENT_COLOR};margin:0;line-height:1.2;\">${slide.headline}</h1>\n        ${subtitleHtml}\n        ${pointsHtml}\n      </div>\n    </div>`;\n}\n\nconst fullHtml = `<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <style>\n    * { margin: 0; padding: 0; box-sizing: border-box; }\n    body { font-family: ${FONT}; background: #000; }\n    @page { size: ${SLIDE_SIZE} ${SLIDE_SIZE}; margin: 0; }\n  </style>\n</head>\n<body>\n${slidesHtml}\n</body>\n</html>`;\n\nconst cleanTopic = topic\n  .toLowerCase()\n  .replace(/[^a-z0-9\\s]/g, '')\n  .replace(/\\s+/g, '-')\n  .substring(0, 50);\n\nconst now = new Date();\nconst dateStr = now.toISOString().split('T')[0];\nconst fileName = `linkedin-carousel-${cleanTopic}-${dateStr}.pdf`;\n\nreturn [{\n  json: {\n    fullHtml,\n    fileName,\n    slideCount: slides.length,\n    topic: $json.topic,\n    brandName: $json.brandName,\n    dateStr\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "97594b9f-cf05-4337-9e73-4b97492a11c1",
      "name": "5. Code \u2014 Generate PDF",
      "type": "n8n-nodes-base.code",
      "position": [
        880,
        64
      ],
      "parameters": {
        "jsCode": "// Generate PDF from HTML using html-pdf-node\n// Make sure html-pdf-node is installed: npm install html-pdf-node\n\nconst htmlPdf = require('html-pdf-node');\n\nconst htmlContent = $json.fullHtml;\nconst fileName = $json.fileName;\nconst slideCount = $json.slideCount;\nconst slideSize = 1080;\n\nconst options = {\n  format: 'A4',\n  width: `${slideSize}px`,\n  height: `${slideSize}px`,\n  printBackground: true,\n  margin: { top: '0px', right: '0px', bottom: '0px', left: '0px' },\n  pageRanges: `1-${slideCount}`\n};\n\nconst file = { content: htmlContent };\n\ntry {\n  const pdfBuffer = await htmlPdf.generatePdf(file, options);\n  const pdfBase64 = pdfBuffer.toString('base64');\n\n  return [{\n    json: {\n      fileName: $json.fileName,\n      slideCount: $json.slideCount,\n      topic: $json.topic,\n      brandName: $json.brandName,\n      dateStr: $json.dateStr,\n      pdfSize: pdfBuffer.length,\n      mimeType: 'application/pdf'\n    },\n    binary: {\n      data: {\n        data: pdfBase64,\n        mimeType: 'application/pdf',\n        fileName: $json.fileName,\n        fileExtension: 'pdf'\n      }\n    }\n  }];\n} catch (error) {\n  throw new Error(`PDF generation failed: ${error.message}. Make sure html-pdf-node is installed on your n8n server.`);\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "e57d01ce-1c29-4294-95af-0bb25c6191d2",
      "name": "6. Google Drive \u2014 Upload PDF",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1248,
        64
      ],
      "parameters": {
        "name": "={{ $json.fileName }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive",
          "cachedResultName": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GDRIVE_FOLDER_ID"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "345fb377-28fd-433d-9ee3-ca57d6a88653",
      "name": "7. Google Sheets \u2014 Log Carousel",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1488,
        64
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('5. Code \u2014 Generate PDF').item.json.dateStr }}",
            "Topic": "={{ $('5. Code \u2014 Generate PDF').item.json.topic }}",
            "File Name": "={{ $('5. Code \u2014 Generate PDF').item.json.fileName }}",
            "Brand Name": "={{ $('5. Code \u2014 Generate PDF').item.json.brandName }}",
            "Drive Link": "=https://drive.google.com/file/d/{{ $json.id }}/view",
            "Slide Count": "={{ $('5. Code \u2014 Generate PDF').item.json.slideCount }}",
            "Generated On": "={{ $now.toFormat('dd MMMM yyyy HH:mm') }}",
            "Drive File ID": "={{ $json.id }}",
            "PDF Size (bytes)": "={{ $('5. Code \u2014 Generate PDF').item.json.pdfSize }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Carousel Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "931b6f1d-9e50-4014-9946-1a9b852b64ae",
      "name": "8. Gmail \u2014 Email PDF to You",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1728,
        64
      ],
      "parameters": {
        "sendTo": "YOUR_EMAIL_ADDRESS",
        "message": "=<div style=\"font-family:Arial,sans-serif;max-width:600px;margin:0 auto;\">\n  <div style=\"background:#0A66C2;padding:28px;text-align:center;border-radius:8px 8px 0 0;\">\n    <h1 style=\"color:#ffffff;font-size:22px;margin:0;\">Your LinkedIn Carousel is Ready</h1>\n  </div>\n  <div style=\"padding:28px;background:#f9f9f9;\">\n    <p style=\"font-size:16px;color:#333;\">Your carousel PDF has been generated and uploaded to Google Drive.</p>\n    <table style=\"width:100%;margin:20px 0;border-collapse:collapse;\">\n      <tr><td style=\"padding:8px;font-weight:bold;color:#555;\">Topic:</td><td style=\"padding:8px;color:#333;\">{{ $('5. Code \u2014 Generate PDF').item.json.topic }}</td></tr>\n      <tr style=\"background:#fff;\"><td style=\"padding:8px;font-weight:bold;color:#555;\">Slides:</td><td style=\"padding:8px;color:#333;\">{{ $('5. Code \u2014 Generate PDF').item.json.slideCount }} slides</td></tr>\n      <tr><td style=\"padding:8px;font-weight:bold;color:#555;\">File:</td><td style=\"padding:8px;color:#333;\">{{ $('5. Code \u2014 Generate PDF').item.json.fileName }}</td></tr>\n      <tr style=\"background:#fff;\"><td style=\"padding:8px;font-weight:bold;color:#555;\">Drive Link:</td><td style=\"padding:8px;\"><a href=\"https://drive.google.com/file/d/{{ $('7. Google Sheets \u2014 Log Carousel').item.json['Drive File ID'] }}/view\" style=\"color:#0A66C2;\">Open in Google Drive</a></td></tr>\n    </table>\n    <div style=\"background:#e8f4fd;border-left:4px solid #0A66C2;padding:16px;border-radius:0 8px 8px 0;margin-top:20px;\">\n      <p style=\"margin:0;font-size:14px;color:#333;font-weight:600;\">How to post on LinkedIn:</p>\n      <ol style=\"margin:8px 0 0;padding-left:20px;font-size:14px;color:#555;line-height:1.8;\">\n        <li>Download the PDF from Google Drive</li>\n        <li>Go to LinkedIn \u2192 Create Post \u2192 Add document</li>\n        <li>Upload the PDF \u2014 LinkedIn converts it to carousel</li>\n        <li>Add your caption \u2192 Post!</li>\n      </ol>\n    </div>\n  </div>\n  <div style=\"background:#0A66C2;padding:16px;text-align:center;border-radius:0 0 8px 8px;\">\n    <p style=\"color:rgba(255,255,255,0.8);font-size:12px;margin:0;\">Generated by n8n LinkedIn Carousel Generator</p>\n  </div>\n</div>",
        "options": {
          "senderName": "LinkedIn Carousel Generator"
        },
        "subject": "=\ud83c\udfa8 LinkedIn Carousel Ready \u2014 {{ $('5. Code \u2014 Generate PDF').item.json.topic }}"
      },
      "typeVersion": 2.1
    }
  ],
  "connections": {
    "5. Code \u2014 Generate PDF": {
      "main": [
        [
          {
            "node": "6. Google Drive \u2014 Upload PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI \u2014 GPT-4o-mini Model": {
      "ai_languageModel": [
        [
          {
            "node": "2. AI Agent \u2014 Generate Slide Content",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "3. Code \u2014 Parse Slides JSON": {
      "main": [
        [
          {
            "node": "4. Code \u2014 Build HTML Slides",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. Code \u2014 Build HTML Slides": {
      "main": [
        [
          {
            "node": "5. Code \u2014 Generate PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6. Google Drive \u2014 Upload PDF": {
      "main": [
        [
          {
            "node": "7. Google Sheets \u2014 Log Carousel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7. Google Sheets \u2014 Log Carousel": {
      "main": [
        [
          {
            "node": "8. Gmail \u2014 Email PDF to You",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Form \u2014 Carousel Topic + Details": {
      "main": [
        [
          {
            "node": "2. AI Agent \u2014 Generate Slide Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. AI Agent \u2014 Generate Slide Content": {
      "main": [
        [
          {
            "node": "3. Code \u2014 Parse Slides JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}