AutomationFlowsAI & RAG › Workflow Email Marketing AI

Workflow Email Marketing AI

Workflow Email Marketing Ai. Uses readBinaryFile, lmChatAzureOpenAi, agent, emailSend. Event-driven trigger; 10 nodes.

Event trigger★★★★☆ complexityAI-powered10 nodesRead Binary FileLm Chat Azure Open AiAgentEmail Send
AI & RAG Trigger: Event Nodes: 10 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Agent → 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
{
  "nodes": [
    {
      "parameters": {},
      "id": "start-node",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "filePath": "/tmp/entreprises.csv",
        "options": {}
      },
      "id": "read-csv",
      "name": "Read Binary File",
      "type": "n8n-nodes-base.readBinaryFile",
      "typeVersion": 1,
      "position": [
        440,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Parse CSV to JSON\n// Get binary data from the previous node\nconst binaryData = $input.first().binary;\nlet csvText;\n\n// Check if binary data exists and get the data\nif (binaryData && binaryData.data) {\n  // If data is base64 encoded\n  csvText = Buffer.from(binaryData.data.data, 'base64').toString('utf-8');\n} else {\n  throw new Error('No binary data found. Make sure the Read Binary File node is properly configured.');\n}\n\n// Simple CSV parser\nconst lines = csvText.trim().split('\\n');\nif (lines.length < 2) {\n  throw new Error('CSV file must have at least a header and one data row.');\n}\n\nconst headers = lines[0].split(',').map(h => h.replace(/\"/g, '').trim());\nconsole.log('CSV Headers:', headers);\n\nconst items = [];\nfor (let i = 1; i < lines.length; i++) {\n  if (lines[i].trim() === '') continue; // Skip empty lines\n  \n  const values = lines[i].split(',').map(v => v.replace(/\"/g, '').trim());\n  const item = {};\n  \n  headers.forEach((header, index) => {\n    item[header] = values[index] || '';\n  });\n  \n  items.push({\n    json: item\n  });\n}\n\nconsole.log(`\u2705 Parsed ${items.length} companies from CSV`);\nconsole.log('First item example:', items[0]);\nreturn items;"
      },
      "id": "parse-csv",
      "name": "Parse CSV",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        640,
        300
      ]
    },
    {
      "parameters": {
        "batchSize": 1,
        "options": {
          "reset": false
        }
      },
      "id": "split-batches",
      "name": "Split in Batches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        840,
        300
      ]
    },
    {
      "parameters": {
        "resource": "{{ $vars.AZURE_OPENAI_RESOURCE }}",
        "apiVersion": "2024-02-15-preview",
        "deploymentId": "gpt-4",
        "options": {
          "temperature": 0.7,
          "maxTokens": 1500
        }
      },
      "id": "azure-openai",
      "name": "Azure OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "typeVersion": 1,
      "position": [
        1040,
        200
      ],
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "agent": "toolsAgent",
        "systemMessage": "Tu es un expert en r\u00e9daction d'emails marketing personnalis\u00e9s en fran\u00e7ais. Tu cr\u00e9es des emails professionnels, engageants et personnalis\u00e9s pour chaque entreprise.\n\nTon objectif est de :\n1. Cr\u00e9er un email personnalis\u00e9 et professionnel\n2. Utiliser les informations sp\u00e9cifiques de l'entreprise\n3. Adapter le ton selon le secteur d'activit\u00e9\n4. Inclure un call-to-action clair\n5. Garder un style chaleureux mais professionnel\n\nFormat de r\u00e9ponse OBLIGATOIRE :\nOBJET: [Sujet accrocheur personnalis\u00e9]\n\nCORPS:\n[Email complet en HTML avec personnalisation]",
        "text": "Cr\u00e9e un email marketing personnalis\u00e9 pour cette entreprise :\n\n**Informations de l'entreprise :**\n- Nom de l'entreprise: {{ $json.nom_entreprise }}\n- Secteur d'activit\u00e9: {{ $json.secteur }}\n- Contact: {{ $json.nom_contact }}\n- Email: {{ $json.email }}\n- Taille entreprise: {{ $json.taille }}\n- Ville: {{ $json.ville }}\n- T\u00e9l\u00e9phone: {{ $json.telephone }}\n\n**Instructions sp\u00e9cifiques :**\n1. Adresse-toi personnellement \u00e0 {{ $json.nom_contact }}\n2. Mentionne sp\u00e9cifiquement leur secteur \"{{ $json.secteur }}\"\n3. Adapte la proposition \u00e0 leur taille d'entreprise \"{{ $json.taille }}\"\n4. Mentionne leur localisation \"{{ $json.ville }}\"\n5. Propose nos services d'automatisation n8n adapt\u00e9s \u00e0 leur besoin\n6. Inclus un call-to-action pour programmer un appel de 30 minutes\n7. Utilise un ton professionnel mais chaleureux\n8. Email en fran\u00e7ais avec du HTML propre\n\nCr\u00e9e maintenant l'email complet !",
        "options": {
          "maxIterations": 3
        }
      },
      "id": "ai-agent",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1,
      "position": [
        1040,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Extract subject and body from AI response\nconst aiResponse = $input.first().json.output;\nlet subject = '';\nlet body = '';\n\n// Parse the AI response to extract OBJET and CORPS\nif (aiResponse.includes('OBJET:')) {\n  const subjectMatch = aiResponse.match(/OBJET:\\s*(.+?)(?=\\n\\nCORPS:|$)/s);\n  if (subjectMatch) {\n    subject = subjectMatch[1].trim();\n  }\n}\n\nif (aiResponse.includes('CORPS:')) {\n  const bodyMatch = aiResponse.match(/CORPS:\\s*([\\s\\S]+?)$/s);\n  if (bodyMatch) {\n    body = bodyMatch[1].trim();\n  }\n} else {\n  // Fallback: use the whole response as body if format is different\n  body = aiResponse;\n}\n\n// Ensure we have content\nif (!subject) {\n  subject = `Proposition personnalis\u00e9e pour ${$('Split in Batches').item.json.nom_entreprise}`;\n}\n\nif (!body) {\n  body = aiResponse;\n}\n\n// Return the parsed data along with recipient info\nreturn [{\n  json: {\n    subject: subject,\n    body: body,\n    recipientEmail: $('Split in Batches').item.json.email,\n    recipientName: $('Split in Batches').item.json.nom_contact,\n    companyName: $('Split in Batches').item.json.nom_entreprise,\n    sector: $('Split in Batches').item.json.secteur\n  }\n}];"
      },
      "id": "extract-email",
      "name": "Extract Email Content",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1240,
        300
      ]
    },
    {
      "parameters": {
        "fromEmail": "{{ $vars.PRIVATE_EMAIL_USER }}",
        "toEmail": "{{ $json.recipientEmail }}",
        "subject": "{{ $json.subject }}",
        "emailType": "html",
        "message": "{{ $json.body }}",
        "options": {
          "replyTo": "{{ $vars.PRIVATE_EMAIL_USER }}",
          "priority": "normal"
        }
      },
      "id": "send-email",
      "name": "Send Email",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2,
      "position": [
        1440,
        300
      ],
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "amount": 5,
        "unit": "seconds"
      },
      "id": "wait-node",
      "name": "Wait 5 seconds",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1,
      "position": [
        1640,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Log the email sending result\nconst emailData = $input.first().json;\nconst recipientData = $('Extract Email Content').first().json;\n\nconsole.log(`\u2705 Email envoy\u00e9 avec succ\u00e8s \u00e0:`);\nconsole.log(`\ud83d\udce7 Destinataire: ${recipientData.recipientName} (${recipientData.recipientEmail})`);\nconsole.log(`\ud83c\udfe2 Entreprise: ${recipientData.companyName}`);\nconsole.log(`\ud83d\udcdd Sujet: ${recipientData.subject}`);\nconsole.log(`\u23f0 Heure d'envoi: ${new Date().toLocaleString('fr-FR')}`);\nconsole.log('---');\n\nreturn [{\n  json: {\n    status: 'success',\n    recipient: recipientData.recipientEmail,\n    company: recipientData.companyName,\n    subject: recipientData.subject,\n    sentAt: new Date().toISOString(),\n    message: `Email envoy\u00e9 avec succ\u00e8s \u00e0 ${recipientData.recipientName} de ${recipientData.companyName}`\n  }\n}];"
      },
      "id": "log-success",
      "name": "Log Success",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1840,
        300
      ]
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Read Binary File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Binary File": {
      "main": [
        [
          {
            "node": "Parse CSV",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse CSV": {
      "main": [
        [
          {
            "node": "Split in Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split in Batches": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Azure OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Extract Email Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Email Content": {
      "main": [
        [
          {
            "node": "Send Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Email": {
      "main": [
        [
          {
            "node": "Wait 5 seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 5 seconds": {
      "main": [
        [
          {
            "node": "Log Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Success": {
      "main": [
        [
          {
            "node": "Split in Batches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    {
      "createdAt": "2024-01-15T10:00:00.000Z",
      "updatedAt": "2024-01-15T10:00:00.000Z",
      "id": "email-marketing",
      "name": "Email Marketing"
    },
    {
      "createdAt": "2024-01-15T10:00:00.000Z",
      "updatedAt": "2024-01-15T10:00:00.000Z",
      "id": "ai-automation",
      "name": "AI Automation"
    }
  ],
  "triggerCount": 1,
  "updatedAt": "2024-01-15T10:00:00.000Z",
  "versionId": "1"
}

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

Workflow Email Marketing Ai. Uses readBinaryFile, lmChatAzureOpenAi, agent, emailSend. Event-driven trigger; 10 nodes.

Source: https://github.com/WizzyDev997/N8N/blob/6f91f33c272255d142e6f57af41b08e6199e352f/workflow_email_marketing_ai.json — 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

This is a Telegram AI-to-Human Handover System that seamlessly transitions customer support conversations between an AI agent and human operators: AI-First Response: When users message the Telegram bo

Telegram Trigger, Telegram, Email Send +7
AI & RAG

Description:

Google Sheets, Email Send, Agent +1
AI & RAG

Automate YouTube channel analysis by fetching channel data, generating a key metrics table and actionable insights using Azure OpenAI (GPT-4o-mini), and delivering the results via email. Integrates Yo

Email Send, Agent, Lm Chat Azure Open Ai +2
AI & RAG

Streamline your lead management process with this AI-driven n8n automation template. The workflow fetches opportunities from HighLevel (GHL), enriches them with contact details, and uses Azure OpenAI

Email Send, Agent, High Level +1
AI & RAG

Automatically qualify and route new leads from a Google Sheet into your CRM with AI-powered scoring and instant sales notifications. Turn raw form submissions into prioritized opportunities—effortless

Google Sheets Trigger, Agent, Lm Chat Azure Open Ai +3