AI ad copy variations for every product

Run once and get four Arabic and English ad variations for every product in your sheet, ready to test.

Easy Saves ~6 hours/month MarketingBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: Manual — you click Run
  1. Read your Products sheet (product, price, benefits).
  2. AI writes 4 ads per product from different angles, 2 Arabic and 2 English.
  3. Save each ad as a row in the Ad copy sheet.

Diagram

▶Run manuallyManual TriggerGRead productsGoogle SheetsWrite ad variationsBasic LLM ChainClaude modelAnthropic Chat Mo…{ }One row per adCodeGSave to Ad copy she…Google Sheets
Trigger App Code AI

Code

JavaScript used in the Code step — already included in the template below.

One row per ad · Code node
// Reads the AI's JSON for each product and turns every ad variation into its own row.
const out = [];
for (const item of $input.all()) {
  const raw = item.json.text || "";
  const data = JSON.parse(raw.slice(raw.indexOf("{"), raw.lastIndexOf("}") + 1));
  (data.ads || []).forEach((ad, i) => out.push({
    json: {
      product: data.product,
      variation: i + 1,
      angle: ad.angle,
      language: ad.language,
      headline: ad.headline,
      primary_text: ad.text,
      status: "draft",
    },
  }));
}
return out;

Build it

Pick your tool — same automation, step by step.

Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder. AI steps use a Claude model node — swap it for OpenAI, Gemini or Ollama if you prefer.

Workflow JSON
Show code (193 lines)
{
  "name": "AI ad copy variations for every product (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## AI ad copy variations for every product\nRun once and get four Arabic and English ad variations for every product in your sheet, ready to test.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "292cf932-28a7-4af9-a243-d7e34e3e3b58",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {},
      "id": "292cf932-28a7-4af9-a243-d7e34e3e3b58",
      "name": "Run manually",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Products",
          "mode": "name"
        },
        "options": {}
      },
      "id": "292cf932-28a7-4af9-a243-d7e34e3e3b58",
      "name": "Read products",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=You write Facebook and Instagram ads for YOUR_BRAND. Audience: YOUR_AUDIENCE.\nProduct: {{ $json.product }}\nPrice: {{ $json.price }}\nKey benefits: {{ $json.benefits }}\n\nWrite 4 ad variations, each from a different angle (problem, benefit, social proof, offer). Two in Arabic, two in English. Headline under 40 characters, text under 125 characters. Never invent discounts, reviews or claims that aren't above.\nReply ONLY with JSON: {\"product\": \"{{ $json.product }}\", \"ads\": [{\"angle\": \"\", \"language\": \"ar|en\", \"headline\": \"\", \"text\": \"\"}]}"
      },
      "id": "292cf932-28a7-4af9-a243-d7e34e3e3b58",
      "name": "Write ad variations",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.5,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "claude-sonnet-5",
          "mode": "list"
        },
        "options": {}
      },
      "id": "292cf932-28a7-4af9-a243-d7e34e3e3b58",
      "name": "Claude model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.3,
      "position": [
        600,
        220
      ]
    },
    {
      "parameters": {
        "jsCode": "// Reads the AI's JSON for each product and turns every ad variation into its own row.\nconst out = [];\nfor (const item of $input.all()) {\n  const raw = item.json.text || \"\";\n  const data = JSON.parse(raw.slice(raw.indexOf(\"{\"), raw.lastIndexOf(\"}\") + 1));\n  (data.ads || []).forEach((ad, i) => out.push({\n    json: {\n      product: data.product,\n      variation: i + 1,\n      angle: ad.angle,\n      language: ad.language,\n      headline: ad.headline,\n      primary_text: ad.text,\n      status: \"draft\",\n    },\n  }));\n}\nreturn out;"
      },
      "id": "292cf932-28a7-4af9-a243-d7e34e3e3b58",
      "name": "One row per ad",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        900,
        0
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Ad copy",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {}
        },
        "options": {}
      },
      "id": "292cf932-28a7-4af9-a243-d7e34e3e3b58",
      "name": "Save to Ad copy sheet",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        1200,
        0
      ]
    }
  ],
  "connections": {
    "Run manually": {
      "main": [
        [
          {
            "node": "Read products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read products": {
      "main": [
        [
          {
            "node": "Write ad variations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write ad variations": {
      "main": [
        [
          {
            "node": "One row per ad",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "One row per ad": {
      "main": [
        [
          {
            "node": "Save to Ad copy sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude model": {
      "ai_languageModel": [
        [
          {
            "node": "Write ad variations",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Write real benefits in the sheet; the AI is told never to invent claims.

Related flows