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.