This project tracks caretaker/tenant readings, generates invoices, and uses a dedicated WhatsApp bot to deliver invoices and reconcile payment proofs through Twilio.
- API service (
server/) – handles tenant/caretaker CRUD, utility readings, invoice PDF generation, and notifies the bot service when an invoice is ready. - WhatsApp bot (
bot/) – consumes/api/whatsapp/invoicecalls to push messages through Twilio, processes incoming WhatsApp webhooks, and records payment proofs into the same database. - Twilio – powers outbound WhatsApp notifications and receives inbound messages. Environment variables described below let the bot authenticate with Twilio, download media assets, and post responses.
npm install(the project currently uses Node.js modules with"type": "module").- Point the
.env(or.env.example) file at your database host and Twilio credentials. - Run the API, the bot, and MySQL. For local development, start both Node services side-by-side or use
docker compose up(the compose file wiresapi→bot→db).
Create an .env file (or copy .env.example) and set these values before running anything:
| Variable | Description |
|---|---|
PORT |
API port (default 3003). |
BOT_PORT |
WhatsApp bot port (default 3004). |
MYSQL_* |
Standard MySQL connection details used by both services. |
MAX_UPLOAD_BYTES |
PDF upload limit. |
DEFAULT_RENT_AMOUNT |
Fallback rent amount for tenants. |
PUBLIC_BASE_URL |
Public hostname that hosts the API (used when generating invoice URLs and for Twilio callbacks). |
BOT_SERVICE_URL |
URL the API uses when notifying the bot (set to http://bot:3004 in Docker, otherwise http://localhost:3004). |
TWILIO_ACCOUNT_SID |
Your Twilio Account SID. |
TWILIO_AUTH_TOKEN |
Your Twilio Auth Token. |
TWILIO_WHATSAPP_NUMBER |
The WhatsApp-enabled Twilio number, e.g. whatsapp:+14155238886 (sandbox) or your own purchased number. |
TWILIO_WHATSAPP_NUMBERmust include thewhatsapp:prefix.- The bot downloads Twilio media with HTTP Basic auth using the
TWILIO_ACCOUNT_SID:TWILIO_AUTH_TOKENpair, so these values must be valid whenever the bot runs. PUBLIC_BASE_URLneeds to be reachable from Twilio (usengrokfor local testing).
node server/index.js– starts the API and uploads/invoice handling.node bot/index.js– starts the WhatsApp bot and wire up Twilio webhooks.- Use the web dashboard or
scripts/mock-flow.jsto exercise the endpoints. The main browser UI lives at the root (/) and the statement audit workspace lives at/statement-audit. The legacy/bot-test-uipath still 301-redirects to/.
Run docker compose up --build to start api, bot, and db. The environment variables live in .env; Docker maps ./uploads so generated PDFs survive restarts.
During development, the compose stack is hot-reloadable: the repository is bind-mounted into the api and bot containers, and both services run with Node watch mode. Saving changes under server/, bot/, lib/, frontend/, or scripts/ should trigger an automatic restart inside Docker.
- Join the WhatsApp sandbox (or request a dedicated Twilio WhatsApp number).
- Sign into https://www.twilio.com/console/whatsapp/sandbox and follow the instructions to link your phone. The sandbox number is usually
whatsapp:+14155238886. - Copy the sandbox number into
TWILIO_WHATSAPP_NUMBERand the Account SID/Auth Token into.env.
- Sign into https://www.twilio.com/console/whatsapp/sandbox and follow the instructions to link your phone. The sandbox number is usually
- Configure Twilio webhooks:
- Set the Messaging webhook (“When a message comes in”) to
https://<PUBLIC_BASE_URL>/webhooks/whatsapp/payment. - If you need to handle media, Twilio will request
MEDIA_URLusing the same auth, so make sure the bot is online and the credentials match.
- Set the Messaging webhook (“When a message comes in”) to
- Beta testing (sandbox):
- Generate an invoice (via the playground, API, or
scripts/mock-flow.js). The API calls/api/whatsapp/invoice, which in turn asks Twilio to deliver the PDF. - Send a WhatsApp message from your sandbox-joined phone to the Twilio number (e.g.,
INV-xxx paid 1200). Confirm the bot replies and persists the payment record inpayments. - Use the bot playground to post to
/webhooks/whatsapp/paymentor/api/whatsapp/invoiceif you need to mock Twilio.
- Generate an invoice (via the playground, API, or
- Production go-live:
- Request access to the Twilio WhatsApp Business API (https://www.twilio.com/whatsapp). Twilio will give you a dedicated
whatsapp:+number. - Update
TWILIO_WHATSAPP_NUMBERto the new value, keepTWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKENup to date, and point Twilio’s webhook athttps://<PRODUCTION_PUBLIC_BASE_URL>/webhooks/whatsapp/payment. - Make sure
PUBLIC_BASE_URLuses HTTPS and that both API and bot services are reachable from Twilio. - Optionally configure
BOT_SERVICE_URLto the DNS name of your bot service, and adjustBOT_PORTif it changes.
- Request access to the Twilio WhatsApp Business API (https://www.twilio.com/whatsapp). Twilio will give you a dedicated
npm testruns the WhatsApp helper unit tests.npm run mockexercises a full flow (caretaker → tenant → invoice → webhook) against whatever API/BOT bases are configured throughAPI_BASE_URL/BOT_BASE_URL.- The frontend in
frontend/now provides a fuller operations dashboard for local development:- register landlords, caretakers, tenants, and properties
- add bills/invoices and send them through the WhatsApp flow
- filter bills by paid/unpaid state
- upload statement PDFs from the browser and keep source PDFs available for audit
- confirm payments manually and trigger tenant thank-you messages through the bot
- The bot service persists every webhook in the
whatsapp_webhookstable and exposes them viaGET /api/whatsapp/webhooksso you can review tenants’ raw payloads and delivery timestamps.
- Open
http://localhost:3003/for the main dashboard (legacy/bot-test-uiredirects here). - Pick a role at login (
landlordorcaretaker) so the home screen shows only the relevant action tiles. - Landlords land on tiles for people, property, statements, and unpaid review; they can also add unit numbers in bulk when creating a property.
- Caretakers land on tiles for bills, people, statements, and unpaid review, but people registration is restricted to allowed options only.
- The top bar shows role-scoped summary totals for properties, tenants, bills, paid amounts, and outstanding balances.
- This project is currently in active dev mode. If you change the schema and want a clean start, it is acceptable to recreate the local database/volume instead of carrying migrations.
- The bootstrap schema in
docker-entrypoint-initdb.d/init.sqlnow includes landlords, properties, tenant unit labels, and WhatsApp webhook storage.
- Repository agents and contributors must update
history.mdwhenever they make source-code changes. See AGENTS.md for the required workflow and commit-style format.
- Acquire a custom domain and ensure
PUBLIC_BASE_URLpoints to it. - Lock down your Twilio credentials and avoid checking them into git (use secrets manager or environment injection).
- Monitor
botlogs for Twilio errors (e.g., authentication, media download failures). - Consider adding health/end-to-end alerts around
/api/whatsapp/invoiceand the payment webhook to catch regressions early.
