omp packages

whatsapp-ng1.1.0

WhatsApp integration for the Pi Coding Agent

jagaliano Published 2 hours ago MIT ~245 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

WhatsApp Logo

whatsapp-ng

Use WhatsApp to talk to your Pi agent: send tasks, share files and voice notes, receive answers, and control the running session from your phone.

Features

  • Manual WhatsApp connection: pair by QR code, keep the saved login, and reconnect when needed or on startup.
  • Allowed contacts: choose who can interact with Pi; add names and aliases, inspect ignored senders, and print contact identifiers from the menu.
  • Allowed groups: allow specific group JIDs with aliases, then choose mention/reply triggers or all-message handling. Other groups do not trigger the agent.
  • Recents and history: browse conversations offline, inspect message details and send native quoted replies.
  • Reliable messaging: stable message IDs, bounded pre-transmission retries and explicit uncertain outcomes instead of blind resends.
  • Terminal menu: manage connection, contacts, groups, history, reply delivery, voice settings and the authorized phone owner through /whatsapp.
  • Phone controls: select models and thinking levels, stop work, compact context or start a new shared session from the owner's phone.
  • Group-only mode: bind Pi to one WhatsApp group with --whatsapp-group <jid>.
  • Media support:
    • Images: forward incoming WhatsApp images to Pi for analysis with a vision-capable model.
    • Audio transcription: use Whisper.cpp/CrispASR locally, a compatible native Whisper addon, or a configured transcription API. FFmpeg first converts voice notes to 16 kHz mono WAV.
    • Documents: save documents for agent access, with bounded text previews for readable PDFs and optional local OCR for scans.
    • Outgoing attachments: explicitly send documents, images, audio, voice notes and video, with optional native quotes.
  • Spoken replies: opt into text, voice, voice + text or input-mirroring output, with per-chat preferences and separate group consent.

All allowed chats share one Pi session and its context. Only allow people and groups you trust with that shared access.

Install and connect

With Pi already installed, install the stable channel:

pi install npm:whatsapp-ng@latest

The 1.1.0 release line includes saved startup preferences and fuzzy /model search. Check the actual channel version with npm view whatsapp-ng@latest version; next is independent and may still point to an older prerelease. Stable versioning does not imply an SLA, all-platform qualification or guaranteed npm/Pi catalog indexing. See the security and qualification limits.

Restart Pi, then:

  1. Open /whatsapp → Connection → Connect WhatsApp and scan the QR code.
  2. Add contacts under Chats / Owner → Allowed Contacts, or groups under Groups → Allowed Groups.
  3. Send a message from an allowed chat. Pi answers in that conversation.

The login is saved. To reconnect automatically without a launch flag, open Connection → Auto-connect on startup → Enabled. This saves autoConnect: true in the extension's config.json; the default is disabled. Only the literal boolean true enables it.

The saved preference applies to TUI and RPC sessions using the same profile, across workspaces, including /reload and /new. Any RPC process that loads the extension, including an extension-enabled subagent, follows that preference; print/JSON runs need an explicit online flag. Only one Pi process can own the profile: preference-based startup skips an occupied/unverified profile lock with one notice rather than repeated retries.

Changing the preference does not immediately connect or disconnect WhatsApp. Existing saved credentials are required; first-time pairing still uses Connect WhatsApp. Explicit Off survives reload/session changes in the current process even with auto-connect enabled; it does not disable other Pi processes. A fresh TUI/RPC process follows the shared saved preference. Cooperative config writes preserve newer auto-connect selections made by another updated Pi process.

The launch flag remains an explicit auto-connect request, even if the saved preference is disabled:

pi --whatsapp-ng-online

Use --whatsapp-group <jid> to bind the extension to one group. Stop any other instance using the same WhatsApp profile before connecting. For an existing installation with an older data directory, use the migration guide rather than pairing again or deleting its data.

Optional system tools

Text chat needs no additional media tools. Install the tools below only for the features you use, following their instructions for macOS, Linux or Windows. System executables and model/language data are not bundled; availability depends on the tool's supported platforms.

Tool Needed for
FFmpeg Audio conversion, video processing and outgoing image/video preparation. Required for voice-note transcription and spoken replies, even with a remote speech API.
Whisper.cpp with a GGML model Local transcription through whisper-cli. Not needed for remote transcription or when using a compatible native addon.
CrispASR with a compatible model Optional beta/experimental local speech toolkit: a Whisper-compatible transcription CLI, or a separately managed STT/TTS server with broader model choices.
Tesseract with language data Local OCR of scanned PDFs. PDFs with readable text do not require OCR.

For local CLI transcription, choose Whisper.cpp or CrispASR; you do not need both. The included whisper-cpp-node addon offers an alternative backend on compatible macOS/Windows builds, not Linux. It includes its own Whisper engine and still needs a model, but no separate CLI. Setting an explicit CLI path disables native-addon fallback.

Make executables available on PATH to the process running Pi, or set FFMPEG_PATH, WHISPER_CLI_PATH or CRISPASR_CLI_PATH for an executable elsewhere. Point WHISPER_MODEL_PATH or CRISPASR_MODEL_PATH to your existing model. Services may have a different environment from your terminal. See PDF/OCR setup and manual checks for scanned documents.

Audio transcription

Choose local transcription or a compatible remote API. FFmpeg is required for both.

Local

Install whisper-cli and point WHISPER_MODEL_PATH to your existing GGML model. Set WHISPER_LANGUAGE to auto or a language code such as en or es in the environment that launches Pi.

Local transcription runs on CPU. Without a model override, the base model downloads on first use. When neither CLI is available and no explicit CLI path is set, compatible macOS/Windows builds can use the included native addon instead; Linux requires a CLI.

CrispASR is another supported local CLI/server option. See the speech reference for discovery order and environment variables.

Local CrispASR speech servers (beta)

CrispASR is a unified C++ speech toolkit, originally based on Whisper.cpp, with many STT and TTS model families and model auto-download/cache options. Treat this optional setup as beta/experimental: it is a fast-moving 0.x project, and model/build compatibility needs checking. STT choices include Whisper, Parakeet, Canary and Qwen3-ASR; TTS choices include Kokoro, Piper, Qwen3-TTS and OmniVoice.

We added http:// support for STT/TTS endpoints to open the way for local servers such as CrispASR, without needing TLS just for localhost. Loopback HTTP is allowed; non-loopback HTTP requires an explicit launch-environment opt-in and is unencrypted. See the setup, model examples and transport safeguards.

CrispASR provides Windows, Linux and macOS builds, with CPU, NVIDIA CUDA, Apple Metal and Vulkan execution options depending on the build, hardware and model—not every combination on every OS. Multilingual Whisper covers 99 STT languages, while upstream OmniVoice advertises 600+ TTS languages; coverage is model/voice-specific, not a promise that every engine supports all languages. These are upstream capabilities, not a full whatsapp-ng validation matrix. Our direct CLI path remains CPU-only and requires a compatible Whisper GGML model; use a separate compatible HTTP server for other model families or GPU acceleration. OmniVoice's reference-audio HTTP flow still has additional integration limits.

The guide explicitly downloads ggml-large-v3-turbo-q5_0.bin using CrispASR's --hf-repo / --hf-file selectors rather than accepting a base-model default. It is an example: choose the model that fits your languages, accuracy, memory and latency needs.

Remote

Use any provider or self-hosted server implementing the OpenAI-compatible /audio/transcriptions API. This is not tied to Groq or to Pi's model provider; chat API compatibility alone does not guarantee transcription support.

From a verified local terminal/RPC request or the configured WhatsApp owner's chat, ask Pi to call configure_wa_stt with your provider's base URL, transcription model and API-key environment-variable name. Other allowed contacts cannot change or clear these settings. Replace these placeholders:

{
  "sttEndpoint": "https://speech.example.com/v1",
  "sttModel": "your-transcription-model",
  "sttEnv": "STT_API_KEY"
}

Set STT_API_KEY securely in the environment that launches Pi, then restart Pi. Pass only the variable's name to the tool, never the key itself. Optional sttLanguage selects a language; omit it or use auto for server detection.

Configuring remote transcription authorizes sending admitted voice-note audio to that endpoint. The provider's billing and retention policies apply. Failures are reported without silently switching providers or falling back to local transcription.

Updates preserve omitted settings. Call configure_wa_stt({}) to return to local transcription. See endpoint and request details for local servers and transport limits.

Speech replies (opt-in)

Open /whatsapp → Voice to choose a speech backend, voice, speed and reply mode:

Mode Output
Text Text only.
Voice A voice note when the answer is suitable for speech.
Voice + text Both formats.
Mirror Voice for verified audio input; text otherwise.

Backends include Fish, OpenAI-compatible speech APIs and the unofficial Microsoft Edge speech service. A compatible CrispASR TTS server, such as the Kokoro example, can provide local synthesis through the same endpoint client. Edge requires no configured API key but is an online service, not offline synthesis. The transcription and speech backends are independent.

Speech is disabled until you approve its destination in the terminal Voice menu. Groups need separate opt-in. Changing the endpoint requires new approval; configuring a backend with configure_wa_tts does not enable speech or grant consent.

Voice settings also let you pause automatic replies for individual chats and send a confirmed preview. Speech uses a separate plain-text copy: emphasis markers, headings, bullets and escaped quotes are cleaned up; short labels such as config.json can be spoken normally. Ordinary approximate values such as “~5 minutes” remain eligible. Voice and audio Mirror keep an answer as text when speaking its link label would omit the address. Voice + text speaks link labels only if the full text send succeeds. The displayed answer is unchanged. Long answers, code/command-like snippets and tables stay as complete text. See the speech reference for backend fields and failure behavior.

Chats and replies

The /whatsapp menu groups settings into Connection, Chats / Owner, Replies, Voice, Groups and Advanced. See Off behavior and diagnostic privacy for shutdown and log retention.

  • Contacts: add phone numbers in +E164 format; use aliases to identify them.
  • Groups: add the group JID. By default, the agent responds to actual WhatsApp mentions of its account or replies to that account's messages. Change this under Groups → Group replies.
  • Recents: browse conversations, inspect messages, reply manually or allow a new chat.
  • Replies: choose whether attachments are followed by a final explanation. Optional elapsed/tool-count stats, file-path summaries, interim text and live activity are off by default.
  • Optional outputs: explicitly approve individual tools whose image results may be shared, or forward future terminal answers to the private owner. These are off by default.
  • Owner: explicitly choose the person authorized to use phone controls. An allowed contact or paired device is not automatically an owner.

WhatsApp @lid identifiers are not phone numbers. Select known conversations in the menu rather than constructing a recipient from displayed digits.

Phone controls

Allowed people can use /help and /status. State-changing commands require the configured owner and affect the shared Pi session.

Command Action
/model [provider/model or search] Select an exact authenticated model, or search providers/models and confirm a match.
/think [level] Change thinking level.
/stop, /abort Stop current work and withdraw queued WhatsApp input.
/compact [focus] Compact session context.
/new Confirm a new Pi session, keeping login, settings and history.
/voice [text|voice|both|mirror] Change this chat's mode within existing speech approvals.
/replies Change reply delivery and optional reporting.
/off Confirm WhatsApp shutdown without logging out. Re-enable from the terminal Connection menu.
/quit Confirm graceful Pi shutdown.

Use /model to browse, /model anthropic to filter by provider, or /model anthropic/opus (also opus anthropic) for case-insensitive fuzzy matching across provider/model identifiers. /model DeepSeek, /model Deepseek and /model deepseek show matching models across all authenticated providers, with provider/model labels kept distinct. Search results require a numbered selection even when only one matches; an exact provider/model still selects directly. Previous/next pages retain the search. Only currently authenticated models are offered; no match leaves the current model unchanged. Private filesystem identifiers stay redacted and are reachable through browsing, not fuzzy search.

Menus use numbered replies. Group selections must quote the menu. Native polls are experimental and require --whatsapp-ng-native-polls. Configuration changes require idle Pi; stop active work explicitly rather than interrupting it through a settings change.

LLM-Callable Tools

The extension registers these tools for Pi's agent:

Tool Direction Description
send_wa_message Outbound Send text to a contact/group, optionally quoting a retained message. Omit jid only when the current turn has one owning conversation; idle manual calls retain the last-conversation/operator fallback.
send_wa_media Outbound Explicitly send a local document, image, audio file, voice note or video, with optional caption and native quote. Uses the same recipient-ownership rules as text.
send_reaction Outbound React to an unambiguous retained message. Optional fromMe and participant fields disambiguate its key; compound emoji are supported.
list_wa_conversations Read-only List local recent conversations. Supports onlyIncoming, onlyAllowed, limit and local scope; returns available scope IDs.
get_wa_conversation_history Read-only Read messages for senderNumber (+E164, raw phone digits or a JID). Supports limit, local scope and opaque cursor / nextCursor pagination.
check_wa_new_messages Read-only List conversations whose latest message is incoming. Supports sinceTimestamp (milliseconds since epoch) and local scope.
request_wa_history Network request / local status {mode:"request",jid,count?} explicitly requests up to 100 older messages for an allowed connected chat; {mode:"status",requestId?} reads retained request status locally.
configure_wa_stt Guarded configuration Owner/local-only: set or update sttEndpoint, sttModel, sttEnv and optional sttLanguage. Pass the key's environment-variable name, never its value; {} selects local transcription.
configure_wa_tts Guarded configuration Update speech backend settings for an authorized local/owner request. Does not grant consent, enable speech or synthesize immediately.

File uploads must be explicit, at most 25 MiB, and under the current workspace or extension media directory. Mentioning a file path does not upload it. Native quotes require a retained, unambiguous message in the same chat.

The three read-only inbox tools use the selected local archive under ~/.pi/agent/extensions/whatsapp-ng/archive/. They work offline, never fetch network history and do not mark messages as read. The list/history tools default to, and cap at, 20 items; check_wa_new_messages returns all matching conversations. Only an explicit request_wa_history request fetches older messages; availability depends on WhatsApp and the linked devices.

Data and privacy

Settings, login, history and downloaded media live under ~/.pi/agent/extensions/whatsapp-ng/. Recents remain readable offline. Archive retention is bounded to 1,000 messages per conversation, 30 days and 100 MiB per account partition; it does not erase Pi transcripts, logs or downloaded media.

  • Allowed chats share model context; routing is not privacy isolation.
  • Images may reach Pi's vision model. Remote transcription and speech send content to the selected service.
  • A successful send means API acceptance, not proof of delivery or reading. An unknown outcome may still arrive; do not automatically resend it.
  • Connection → Turn WhatsApp off (or /off) keeps your login. Advanced → Logoff (Delete Session) resets the current authentication profile. Do not delete login or history to resolve a lock.
  • This uses an unofficial WhatsApp transport. Protocol changes or account policies can disrupt it.

See the operating reference for migration, recovery, media formats, history and diagnostics. Security reports must not include credentials or private conversation dumps.

Development

The development baseline is Node 26.x and Pi 1.4.0.

git clone https://github.com/jagaliano/whatsapp-ng.git
cd whatsapp-ng
npm ci --ignore-scripts --legacy-peer-deps --no-audit --no-fund
npm test
npm run lint
npm run typecheck
pi --no-extensions -e ./whatsapp-ng.ts

Maintainers can use the release guide for explicit local version bumps, validated tarball preparation and separately confirmed publication. PR/main CI and a default-off, environment-gated tag-triggered OIDC workflow are provided; npm requires a first manual package publication before trusted publishing can be configured. RC1 is published; the working version is 1.1.0-rc.2. Preparing a candidate does not bump or publish it.

Use a disposable HOME/Pi agent directory and credential-free environment for validation; the isolated setup in scripts/release.mjs is the reference. A deliberate source launch with your normal HOME shares saved settings/auth and may auto-connect. Do not run a second same-profile owner.

System tools must be installed separately. Add --verbose for extension diagnostics, not message bodies or protocol-key traces. See dependencies and platform checks, the source-only manual acceptance guide, and design records. Package search is not exact availability: see discovery checks.

Support and license

Report bugs through GitHub issues. See the changelog and MIT license.

Based on Rapha Castelloes' original project, maintained by José Antonio Galiano Sandoval. Older names and paths are listed in the migration reference.

Original license evidence refers to the upstream npm package at 1.0.70 and the advisory upstream notice inquiry; no new upstream response is claimed.

The local speech overview is adapted from CrispStrobe/CrispASR and its contributors' documentation; see the guide's credits and upstream references.