JavaScript, webdev

Schedule WhatsApp Messages with wacli Mission Control

Send later, finally

You’re deep in a terminal-based workflow, firing off messages with wacli, and then it hits you: you need to send this at 9am, not right now. So you either wait around, or you lose the moment. Every other headless messaging tool leaves you stuck with that choice.

Not anymore.
Scheduled sends are the headline feature of wacli Mission Control — and honestly, the reason I built it.

The gap it fills

If you’re a developer, power user, or sysadmin, you’ve probably felt the friction of modern desktop messaging apps: memory-hungry, closed to automation, and standing between you and your own data.

CLI tools like wacli solve that — speed, privacy, SQLite storage, full-text search, all from the terminal. But once you’re juggling a dozen active threads, rich media, emoji reactions, and scheduled replies, raw terminal output stops scaling.

So I built wacli Mission Control (wacli-ui): a lightweight, high-density, local-first web console for people who want terminal-grade speed and privacy with a UI that doesn’t get in the way — including a proper interface for the send-later queue that started this whole thing.

Why

Most third-party messaging integrations fall into one of two traps:

  1. Cloud-hosted relays that compromise end-to-end privacy by transmitting authentication tokens and message history through remote third-party servers.
  2. Fragile web scrapers that consume gigabytes of RAM and break every time a web layout updates.

wacli Mission Control takes a completely different path:

  • 100% Local-First & Private: Binds exclusively to 127.0.0.1. No external tracking, no cloud telemetry, no proxy relays.
  • Powered by Local SQLite & FTS5: Queries your messages instantly using SQLite’s Full-Text Search index.
  • Safe by Default: Starts in read-only mode with explicit two-step mutation guardrails to prevent accidental dispatches.
  • Zero-Polling Realtime Stream: Uses a supervised background daemon with an HMAC-SHA256 verified webhook listener and real-time WebSockets.

The 3-Pane Operator Interface

Mission Control features a high-density, dark-mode 3-pane cockpit crafted for fast navigation:

┌──────────────────────────────────────────────────────────────────────────────┐
│ wacli Mission Control │
├───────────────────┬──────────────────────────────────────┬───────────────────┤
│ CHATS RAIL │ THREAD VIEW │ STATUS STRIP │
│ │ │ │
│ • Unread Badges │ • Delivery Ticks (Sent/Read) │ • Daemon Health │
│ • Presence Typing │ • Media Previews & Inline Audio │ • Sync Progress │
│ • Filter Tabs │ • Reactions & Emoji Drawer Popover │ • Process Uptime │
│ • Pin / Mute / │ • Reply Threading & Message Actions │ • Real-time Send │
│ Archive status │ • Fixed Composer & "Send Later" │ Audit Stream │
└───────────────────┴──────────────────────────────────────┴───────────────────┘

1. Left Rail — Chat Management & Live Presence

  • Real-time unread badges, contact names, and JID resolution.
  • Live typing... presence indicators.
  • Quick filter tabs: All, Unread, Pinned, Muted, and Archived.

2. Center Pane — Thread View, Media & Composer

  • Chronological message history with group sender attribution and delivery receipts (sent, delivered, read).
  • Interactive Actions: Quick reply threading, clipboard copying, starring, and an expanded category-indexed Emoji Reaction Drawer.
  • Rich Media Viewer: Inline image zoom, waveform audio playback for voice notes, video rendering, and document attachments.
  • Fixed Composer: Auto-expanding multi-line text input, reply pills, file attachments, and a built-in “Send Later” scheduler.

3. Right Rail — Real-time Telemetry & Send Audit Log

  • Sync daemon process status, PID, and store lock delegation.
  • WebSocket stream health and heartbeat indicators.
  • Live outgoing audit trail tracking all dispatched messages, media, and reactions.

Deep Dive: Safe-by-Default Architecture

One of the biggest risks of programmatic messaging interfaces is accidental sends. Mission Control handles this through a multi-tiered safety model:

  1. Read-Only Mode by Default: When you start the console, all outgoing operations (text dispatches, media uploads, emoji reactions, scheduled jobs) are strictly locked.
  2. Two-Step Confirmation Guardrail: Even when unlocked, actions trigger a SendConfirmModal showing the recipient JID, the raw message payload preview, and explicit user confirmation before dispatching.
  3. Session Persistence: Safety preferences are saved across server reboots, ensuring the app never silently wakes up in an unlocked state.

Architecture & Data Pipeline

Under the hood, Mission Control coordinates a supervised Go binary, an Express 5 backend, and a modern React 19 frontend:

┌────────────────┐ HTTP (REST, JSON) ┌────────────────┐ child_process.execFile ┌──────────┐
│ │ ──────────────────────────────────► │ Express 5 API │ ─────────────────────────► │ wacli │ (one-shot queries,
│ Browser UI │ ◄────────────────────────────────── │ (Port :3002) │ ◄───────────────────────── │ --json │ WACLI_READONLY=1)
│ (React 19 + │ └────────────────┘ └──────────┘
│ Vite 7) │ ▲ ▲
│ │ WebSocket (ws events) │ │ stderr NDJSON (lifecycle)
│ │ ◄─────────────────────────────────────┤ │
└────────────────┘ │ ┌──────────────┐
HTTP POST │ │ wacli sync │ (supervised daemon,
(HMAC-SHA256) └─────│ --follow │ --webhook,
│ --events) │ --events)
└──────────────┘
  • Daemon Supervision: The API launches wacli sync --follow as a child process with exponential backoff restarts and health checks.
  • Cryptographic Webhook Validation: Events (message.created, receipt.updated, presence.updated) emitted by the sync daemon are signed via HMAC-SHA256 and ingested by the internal API router before broadcasting to active WebSockets.
  • SQLite FTS5 Search: Pressing Cmd+K (or Ctrl+K) opens instant global message search across your entire SQLite message store in milliseconds.

Getting Started in 60 Seconds

Prerequisites

Make sure you have Node.js 20+ and the wacli CLI installed and authenticated:

# 1. Verify wacli is installed and authenticated
wacli --version
wacli auth

Option A: Launch with npx (Zero Installation)

npx wacli-mission-control

Option B: Install Globally via npm

npm install -g wacli-mission-control
# Launch and automatically open your default browser
wacli-mission-control --open

Option C: Run from Source

git clone https://github.com/greenido/wacli-ui.git
cd wacli-ui
npm install
npm run dev

Visit http://127.0.0.1:5174 (Web UI) and http://127.0.0.1:3002 (API Server).

Essential Keyboard Shortcuts

ShortcutAction
Cmd + K / Ctrl + KOpen / close global full-text search
EnterSend message from composer (single line)
Shift + EnterInsert newline in composer
EscDismiss active modal, emoji drawer, or search palette

The Tech Stack

  • Core CLI / Engine: wacli (Go, whatsmeow, SQLite FTS5)
  • Backend API: Node.js 20+, Express 5, ws, multer, HMAC validation
  • Frontend App: React 19, TypeScript, Vite 7, Tailwind CSS v3, TanStack Query v5, Zustand, Lucide Icons, date-fns
  • License: MIT

What’s Next & Getting Involved

wacli Mission Control is open source and actively maintained.
Whether you are interested in extending keyboard navigation, refining media previewers, adding custom automation hooks, or improving search filters, contributions and feedback are welcome.

Take control of your local messaging workflow—safe, fast, and private 🚀


Discover more from Ido Green

Subscribe to get the latest posts sent to your email.

Standard

Leave a comment