AI-powered daily message sender for WhatsApp, powered by OpenWA
Send a daily heartfelt message to someone you care about — automatically generated by AI, delivered via WhatsApp. Set it up once, and waify handles the rest.
- Docker (for the WhatsApp API server)
- Node.js 22+
- A Google Gemini API key — get one free
- A WhatsApp account on your phone
npm install -g @deckasoft/waify
waify setup # guided wizard: starts OpenWA, scans QR, configures everything
waify send # send your first message| Command | Description |
|---|---|
waify setup |
First-run wizard — starts Docker services, links WhatsApp, configures AI, recipient, and schedule |
waify send |
Generate a message with Gemini and send it via WhatsApp |
waify preview |
Preview generated messages without sending (-n 3 for multiple candidates) |
waify tui |
Launch the interactive terminal UI (tabs: Home, History, Settings, Prompt, Schedule) |
waify history |
View sent message log (--tail 20, --grep "pattern") |
waify config list |
Show current configuration |
waify config get <key> |
Get a single config value |
waify config set <key> <value> |
Update a config value |
waify prompt show |
Show the current AI system prompt and examples |
waify prompt edit |
Open the prompt in $EDITOR |
waify prompt add-example <text> |
Add a few-shot example to the prompt |
waify schedule list |
List scheduled jobs |
waify schedule add <name> <cron> |
Add a 6-field cron job (e.g. "0 0 9 * * *" — sec min hour dom month dow) |
waify schedule remove <name> |
Remove a scheduled job |
All config files live in ~/.config/waify/:
| File | Contents |
|---|---|
config.json |
OpenWA URL, session ID, recipient, message language, timezone |
prompt.json |
AI system prompt + few-shot examples |
schedule.json |
Scheduled send jobs (6-field cron) |
.env |
API keys (Gemini, OpenWA) |
docker-compose.yml |
Generated by waify setup |
Dockerfile / ofelia.ini |
Generated by waify setup — sender image + scheduler config |
messages.log |
Send history |
The OpenWA API key (
OPENWA_API_KEY) is generated by the OpenWA server (random, per install) and auto-captured bywaify setupfrom the container's/app/data/.api-key. There's no fixed default to set by hand — only the Gemini key is yours to supply.
Environment variable overrides:
| Variable | Default | Description |
|---|---|---|
WAIFY_DATA_DIR |
~/.config/waify |
Override config directory |
WAIFY_ENV_PATH |
~/.config/waify/.env |
Override .env file path |
Scheduling runs on an Ofelia scheduler container that fires a transient sender container per job tick. waify setup generates the Dockerfile, builds the openwa-scripts-sender:latest image locally, and starts the scheduler — so scheduling works out of the box after setup.
In waify setup and the TUI you pick a time + frequency (Daily / Weekdays / Weekends / Custom days) and a timezone from a list — the cron is generated for you and evaluated in your local timezone. The CLI waify schedule add still takes a raw 6-field cron (sec min hour dom month dow) for power users. Changes restart the scheduler automatically; to restart manually:
waify schedule add morning "0 0 9 * * *"
docker compose -f ~/.config/waify/docker-compose.yml restart schedulerYou also choose the message language in setup and the TUI Settings tab; messages are generated in that language while reusing the example tone.
waify uses OpenWA as its WhatsApp API server. OpenWA runs locally in Docker and exposes a REST API that waify uses to send messages. All your WhatsApp data stays on your machine.
- Multi-recipient support (schema already supports arrays — currently capped at 1)
- Additional AI providers (OpenAI, Anthropic, Ollama) via the
AIProviderinterface - Additional transport adapters (Telegram, SMS)
- NX monorepo with the deckasoft/openwa fork
Contributions are welcome! See CONTRIBUTING.md for local setup, the branch/PR workflow, and our commit conventions — note that PR titles must be Conventional Commits, since they drive the automated release. Please also read our Code of Conduct. For security issues, see SECURITY.md — do not open a public issue.
MIT — see LICENSE