AutomationFlowsAI & RAG › Generate Digital Product Launch Content with Openai Gpt-4o-mini and Google…

Generate Digital Product Launch Content with Openai Gpt-4o-mini and Google…

Original n8n title: Generate Digital Product Launch Content with Openai Gpt-4o-mini and Google Sheets

ByIbrahim Edhem @harbutlu on n8n.io

This workflow generates a multi-channel digital product launch content pack from product details, using OpenAI to create a blog intro, LinkedIn post, X post, Instagram caption, and launch email, and can optionally append the results to Google Sheets. Runs manually when you…

Event trigger★★★★☆ complexityAI-powered10 nodesChain LlmOpenAI ChatGoogle Sheets
AI & RAG Trigger: Event Nodes: 10 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Chainllm → Google Sheets 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": "550e8400-e29b-41d4-a716-446655440099",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Launch Content Pack \u2014 Digital Product Marketing",
  "tags": [],
  "nodes": [
    {
      "id": "f271241b-b7c8-422a-a32a-9a9317c9e49b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        128
      ],
      "parameters": {
        "width": 480,
        "height": 768,
        "content": "## Launch Content Pack \u2014 Digital Product Marketing\n\n### How it works\n\nThis workflow creates a digital product launch content pack from sample product data. It is started manually, passes product details into an OpenAI-powered LLM chain, formats the generated response, and can optionally save the final content to Google Sheets.\n\n### Setup steps\n\n- Configure OpenAI credentials for the OpenAI Chat Model used by the LLM chain.\n- Review and replace the sample product fields in the Sample Product Data node with the actual product details.\n- If saving results, add Google Sheets credentials, configure the target spreadsheet and sheet, then enable or activate the optional Google Sheets node.\n- Run the workflow manually to generate and inspect the formatted content pack.\n\n### Customization\n\nAdjust the sample product fields and LLM prompt to change the product positioning, campaign angle, tone, or content formats. The Google Sheets destination can be changed to another storage or publishing step if needed."
      },
      "typeVersion": 1
    },
    {
      "id": "6ce985fb-0c71-43da-bbd1-e5db1ce3a991",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        128
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 336,
        "content": "## Prepare product input\n\nStarts the workflow manually and loads sample digital product marketing details that will be used as the source data for content generation."
      },
      "typeVersion": 1
    },
    {
      "id": "20e6937a-33bc-4642-b962-008696c2f094",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        672,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 528,
        "content": "## Generate launch copy\n\nUses the LLM chain and its nearby OpenAI chat model to create the launch content pack from the prepared product data."
      },
      "typeVersion": 1
    },
    {
      "id": "50151305-0520-44c1-aa9a-6f38fd308967",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1056,
        128
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 336,
        "content": "## Format and save output\n\nNormalizes the LLM response into a content pack structure and optionally writes the finished results to Google Sheets once credentials are configured."
      },
      "typeVersion": 1
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "Launch Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        250,
        300
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "Set Product Data",
      "type": "n8n-nodes-base.set",
      "position": [
        470,
        300
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"productName\": \"Prompt Pack Pro: ChatGPT for Etsy Sellers\",\n  \"tagline\": \"50 copy-paste prompts that write your listings, emails, and social posts \u2014 in your brand voice.\",\n  \"price\": \"$27\",\n  \"productURL\": \"https://your-store.gumroad.com/l/promptpackpro\",\n  \"targetAudience\": \"Etsy sellers who hate writing but need to show up consistently online\",\n  \"brandTone\": \"Warm, direct, no-fluff \u2014 like a smart friend who happens to be a copywriter\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440003",
      "name": "Create Launch Content",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        720,
        300
      ],
      "parameters": {
        "text": "={{ \"Product Name: \" + $json.productName + \"\\nTagline: \" + $json.tagline + \"\\nPrice: \" + $json.price + \"\\nProduct URL: \" + $json.productURL + \"\\nTarget Audience: \" + $json.targetAudience + \"\\nBrand Tone: \" + $json.brandTone }}",
        "messages": {
          "messageValues": [
            {
              "type": "SystemMessagePromptTemplate",
              "message": "You are an expert launch copywriter for digital products sold on Gumroad and Etsy.\n\nReturn ONLY valid JSON, no markdown, no code fences, no prose, no explanation. The JSON object must contain exactly these keys: blog_intro, linkedin_post, x_post, instagram_caption, launch_email. Return exactly this json structure:\n\n{\"blog_intro\": \"<200-word benefit-led blog intro that hooks the reader, focuses on outcomes not features, and ends with a clear CTA linking to the product URL>\", \"linkedin_post\": \"<150-200 word professional LinkedIn post; insight-led opening, 2-3 short paragraphs, closes with CTA including the product URL>\", \"x_post\": \"<punchy X/Twitter post under 240 characters total including the product URL; hook-first>\", \"instagram_caption\": \"<100-150 word Instagram caption; warm and vivid tone, 3-5 relevant hashtags at the end, CTA with product URL>\", \"launch_email\": \"<launch email where the first line is exactly 'Subject: [your subject line here]', then a blank line, then 200-250 word benefit-led body, clear CTA with product URL, warm sign-off>\"}\n\nRules:\n- Every single asset MUST include the exact product URL from the input.\n- Lead with benefits and transformation, never with feature lists.\n- Match the stated brand tone exactly.\n- Write real, publish-ready copy \u2014 no placeholders, no filler.\n- Output the JSON object only \u2014 nothing before or after it."
            }
          ]
        },
        "promptType": "define",
        "needsFallback": false,
        "hasOutputParser": false
      },
      "typeVersion": 1.9
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440004",
      "name": "OpenAI GPT-4 Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        720,
        520
      ],
      "parameters": {
        "model": {
          "mode": "id",
          "value": "gpt-4o-mini"
        },
        "options": {
          "temperature": 0.7,
          "responseFormat": "json_object"
        },
        "responsesApiEnabled": false
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440005",
      "name": "Format Launch Content",
      "type": "n8n-nodes-base.code",
      "position": [
        1104,
        304
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// Shape-agnostic reader for the Basic LLM Chain ('Generate Launch Content').\n// The Basic LLM Chain can hand us the data in EITHER of two shapes, depending\n// on the model's Response Format:\n//   PATH A (already-parsed): because OpenAI Chat Model has Response Format =\n//     JSON, the chain auto-parses the model's JSON and exposes the 5 content\n//     keys DIRECTLY at the top level of item.json. There is no `text` field.\n//   PATH B (text-to-parse): the chain returns the raw string under `text`\n//     (or `output` / `response`), which we must JSON.parse ourselves.\n// This code handles both without assuming which one occurred.\nconst item = $input.first();\nconst data = item.json || {};\nconst required = ['blog_intro', 'linkedin_post', 'x_post', 'instagram_caption', 'launch_email'];\n\n// Coerce any value to a string so downstream nodes always get clean text,\n// even if the model returned a number, null, or an object for a field.\nfunction asString(v) { return (v === undefined || v === null) ? '' : String(v); }\n\nlet parsed;\nlet pathTaken;\n\n// PATH A \u2014 the 5 keys are already present at the top level: use them directly.\nif (required.some(function (key) { return key in data; })) {\n  parsed = data;\n  pathTaken = 'already-parsed';\n} else {\n  // PATH B \u2014 fall back to a raw text field and parse it ourselves.\n  const raw = data.text ?? data.output ?? data.response;\n  if (raw === undefined || raw === null || raw === '') {\n    throw new Error(\n      'Could not find content. No top-level content keys and no text/output/response field. ' +\n      'Received keys: ' + JSON.stringify(Object.keys(data))\n    );\n  }\n  // The model may wrap JSON in markdown code fences (```json ... ```). Strip them.\n  let cleaned = String(raw).trim()\n    .replace(/^```(?:json)?\\s*/i, '')  // opening fence\n    .replace(/\\s*```$/i, '')           // closing fence\n    .trim();\n  try {\n    parsed = JSON.parse(cleaned);\n  } catch (e) {\n    throw new Error(\n      'LLM did not return valid JSON. Parse error: ' + e.message +\n      '\\n--- Raw text received ---\\n' + String(raw)\n    );\n  }\n  pathTaken = 'text-to-parse';\n}\n\n// Only fail if a key is genuinely ABSENT. A present-but-empty value is fine.\nconst missing = required.filter(function (key) { return !(key in parsed); });\nif (missing.length > 0) {\n  throw new Error(\n    'Content is missing required key(s): ' + missing.join(', ') +\n    ' (path: ' + pathTaken + '). Received keys: ' + JSON.stringify(Object.keys(parsed))\n  );\n}\n\nreturn [{\n  json: {\n    blog_intro: asString(parsed.blog_intro),\n    linkedin_post: asString(parsed.linkedin_post),\n    x_post: asString(parsed.x_post),\n    instagram_caption: asString(parsed.instagram_caption),\n    launch_email: asString(parsed.launch_email)\n  }\n}];",
        "language": "javaScript"
      },
      "typeVersion": 2
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440006",
      "name": "Append Launch Content to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "disabled": true,
      "position": [
        1344,
        304
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": []
        },
        "options": {
          "valueInputMode": "USER_ENTERED"
        },
        "resource": "sheet",
        "operation": "append",
        "sheetName": {
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "mode": "id",
          "value": "YOUR_SPREADSHEET_ID"
        },
        "authentication": "oAuth2"
      },
      "typeVersion": 4.7
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "550e8400-e29b-41d4-a716-446655440000",
  "connections": {
    "Launch Trigger": {
      "main": [
        [
          {
            "node": "Set Product Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Product Data": {
      "main": [
        [
          {
            "node": "Create Launch Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI GPT-4 Model": {
      "ai_languageModel": [
        [
          {
            "node": "Create Launch Content",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Create Launch Content": {
      "main": [
        [
          {
            "node": "Format Launch Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Launch Content": {
      "main": [
        [
          {
            "node": "Append Launch Content to Sheets",
            "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

This workflow generates a multi-channel digital product launch content pack from product details, using OpenAI to create a blog intro, LinkedIn post, X post, Instagram caption, and launch email, and can optionally append the results to Google Sheets. Runs manually when you…

Source: https://n8n.io/workflows/16670/ — 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

Episode 11: AI shorts factory app. Uses httpRequest, googleSheets, lmChatOpenAi, lmChatOllama. Event-driven trigger; 96 nodes.

HTTP Request, Google Sheets, OpenAI Chat +15
AI & RAG

This end-to-end AI-powered recruitment automation workflow helps HR and talent acquisition teams automate the complete hiring pipeline—from resume intake and parsing to GPT-4-based evaluation, TA appr

Form Trigger, Output Parser Structured, Google Drive +10
AI & RAG

This n8n template demonstrates how to audit your brand’s visibility across multiple AI systems and automatically log the results to Google Sheets. It sends the same prompt to OpenAI, Perplexity, and (

Agent, Google Sheets, OpenAI Chat +4
AI & RAG

Transform a single quote into a fully-rendered cinematic short video — with voice-over, visuals, and music — then publish it directly to TikTok, Instagram Reels, and YouTube Shorts. This isn’t just au

Agent, HTTP Request, Jwt +7
AI & RAG

This workflow is perfect for creators, solopreneurs, and personal brands who want to consistently publish bold, high-performing content on X (Twitter) — without writing a single line themselves. After

OpenAI Chat, Memory Buffer Window, Tool Workflow +10