Getting Started
Chat with your local bot in a browser tab. No Meta account, no phone number, no tunnel.
Getting a WhatsApp Business account approved takes time you probably do not want to spend before your first commit. The mock interface is a small web app that looks like WhatsApp and talks to your local API instead of Meta.
Two pieces, wired in opposite directions.
POST /devhooks on your API. That endpoint exists only when MOCK_WHATSAPP is on.messages table, and the mock app polls that table directly every two seconds.That is why the mock app needs your database URL as well as your API URL. It is a reader of Twiga's own database, not a WhatsApp emulator.
.env:MOCK_WHATSAPP=TrueThen restart the API. Settings are read once at import, so an edit without a restart does nothing. You should see Starting with mock whatsapp enabled in the logs.git clone https://github.com/Tanzania-AI-Community/mock-whatsapp.git
cd mock-whatsapp
pnpm installIt is a Next.js app and needs Node 18 or newer..env in the mock repository:DATABASE_URL=postgresql://postgres:your_password@localhost:5432/twiga_db
CHATBOT_CALLBACK_URL=http://0.0.0.0:8000/devhooksNote the differences from Twiga's own .env: the host is localhost, because this app runs outside Docker, and the callback path is /devhooks, not /webhooks.pnpm run devOpen http://localhost:3000 and send a message.The README in the mock repo has a stale URL
It shows a placeholder callback ofhttp://localhost:3001/api/webhook, which is not a Twiga endpoint. Use the value above, which matches the .example.env in that repository and the route in app/main.py.When an unknown number messages Twiga outside production, the app skips onboarding and creates a ready-made user: an active teacher who teaches Geography, Form 2. This is keyed on ENVIRONMENT, not on the mock flag.
That dummy user depends on the Geography class existing, which is what make generate-local-data creates. If you skipped seeding, your first message fails.
Worth knowing before you file a bug against something that is not broken.
| Not available | Why |
|---|---|
| WhatsApp Flows | Flow messages are no-ops, so onboarding and the settings menu options dead-end. |
| Images and PDFs | Exam and LaTeX delivery report success but send nothing. Rendered images are written to local disk instead. |
| Template messages | Approval and reminder templates cannot be exercised. |
| Buttons and list replies | The mock only sends plain text. To test interactive replies, post JSON to /devhooks yourself. |
| Multiple users | Every message is sent as the same number, and the view is not filtered by user, so all conversations appear in one thread. |
| Rate limiting | Redis only starts in production and staging. |
| Signature verification | Skipped entirely in mock mode, so a broken HMAC implementation will not show up here. |
The interface also hides some rows on purpose. It shows only user and assistant messages that are marked as visible, so it is a view of the conversation, not a debugger for the model transcript. Read the messages table directly for that.
Never enable this in a deployment
MOCK_WHATSAPP=True does more than redirect traffic. It disables signature verification on /webhooks and /flows as well, and it opens /devhooks, which has no authentication of any kind. Anyone who can reach the service could send messages as any user. Both .env templates ship with the flag on, so check it before you deploy.