# Chowdeck Ghana — WhatsApp win-back
Sends approved WhatsApp template messages to churned Ghana customers,
receives their replies, and routes each conversation to the staff member who
originally called that customer.
One repository, two halves:
- **`backend/`** — Node/Express API and Postgres. Also serves the interface.
- **`frontend/`** — React interface, built by Vite.
---
## Running it
You need Docker. Nothing else — Node, Postgres and ffmpeg all live inside the
containers.
```bash
git clone
cd platform
cp env.example .env
```
Then open `.env` and fill in five values. The file explains each one; the
short version:
| | |
|---|---|
| `JWT_SECRET` | any 32+ random characters — the file shows a command to generate one |
| `WA_ACCESS_TOKEN` | Meta system user token |
| `WA_PHONE_NUMBER_ID` | the sender's ID — **not** the phone number, **not** the WABA ID |
| `WA_VERIFY_TOKEN` | any string you invent; the same value goes in Meta's webhook form |
| `WA_TEMPLATE_LANG` | `en` — the language the templates are approved under |
Then:
```bash
docker compose up --build
```
Open .
Create the first account:
```bash
docker compose exec api npm run seed -- "Your Name" you@chowdeck.com a-password
```
## Checking it works
```bash
curl localhost:3001/health # {"ok":true,"database":"connected"}
docker compose exec api npm test # 242 integration tests, against a mock Meta
```
The tests do not touch the real WhatsApp API and cost nothing to run.
## Receiving replies
Replies arrive by webhook, so Meta needs a public address to reach. Locally
that means a tunnel:
```bash
ngrok http 3001
```
Then in the Meta app under WhatsApp → Configuration:
- Callback URL: `https:// /webhook`
- Verify token: whatever you set `WA_VERIFY_TOKEN` to
- Subscribe to the `messages` field
The startup log prints the tunnel address it detected, so you can check it
matches.
**A free tunnel gets a new address every restart**, and Meta drops undelivered
events after a few hours. …