AutomationFlowsAI & RAG › Generate Twitter/x Captions From Google Drive Images Using Cloudinary &…

Generate Twitter/x Captions From Google Drive Images Using Cloudinary &…

Original n8n title: Generate Twitter/x Captions From Google Drive Images Using Cloudinary & Gpt-4o-mini

ByRahul Joshi @rahul08 on n8n.io

Description

Event trigger★★★★☆ complexityAI-powered13 nodesChain LlmLm Chat Azure Open AiEmail SendHTTP RequestGoogle Drive TriggerGoogle Drive
AI & RAG Trigger: Event Nodes: 13 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #7278 — we link there as the canonical source.

This workflow follows the Chainllm → Emailsend 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
{
  "id": "AaKfljggy90pXuZs",
  "name": "Twitter caption generator",
  "tags": [],
  "nodes": [
    {
      "id": "406e4913-92c2-4619-9c96-64a9d1ddb556",
      "name": "Basic LLM Chain",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        672,
        0
      ],
      "parameters": {
        "text": "={{ $json.secure_url }} || Analyze this automation image and generate a classy and attractive caption for Twitter (X) based on the instructions in the system prompt.",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "=You are a professional Twitter (X) content strategist and email designer.\n\nWhen given an image url , dashboard, or visual automation, analyze it deeply and return the following two outputs:\n\nA short, professional subject line (max 60 characters).\n\nA complete HTML email body with inline CSS that includes:\n\nThe image (use {{ $json.secure_url }} in the src attribute).\n\nA Twitter (X)-style post block (formatted like a professional social copy within the email) that contains:\n\u2022 Headline (bold, 1 line)\n\u2022 Primary tweet \u2014 one tweet, punchy, <= 280 characters, optimized for engagement (clear hook + value + CTA).\n\u2022 Tweet thread \u2014 3 short tweets (each <= 280 characters) that expand the idea: Hook \u2192 Insight \u2192 Action. Number the tweets (1/3, 2/3, 3/3).\n\u2022 Alt text for the image (1\u20132 lines, descriptive, <120 characters).\n\u2022 Suggested first-reply (one short reply to pin under the tweet/thread, e.g., resources or link).\n\u2022 10\u201312 relevant Twitter/X hashtags (high-signal, platform-appropriate \u2014 avoid over-stuffing; pick the most relevant).\n\u2022 Suggested @mentions (1\u20133 accounts types to mention, e.g., partner, tool, or community handles; leave as placeholders if unknown).\n\u2022 Recommended posting windows (IST) \u2014 3 time slots ideal for engagement.\n\nA compact, professional summary section inside the email with:\n\u2022 2\u20133 sentence overview of the visual\n\u2022 Bullet list of Key features (3\u20136 bullets)\n\u2022 Bullet list of Ideal users (2\u20135 bullets)\n\u2022 \u201cBuilt with\u201d list (tools/tech stack; 3\u20136 items)\n\u2022 Single-line CTA (e.g., \u201cTry it\u201d, \u201cRequest demo\u201d, \u201cReply to learn more\u201d)\n\nDesign & accessibility:\n\u2022 Use {{ $json.secure_url }} for the image src.\n\u2022 Include the alt text near the image tag (use the same alt text as in the Twitter block).\n\u2022 Max width 600px, centered content.\n\u2022 White content card on a light gray background, soft box shadow, clean spacing, readable bullets.\n\u2022 Inline CSS only (no external styles).\n\u2022 Fonts: Arial or Helvetica.\n\u2022 Email must render well in Gmail & Outlook.\n\u2022 Keep markup simple and robust: tables are allowed if needed for Outlook compatibility, but keep it clean.\n\nStyle & length rules:\n\nSubject line \u2264 60 characters.\n\nPrimary tweet and each thread tweet \u2264 280 characters (include a character count comment next to each tweet inside the email as a small, parenthetical note).\n\nHeadline: single bold line inside the email.\n\nHashtags: 10\u201312 total.\n\nKeep the whole email concise \u2014 one glance should tell the reader what the visual does and how to share it on X.\n\n\ud83c\udfaf Your response must follow this exact format \u2014 do not include code blocks or markdown:\n\nSubject: [your subject line here]\nBody: [your full HTML content here \u2014 one line or multiline]\n\nDo not return JSON. Do not use ``` or Markdown formatting."
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "891fb13d-10e5-4f9e-aaca-d1f8529b299f",
      "name": "Azure OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        768,
        224
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1d3b6dc1-e7f2-4577-b17f-c2872831d5ad",
      "name": "Send email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1072,
        0
      ],
      "parameters": {
        "html": "={{ $json.text }}",
        "options": {},
        "subject": "Twitter Post",
        "toEmail": "<RECIEVER_EMAIL",
        "fromEmail": "<YOUR_EMAIL>"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "4d7f5f02-0d0d-44e6-90b9-738b5779596e",
      "name": "upload frames to cloudinary",
      "type": "n8n-nodes-base.httpRequest",
      "maxTries": 5,
      "position": [
        448,
        0
      ],
      "parameters": {
        "url": "https://api.cloudinary.com/v1_1/dpuvigpmt/image/upload",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "file",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            },
            {
              "name": "upload_preset",
              "value": "upload"
            }
          ]
        },
        "genericAuthType": "httpBasicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2
    },
    {
      "id": "cda8a3ff-4b61-4d68-8fca-580b10750baf",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1072,
        -320
      ],
      "parameters": {
        "color": 3,
        "height": 304,
        "content": "Type: n8n-nodes-base.emailSend\n\nPurpose: Delivers generated captions via email\n\nWhat it does:\n\nSends email with generated captions\nIncludes file links and AI suggestions\nOutput: Email notification with results"
      },
      "typeVersion": 1
    },
    {
      "id": "8ef3c770-d420-49a2-a6d1-ffa0592e5abb",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        -352
      ],
      "parameters": {
        "color": 4,
        "height": 336,
        "content": "Type: n8n-nodes-base.langchain\n\nPurpose: Generates Twitter captions using AI\n\nWhat it does:\n\nAnalyzes uploaded content\nCreates engaging Twitter captions\n\nAdds hashtags and optimizes for social media\n\nOutput: Generated caption text"
      },
      "typeVersion": 1
    },
    {
      "id": "809d5a50-725c-46ce-a28a-ad4ade39cf50",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        -336
      ],
      "parameters": {
        "color": 5,
        "height": 320,
        "content": "Type: n8n-nodes-base.httpRequest \n\nPurpose: Uploads files to Cloudinary storage\nWhat it does:\n\nTakes file from Google Drive\n\nUploads to Cloudinary cloud storage \n\nCreates public URLs for AI processing\nOutput: Cloudinary URLs and file links"
      },
      "typeVersion": 1
    },
    {
      "id": "d55c6928-f5ab-487c-a560-6df24b23c1f4",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        176
      ],
      "parameters": {
        "color": 6,
        "height": 240,
        "content": "Type: n8n-nodes-base.googleDrive\n\nPurpose: Downloads file content from Google Drive \n\nWhat it does: Gets the actual file data for processing \n\nOutput: File content ready for upload"
      },
      "typeVersion": 1
    },
    {
      "id": "37e94fb7-07c1-4268-bd70-90aa250f9e63",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -192,
        -272
      ],
      "parameters": {
        "color": 7,
        "height": 256,
        "content": "Type: n8n-nodes-base.googleDriveTrigger\n\nPurpose: Monitors Google Drive for new files \n\nWhat it does: Automatically starts workflow when new file is uploaded\n\nOutput: File information (name, URL, metadata)"
      },
      "typeVersion": 1
    },
    {
      "id": "0fc331db-8dae-4974-a19a-bbfea8d3107b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        528,
        352
      ],
      "parameters": {
        "color": 4,
        "height": 224,
        "content": "Type: n8n-nodes-base.azureOpenAi\n\nPurpose: Alternative AI for caption generation\nWhat it does: Backup AI service for creating captions\n\nOutput: Additional caption suggestions\n"
      },
      "typeVersion": 1
    },
    {
      "id": "eb3add42-5770-45c0-a2e7-2958def4a8eb",
      "name": "Get files from drive",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {
        "event": "fileUpdated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "1GDkSI9txB88oOcu_jr1tXEzkT0_FoGmC",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1GDkSI9txB88oOcu_jr1tXEzkT0_FoGmC",
          "cachedResultName": "Instagram "
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "535f3639-dcc5-4fd3-9c14-ca740ed3b138",
      "name": "Download the drive files",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        224,
        0
      ],
      "parameters": {
        "fileId": "={{ $json[\"id\"] }}",
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "47369773-409f-4a02-8b4b-22e5c19c0d2a",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -608,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 336,
        "height": 592,
        "content": "Pre-conditions & API Requirements\n\nGoogle Drive\n\nNeeds OAuth2 credentials (googleDriveOAuth2Api)\n\nAccess must be granted to the folder being monitored.\n\nCloudinary\n\nRequires Cloudinary API key & secret (used in HTTP Request node for uploads).\n\nEnsure an upload_preset is configured in your Cloudinary account.\n\nAzure OpenAI\n\nRequires an Azure OpenAI endpoint and API key.\n\nModel: gpt-4o-mini (already configured in the JSON).\n\nSMTP Email\n\nYou\u2019ll need an SMTP credential to send the generated captions to your email."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "383087ac-19f2-452d-a452-0d553ac7c581",
  "connections": {
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Send email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get files from drive": {
      "main": [
        [
          {
            "node": "Download the drive files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Download the drive files": {
      "main": [
        [
          {
            "node": "upload frames to cloudinary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "upload frames to cloudinary": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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

Description

Source: https://n8n.io/workflows/7278/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

Description:

Google Drive Trigger, Google Drive, Chain Llm +3
AI & RAG

This n8n template demonstrates how to automate YouTube content repurposing using AI. Upload a video to Google Drive and automatically generate transcriptions, A/B testable titles, AI thumbnails, short

Airtable, Google Drive Trigger, OpenAI +5
AI & RAG

Awesome N8N Templates. Uses notion, lmChatOpenAi, outputParserStructured, chainLlm. Event-driven trigger; 36 nodes.

Notion, OpenAI Chat, Output Parser Structured +8
AI & RAG

This workflow is designed for finance professionals, accountants, small business owners in Colombia, or anyone needing to automate the extraction of invoice data and its entry into Google Sheets. It's

Lm Chat Azure Open Ai, Output Parser Structured, Google Drive Trigger +3
AI & RAG

How it works Downloads markdown documents from a Google Drive folder containing private information, uses the Ollama model to identify and extract sensitive data, and stores the sanitized text in a si

HTTP Request, Google Drive, Chain Llm +3