{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "ec8ae23d-d6a0-4802-bded-8548d11b472a",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -176,
        -64
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "67aef980-1870-4744-ad6c-29e7800aba9e",
      "name": "Get row(s) in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        48,
        -64
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ '' }}",
              "lookupColumn": "Sent"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/13PdKwhFKcr-w_IDZwJkuJeidohcxZdQSiRlXYw2EcDs/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "13PdKwhFKcr-w_IDZwJkuJeidohcxZdQSiRlXYw2EcDs",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/13PdKwhFKcr-w_IDZwJkuJeidohcxZdQSiRlXYw2EcDs/edit?usp=drivesdk",
          "cachedResultName": "n8n - Users"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": false
    },
    {
      "id": "41860342-ee59-4c13-a5e8-eb0576c01d30",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        496,
        -128
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "4b9b72a3-917b-4ced-aa47-6cc5aa6ffc84",
              "name": "Phone number",
              "type": "string",
              "value": "={{ $json[\"Phone number\"] }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "be86c907-43d2-470e-ba19-0bcd0ecef31d",
      "name": "Send message template",
      "type": "@woztell-sanuker/n8n-nodes-woztell-sanuker.woztell",
      "position": [
        720,
        -128
      ],
      "parameters": {
        "wabaId": "2164086713815148",
        "buttons": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "channel": {
          "__rl": true,
          "mode": "list",
          "value": "5bbd6577be060184faf82fe6",
          "cachedResultName": "Sanuker WhatsApp(5bbd6577be060184faf82fe6)"
        },
        "headers": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "carousel": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "language": "en",
        "template": {
          "__rl": true,
          "mode": "list",
          "value": "{\"id\":\"895782289870972\",\"name\":\"n8ntmplate_shopify_ordercreated_noproducts\",\"category\":\"UTILITY\",\"languages\":[\"en\"],\"statuses\":[{\"language\":\"en\",\"status\":\"APPROVED\"}],\"templates\":[{\"language\":\"en\",\"status\":\"APPROVED\",\"rejected_reason\":\"NONE\",\"components\":[{\"type\":\"BODY\",\"text\":\"Hi {{1}}, thanks for your order.\\nWe\u2019ve received your payment for Order {{2}} and we\u2019re preparing it now.\\n\\nWe\u2019ll send your tracking link as soon as it ships.\\n\\nIf you need anything, just reply here anytime.\",\"example\":{\"body_text\":[[\"Jamie\",\"#1234\"]]}}],\"quality_score\":{\"score\":\"UNKNOWN\",\"date\":1770373277}}]}",
          "cachedResultName": "n8ntmplate_shopify_ordercreated_noproducts"
        },
        "operation": "sendTemplates",
        "variables": {
          "value": {
            "Variable #1": "={{ $json.Name }}",
            "Variable #2": "={{ $json.row_number }}"
          },
          "schema": [
            {
              "id": "Variable #1",
              "type": "string",
              "display": true,
              "required": true,
              "displayName": "Variable #1",
              "defaultMatch": false
            },
            {
              "id": "Variable #2",
              "type": "string",
              "display": true,
              "required": true,
              "displayName": "Variable #2",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "recipientId": "={{ $json[\"Phone number\"] }}",
        "requestOptions": {}
      },
      "credentials": {
        "woztellCredentialApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ae418aa6-1bcc-455d-b1cf-046b5bc19152",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        272,
        -64
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "81bed00c-bace-454e-a531-1d8f22f41962",
      "name": "Update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Updating delivery status (Success/Failure) for sent templates.",
      "position": [
        944,
        -128
      ],
      "parameters": {
        "columns": {
          "value": {
            "Sent": "={{ ($json.ok === 1 && $json.sendResult.ok === 1 && $json.sendResult.result[0].ok === 1) ? 'succcess' : 'failed' }}",
            "row_number": "={{ $('Edit Fields').item.json.row_number }}"
          },
          "schema": [
            {
              "id": "Phone number",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Phone number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Sent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/13PdKwhFKcr-w_IDZwJkuJeidohcxZdQSiRlXYw2EcDs/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "13PdKwhFKcr-w_IDZwJkuJeidohcxZdQSiRlXYw2EcDs",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/13PdKwhFKcr-w_IDZwJkuJeidohcxZdQSiRlXYw2EcDs/edit?usp=drivesdk",
          "cachedResultName": "n8n - Users"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.7
    },
    {
      "id": "ea729099-596d-439b-af83-e12940706f1b",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        1168,
        -64
      ],
      "parameters": {
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "72be80c6-4826-4e8f-9b33-abd2baaade0a",
      "name": "On form submission",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -176,
        240
      ],
      "parameters": {
        "options": {},
        "formTitle": "Upload files",
        "formFields": {
          "values": [
            {
              "fieldType": "file",
              "fieldLabel": "File",
              "requiredField": true,
              "acceptFileTypes": ".csv"
            }
          ]
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "85e4294b-b95b-4613-a688-cb5f5f37fd61",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        48,
        240
      ],
      "parameters": {
        "options": {},
        "binaryPropertyName": "File"
      },
      "typeVersion": 1.1
    },
    {
      "id": "b2f71a69-c43d-4afb-a558-9044f95f0fde",
      "name": "Edit Fields1",
      "type": "n8n-nodes-base.set",
      "position": [
        496,
        176
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "4b9b72a3-917b-4ced-aa47-6cc5aa6ffc84",
              "name": "Phone number",
              "type": "string",
              "value": "={{ $json[\"Phone number\"] }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "fba9f360-abe6-437b-9d4d-87b11553fba9",
      "name": "Send message template1",
      "type": "@woztell-sanuker/n8n-nodes-woztell-sanuker.woztell",
      "position": [
        720,
        176
      ],
      "parameters": {
        "wabaId": "2164086713815148",
        "buttons": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "channel": {
          "__rl": true,
          "mode": "list",
          "value": "5bbd6577be060184faf82fe6",
          "cachedResultName": "Sanuker WhatsApp(5bbd6577be060184faf82fe6)"
        },
        "headers": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "carousel": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "language": "en",
        "template": {
          "__rl": true,
          "mode": "list",
          "value": "{\"id\":\"895782289870972\",\"name\":\"n8ntmplate_shopify_ordercreated_noproducts\",\"category\":\"UTILITY\",\"languages\":[\"en\"],\"statuses\":[{\"language\":\"en\",\"status\":\"APPROVED\"}],\"templates\":[{\"language\":\"en\",\"status\":\"APPROVED\",\"rejected_reason\":\"NONE\",\"components\":[{\"type\":\"BODY\",\"text\":\"Hi {{1}}, thanks for your order.\\nWe\u2019ve received your payment for Order {{2}} and we\u2019re preparing it now.\\n\\nWe\u2019ll send your tracking link as soon as it ships.\\n\\nIf you need anything, just reply here anytime.\",\"example\":{\"body_text\":[[\"Jamie\",\"#1234\"]]}}],\"quality_score\":{\"score\":\"UNKNOWN\",\"date\":1770373277}}]}",
          "cachedResultName": "n8ntmplate_shopify_ordercreated_noproducts"
        },
        "operation": "sendTemplates",
        "variables": {
          "value": {
            "Variable #1": "={{ $json.Name }}",
            "Variable #2": "=test"
          },
          "schema": [
            {
              "id": "Variable #1",
              "type": "string",
              "display": true,
              "required": true,
              "displayName": "Variable #1",
              "defaultMatch": false
            },
            {
              "id": "Variable #2",
              "type": "string",
              "display": true,
              "required": true,
              "displayName": "Variable #2",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "recipientId": "={{ $json[\"Phone number\"] }}",
        "requestOptions": {}
      },
      "credentials": {
        "woztellCredentialApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f10295e5-ff39-406b-91a4-f57cf80f440f",
      "name": "Loop Over Items1",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        272,
        240
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "ca3dfe4c-ffba-4eca-bb82-adfa290c6241",
      "name": "Wait1",
      "type": "n8n-nodes-base.wait",
      "position": [
        944,
        240
      ],
      "parameters": {
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "4a87721c-5b9c-4509-8f9d-0b9d047c9b2f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -256,
        -144
      ],
      "parameters": {
        "color": 4,
        "height": 544,
        "content": "### Google Sheets / n8n forms integration.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "5e1c4139-6a6a-491d-8e51-5db96cce5e0d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -912,
        -784
      ],
      "parameters": {
        "color": 5,
        "width": 560,
        "height": 1552,
        "content": "## \u2728 What this template does\nThis workflow sends WhatsApp template messages in bulk to a contact list stored in Google Sheets or uploaded via CSV.\n\nIt automatically loops through each contact, sends the selected WhatsApp template via WOZTELL, and updates the sheet with the delivery status.\n\nUse this for campaigns, announcements, onboarding sequences, or follow up outreach.\n\n## \ud83d\udc77 Who it\u2019s for\nBuilt for teams that need to send WhatsApp template messages to a contact list for campaigns, outreach, or announcements. Suitable for event organisers, marketing, sales, or agencies managing bulk messaging.\n\n## \u2699\ufe0f How it works\n1. Retrieves unsent contacts from Google Sheets or CSV upload.\n2. Loops through each contact.\n3. Sends a WhatsApp template message.\n4. Updates the sheet with success or failure status.\n5. Waits briefly before processing the next contact to prevent rate issues.\n\n## \ud83e\udded How to use\n1. Import this template into n8n.\n2. Connect your Google Sheets credentials.\n3. Connect your WOZTELL credentials.\n4. Select your approved WhatsApp template.\n5. Map sheet columns to template variables.\n6. Execute the workflow.\n\n## \ud83e\udde9 Requirements\n- Google Sheets access or CSV file\n- n8n account\n- WOZTELL account with WhatsApp channel configured\n- Approved WhatsApp template\n\n## \ud83e\udde0 Customization ideas\n- Replace the CSV source with other supported inputs such as n8n Form upload, Google Sheets, OneDrive, or Zoho Sheet\n- Adjust the field mapping logic or add code nodes to match your data schema\n- Send messages through different WOZTELL channels or multiple sender numbers based on routing rules\n- Add opt in validation before sending\n- Schedule automatic campaign execution instead of manual trigger\n- Add campaign tags or tracking columns\n\n## \ud83e\udd16About WOZTELL\nThis template uses WOZTELL to connect n8n with the official WhatsApp Business Platform, allowing you to send and receive WhatsApp messages through approved templates and automation workflows.\n\nYou can create a WOZTELL account and register a WhatsApp Business API account for free.\n\n1. Sign up [here](\nhttps://platform.woztell.com/signup?lang=en&utm_campaign=plugin-n8n&utm_medium=plugin-n8n&utm_source=N8N)\n2. Verify your email and complete your account setup.\n3. Follow the WhatsApp Business API [setup guide](\nhttps://doc.woztell.com/docs/procedures/basic-whatsapp-chatbot-setup/standard-procedures-wa-connect-waba/)\n##\nOnce your WhatsApp Business account is connected and message templates are approved, you can activate this workflow.\n\n## \ud83d\ude80 More templates\nWe\u2019re continuously building more WOZTELL n8n templates. Check our n8n profile to explore the latest workflows."
      },
      "typeVersion": 1
    },
    {
      "id": "1978c66d-e2df-4a86-b460-7939c1e7befc",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -368
      ],
      "parameters": {
        "width": 208,
        "height": 192,
        "content": "### 1) Starts the bulk sending process manually\n\nClick \u201cExecute workflow\u201d to begin sending messages from the contact list."
      },
      "typeVersion": 1
    },
    {
      "id": "3a04025d-12aa-4d23-a0a1-eaf760a96747",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -608
      ],
      "parameters": {
        "width": 208,
        "height": 432,
        "content": "### 2) Retrieves unsent contacts from Google Sheets\n\nReads rows where the \u201cSent\u201d column is empty.\n\nSet up Google Sheets credentials following the [official n8n documentation](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets/).\n\nMake a copy of [this sample sheet template](https://docs.google.com/spreadsheets/d/1nw8PywwbaQSsNvsifFumWf1yMFodGrIa_EttKYM2BMM/edit?usp=sharing), or make sure your sheet includes:\n\u2022 Phone number column\n\u2022 Name column\n\u2022 Sent column\n\nOnly rows where \u201cSent\u201d is empty will be processed."
      },
      "typeVersion": 1
    },
    {
      "id": "ed63ec8c-0cfa-45d1-a903-3c23f24d8278",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        224,
        -368
      ],
      "parameters": {
        "width": 208,
        "height": 192,
        "content": "### 3) Loops through contacts one by one"
      },
      "typeVersion": 1
    },
    {
      "id": "451dee2c-35dd-4cf0-9725-5ab5240420d8",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        -368
      ],
      "parameters": {
        "width": 208,
        "height": 192,
        "content": "### 4) Extracts the phone number for WhatsApp sending\n\nPlease ensure the phone number format includes country code without symbols."
      },
      "typeVersion": 1
    },
    {
      "id": "ed195a24-9817-42a6-b7d5-448e3f5eeffd",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        672,
        -800
      ],
      "parameters": {
        "width": 208,
        "height": 624,
        "content": "### 5) Sends WhatsApp template message\n\nSends the selected approved WhatsApp template to the contact.\n\nSet up your WOZTELL credentials. To generate the access token, follow the step-by-step guide [here]( https://support.woztell.com/portal/en/kb/articles/access-token#Access_Token_Generation).\n\nRequired permissions:\n- channel:getBasicInfo\n- bot:sendResponses\n- channel:getEnvironmentInfo\n- channel:getDetails\n###\n\nFor the WOZTELL Channel API field, follow [this guide](https://support.woztell.com/portal/en/kb/articles/access-token-channels-in-woztell#How_to_Create_an_Access_Token_for_a_Channel_in_WOZTELL) to create a new token. If you have already generated a token, you may reuse it.\n\nMap Google Sheets columns into template variables before running. "
      },
      "typeVersion": 1
    },
    {
      "id": "b8714ba3-5abd-4560-ba38-bf7ae2b7b3af",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        -464
      ],
      "parameters": {
        "width": 208,
        "height": 288,
        "content": "### 6) Updates delivery status in Google Sheets\n\nMarks the row as:\n\u2022 success\n\u2022 failed\n\nThis helps track campaign performance and prevents duplicate sending.\n\nRequires Google Sheets credentials."
      },
      "typeVersion": 1
    },
    {
      "id": "0d6db43d-cbe3-4dc3-8955-c5ef97fd1c18",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        -464
      ],
      "parameters": {
        "width": 208,
        "height": 288,
        "content": "### 7) Adds delay between messages\n\nPauses briefly before processing the next contact.\n\nThis helps avoid rate limits and improves delivery reliability.\n\nYou can adjust the wait duration if needed."
      },
      "typeVersion": 1
    },
    {
      "id": "d6543168-e728-4ed6-bea0-427d498637f6",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        448
      ],
      "parameters": {
        "width": 208,
        "height": 240,
        "content": "### 1) Alternative entry: Upload CSV file\n\nAllows uploading a CSV file containing contact details.\n\nMake a copy of [this sample csv template](https://drive.google.com/file/d/19uI0twb8OQyeO2YoQ3x5MUntkb3v4Sve/view?usp=drive_link), or make sure your file includes:\n\u2022 Phone number column\n\u2022 Name column"
      },
      "typeVersion": 1
    },
    {
      "id": "30de3251-3550-40e0-b018-59c651ef862c",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        448
      ],
      "parameters": {
        "width": 208,
        "height": 240,
        "content": "### 2) Extracts contact data from uploaded CSV\n\nConverts CSV rows into structured items for processing."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait1": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Send message template",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields1": {
      "main": [
        [
          {
            "node": "Send message template1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items1": {
      "main": [
        [],
        [
          {
            "node": "Edit Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On form submission": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update row in sheet": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send message template": {
      "main": [
        [
          {
            "node": "Update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send message template1": {
      "main": [
        [
          {
            "node": "Wait1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}