Skip to content

Dharshan2208/wha-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wha-cli (WhatsApp TUI)

A terminal user interface (TUI) for WhatsApp built with Go, Bubble Tea, and the whatsmeow library.

Note: This project stores WhatsApp session data and message history locally in SQLite databases (whatsapp.db, messages.db). Treat these files as sensitive.

Overview

wha-cli lets you read and send WhatsApp messages from your terminal in a keyboard-driven UI. It connects to WhatsApp using whatsmeow (companion-device style login via QR code), renders a two-pane chat/messages experience with Bubble Tea + Lip Gloss, and persists chat/message data locally so the UI can load quickly on subsequent runs.

What problem does it solve?

If you live in the terminal, switching to a phone/desktop app to reply to messages is disruptive. wha-cli provides a lightweight, distraction-minimizing interface to:

  • See your available chats (contacts + selected groups)
  • Open a chat and read recent history
  • Send replies without leaving the terminal

Features

Core

  • QR-based login on first run (session persisted in whatsapp.db)
  • Chat list from WhatsApp contact store + joined groups
  • Local caching of chats + messages in messages.db (SQLite)
  • Loads recent history per chat (currently last 50 messages)
  • Unread badge counter (tracked in local DB/UI)
  • Automatic reconnect with backoff when the WhatsApp connection drops

Messaging

  • Receive and display incoming messages in real time
  • Send text messages from the input panel
  • Basic handling for non-text message types (rendered as placeholders like 📷 [Image], 🎥 [Video], etc.)
  • Message deduplication at the database layer (INSERT OR IGNORE on (id, chat_jid))

TUI / UX

  • Bubble Tea alt-screen UI with three focus areas: chat list, messages, input
  • Keyboard navigation and message scrolling
  • Timestamps per message and “older/newer messages” scroll hints

Tech stack

  • Language: Go
  • TUI: github.com/charmbracelet/bubbletea, github.com/charmbracelet/lipgloss
  • WhatsApp client: go.mau.fi/whatsmeow
  • Storage: SQLite (github.com/mattn/go-sqlite3)
  • Config: .env loader (github.com/joho/godotenv)
  • QR rendering: github.com/mdp/qrterminal/v3

Architecture

Folder structure

cmd/
  main.go                # Entry point: config + DB + WhatsApp + TUI wiring
internal/
  client/                # whatsmeow wrapper, event conversion, chat filtering
  config/                # reads contacts.env (ALLOWED_GROUP_*)
  store/                 # SQLite schema + chat/message queries
  sync/                  # background event loop + reconnect + Bubble Tea commands
  types/                 # shared types and Bubble Tea messages
  ui/                    # Bubble Tea model/update/view + rendering

High-level flow

startup
  -> load config (contacts.env)
  -> open messages.db (migrate schema)
  -> open whatsapp.db (whatsmeow device/session store)
  -> connect (QR on first login)
  -> load chats:
       messages.db first
       else WhatsApp contacts + joined groups (filtered) -> persist to messages.db
  -> start Bubble Tea program (TUI)
  -> start background sync loop:
       WhatsApp events -> persist -> send Bubble Tea messages -> update UI

Installation & setup

Prerequisites

  • Go (see go.mod for the configured version)
  • A working C toolchain for CGO (required by github.com/mattn/go-sqlite3)
    • macOS: Xcode Command Line Tools
    • Linux: gcc/clang + standard build tools
    • Windows: MSVC build tools

Build

git clone "https://github.com/Dharshan2208/wha-cli"
cd wha-cli
go mod download
go build -o wha-cli ./cmd

First run (QR login)

./wha-cli

On the first run, the app prints a QR code to the terminal. Scan it with WhatsApp (Linked Devices) to authorize.

Local files created

By default, databases are created in the current working directory:

  • whatsapp.db: WhatsApp session/device store (managed by whatsmeow)
  • messages.db: app cache for chats/messages (managed by this project)

These files are ignored by .gitignore and should not be committed.

Usage

Keyboard controls

  • Tab: cycle focus (Chats → Messages → Input)
  • / :
    • In Chats: move selection (with scrolling)
    • In Messages: scroll older/newer messages
  • Enter:
    • In Chats: open selected chat (loads history, clears unread)
    • In Input: send typed message
  • Esc: return to chat list
  • Backspace: delete character (Input focus)
  • q: quit (only when not typing)
  • Ctrl+C: quit

Configuration

Chat filtering (contacts.env)

On startup, the app loads contacts.env from the repository root (via godotenv.Load("contacts.env")).

Supported variables:

  • ALLOWED_GROUP_JIDS: comma-separated group JIDs (e.g. 1203...@g.us)
  • ALLOWED_GROUP_NAMES: comma-separated group names (case-insensitive)

Example:

ALLOWED_GROUP_JIDS=1212234567890@g.us,12036333028324722@g.us
ALLOWED_GROUP_NAMES=E204-Roommates,RandomInfo

Notes / assumptions based on current code:

  • Groups are shown only if they match an allowed JID or name.
  • Contacts are shown only if WhatsApp has a display name for them (push name or full name). On fresh sessions, some contacts may be hidden until WhatsApp metadata is populated.

Database / storage

messages.db contains two tables:

  • chats: per-chat metadata (name, last message preview, unread count)
  • messages: per-chat messages (id + timestamp + sender + text + from-me flag)

Key details:

  • messages(chat_jid) has a foreign key to chats(jid).
  • Messages are deduplicated with a composite primary key: (id, chat_jid).
  • An index supports fetching recent history efficiently: idx_messages_chat_jid (chat_jid, timestamp DESC).

Contributing

Contributions are welcome.

Known issues / limitations

Based on the current implementation:

  • Message history loading is fixed to the most recent 50 messages per chat (no pagination UI yet, even though the store supports GetMessagesBefore).
  • Sending is text-only (no media sending).
  • Group listing is opt-in via ALLOWED_GROUP_*; if you don’t configure it, groups won’t appear.
  • Contact filtering may hide contacts without populated names in the WhatsApp store on first login.
  • Groups name is still not coming
  • Groups not in .env file is still appearing in the chatlist

Roadmap

Ideas that fit the current design:

  • Paginated history loading (“load older messages” using GetMessagesBefore)
  • Search/filter in chat list
  • Better contact/group metadata sync (names, avatars)
  • Media preview improvements and/or media download

License

This project is licensed under the AGPL-3.0 License — see the LICENSE file for details.

About

Whatsapp CLI built for fun and learning ...btw have lots of stuffs to do...have to figure out

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages