Warning
For educational purposes only. This project uses the unofficial WhatsApp multi-device protocol via whatsmeow. Running automated bots on a personal WhatsApp account violates WhatsApp's Terms of Service and risks having your account permanently banned.
Do not use this in production or at any scale.
If you need a production-grade WhatsApp integration, use the official WhatsApp Business Platform (Cloud API) provided by Meta.
A microservices-based WhatsApp bot that transcribes voice messages and audio files, with optional AI-powered responses via Groq.
- Features
- Technologies Used
- Setup
- Usage
- Configuration
- Testing
- API Endpoint
- Contributing
- Acknowledgements
- Transcribes WhatsApp voice notes and regular audio files
- Two trigger modes — transcribe-only, or transcribe and send to Groq for an AI response
- Early validation: replies with a usage hint if the quoted message is not audio
- Configurable transcription server URL and message prefix
- No GCC required — uses a pure-Go SQLite driver (
modernc.org/sqlite)
- Go
- Python
- FastAPI + Uvicorn
- SQLite (via
modernc.org/sqlite- no CGO) - whatsmeow — unofficial WhatsApp multi-device library
- Faster-Whisper — local speech recognition
- Groq API — fast LLM inference
![]() |
![]() |
|---|
- Go 1.25+
- Python 3.x with uv
- A Groq API key from console.groq.com/keys
Note
GCC is no longer required. The project switched from mattn/go-sqlite3
(CGO) to modernc.org/sqlite (pure Go), so it builds on any platform
without a C compiler.
Copy sample.env to .env and fill in your values:
GROQ_API_KEY=your_key_here
TRANSCRIBE_URL=http://<flask-server-ip>:5000/transcribe| Variable | Required | Description |
|---|---|---|
GROQ_API_KEY |
For 1> transcribe |
Groq API key for AI responses |
TRANSCRIBE_URL |
No | Transcription server URL. Defaults to http://127.0.0.1:5000/transcribe |
The easiest way to run both services together. Only GROQ_API_KEY needs to
be set — TRANSCRIBE_URL is wired automatically via Docker's internal network.
-
Copy
sample.envto.envand add your Groq API key:GROQ_API_KEY=your_key_here
-
Build and start both services:
docker compose up --build
The first build downloads the
medium.enWhisper model (~1.5 GB) and bakes it into the image. Subsequent starts are instant. -
On first run, scan the QR code printed in the terminal to log into WhatsApp.
If running detached (
-d), view the QR code with:docker compose logs -f bot
The WhatsApp session is stored in a named Docker volume (whatsapp_session) so
you only need to scan the QR code once. The transcription API docs are available
at http://localhost:8000/docs.
Install dependencies:
go mod tidyBuild the binary:
# Linux / macOS
go build -o whatsapp-bot .
# Windows
go build -o whatsapp-bot.exe .Note
Use go build rather than go run. On some platforms (e.g. Windows with
Application Control policies), go run compiles to a temp directory that
may be blocked from executing.
Install dependencies via uv:
uv sync-
Start the transcription server:
uv run main.py
If the bot runs on a different machine, note the server's IP address and set it as
TRANSCRIBE_URLin your.env. -
Start the bot:
# Linux / macOS ./whatsapp-bot # Windows .\whatsapp-bot.exe
-
On first run, scan the QR code displayed in the terminal to log into WhatsApp.
-
Reply to a voice note or audio file with one of the trigger commands below.
| Command | Behaviour |
|---|---|
1> transcribe |
Transcribe the audio, then send the transcript to Groq for an AI response |
2> transcribe |
Transcribe the audio only. No AI response sent |
The trigger can appear anywhere in the message (e.g. can you 1> transcribe this?).
If you reply to a message that is not a voice note or audio file, the bot will send a hint explaining what to do instead.
./whatsapp-bot --message-head "Transcript: "--message-head sets the text prepended to every transcription reply.
Defaults to *Transcript:*\n> (bold label with a block-quote indent).
| Setting | How to change |
|---|---|
| Transcription server URL | Set TRANSCRIBE_URL in .env |
| Groq AI model | Edit the Model field in groq/groq.go |
| Whisper model size | Edit model_name in main.py (default: medium.en) |
| Transcription reply prefix | Pass --message-head flag at startup |
Run the full test suite:
go test ./...For verbose output:
go test ./... -v18 tests are included across two packages:
| Test | Package | Cases |
|---|---|---|
TestParseTrigger |
main |
9 - trigger command parsing edge cases |
TestGetTranscription |
main |
4 - HTTP client against a local test server |
TestHtmlToWhatsAppFormat |
groq |
10 - HTML-to-WhatsApp text conversion |
TestSendPostRequestGroq |
groq |
4 - Groq API client against a local test server |
All tests run without network access or external services.
The transcription service exposes a single endpoint:
POST /transcribe
- Request body: raw binary audio data (
application/octet-stream) - Response: JSON object
{
"transcription": "the transcribed text",
"language": "en"
}- Create a new issue
- Fork the repository
- Create a new branch
- Commit your changes
- Push to the branch
- Create a new Pull Request

