WhatsApp + Supabase: nurture leads without gaps
Your leads don’t go cold because you “forgot marketing.” They go cold because follow-ups happen in bursts, across too many tools, and someone eventually misses a message (or sends two).
This WhatsApp Supabase automation hits hardest when you’re juggling volume: a sales manager watching response times, a founder doing follow-ups between meetings, or a marketing lead trying to keep “new” leads from stalling after the first touch.
This workflow checks Supabase every hour, sends the right WhatsApp template via Gallabox based on lead status and message count, and logs everything so you always know what was sent, when, and why.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: WhatsApp + Supabase: nurture leads without gaps
flowchart LR
subgraph sg0["Schedule Flow"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Get many rows1"]
n1@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch2", pos: "b", h: 48 }
n2@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch3", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch4", pos: "b", h: 48 }
n4@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch5", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items1", pos: "b", h: 48 }
n6@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger3", pos: "b", h: 48 }
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Create Logs"]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>new_lead_0"]
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Update a row1"]
n10@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items2", pos: "b", h: 48 }
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Create Logs1"]
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Update a row2"]
n13@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items3", pos: "b", h: 48 }
n14["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Create Logs2"]
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Update a row3"]
n16@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items4", pos: "b", h: 48 }
n17["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Create Logs3"]
n18["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>new_lead_2"]
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/supabase.svg' width='40' height='40' /></div><br/>Update a row4"]
n20@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If StatusCode 202", pos: "b", h: 48 }
n21@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If StatusCode ", pos: "b", h: 48 }
n22@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If StatusCode 203", pos: "b", h: 48 }
n23@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If StatusCode 204", pos: "b", h: 48 }
n24@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If Interval", pos: "b", h: 48 }
n25@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If Interval1", pos: "b", h: 48 }
n26@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If2", pos: "b", h: 48 }
n27@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Disposition Switch", pos: "b", h: 48 }
n28@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Count Switch", pos: "b", h: 48 }
n29["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>new_lead_"]
n30["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>new_lead_3"]
n26 --> n18
n29 --> n11
n8 --> n7
n18 --> n17
n30 --> n14
n7 --> n21
n24 --> n29
n28 --> n5
n28 --> n10
n28 --> n13
n28 --> n16
n11 --> n20
n14 --> n22
n17 --> n23
n25 --> n30
n9 --> n5
n12 --> n10
n15 --> n13
n19 --> n16
n0 --> n27
n21 --> n9
n5 --> n8
n10 --> n24
n13 --> n25
n16 --> n26
n20 --> n12
n22 --> n15
n23 --> n19
n6 --> n0
n27 --> n28
n27 --> n1
n27 --> n2
n27 --> n3
n27 --> n4
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n6 trigger
class n1,n2,n3,n4,n20,n21,n22,n23,n24,n25,n26,n27,n28 decision
class n8,n18,n29,n30 api
classDef customIcon fill:none,stroke:none
class n0,n7,n8,n9,n11,n12,n14,n15,n17,n18,n19,n29,n30 customIcon
The Problem: Lead follow-ups slip (or spam) when the process isn’t managed
Most teams start with good intentions: “We’ll WhatsApp every new lead.” Then reality shows up. A rep sends Message 1, gets busy, forgets Message 2, and the lead cools off. Or worse, two people message the same lead because nobody can see the last touch. Now you look disorganized. Even if you log activity in a CRM, it’s usually delayed, incomplete, or missing the exact template that went out. That confusion compounds when you have different lead dispositions (new_lead, test_ride, Booking, walk_in, Sale) and each needs a different cadence.
It adds up fast. Here’s where it breaks down in day-to-day operations.
- Someone has to check Supabase (or your CRM export) and decide who gets nudged, which turns “quick follow-up” into a recurring admin task.
- Message sequencing is fragile, so leads get stuck on the first message or receive the wrong template for their stage.
- Without a reliable “last message sent” record, teams either double-message or hesitate and wait too long.
- When logging is inconsistent, you can’t audit outcomes, troubleshoot delivery, or confidently scale volume.
The Solution: An hourly WhatsApp journey that reads Supabase, sends the right template, and logs every touch
This workflow turns your Supabase contacts table into the single source of truth for follow-ups. Every hour, n8n pulls the contacts that matter, then routes each person by their Disposition (like new_lead) and by how many messages they’ve already received (Count). For new leads, it decides which WhatsApp template to send next, checks timing rules so you don’t hammer someone too quickly, and sends the message through the Gallabox API. Immediately after, it writes a clean log record (message ID, status code, timestamps, which message number) and only increments the lead’s Count when Gallabox accepts the message (status code 202). So the sequence progresses automatically, without guesswork.
The workflow starts on an hourly schedule, then uses Supabase data to pick the correct branch. After that, Gallabox handles the WhatsApp send, and Supabase gets updated with both a log entry and the lead’s new “last_message_sent” timestamp.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you get 40 new leads a day and your sequence is 4 messages. Manually, even “just” 2 minutes to look up the lead, pick the right template, send it, and note it down is roughly 80 minutes per day for Message 1 alone, then more time for Messages 2–4 as they come due. With this workflow, the human time is basically reviewing replies and exceptions, maybe 10 minutes a day, while the hourly run handles the sends and logging in the background. That’s about an hour back most days, without sacrificing speed.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Supabase for contacts table, counts, and message logs.
- Gallabox (WhatsApp API) to send WhatsApp template messages.
- Gallabox API key + secret (get it from your Gallabox developer/API settings).
Skill level: Intermediate. You’ll connect credentials, map a few fields, and be comfortable testing with real log rows.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
An hourly check runs automatically. The schedule trigger fires every hour, so your system keeps nudging leads without anyone remembering to “run follow-ups.”
Supabase becomes the decision-maker. n8n fetches rows from your contacts table (name, phone, Disposition, Count, last_message_sent) and uses that data to decide who should get the next message.
Leads are routed into the right message path. First it routes by Disposition, then for new leads it routes again by Count (0, 1, 2, 3). Some paths include an interval check (like “at least 4 hours” or “exactly 24 hours”) to avoid sending too soon.
WhatsApp templates go out, then everything gets logged. Gallabox receives a template send request, Supabase logs message metadata (including status codes), and the workflow only increments the Count and updates last_message_sent when the send is accepted.
You can easily modify the timing rules and the template names to match your brand and funnel. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Schedule Trigger
This workflow starts on a timed schedule and kicks off the outreach pipeline.
- Add the Hourly Schedule Trigger node as the workflow trigger.
- Set the Rule interval field to
hours(already set in the node). - Optionally keep Flowpast Branding as a sticky note for documentation purposes.
Tip: Use the schedule trigger for predictable hourly outreach and to minimize rate-limit spikes in WhatsApp sending.
Step 2: Connect Supabase
Supabase is used as the primary data source and for logging/updates across multiple nodes.
- Open Fetch Contact Rows and set Table to
contacts_ampere, Operation togetAll, and Return All totrue. - Credential Required: Connect your supabaseApi credentials in Fetch Contact Rows.
- Connect Supabase credentials to all Supabase write nodes used for logs and updates: Insert Message Log A, Insert Message Log B, Insert Message Log C, Insert Message Log D, Modify Contact Row A, Modify Contact Row B, Modify Contact Row C, and Modify Contact Row D.
⚠️ Common Pitfall: Only Fetch Contact Rows, Insert Message Log D, and Modify Contact Row D have Supabase credentials preconfigured. You must add supabaseApi credentials to the remaining Supabase nodes or they will fail at runtime.
Step 3: Configure Routing and Message Count Logic
This workflow routes contacts by disposition and message count to determine which template to send next.
- In Route by Disposition, keep the condition checks using
{{ $json.Disposition }}for valuesnew_lead,test_ride,Booking,walk_in, andSale. - In Route by Message Count, verify the count checks using
{{ $json.Count }}for0,1,2, and3. - Keep the supporting switches Route Count Zero, Route Count One, Route Count Two, and Route Count Three in place for additional routing control (these are optional but useful for future branching).
- Route by Message Count outputs to both Batch Iterate A, Batch Iterate B, Batch Iterate C, and Batch Iterate D in parallel.
Tip: If you add new dispositions, duplicate one rule in Route by Disposition and update the rightValue to match your new status.
Step 4: Set Up Batch Iteration and Interval Gates
Batching controls throughput, and interval checks ensure messages are sent only when the timing conditions are met.
- Keep the batch nodes Batch Iterate A, Batch Iterate B, Batch Iterate C, and Batch Iterate D in series as configured to control message flow.
- In Validate Interval B, verify the condition
{{ $json.interval }}isgte 0. - In Validate Interval C, verify the condition
{{ $json.interval }}isequals 24. - In Validate Interval D, verify the condition
{{ $json.interval }}isgte 24.
⚠️ Common Pitfall: If interval values are missing from your contact records, the Validate Interval B, Validate Interval C, and Validate Interval D nodes will block sending. Ensure interval is populated in contacts_ampere.
Step 5: Configure WhatsApp Template Sends
These HTTP requests send WhatsApp template messages through the Gallabox API.
- In Send WhatsApp Template A, set URL to
https://server.gallabox.com/devapi/messages/whatsappand Method toPOST. - In Send WhatsApp Template A, keep the JSON Body with dynamic values for recipient name and phone:
{{ $json.name }}and91{{ $json.phone }}. - Repeat the same settings for Send WhatsApp Template B, Send WhatsApp Template C, and Send WhatsApp Template D (all use the same template payload).
- Make sure JSON Headers in Send WhatsApp Template A, Send WhatsApp Template C, and Send WhatsApp Template D include your API key (currently
[CONFIGURE_YOUR_API_KEY]).
⚠️ Common Pitfall: These nodes use authentication = genericCredentialType with genericAuthType = httpCustomAuth, but no credentials are configured. You must add a custom HTTP auth credential or the requests will fail.
Step 6: Configure Logging and Contact Updates
Each message is logged, status-checked, and used to update the contact record for future routing.
- In Insert Message Log A, confirm the Table is
logs_nurture_ampereand fields map to values like{{ $json.body.id }},{{ $('Route by Message Count').item.json.phone }}, and{{ $('Route by Message Count').item.json.Count + 1}}. - Repeat log mapping for Insert Message Log B, Insert Message Log C, and Insert Message Log D (same fields and expressions).
- In each status check node (Check Status 202 A, Check Status 202 B, Check Status 202 C, Check Status 202 D), keep the condition
{{ $json.status_code }}equals202. - In each update node, set Table to
contacts_ampereand keep field updates such as{{ $('Batch Iterate A').item.json.Count + 1}}and{{ $('Send WhatsApp Template A').item.json.headers.date }}(match the corresponding A/B/C/D nodes).
Tip: The update nodes are wired to loop back into the corresponding batch node, allowing multiple contacts to process sequentially.
Step 7: Test and Activate Your Workflow
Validate your routing, logging, and updates with a controlled test run before turning the automation on.
- Click Execute Workflow to run a manual test starting from Hourly Schedule Trigger.
- Confirm that Fetch Contact Rows returns records from
contacts_ampereand that Route by Disposition and Route by Message Count route items correctly. - Verify successful WhatsApp sends by checking Insert Message Log A through Insert Message Log D for a new log entry and a
202status code. - Check that Modify Contact Row A through Modify Contact Row D update the
Countandlast_message_sentfields as expected. - When satisfied, toggle the workflow to Active to enable hourly processing.
Common Gotchas
- Gallabox credentials can expire or need specific permissions. If things break, check your Gallabox API settings and template approvals first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Supabase updates can fail silently if Row Level Security blocks writes. If logs aren’t inserting or Count isn’t incrementing, check RLS policies on contacts_ampere and logs_nurture_ampere.
Frequently Asked Questions
About 45 minutes if your Supabase table and Gallabox templates are ready.
No. You’ll mostly connect accounts, map fields, and test with a few contacts.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in Gallabox/WhatsApp messaging costs based on your plan and message volume.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and you should. The workflow already routes by Disposition using a switch, so you can replicate the new_lead message-count logic for test_ride, Booking, walk_in, or Sale by adding message templates and Count rules to those branches. Common customizations include changing the interval checks (4 hours vs 24 hours), swapping template names in the Gallabox HTTP request, and writing extra fields to your logs table for reporting.
Usually it’s an invalid API key/secret or a missing header in the HTTP request. Check that your Gallabox templates are approved and the channelId matches the WhatsApp channel you’re sending from. Also watch for rate limiting if you push a big batch at once; splitting into smaller batches helps. Finally, confirm phone numbers are in the format Gallabox expects, because one bad recipient can make it look like “the integration is down.”
A few thousand contacts per day is realistic for most setups, and the split-in-batches nodes help you pace sends.
Often, yes, because this workflow relies on branching logic (Disposition plus Count plus interval checks) and clean database writes, which is awkward and expensive in simpler automation tools. n8n also lets you self-host, which means you’re not paying per tiny step once volume grows. Zapier or Make can still be fine for a two-step “new row → send message” flow, but sequencing is where they start to feel brittle. Honestly, if you’re planning more than one follow-up message, n8n tends to be the calmer option. Talk to an automation expert if you want help choosing.
Once this is running, your follow-ups stop depending on someone’s memory. The workflow keeps the sequence moving, and your team can focus on replies that actually close deals.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.