Open-Source Cold Email & Warmup Platform
Warmbly 是開源的冷郵件平台:溫暖您的收件箱、發送活動、並對每個回覆進行分流。可在我們的雲端運行或自行託管整個系統。
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Turn walk-ins into regulars. A simple loyalty program for neighbourhood shops: a stamp card on the customer's phone number — every few visits, a free reward. Live at www.regularhood.in (formerly Habiturn, at habiturn.sidhar.me, which now redirects there).
server/data/loyalty.db, Node's built-in node:sqlite)A digital stamp card: every N visits → one reward (e.g. every 5 visits → free chai). A customer is just a phone number — no names, QR codes, points, PINs or sign-up.
/w/<link>: their stamps, what's left to the reward and their visits; English / हिंदी, no app
or login. Old counter-poster QRs (/join/<code>) show the shop's rule; old bill QR and PIN login links explain
there's nothing to scan any moreShops from before the stamp card keep their customers: each customer's past bills became stamps (up to one short of the reward, so their next visit earns it), and the shop's cheapest reward became its one reward.
/admin is the platform owner's panel: every shop's health (active / sleeping / new / never started / paused), a
"needs a call" list of shops that went quiet or never set up their card, and per-shop numbers (their card rule,
customers, visits and rewards given, customers who came back, rewards waiting). Support actions: a one-time password
reset link (24 hours), pausing a shop (no logins or new visits — customers' cards still open) and notes. Every admin action is in the admin log. Admins see counts and
totals only, never customers' names or phone numbers.
Admins are created only on the server — never from the website:
npm run create-admin -w server -- [email protected]
It asks for the password (hidden, at least 12 characters). Run it again to set a new password.
Needs Node.js 22.16 or newer.
One command (or double-click start.bat on Windows):
npm install # first time only
npm start
Open http://localhost:4000. npm start builds the website and API and runs them as one server on port 4000.
While changing code (live reload):
npm run dev
Also open http://localhost:4000 — the website dev server forwards /api to the API on port 4001.
Putting it online: see DEPLOY.md (VPS with Docker + automatic HTTPS, or Railway). The database is copied
to data/backups once a day (last 14 kept). Behind a proxy, set TRUST_PROXY=1.
Set JWT_SECRET in production (otherwise one is generated into server/data/), and optionally PORT and DB_FILE. Back up server/data/ — it is the whole database.
All routes except signup/login need Authorization: Bearer <token>.
| Method | Path | |
|---|---|---|
| POST | /api/auth/signup | { name, email, password } → { token, merchant } |
| POST | /api/auth/login | { email, password } → { token, merchant } |
| GET / PATCH | /api/me | shop details / update { name, phone, visitsNeeded, rewardName, inactiveDays } |
| POST | /api/visits | { phone, tz } → one visit (once a day per number); { already, isNew, visitId, customer } |
| POST | /api/customers/:id/reward | the shop handed over the reward; the card starts again |
| POST | /api/transactions/:id/undo | take back one visit or reward |
| GET | /api/today?tz=330 | today's visits and rewards |
| GET | /api/customers | list (?q= search, ?filter=reward or inactive) |
| GET | /api/customers/suggest?digits= | known numbers starting with these digits (4+) |
| GET / PATCH / DELETE | /api/customers/:id | customer with visit history / change number { phone } / delete with history |
| GET | /api/share | customers and referrals, for the share image |
| GET | /api/activity?limit=200 | activity log |
| GET | /api/export/customers.csv, /api/export/transactions.csv | spreadsheet downloads |
| GET | /api/public/wallet/:token | the customer's stamp card (no login) |
| GET | /api/public/wallet/:token/manifest | per-card app manifest for "Add to Home Screen" |
| GET | /api/public/join/:code | the shop's rule, for old counter-poster QR codes (no login) |
The database schema upgrades itself on start (PRAGMA user_version), keeping existing data.