This workflow corresponds to n8n.io template #14829 — we link there as the canonical source.
This workflow follows the HTTP Request → OpenAI 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 →
{
"name": "AI-Powered WhatsApp Retargeting: Smart 10-Day Post-Purchase Offers",
"nodes": [
{
"id": "4e0e2d86-1f15-4689-8c9a-33a7d8ceb689",
"name": "Daily Check (10:01 AM)",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-128,
48
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 10,
"triggerAtMinute": 1
}
]
}
},
"typeVersion": 1.3
},
{
"id": "275e2a92-1cf2-4b96-a0f7-9d569cb6b46c",
"name": "Fetch 10-Day Old Invoices",
"type": "n8n-nodes-base.odoo",
"position": [
96,
48
],
"parameters": {
"options": {},
"resource": "custom",
"operation": "getAll",
"returnAll": true,
"filterRequest": {
"filter": [
{
"value": "={{ $today.minus({ days: 9 }).toFormat('yyyy-MM-dd') }}",
"fieldName": "date"
},
{
"value": "2026-04-01",
"operator": "greaterOrEqual",
"fieldName": "date"
}
]
},
"customResource": "account.move"
},
"typeVersion": 1
},
{
"id": "092688c8-1565-4e7a-b27b-7bf9c3678da3",
"name": "Retrieve Customer Contact",
"type": "n8n-nodes-base.odoo",
"position": [
320,
48
],
"parameters": {
"options": {},
"resource": "custom",
"operation": "get",
"customResource": "res.partner",
"customResourceId": "={{ $json.partner_id[0] }}"
},
"typeVersion": 1
},
{
"id": "533de3e1-fc10-423e-a67d-2ce5c3a8b453",
"name": "Send WhatsApp Discount",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
1120,
-32
],
"parameters": {
"url": "YOUR_EVOLUTION_API_URL",
"method": "POST",
"options": {},
"jsonBody": "={\n \"number\": \"{{ (() => { let num = ($('Retrieve Customer Contact').item.json.mobile || $('Retrieve Customer Contact').item.json.phone || '').toString().replace(/\\\\D/g, ''); if (num.startsWith('0')) { num = '20' + num.substring(1); } else if (num.startsWith('1')) { num = '20' + num; } return num; })() }}\",\n \"text\": {{ JSON.stringify($json.output[0].content[0].text || \"\") }}\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "YOUR_EVOLUTION_API_KEY"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "8861ed16-41b9-424c-bd74-c61944c731e2",
"name": "Process Customers (One by One)",
"type": "n8n-nodes-base.splitInBatches",
"position": [
544,
48
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "c4c8ff4e-0cbc-44f5-ad19-c3bc40468c3a",
"name": "Generate AI Message",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
768,
-32
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "GPT-4O-MINI"
},
"options": {},
"responses": {
"values": [
{
"role": "system",
"content": "You are an expert Egyptian marketing copywriter for \"XQ Pharma\", a personal care brand.\nYour task is to write a personalized WhatsApp message to a returning customer, offering them an EXTRA 10% discount valid for 48 hours.\n\nStrict Rules:\n1. Language & Tone: Extremely warm, friendly, and classy Egyptian colloquial Arabic (\u0627\u0644\u0639\u0627\u0645\u064a\u0629 \u0627\u0644\u0645\u0635\u0631\u064a\u0629).\n2. Offer Details (IMPORTANT): You MUST clearly state that this 10% is an ADDITIONAL discount (\u062e\u0635\u0645 \u0625\u0636\u0627\u0641\u064a) on top of the existing offers and discounts already available on the page.\n3. Length: Medium length, around 6 to 7 lines to allow for a richer, more engaging message.\n4. Emojis: Use emojis generously and naturally throughout the text to match the friendly tone.\n5. Call to Action (CRITICAL): The customer MUST be directed to contact the brand via Social Media pages (Facebook/Instagram messages) to claim the discount. Make it clear they should send a message to the \"Page\" (\u0627\u0644\u0635\u0641\u062d\u0629) to order.\n6. The Closing: Add a warm Egyptian closing phrase related to social media (e.g., \"\u0645\u0633\u062a\u0646\u064a\u064a\u0646 \u0631\u0633\u0627\u0644\u062a\u0643 \u0639\u0644\u0649 \u0631\u0633\u0627\u064a\u0644 \u0627\u0644\u0628\u064a\u062f\u062c\", \"\u0646\u0648\u0631\u0648\u0646\u0627 \u0639\u0644\u0649 \u0627\u0644\u0635\u0641\u062d\u0629 \u0639\u0634\u0627\u0646 \u062a\u0633\u062a\u0641\u064a\u062f\u0648\u0627 \u0628\u0627\u0644\u0639\u0631\u0636\", \"\u0641\u0631\u064a\u0642\u0646\u0627 \u0645\u0633\u062a\u0646\u064a\u0643 \u0639\u0644\u0649 \u0631\u0633\u0627\u064a\u0644 \u0627\u0644\u0635\u0641\u062d\u0629\").\n7. Forbidden Phrases: DO NOT use any legal or formal disclaimers like \"(\u062a\u0637\u0628\u0642 \u0627\u0644\u0634\u0631\u0648\u0637 \u0648\u0627\u0644\u0623\u062d\u0643\u0627\u0645)\" or anything similar. Keep it 100% casual and friendly.\n8. Output format: Output ONLY the final Arabic message text. Do not include any conversational filler."
},
{
"content": "=Write the discount message for this customer.\nCRITICAL INSTRUCTIONS FOR THE NAME: \n1. Greet them casually using \"\u0623\u0647\u0644\u0627\u064b \u064a\u0627\" or \"\u064a\u0627 \u0645\u0633\u0627\u0621 \u0627\u0644\u0641\u0644 \u064a\u0627\".\n2. Use ONLY their FIRST name (do not use the full name).\n3. If the name is in English, write it in correct and natural Arabic spelling (e.g., \"Omnea\" becomes \"\u0623\u0645\u0646\u064a\u0629\" not \"\u0623\u0645\u0648\u064a\u0646\u0629\").\n\nCustomer Name: {{ $json.name || '\u0639\u0645\u064a\u0644\u0646\u0627 \u0627\u0644\u0639\u0632\u064a\u0632' }}"
}
]
},
"builtInTools": {}
},
"typeVersion": 2.1
},
{
"id": "2e819604-c8cf-4946-ad58-19e846521e82",
"name": "Wait 1 Mins (Anti-Ban)",
"type": "n8n-nodes-base.wait",
"position": [
1344,
48
],
"parameters": {
"unit": "minutes",
"amount": 1
},
"typeVersion": 1.1
},
{
"id": "sticky-note-main",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
-260
],
"parameters": {
"width": 640,
"height": 260,
"content": "### How it works\nThis workflow automatically detects customers who made a purchase exactly 10 days ago, generates a highly personalized, natural-sounding Arabic promotional message using OpenAI, and sends it directly via WhatsApp. It includes an anti-ban loop to pace the messages.\n\n### Setup steps\n1. **Odoo:** Connect your credentials to fetch Invoices and Contacts.\n2. **OpenAI:** Add your API Key to the AI Node to generate the custom copywriting.\n3. **WhatsApp:** Update the HTTP Request node with your Evolution API credentials (or switch to your preferred WhatsApp provider node)."
},
"typeVersion": 1
},
{
"id": "sticky-note-step1",
"name": "Sticky Note 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
-20
],
"parameters": {
"color": 7,
"width": 580,
"height": 240,
"content": "## 1. Fetch Target Customers\nTriggers daily at 10:01 AM, searches Odoo for invoices that are exactly 10 days old, and retrieves the customer's name and phone number."
},
"typeVersion": 1
},
{
"id": "sticky-note-step2",
"name": "Sticky Note 2",
"type": "n8n-nodes-base.stickyNote",
"position": [
500,
-100
],
"parameters": {
"color": 7,
"width": 460,
"height": 280,
"content": "## 2. AI Copywriting & Loop\nProcesses the customers one by one. The AI Agent takes the customer's name and generates a personalized, colloquial Egyptian Arabic message offering an extra 10% discount."
},
"typeVersion": 1
},
{
"id": "sticky-note-step3",
"name": "Sticky Note 3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1060,
-100
],
"parameters": {
"color": 7,
"width": 440,
"height": 280,
"content": "## 3. WhatsApp Sending & Anti-Ban\nSends the AI-generated message via Evolution API to the customer's WhatsApp, then pauses for 1 minute before sending the next message to prevent spam bans."
},
"typeVersion": 1
}
],
"connections": {
"Generate AI Message": {
"main": [
[
{
"node": "Send WhatsApp Discount",
"type": "main",
"index": 0
}
]
]
},
"Daily Check (10:01 AM)": {
"main": [
[
{
"node": "Fetch 10-Day Old Invoices",
"type": "main",
"index": 0
}
]
]
},
"Send WhatsApp Discount": {
"main": [
[
{
"node": "Wait 1 Mins (Anti-Ban)",
"type": "main",
"index": 0
}
]
]
},
"Wait 1 Mins (Anti-Ban)": {
"main": [
[
{
"node": "Process Customers (One by One)",
"type": "main",
"index": 0
}
]
]
},
"Fetch 10-Day Old Invoices": {
"main": [
[
{
"node": "Retrieve Customer Contact",
"type": "main",
"index": 0
}
]
]
},
"Retrieve Customer Contact": {
"main": [
[
{
"node": "Process Customers (One by One)",
"type": "main",
"index": 0
}
]
]
},
"Process Customers (One by One)": {
"main": [
[],
[
{
"node": "Generate AI Message",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
What Problem Does It Solve? Generic, automated retention messages often feel like spam and fail to engage returning customers. Manually tracking which customers ordered exactly 10 days ago to send them tailored offers is extremely time-consuming. Sending bulk promotional…
Source: https://n8n.io/workflows/14829/ — 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.
AI Institutional Stock Valuation Engine with Risk Scoring & Scenario Targets
Overview This is a production-grade, fully automated stock analysis system built entirely in n8n. It combines institutional-level financial analysis, dual AI model consensus, and a self-improving back
This automation is a complete end-to-end system designed to find, qualify, and contact B2B leads — fully automated and powered by AI. Searches for target companies on LinkedIn via Ghost Genius API, us
This comprehensive n8n automation template orchestrates a complete end-to-end workflow for generating engaging short-form Point-of-View (POV) style videos using multiple AI services and automatically
A professional AI equity analysis automation built on n8n that transforms structured financial data and real-time news into disciplined, risk-adjusted price targets and actionable BUY/HOLD/SELL signal