{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automatically Send WhatsApp Discount Codes to Shopify Customers",
  "nodes": [
    {
      "id": "f168dde7-9e0e-407c-b303-6ea10aac4353",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        1232,
        624
      ],
      "parameters": {
        "path": "a9b6a936-e5f2-4d4c-9cf9-182de0a970d5",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "8195a385-5359-49ac-98ec-fa1b420f2f1d",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        3024,
        640
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3ab8725a-9268-45fd-b91c-0e055fe6fa7c",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.exists }}",
              "rightValue": "=\"true\""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "0c976026-d9ac-4ee2-a5ee-e37bb007c50e",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        3504,
        704
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "31e045f5-511e-49f7-8695-0043fe6fb5bb",
      "name": "Clean WhatsApp Number",
      "type": "n8n-nodes-base.code",
      "position": [
        2512,
        640
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nconst updatedItems = items.map((item) => {\n  const waNo = item?.json?.[\"number\"];\n  const waNoStr = typeof waNo === 'string'\n    ? waNo\n    : (waNo !== undefined && waNo !== null ? String(waNo) : \"\");\n\n  const cleanedNumber = waNoStr.replace(/\\D/g, \"\"); // Remove non-digit characters\n\n  item.json[\"number\"] = cleanedNumber;\n\n  return item;\n});\n\nreturn updatedItems;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "aaa23891-6e2d-4cca-bdcd-276b3b53ed17",
      "name": "Clean Webhooks Response Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1456,
        624
      ],
      "parameters": {
        "jsCode": "const result = $input.all().map(item => {\n  const body = item.json.body || {};\n  \n  return {\n    discount_id: body.admin_graphql_api_id,\n    title: body.title,\n    status: body.status,\n    created_at: body.created_at,\n    updated_at: body.updated_at,\n    shop_domain: item.json.headers['x-shopify-shop-domain'],\n  };\n});\n\nreturn result;"
      },
      "typeVersion": 2
    },
    {
      "id": "b1fdf13b-9648-4fb0-8785-255261aa84bd",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2256,
        624
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "484ecd1a-c9da-4e4e-aad6-663ada850870",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -128,
        336
      ],
      "parameters": {
        "width": 1168,
        "height": 1248,
        "content": "# Automatically Send WhatsApp Discount Codes to Shopify Customers Using Rapiwa\n\n## Overview\nThis n8n workflow **triggers when a new discount code is created in Shopify**. It **fetches customers**, **filters high-spending** customers  **who spent in store**, **validates their WhatsApp numbers via Rapiwa**, sends a promotional WhatsApp message with the discount code to verified numbers, and logs all attempts to a Google Sheet.\n\n## How it works (step-by-step)\n3. Fetch all customers\n\t- `Get All Customer Data In Store` (HTTP Request)\n\t- Pulls the complete customer list from Shopify\n\n4. Filter high-spending customers\n\t- Filters customers where `total_spent > `who spent in store`` and maps necessary fields (name, phone, email, totalSpent)\n\n5. Loop over customers\n\t- Processes customers one-by-one (or in small batches)\n\n6. Clean WhatsApp number\n\t- Removes non-digit characters from phone numbers\n\n7. Verify WhatsApp number\n\t- Endpoint: `https://app.rapiwa.com/api/verify-whatsapp` (POST)\n\t- Sends the cleaned number and expects `data.exists === true` for valid numbers\n\n8. Conditional path: verified vs unverified\n\t- If verified: send message and append to Google Sheet with `verify: verified`, `status: sent`\n\t- If not verified: append to Google Sheet with `verify: unverified`, `status: not sent`\n\n9. Send WhatsApp message (verified only)\n\t- Node: `Send Message Using Rapiwa` (HTTP Request)\n\n10. Append results to Google Sheets\n\t - Verified: append/update row with `verify: verified`, `status: sent`\n\t - Unverified: append/update row with `verify: unverified`, `status: not sent`\n\n11. Wait (throttle)\n\t - Add a small delay (e.g., 2 seconds) between iterations to avoid API limits and sheet quota issues\n\n## Google Sheet format (example rows)\n- **A Google Sheet** formatted like this \u27a4 [Sample](https://docs.google.com/spreadsheets/d/1Zx_WXQW29NsITFPJ-SnjHgOlouvzG_sBNGzSA_B8cSA/edit?usp=sharing)\n\n## Support & Help\n- **Rapiwa Website:** [https://rapiwa.com](https://rapiwa.com/)\n- **WhatsApp**: [Chat on WhatsApp](https://wa.me/8801322827799)\n- **Discord**: [SpaGreen Community](https://discord.gg/SsCChWEP)\n- **Facebook Group**: [SpaGreen Support](https://www.facebook.com/groups/spagreenbd)\n- **Website**: [https://spagreen.net](https://spagreen.net)\n- **Developer Portfolio**: [Codecanyon SpaGreen](https://codecanyon.net/user/spagreen/portfolio)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d7993dbb-5885-4a16-81d8-2c9b9d868886",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1088,
        352
      ],
      "parameters": {
        "width": 624,
        "height": 560,
        "content": "## 1. Webhook \nReceives Shopify Webhook (discount creation) via HTTP POST request.  \nThis is triggered when a discount is created in your Shopify store.\n\n## 2. Clean Webhooks Response Data\nExtracts useful fields (`title`, `status`, `created_at`, `shop_domain`, etc.) from the incoming Shopify webhook and formats them for further use.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "dc59f834-6f18-42a8-870b-22cf09a92eda",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1728,
        352
      ],
      "parameters": {
        "width": 448,
        "height": 560,
        "content": "## 1. Get All Customer Data In Store\nFetches all customer data from the Shopify store using your API credentials.\n\n\n## 2. Clean HTTP Request Data (Filter & Format Customers) \nFilters customers whose total spent is greater than 5000, and extracts customer details.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3366ce0c-0d80-4c99-b750-ddbe9a3565c7",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2448,
        352
      ],
      "parameters": {
        "width": 384,
        "height": 560,
        "content": "## 1. Clean WhatsApp Number\nCleans the WhatsApp number by:\n- Converting it to a string (if needed)  \n- Removing non-digit characters  \n\n## 2. Check Valid WhatsApp Number Using Rapiwa\n**API Endpoint:**   \nUses the Rapiwa API to verify whether the cleaned number is associated with a valid WhatsApp account.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e0f334ec-45b0-4ba4-bd92-fc72f687bf6a",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2928,
        176
      ],
      "parameters": {
        "width": 816,
        "height": 736,
        "content": "## 1. Node: If (Condition Check)  \nChecks the Rapiwa API response to see if the phone number is verified as a WhatsApp number.\n\n## 2. Node: Send Message Using Rapiwa  \nSends a personalized discount message via WhatsApp to customers with verified WhatsApp numbers.\n\n## 3. Node: Append Rows in Sheet Verified & Sent  \nLogs details of customers with verified WhatsApp numbers and sent messages into a Google Sheet.\n\n## 4. Node: Append Rows in Sheet Unverified & Not sent  \nLogs customers with unverified WhatsApp numbers and marks them as \u201cnot sent\u201d in the Google Sheet.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "56c123fc-edad-4d59-bb62-e3d009d0dbcf",
      "name": "Get All Customer Data In Shopify Store",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1776,
        624
      ],
      "parameters": {
        "url": "https://your_domain_/admin/api/2025-07/customers.json",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-Shopify-Access-Token",
              "value": "your_shopify_accesstoken like this\u27a1\ufe0fshpat_57xx78xxxxx90fxxx67"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "22ae91ae-2286-46ce-b1e6-8f6cac7d3fc4",
      "name": "Clean Customer Data In Shopify Store",
      "type": "n8n-nodes-base.code",
      "position": [
        1984,
        624
      ],
      "parameters": {
        "jsCode": "const customers = items[0].json.customers;\n\nif (!Array.isArray(customers)) {\n  throw new Error(\"Customers not found or not an array\");\n}\n\nreturn customers\n  .filter((customer) => {\n    const totalSpent = parseFloat(customer.total_spent || '0.00');\n    return totalSpent > 5000;\n  })\n  .map((customer) => {\n    const address = customer.default_address || {};\n    const fullName = `${customer.first_name || ''} ${customer.last_name || ''}`.trim();\n\n    return {\n      json: {\n        customerId: customer.id || null,\n        customerName: fullName,\n        email: customer.email || 'N/A',\n        number: customer.phone || address.phone || 'N/A',\n        totalSpent: customer.total_spent || '0.00',\n        ordersCount: customer.orders_count || 0,\n        address: address.address1 || 'N/A',\n        city: address.city || 'N/A',\n        country: address.country || 'N/A',\n        state: customer.state || 'N/A',\n      }\n    };\n  });\n"
      },
      "typeVersion": 2
    },
    {
      "id": "4f0c8dca-3b77-4aeb-b61d-5d72951d8425",
      "name": "Save data Sheet Unverified & Not sent",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3264,
        704
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ $('Clean WhatsApp Number').item.json.customerName }}",
            "title": "={{ $('Webhook').item.json.body.title }}",
            "number": "={{ $json.data.number }}",
            "status": "not sent",
            "verify": "=unverified",
            "created_at": "={{ $('Clean Webhooks Response Data').item.json.created_at }}",
            "discount_id": "={{ $('Webhook').item.json.body.admin_graphql_api_id }}",
            "shop_domain": "={{ $('Webhook').item.json.headers[\"x-shopify-shop-domain\"] }}"
          },
          "schema": [
            {
              "id": "discount_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "discount_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "shop_domain",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "shop_domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "number",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "verify",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "verify",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zx_WXQW29NsITFPJ-SnjHgOlouvzG_sBNGzSA_B8cSA/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Zx_WXQW29NsITFPJ-SnjHgOlouvzG_sBNGzSA_B8cSA",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zx_WXQW29NsITFPJ-SnjHgOlouvzG_sBNGzSA_B8cSA/edit?usp=drivesdk",
          "cachedResultName": "Shopify - Send WhatsApp promo code to customers"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "91abd2bc-3bb1-4ebc-a1dd-d30218ffd60d",
      "name": "Save data in Sheet Verified & Sent",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3472,
        512
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ $('Clean WhatsApp Number').item.json.customerName }}",
            "title": "={{ $('Webhook').item.json.body.title }}",
            "number": "={{ $('Clean WhatsApp Number').item.json.number }}",
            "status": "sent",
            "verify": "verified",
            "created_at": "={{ $('Clean Webhooks Response Data').item.json.created_at }}",
            "discount_id": "={{ $('Webhook').item.json.body.admin_graphql_api_id }}",
            "shop_domain": "={{ $('Webhook').item.json.headers[\"x-shopify-shop-domain\"] }}"
          },
          "schema": [
            {
              "id": "discount_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "discount_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "shop_domain",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "shop_domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "number",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "verify",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "verify",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zx_WXQW29NsITFPJ-SnjHgOlouvzG_sBNGzSA_B8cSA/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Zx_WXQW29NsITFPJ-SnjHgOlouvzG_sBNGzSA_B8cSA",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zx_WXQW29NsITFPJ-SnjHgOlouvzG_sBNGzSA_B8cSA/edit?usp=drivesdk",
          "cachedResultName": "Shopify - Send WhatsApp promo code to customers"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "fc3e6a69-1504-4f5e-a514-281423af0edd",
      "name": "Rapiwa",
      "type": "n8n-nodes-rapiwa.rapiwa",
      "position": [
        2688,
        640
      ],
      "parameters": {
        "number": "={{ $json.number }}",
        "operation": "verifyWhatsAppNumber"
      },
      "credentials": {
        "rapiwaApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5ecf41dc-a221-4b4c-b73f-bfd57f458392",
      "name": "Rapiwa1",
      "type": "n8n-nodes-rapiwa.rapiwa",
      "position": [
        3248,
        512
      ],
      "parameters": {
        "number": "={{ $json.data.number }}",
        "messageType": "=Hey *{{ $('Clean WhatsApp Number').item.json.customerName }}*,\n\nYou're one of our favorite customers!\nWe've just created a new discount rule at our store, and we\u2019ve got something special just for you! \ud83c\udf89\nDiscount Code: *{{ $('Clean Webhooks Response Data').item.json.title }}*\n\nUse this code on your next order to enjoy an exclusive discount.\n\n\u2013 Team *SpaGreen Creative*"
      },
      "credentials": {
        "rapiwaApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Rapiwa1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save data Sheet Unverified & Not sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rapiwa": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rapiwa1": {
      "main": [
        [
          {
            "node": "Save data in Sheet Verified & Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Clean Webhooks Response Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Clean WhatsApp Number",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean WhatsApp Number": {
      "main": [
        [
          {
            "node": "Rapiwa",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean Webhooks Response Data": {
      "main": [
        [
          {
            "node": "Get All Customer Data In Shopify Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save data in Sheet Verified & Sent": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean Customer Data In Shopify Store": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save data Sheet Unverified & Not sent": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All Customer Data In Shopify Store": {
      "main": [
        [
          {
            "node": "Clean Customer Data In Shopify Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}