This workflow corresponds to n8n.io template #9560 — we link there as the canonical source.
This workflow follows the Google Sheets → HTTP Request 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 →
{
"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
}
]
]
}
}
}
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.
googleSheetsOAuth2ApirapiwaApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n workflow automatically sends WhatsApp promotional messages to top customers whenever a new discount code is created in Shopify. It’s perfect for store owners, marketers, sales teams, or support agents who want to engage their best customers effortlessly. The workflow…
Source: https://n8n.io/workflows/9560/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow is a complete, production-ready solution for recovering abandoned carts in Shopify stores using a multi-channel, multi-touch approach. It automates personalized follow-ups via Email, SMS
01_order_processing_tilda. Uses stickyNote, googleSheets, httpRequest, telegram. Webhook trigger; 25 nodes.
Turn every sales meeting into a coaching opportunity. This workflow automatically analyzes tldv meeting recordings using OpenAI (GPT-4) to provide instant, actionable feedback to your sales team.
Automated video processing system that monitors S3 for new uploads, generates thumbnails and preview clips, extracts metadata, transcodes to multiple formats, and distributes to CDN with webhook notif
This n8n workflow enables automated cross-selling by identifying each WooCommerce customer's most frequently purchased product, finding a related product to recommend, and sending a personalized Whats