AutomationFlowsSlack & Telegram › Send Woocommerce Cross-sell Offers to Customers via Whatsapp Using Rapiwa API

Send Woocommerce Cross-sell Offers to Customers via Whatsapp Using Rapiwa API

ByRapiwa @rapiwa on n8n.io

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 WhatsApp message using the Rapiwa API. It also verifies whether the user's number is…

Cron / scheduled trigger★★★★☆ complexity23 nodesWooCommerceHTTP RequestGoogle SheetsN8N Nodes Rapiwa
Slack & Telegram Trigger: Cron / scheduled Nodes: 23 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #10141 — 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 →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "3aa7faa0-03bf-4c72-a367-814e04c7364b",
      "name": "Get many customers",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        224,
        624
      ],
      "parameters": {
        "filters": {},
        "resource": "customer",
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c6727ef0-e304-4dfb-a5e4-8ce05b0c0292",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -64,
        624
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b7688e2b-954b-4aa0-839c-16a6ae6242bc",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        720,
        624
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "574cdebf-bedc-40c3-9bf1-fe63777703fa",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        3280,
        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": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.exists }}",
              "rightValue": "=\"true\""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8c573bbd-192d-4db0-a59a-27bcd642d45f",
      "name": "Code (get paying_customer)",
      "type": "n8n-nodes-base.code",
      "position": [
        464,
        624
      ],
      "parameters": {
        "jsCode": "const buyingCustomers = [];\n\nfor (const item of $input.all()) {\n  const spent = parseFloat(item.json.total_spent || '0');\n  \n  if (item.json.is_paying_customer === true || spent > 0) {\n    buyingCustomers.push(item);\n  }\n}\n\nreturn buyingCustomers;"
      },
      "typeVersion": 2
    },
    {
      "id": "06fb86fe-e45e-4037-aa2c-988b6c181e0d",
      "name": "Code (clean data)",
      "type": "n8n-nodes-base.code",
      "position": [
        2048,
        640
      ],
      "parameters": {
        "jsCode": "const products = $input.all();\n\nconst output = [];\n\nfor (const item of products) {\n  const categories = item.json.categories || [];\n\n  output.push({\n    json: {\n      product_id: item.json.id,\n      product_name: item.json.name,\n      categories\n    }\n  });\n}\n\nreturn output;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "b37e5fb1-8359-419a-a8d9-0030ec6ba007",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        3776,
        736
      ],
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "66f15998-30e3-4469-9850-17479d133d14",
      "name": "get customer data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1024,
        640
      ],
      "parameters": {
        "url": "=https://your_shop_domain/wp-json/wc/v3/orders?customer={{ $json.id }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "wooCommerceApi"
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "12bbeaa6-64c2-45dc-a964-cb10763c0952",
      "name": "get specific product data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1760,
        640
      ],
      "parameters": {
        "url": "=https://your_shop_domain/wp-json/wc/v3/products/{{ $json.product_id }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "wooCommerceApi"
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "346fb83b-2e7c-4d4c-a20c-e03225f367e7",
      "name": "get specific product recommend latest product",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2416,
        640
      ],
      "parameters": {
        "url": "=https://your_shop_domain/wp-json/wc/v3/products?category={{ $json.categories[0].id }}&orderby=date&order=desc&per_page=1",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "wooCommerceApi"
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "335b6260-c039-4e9e-b8f2-5a25d954972a",
      "name": "get most buy product id & Clear Number",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        640
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\n// First, clean the \"phone\" field in billing of all orders\nconst cleanedItems = items.map(item => {\n  const billing = item?.json?.billing;\n  if (billing && billing.phone) {\n    const rawPhone = String(billing.phone);\n    const cleanedPhone = rawPhone.replace(/\\D/g, \"\"); // remove non-digits\n    item.json.billing.phone = cleanedPhone;\n  }\n  return item;\n});\n\nlet topProduct = null;\n\n// Then, find the top product by quantity from cleaned items\nfor (const order of cleanedItems) {\n  const lineItems = order.json.line_items || [];\n  const billing = order.json.billing || {};\n\n  for (const item of lineItems) {\n    if (item.product_id) {\n      const currentProduct = {\n        json: {\n          product_id: item.product_id,\n          product_name: item.name || \"\",\n          quantity: item.quantity || 0,\n          customer_name: `${billing.first_name || ''} ${billing.last_name || ''}`.trim(),\n          email: billing.email || '',\n          address: billing.address_1 || '',\n          phone: billing.phone || ''\n        }\n      };\n\n      if (!topProduct || currentProduct.json.quantity > topProduct.json.quantity) {\n        topProduct = currentProduct;\n      }\n    }\n  }\n}\n\nreturn topProduct ? [topProduct] : [];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "dccbbc8e-1618-4e4b-b3aa-8395883ad5e2",
      "name": "Save State of Rows in Verified & Sent",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3776,
        512
      ],
      "parameters": {
        "columns": {
          "value": {
            "suk": "={{ $('get specific product recommend latest product').item.json.sku }}",
            "name": "={{ $('get most buy product id & Clear Number').item.json.customer_name }}",
            "email": "={{ $('get most buy product id & Clear Number').item.json.email }}",
            "price": "={{ $('get specific product recommend latest product').item.json.price }}",
            "staus": "sent",
            "title": "={{ $('get specific product recommend latest product').item.json.name }}",
            "number": "={{ $('get most buy product id & Clear Number').item.json.phone }}",
            "address1": "={{ $('get most buy product id & Clear Number').item.json.address }}",
            "validity": "verified",
            "product link": "={{ $('get specific product recommend latest product').item.json.permalink }}"
          },
          "schema": [
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "number",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "address1",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "address1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "price",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "price",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "suk",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "suk",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "product link",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "product link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "validity",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "validity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "staus",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "staus",
              "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/1yTxkAM1kq2udndvG5M2jUuQCY8SkvoLgrspQ100LvKs/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1yTxkAM1kq2udndvG5M2jUuQCY8SkvoLgrspQ100LvKs",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1yTxkAM1kq2udndvG5M2jUuQCY8SkvoLgrspQ100LvKs/edit?usp=drivesdk",
          "cachedResultName": "Send WooCommerce Cross-Sell Offers to Customers via WhatsApp Using Rapiwa API"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "b8b8e6e2-d28a-4e7c-a55c-8df6ca64c4d5",
      "name": "Save State of Rows in Unerified & Not sent",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3568,
        736
      ],
      "parameters": {
        "columns": {
          "value": {
            "suk": "={{ $('get specific product recommend latest product').item.json.sku }}",
            "name": "={{ $('get most buy product id & Clear Number').item.json.customer_name }}",
            "email": "={{ $('get most buy product id & Clear Number').item.json.email }}",
            "price": "={{ $('get specific product recommend latest product').item.json.price }}",
            "staus": "not sent",
            "title": "={{ $('get specific product recommend latest product').item.json.name }}",
            "number": "={{ $('get most buy product id & Clear Number').item.json.phone }}",
            "address1": "={{ $('get most buy product id & Clear Number').item.json.address }}",
            "validity": "unverified",
            "product link": "={{ $('get specific product recommend latest product').item.json.permalink }}"
          },
          "schema": [
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "number",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "address1",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "address1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "price",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "price",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "suk",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "suk",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "product link",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "product link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "validity",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "validity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "staus",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "staus",
              "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/1yTxkAM1kq2udndvG5M2jUuQCY8SkvoLgrspQ100LvKs/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1yTxkAM1kq2udndvG5M2jUuQCY8SkvoLgrspQ100LvKs",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1yTxkAM1kq2udndvG5M2jUuQCY8SkvoLgrspQ100LvKs/edit?usp=drivesdk",
          "cachedResultName": "Send WooCommerce Cross-Sell Offers to Customers via WhatsApp Using Rapiwa API"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "773f0d84-2270-4714-854e-1bfc236c2a5c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        432
      ],
      "parameters": {
        "width": 1168,
        "height": 1696,
        "content": "# Send WooCommerce Cross-Sell Offers to Customers via WhatsApp Using Rapiwa API\n\n## Overview\nThis 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 WhatsApp message** using the **Rapiwa API**. It also verifies whether the user's number is WhatsApp-enabled before sending, and logs both successful and unsuccessful attempts to Google Sheets for tracking.\n\n\n## Features\n- Loops through all customers with at least one completed order.\n- Detects the most frequently purchased product for each customer.\n- Fetches a related (upsell/cross-sell) product for recommendation.\n- Verifies if the customer's phone number is registered on WhatsApp using Rapiwa.\n- Sends a templated cross-sell promo message through WhatsApp.\n- Logs verified/sent vs. unverified/not sent messages in Google Sheets.\n- Controls rate with SplitInBatches and Wait to prevent spamming or rate-limiting.\n\n## Requirements\n- n8n instance (self-hosted or cloud)\n- WooCommerce API credentials with read access\n- Rapiwa account with a valid token (for message & verification APIs)\n- Google Sheets access & OAuth2 credentials\n- WooCommerce store with real purchase data and related product configurations\n\n\n## Google Sheet Required Columns\nYou\u2019ll need two Google Sheets (or two tabs in one spreadsheet):\n**A Google Sheet formatted like this** \u27a4 [sample](https://docs.google.com/spreadsheets/d/1yTxkAM1kq2udndvG5M2jUuQCY8SkvoLgrspQ100LvKs/edit?usp=sharing)\n\n## How to Use This Workflow\n### Step 1: Setup Credentials\n- Add your WooCommerce, Rapiwa, and Google Sheets credentials in n8n Credentials.\n- Make sure Rapiwa token is set up as HTTP Bearer Auth.\n\n### Step 2: Prepare Your Google Sheets\n- Create a sheet with the columns listed above.\n- Copy its URL and paste the Sheet ID into the appropriate nodes in the workflow.\n\n### Step 3: Import Workflow\n- Use the Import feature in n8n and load your provided JSON file.\n\n### Step 4: Configure the Flow\n- Check Code nodes (Find Most Purchased Product, Format WhatsApp Number) to ensure data structure matches your WooCommerce setup.\n- Customize the WhatsApp message template in the Send Message via Rapiwa node.\n\n### Step 5: Test It\n- Start with test users or your own number to validate WhatsApp message formatting and delivery.\n\n\n## Notes & Warnings\n- Make sure the Rapiwa API responses are parsed properly (`data.exists === true`).\n- If your WooCommerce product data uses variations or custom meta, adjust the product lookup nodes.\n- Phone number cleaning must ensure the format matches E.164 format (e.g., 8801XXXXXXXXX).\n- Monitor Rapiwa rate limits\u2014too many failed verifications may lead to temporary bans.\n- Always test with a small user batch before going full production.\n\n\n## Useful Links\n- **Dashboard:** [https://app.rapiwa.com](https://app.rapiwa.com/login)\n- **Official Website:** [https://rapiwa.com](https://rapiwa.com/)\n- **Documentation:** [https://docs.rapiwa.com](https://docs.rapiwa.com/)\n\n## Support & Help\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": "0a51cbe3-e0c7-4c4a-b65b-d5536900194a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        272
      ],
      "parameters": {
        "width": 528,
        "height": 688,
        "content": "## Get Many Customers\n**Purpose:** Retrieves all customer records from WooCommerce  \n**How it works:**  \n- Fetches complete customer dataset including purchase history  \n**Output:** Raw customer data with purchase details  \n\n---\n\n## Code (Get Paying Customer)\n**Purpose:** Filters customers to identify only those with purchase history  \n**How it works:**  \n- Analyzes `total_spent` and `is_paying_customer` fields  \n- Creates a new array containing only paying customers  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "91a455c8-9ad2-4390-a750-40c92683a8b3",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        432
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 368,
        "content": "## Schedule Trigger\n**Purpose:** Initiates the workflow at specified intervals  \n**How it works:**  \n- Configured with time-based triggers (e.g., daily, weekly)   \n"
      },
      "typeVersion": 1
    },
    {
      "id": "6ffff150-fd0e-400e-9f4f-878c23d4fc7b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        192
      ],
      "parameters": {
        "width": 688,
        "height": 768,
        "content": "## Get Customer Data\n**Purpose:** Retrieves detailed order history for each customer  \n**How it works:**  \n- Makes API call to WooCommerce with customer ID  \n- Fetches all orders associated with the customer  \n**API Endpoint:**  \n```\nhttps://your_shop_domain/wp-json/wc/v3/orders?customer={{ $json.id }}\n```\n\n\n\n## Get Most Buy Product ID & Clear Number\n**Purpose:** Identifies customer's most purchased product and cleans phone number  \n**How it works:**  \n- Analyzes order line items to find the product with the highest quantity purchased  \n- Removes all non-digit characters from the phone number  "
      },
      "typeVersion": 1
    },
    {
      "id": "2b4ce264-bcb6-4554-9f7a-3b90af6e407c",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1568,
        208
      ],
      "parameters": {
        "width": 720,
        "height": 752,
        "content": "## Get Specific Product Data\n**Purpose:** Retrieves detailed information about the most purchased product  \n**How it works:**  \n- Makes an API call to WooCommerce using the product ID  \n- Fetches product details including category information  \n**API Endpoint:**  \n```\nhttps://your_shop_domain/wp-json/wc/v3/products/{{ $json.product_id }}\n```\n\n## Code (Clean Data)\n**Purpose:** Extracts and formats product category information\n**How it works:**\n- Processes product categories for recommendation logic\n- Structures data for category-based product search\n**Output:** Product data with category IDs for recommendation search\n"
      },
      "typeVersion": 1
    },
    {
      "id": "5834724b-c8eb-4c1b-9d27-8895be551bf2",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2304,
        272
      ],
      "parameters": {
        "width": 448,
        "height": 688,
        "content": "## Get Specific Product Recommend Latest Product\n**Purpose:** Finds the latest product in the same category as customer's favorite\n**How it works:**\n- Makes API call to WooCommerce with category ID\n\n**API Endpoint:**\n```\nhttps://your_shop_domain/wp-json/wc/v3/products?category={{ $json.categories[0].id }}&orderby=date&order=desc&per_page=1\n```\n"
      },
      "typeVersion": 1
    },
    {
      "id": "60d68dcd-39f4-4df9-9f90-1aa7f2451b87",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2768,
        416
      ],
      "parameters": {
        "width": 384,
        "height": 544,
        "content": "## Check Valid WhatsApp Number Using Rapiwa\n**Purpose:** Verifies if customer's phone number is registered on WhatsApp\n**How it works:**\n- Sends POST request to Rapiwa verification endpoint\n- Uses Bearer Token authentication\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3900ad3e-04c4-4e08-87ba-15588d3308df",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3168,
        -48
      ],
      "parameters": {
        "width": 784,
        "height": 1008,
        "content": "### If (Decision Node)\n**Purpose:** Routes workflow based on WhatsApp verification result  \n\n## Rapiwa Sender\n**Purpose:** Sends personalized WhatsApp message with product recommendation  \n**How it works:**  \n- Constructs message with customer name and product details  \n**API Endpoint:**  \n`https://app.rapiwa.com/api/send-message`\n\n\n## Save State of Rows in Verified & Sent\n**Purpose:** Logs successful message delivery to Google Sheets  \n**How it works:**  \n- Appends row with customer and product details  \n- Marks as \"verified\" and \"sent\"  \n\n\n## Save State of Rows in Unverified & Not Sent\n**Purpose:** Logs unverified numbers to Google Sheets  \n**How it works:**  \n- Appends row with same details as above  \n- Marks as \"unverified\" and \"not sent\" \n\n## Wait\n**Purpose:** Adds delay between customer processing\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cf625c69-6343-48bc-95f0-cccab54c8c8f",
      "name": "Rapiwa (verify whatsapp number)",
      "type": "n8n-nodes-rapiwa.rapiwa",
      "position": [
        2944,
        640
      ],
      "parameters": {
        "number": "={{ $('get most buy product id & Clear Number').item.json.phone }}",
        "operation": "verifyWhatsAppNumber"
      },
      "credentials": {
        "rapiwaApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3af5524a-34a7-421c-9e01-d00baf27d9f7",
      "name": "Rapiwa (Send Message)",
      "type": "n8n-nodes-rapiwa.rapiwa",
      "position": [
        3568,
        512
      ],
      "parameters": {
        "number": "={{ $json.data.number }}",
        "message": "=Hello {{ $('get most buy product id & Clear Number').item.json.customer_name }},\n\nThanks again for your recent purchase! \ud83c\udf81  \nWe thought you might also love *{{ $('get specific product recommend latest product').item.json.name }}* - it\u2019s a favorite among our customers who bought something similar.\n\nOnly *BDT {{ $('get specific product recommend latest product').item.json.price }}* \u2013 limited stock!  \nCheck it out \ud83d\udc49 {{ $('get specific product recommend latest product').item.json.permalink }}\n\nLet us know if you need any help.\n- Team *SpaGreen Creative*"
      },
      "credentials": {
        "rapiwaApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Rapiwa (Send Message)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save State of Rows in Unerified & Not sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "get customer data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get many customers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code (clean data)": {
      "main": [
        [
          {
            "node": "get specific product recommend latest product",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get customer data": {
      "main": [
        [
          {
            "node": "get most buy product id & Clear Number",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many customers": {
      "main": [
        [
          {
            "node": "Code (get paying_customer)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rapiwa (Send Message)": {
      "main": [
        [
          {
            "node": "Save State of Rows in Verified & Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get specific product data": {
      "main": [
        [
          {
            "node": "Code (clean data)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code (get paying_customer)": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Rapiwa (verify whatsapp number)": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save State of Rows in Verified & Sent": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get most buy product id & Clear Number": {
      "main": [
        [
          {
            "node": "get specific product data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save State of Rows in Unerified & Not sent": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get specific product recommend latest product": {
      "main": [
        [
          {
            "node": "Rapiwa (verify whatsapp number)",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

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 WhatsApp message using the Rapiwa API. It also verifies whether the user's number is…

Source: https://n8n.io/workflows/10141/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

This workflow is for Shopify store owners, customer success, and marketing teams who want to automatically check customers’ WhatsApp numbers and send personalized messages with discount codes for canc

HTTP Request, N8N Nodes Rapiwa, Google Sheets
Slack & Telegram

Elevate your shopping experience with an AI-driven personal assistant that lives right in your WhatsApp. This template automates the entire lifecycle of a shopping list—from intelligent intake and liv

HTTP Request, Google Sheets, N8N Nodes Wati
Slack & Telegram

This workflow automates plant care reminders and records using Google Sheets, Telegram, and OpenWeather API.

Google Sheets, HTTP Request, Telegram
Slack & Telegram

Apollo Data Enrichment Using Company Id to automatically finds contacts for companies listed in your Google Sheet, enriches each person with emails and phone numbers via Apollo’s API, and writes verif

Google Sheets, HTTP Request, Error Trigger +1
Slack & Telegram

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

N8N Nodes Scrapegraphai, HTTP Request, Google Sheets +2