--- type: overview title: Quickstart description: What the wh WhatsApp terminal client with per-chat and global AI autoreply (system prompt in SOUL.md, reply delay, image descriptions, voice-note transcriptions) does, how to build and run it, and where to find each topic in this wiki. tags: [overview, quickstart, rust, whatsapp, tui, ai, web-panel, pairing, transcription] sources: - id: openwiki-source-651d1fb6c9e49916a916ab51 resource: repo://Cargo.toml - id: openwiki-source-9fec9d1af408501c9c455161 resource: repo://src/app.rs - id: openwiki-source-043e6252badc57a1ee6bfb48 resource: repo://src/autoreply.rs - id: openwiki-source-2a737474d86fc75cc9d9694f resource: repo://src/config.rs - id: openwiki-source-b55a21a31ede1b56cd31a6a6 resource: repo://src/main.rs generated: { by: "claude-code", at: "2026-10-25T13:15:27.881Z" } verified: - by: openwiki/0.7.2 at: 2026-10-25T13:15:27.881Z --- # Quickstart `wh` (`Cargo.toml:1-5`) is a Rust terminal client for WhatsApp. It links as a companion device by QR code, shows chats and contacts in a [ratatui](architecture/terminal-ui.md) interface, stores messages locally in SQLite and can answer incoming messages automatically with an OpenAI-compatible model — chat by chat or for all chats at once — in private chats and in groups (broadcasts, status and newsletters excluded). An optional [web control panel](integrations/web-control-panel.md) lets a browser toggle the autoreplies, pair WhatsApp from the QR shown in the page, request a new pairing and stop the bot. ## Build and run ```sh cargo build --release cargo run --release cargo test ``` The crate uses edition 2024. `whatsapp-rust` is built with `default-features = false` because its default `simd` feature needs nightly (`Cargo.toml:8-10`). TLS uses `ring` only: `reqwest` is built with `rustls-no-provider` and the `ring` provider is installed when the AI client is built, avoiding the large `aws-lc-sys` C build (`Cargo.toml:13-16`); this keeps the Linux musl cross-compile with `cargo-zigbuild` (see `README.md`) fast. The release profile only strips symbols, without LTO (`Cargo.toml:31-33`). `[lints.rust] linker_messages = "allow"` (`Cargo.toml:35-37`) silences the informational MSVC linker line printed because the binary exports symbols. `wh --version` (or `-V`) prints `wh .. ()`, where the build number is the git commit count, and exits; the same version is shown at the bottom right of the main screen (`src/main.rs:31-58`, `build.rs`). On first start the app shows a QR code: scan it from WhatsApp → *Linked devices*. The session is kept in `session.db`, so later starts connect directly; `F8` twice (on any screen) or the web panel's "Nuovo QR" unlinks the device, empties `session.db` and shows a new QR without restarting ([WhatsApp relink and pairing](workflows/relink-and-pairing.md)). Main keys: `Tab` switches list/input, `Enter` opens a chat or sends, typing in the list filters it, `PgUp`/`PgDn`/`Home`/`End` move through the list, `F2` chats/contacts, `F3` toggles autoreply for the selected chat (list focus) or the open chat (input focus), `F4` toggles the global autoreply ("AI tutte"), `Canc` twice deletes the selected chat locally, `F10` quits and clears the screen ([key bindings](architecture/app-state.md#key-bindings)). ## Configuration in short Settings live in `config.toml` inside the data directory `/wh` (on Windows `%APPDATA%\wh`, on Linux `~/.config/wh`), next to `session.db` and `history.db` (`src/config.rs:55-68`, `src/config.rs:206-210`); the repository's `config.toml.global.template` lists every key. The system prompt is not a key: it is the file `SOUL.md` in the same folder (start from `soul.md.template`), and the optional `VISION.md` replaces the built-in request used to describe images. The three files are checked every 2 seconds and reloaded when they change, without restarting; only `web_port` needs a restart ([live reload](operations/configuration-and-data.md#live-reload)). The two databases are separate by design: `session.db` is the WhatsApp library's session and key store, `history.db` holds the app's chats, messages, autoreply flags and image descriptions. Without `openai_api_key` and a non-blank `SOUL.md` the app still runs as a plain WhatsApp client. Optional keys tune the reply delay (`reply_delay_seconds`), the startup catch-up (`catch_up_seconds`), AI retries (`ai_retries`), the vision model (`openai_vision_model`), an AI request log (`ai_log`, written to `ai_requests.log` in the same folder) and the web panel port (`web_port`, unauthenticated, all interfaces). Four more `transcribe_*` keys enable voice-note transcription against any OpenAI-compatible `audio/transcriptions` endpoint (off by default; Groq with `whisper-large-v3-turbo` as the default endpoint and model). The old keys `system_prompt`, `cooldown_seconds` and `group_cooldown_seconds` are ignored. Keys and defaults: [Configuration and data](operations/configuration-and-data.md). ## Autoreply in one paragraph The first unanswered message of an enabled chat starts a `reply_delay_seconds` wait; messages arriving meanwhile join the same reply. Images are described once by the vision model and only their descriptions reach the AI; voice notes are transcribed once (when `transcribe_key` is set, Groq by default) and their text enters the reply context. The reply is dropped if the owner answered by hand, and the model can stay silent by calling the `no_reply` tool, whose use is decided by `SOUL.md`. Details: [AI auto-reply workflow](workflows/ai-autoreply.md). ## Startup in one line `main` prints the version and exits for `--version`; otherwise it loads the config, opens the history, starts the WhatsApp client, the optional web panel, the configuration watcher and an input thread, then runs the draw/receive loop until quit (`src/main.rs:54-82`, see [Runtime and event loop](architecture/runtime-and-event-loop.md)). ## Where to look | Task | Page | Source | |---|---|---| | Startup, version flag, channels, threads, config watcher, main loop | [Runtime and event loop](architecture/runtime-and-event-loop.md) | `src/main.rs`, `src/config_watch.rs`, `build.rs` | | Events, state, keys, filter, chat deletion, config reload, relink, reply orchestration, background tasks | [Application state](architecture/app-state.md) | `src/app.rs` | | Screens, rendering, message formatting, footer version | [Terminal UI](architecture/terminal-ui.md) | `src/ui.rs` | | WhatsApp session, relink, events, JIDs, media | [WhatsApp client](integrations/whatsapp-client.md) | `src/whatsapp.rs` | | AI HTTP requests, `no_reply` tool, image descriptions, retries, errors | [AI client](integrations/ai-client.md) | `src/ai.rs` | | Web control panel: routes, security, pairing QR, browser page | [Web control panel](integrations/web-control-panel.md) | `src/web.rs`, `src/web_page.html` | | When and how the AI replies (global/per-chat, groups, reply delay, owner-answered drop, images, catch-up, context) | [AI auto-reply workflow](workflows/ai-autoreply.md) | `src/autoreply.rs`, `src/app.rs` | | Pairing, F8 / "Nuovo QR" relink, session reset, new QR in TUI and web | [WhatsApp relink and pairing](workflows/relink-and-pairing.md) | `src/app.rs`, `src/whatsapp.rs`, `src/web.rs` | | Local SQLite messages, chats, contacts, settings, image descriptions | [History store](concepts/history-store.md) | `src/history.rs` | | Config keys, `SOUL.md` / `VISION.md`, live reload, data dir, build profile, security notes | [Configuration and data](operations/configuration-and-data.md) | `src/config.rs`, `src/config_watch.rs` | | Test suites, the ignored live relink test and how to run them | [Unit tests](testing/unit-tests.md) | `src/*.rs` |