{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "WhatsApp Bulk Campaign from Google Sheets via MoltFlow",
  "tags": [
    {
      "name": "whatsapp"
    },
    {
      "name": "automation"
    },
    {
      "name": "moltflow"
    },
    {
      "name": "bulk messaging"
    },
    {
      "name": "google sheets"
    },
    {
      "name": "campaigns"
    }
  ],
  "nodes": [
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000010",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        -300
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 310,
        "content": "## WhatsApp Bulk Campaign\nSend personalized WhatsApp campaigns to contacts imported from Google Sheets using [MoltFlow](https://molt.waiflow.app).\n\n**How it works:**\n1. Click Execute to start\n2. Contacts are read from your Google Sheet\n3. A custom group is created in MoltFlow\n4. A bulk send job sends messages with smart delays\n5. Campaign progress is checked and summarized"
      },
      "typeVersion": 1
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000011",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        420,
        -300
      ],
      "parameters": {
        "color": 5,
        "width": 400,
        "height": 270,
        "content": "## Setup (5 min)\n1. Create a [MoltFlow account](https://molt.waiflow.app) and connect WhatsApp\n2. Generate API key with Outreach scope preset\n3. Prepare Google Sheet with columns: phone, name, message_override\n4. Connect Google Sheets OAuth2 credential\n5. Paste your Sheet URL in the Google Sheets node\n6. Set YOUR_SESSION_ID in the Format Contacts node\n7. Add MoltFlow API Key: Header Auth with X-API-Key"
      },
      "typeVersion": 1
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000001",
      "name": "Start Campaign",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {
        "notice": ""
      },
      "typeVersion": 1
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000002",
      "name": "Read Contacts from Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        220,
        0
      ],
      "parameters": {
        "options": {},
        "operation": "read",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "YOUR_GOOGLE_SHEET_URL"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000003",
      "name": "Format Contacts",
      "type": "n8n-nodes-base.code",
      "position": [
        440,
        0
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const SESSION_ID = 'YOUR_SESSION_ID';\nconst defaultMessage = 'Hi {{name}}, we have an exclusive offer just for you! Reply YES to learn more.';\n\nconst rows = $input.all();\nconst today = new Date().toISOString().slice(0, 10);\nconst members = rows.map(row => {\n  const data = row.json;\n  return {\n    phone: String(data.phone || data.Phone || '').replace(/[^0-9]/g, ''),\n    name: data.name || data.Name || ''\n  };\n}).filter(m => m.phone.length >= 7);\n\nreturn [{\n  json: {\n    session_id: SESSION_ID,\n    group_name: 'Campaign ' + today,\n    members: members,\n    member_count: members.length,\n    message: defaultMessage\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000004",
      "name": "Create Custom Group",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        660,
        0
      ],
      "parameters": {
        "url": "https://apiv2.waiflow.app/api/v2/custom-groups",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ name: $json.group_name, members: $json.members }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000005",
      "name": "Prepare Bulk Send",
      "type": "n8n-nodes-base.code",
      "position": [
        880,
        0
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const createResponse = $input.first().json;\nconst groupId = createResponse.id;\nconst sessionId = $('Format Contacts').first().json.session_id;\nconst message = $('Format Contacts').first().json.message;\nconst memberCount = createResponse.member_count || $('Format Contacts').first().json.member_count;\n\nreturn [{\n  json: {\n    custom_group_id: groupId,\n    session_id: sessionId,\n    message_type: 'text',\n    message_content: message,\n    member_count: memberCount,\n    group_name: createResponse.name\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000006",
      "name": "Create Bulk Send Job",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1100,
        0
      ],
      "parameters": {
        "url": "https://apiv2.waiflow.app/api/v2/bulk-send",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ custom_group_id: $json.custom_group_id, session_id: $json.session_id, message_type: $json.message_type, message_content: $json.message_content }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000007",
      "name": "Wait 30s",
      "type": "n8n-nodes-base.wait",
      "position": [
        1320,
        0
      ],
      "parameters": {
        "unit": "seconds",
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000008",
      "name": "Check Campaign Progress",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1540,
        0
      ],
      "parameters": {
        "url": "={{ 'https://apiv2.waiflow.app/api/v2/bulk-send/' + $('Create Bulk Send Job').first().json.id }}",
        "method": "GET",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c1b2c3d4-3333-4000-c000-000000000009",
      "name": "Campaign Summary",
      "type": "n8n-nodes-base.code",
      "position": [
        1760,
        0
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const job = $input.first().json;\nreturn [{ json: {\n  job_id: job.id,\n  status: job.status,\n  group_name: job.group_name || 'N/A',\n  total_recipients: job.total_recipients,\n  sent: job.sent_count,\n  failed: job.failed_count,\n  remaining: job.total_recipients - job.sent_count - job.failed_count,\n  started_at: job.started_at,\n  completed_at: job.completed_at,\n  estimated_completion: job.estimated_completion\n} }];"
      },
      "typeVersion": 2
    }
  ],
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Wait 30s": {
      "main": [
        [
          {
            "node": "Check Campaign Progress",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Campaign": {
      "main": [
        [
          {
            "node": "Read Contacts from Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Contacts": {
      "main": [
        [
          {
            "node": "Create Custom Group",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Bulk Send": {
      "main": [
        [
          {
            "node": "Create Bulk Send Job",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Custom Group": {
      "main": [
        [
          {
            "node": "Prepare Bulk Send",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Bulk Send Job": {
      "main": [
        [
          {
            "node": "Wait 30s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Campaign Progress": {
      "main": [
        [
          {
            "node": "Campaign Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Contacts from Sheet": {
      "main": [
        [
          {
            "node": "Format Contacts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}