Skip to main content

Case study · SaaS / Communications

BulkReachMulti-tenant bulk and scheduled messaging for Slack and WhatsApp

A multi-tenant SaaS for sending bulk and scheduled messages to Slack workspaces and WhatsApp numbers, with a dashboard, a marketing site, and a separate always-on messaging service.

BulkReach social card: the BulkReach logo with the line "Reach everyone, without the copy-paste."

The challenge

Teams that announce to many Slack channels or WhatsApp contacts need sends that respect rate limits, survive timeouts, keep each customer's data isolated, and never message people who have not opted in.

The solution

Every send becomes a queue of per-recipient delivery rows. A dispatcher drains that queue under each platform's rate limits, started immediately after a send and by a Postgres cron job every minute — so interrupted campaigns resume instead of restarting, and scheduled sends are simply queued sends that are not due yet.

What we built

  • Slack OAuth v2 install and paced channel messaging
  • WhatsApp delivery through a dedicated always-on Node service
  • Scheduled sends without a separate scheduler table
  • CSV contact import with explicit consent confirmation and opt-out re-checked at send time
  • Statically prerendered marketing pages with structured data, sitemap, and llms.txt

Architecture

Application
Next.js 16 (App Router, Server Actions), TypeScript, Tailwind CSS v4
Data
Supabase Postgres with row-level security and Auth
Messaging
Slack Web API; WhatsApp service on Render
Scheduling
pg_cron + pg_net, one tick a minute

Engineering challenges

  • Tenant isolation written into every row-level security policy, plus an audit query that must return zero rows
  • Slack tokens and messaging sessions encrypted at rest with AES-256-GCM
  • Scheduling on pg_cron and pg_net, which skips the HTTP call entirely when nothing is due
  • Randomised send spacing and a hard floor between WhatsApp messages

Next step

Have a similar problem to solve?

A free 30-minute discovery call, then a written scope and a fixed-price quote — before you commit to anything.