Bot Telegram bán tài khoản số (digital accounts) chạy trên Cloudflare Workers, nạp tiền tự động qua SePay + VietQR, giao hàng tức thì, kèm Telegram Mini App cho người mua và CMS Vue 3 cho quản trị.
Toàn bộ hệ thống (bot + API + CMS + database + cron) gói gọn trong một Cloudflare Worker duy nhất, chạy được trên free tier.
# Clone repo git clone <repo-url> cd telegram-bot-shop-acc-cloudflare-d1 # Cài dependencies backend npm install # Cài dependencies CMS cd cms && npm install && cd .. # Cài dependencies Mini App cd miniapp && npm install && cd ..
Mẹo:
npm run build:miniapptự chạynpm --prefix miniapp installtrước khi build nên có thể bỏ qua bước cài thủ công cho Mini App.
/newbot → đặt tên → nhận BOT_TOKEN/setcommands → chọn bot → nhập:
start - Trang chủ
admin - Quản trị (chỉ admin)
huy - Huỷ thao tác hiện tại
# Tạo database trên Cloudflare npx wrangler d1 create telegram-shop-bot-db
Copy database_id từ output và thay vào wrangler.toml:
[[d1_databases]] binding = "DB" database_name = "telegram-shop-bot-db" database_id = "YOUR_ACTUAL_DATABASE_ID" # ← thay ở đây
.dev.vars)
# Copy file mẫu cp .dev.vars.example .dev.vars # Mở .dev.vars và điền giá trị thật cho từng biến
Nội dung .dev.vars:
BOT_TOKEN=your_telegram_bot_token
TELEGRAM_SECRET_TOKEN=your_telegram_secret_token
SEPAY_API_KEY=your_sepay_api_key
ADMIN_IDS=123456789,987654321
JWT_SECRET=your_jwt_secret_at_least_32_chars
BANK_NAME=Vietcombank
BANK_ACCOUNT=1017588888
BANK_OWNER=NGUYEN VAN A
.dev.varsđã được.gitignore— không commit token thật lên repo.
wrangler secret)
npx wrangler secret put BOT_TOKEN # Telegram Bot Token npx wrangler secret put TELEGRAM_SECRET_TOKEN # Chuỗi ngẫu nhiên verify webhook Telegram npx wrangler secret put SEPAY_API_KEY # API Key từ my.sepay.vn → Webhook npx wrangler secret put ADMIN_IDS # Telegram IDs admin (cách nhau dấu phẩy) npx wrangler secret put JWT_SECRET # Chuỗi ngẫu nhiên ≥ 32 ký tự cho CMS npx wrangler secret put BANK_NAME # Tên ngân hàng nhận tiền npx wrangler secret put BANK_ACCOUNT # Số tài khoản npx wrangler secret put BANK_OWNER # Tên chủ tài khoản
Phần lớn cấu hình vận hành có thể chỉnh trực tiếp trong CMS (lưu vào bảng system_config) mà không cần redeploy hay đặt lại secret. Lúc chạy, hệ thống resolve theo thứ tự DB trước, env sau: nếu key trong system_config có giá trị (non-empty) thì dùng giá trị đó, ngược lại fallback về secret/var của Worker.
Key trong CMS (system_config) | Env fallback | Dùng cho |
|---|---|---|
bot_token | BOT_TOKEN | Gửi tin nhắn bot, xác thực initData Mini App |
telegram_secret_token | TELEGRAM_SECRET_TOKEN | Xác thực webhook Telegram |
admin_ids | ADMIN_IDS | Phân quyền admin trong bot (/admin) |
sepay_api_key | SEPAY_API_KEY | Xác thực webhook SePay |
bank_name / bank_account / bank_owner | BANK_NAME / BANK_ACCOUNT / BANK_OWNER | Thông tin nhận tiền (VietQR + caption CK) |
min_deposit / max_deposit | (seed mặc định trong DB) | Hạn mức nạp — áp dụng cho cả tạo yêu cầu nạp lẫn webhook SePay khi cộng tiền |
Hệ quả:
wrangler secret put cho các key trên — chỉ cần vào CMS → Cấu hình điền giá trị rồi Lưu (vẫn nên giữ JWT_SECRET ở secret vì dùng cho đăng nhập CMS).system_config trống nhưng env có giá trị, form tự điền sẵn giá trị env để admin xem/sửa; bấm Lưu sẽ ghi (promote) vào DB.telegram_secret_token trong CMS thì phải set lại Telegram webhook với secret_token mới cho khớp (xem mục 9).
Migration nằm trong migrations/, chạy theo thứ tự:
| File | Mô tả |
|---|---|
0001_initial_schema.sql | Toàn bộ bảng + index + dữ liệu config mặc định |
0002_add_success_template.sql | Thêm cột success_template cho product_types |
0003_remove_broadcast_config.sql | Gỡ config broadcast_enabled (bỏ tính năng broadcast) |
0004_add_user_ban.sql | Thêm banned_at cho users (tính năng khoá tài khoản; dùng is_active làm cờ ban) |
0005_add_sepay_api_key_config.sql | Thêm key sepay_api_key vào system_config (cấu hình SePay API key qua CMS) |
0006_add_telegram_config.sql | Thêm key bot_token, telegram_secret_token, admin_ids vào system_config (cấu hình Telegram qua CMS) |
# Local (cho development) npm run db:migrate:local # Remote (production) npm run db:migrate:remote
Khi nâng cấp DB đã có sẵn, chỉ cần chạy lại lệnh trên — Wrangler tự áp các migration chưa chạy.
Sau khi migrate, tạo admin user cho CMS.
Bước 1 — Tạo file test/hash_password.js để sinh hash bcrypt (dự án dùng ESM):
// test/hash_password.js
import bcrypt from 'bcryptjs'
const password = process.argv[2]
if (!password) {
console.error('Usage: node test/hash_password.js <password>')
process.exit(1)
}
const hash = await bcrypt.hash(password, 10)
console.log(hash)Bước 2 — Sinh hash:
node test/hash_password.js YOUR_PASSWORD
Bước 3 — Insert admin vào D1:
# Local
npx wrangler d1 execute telegram-shop-bot-db --local \
--command="INSERT INTO admin_users (username, password_hash, display_name) VALUES ('admin', 'PASTE_HASH_HERE', 'Admin')"
# Remote
npx wrangler d1 execute telegram-shop-bot-db --remote \
--command="INSERT INTO admin_users (username, password_hash, display_name) VALUES ('admin', 'PASTE_HASH_HERE', 'Admin')"
# Chạy Worker locally (port 8787) npm run dev # Trong terminal khác, chạy CMS dev server (port 5173, proxy API sang 8787) cd cms && npm run dev # Hoặc chạy Mini App dev server (proxy /api/app sang 8787) cd miniapp && npm run dev
Truy cập:
Mini App cần chạy trong Telegram để có
initDatathật; mở trực tiếp trên trình duyệt sẽ hiện màn "Mở lại từ Telegram" (API trả 401 vì thiếu initData hợp lệ).
# Build riêng nếu cần npm run build:cms # CMS → dist/cms/ npm run build:miniapp # Mini App → dist/miniapp/ npm run build:all # Build cả hai # Deploy: tự build cả CMS + Mini App (hook predeploy) rồi đẩy Worker lên Cloudflare npm run deploy
npm run deploycó hookpredeploy = build:allnên tự build cả CMS lẫn Mini App trước khiwrangler deploy— không cần build thủ công trước.wrangler.tomldùng[site] bucket = "./dist", KV key theo thư mục con:cms/...phục vụ tại/cms/*,miniapp/...phục vụ tại/app/*. Lưu ý: nếu gọi thẳngnpx wrangler deploy(bỏ qua npm) thì KHÔNG có predeploy → phải tựnpm run build:alltrước.
# Thay YOUR_BOT_TOKEN, YOUR_WORKER_URL, YOUR_TELEGRAM_SECRET_TOKEN
curl -X POST "https://api.telegram.org/botYOUR_BOT_TOKEN/setWebhook" \
-H "Content-Type: application/json" \
-d '{
"url": "https://YOUR_WORKER_URL/webhook/telegram",
"secret_token": "YOUR_TELEGRAM_SECRET_TOKEN"
}'
https://YOUR_WORKER_URL/webhook/sepaySEPAY_API_KEY (Worker yêu cầu header Authorization: Apikey <key>)Key này có thể đặt ở secret
SEPAY_API_KEYhoặc trong CMS → Cấu hình → SePay (system_config.sepay_api_key, ưu tiên DB). Mã chuyển khoảnNAP…được nhận diện từ trườngcodecủa SePay trước, nếu không có thì dò trongcontent.
npm test # Chạy tất cả tests npm run test:watch # Watch mode
test/e2e_full_flow.sh chạy 17 test case end-to-end qua HTTP thật (webhook Telegram/SePay + admin API + D1 local): nạp tiền, mua hàng, mua khi hết tiền, race condition spam mua nhiều thiết bị, idempotency webhook, duyệt tay, auth, bảo toàn sổ cái. Kết quả xuất ra docs/E2E_REPORT.md.
# Terminal 1: chạy Worker local npm run dev # Terminal 2: chạy E2E (in tiến trình realtime từng test case) bash test/e2e_full_flow.sh
Nguồn : 6c696e68
Tổng có 0 đánh giá