Mã nguồn miễn phí được cung cấp dưới dạng hiện trạng (AS IS), không kèm theo bất kỳ hình thức hỗ trợ, bảo hành hay cam kết kỹ thuật nào từ phía chúng tôi. Mã nguồn chỉ phục vụ mục đích tham khảo, học tập và nghiên cứu. Người sử dụng tự chịu trách nhiệm đối với việc triển khai, chỉnh sửa và sử dụng mã nguồn. Chúng tôi không chịu trách nhiệm đối với bất kỳ thiệt hại, rủi ro, tranh chấp hoặc vấn đề pháp lý nào phát sinh từ việc sử dụng mã nguồn này.
Hướng dẫn cài đặt
Telegram Shop Bot
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.
1. Cài đặt
# Clone repo
git clone
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:miniapp tự chạy npm --prefix miniapp install trước khi build nên có thể bỏ qua bước cài thủ công cho Mini App.
2. Tạo Telegram Bot
Mở Telegram, chat với @BotFather
Gửi /newbot → đặt tên → nhận BOT_TOKEN
Gửi /setcommands → chọn bot → nhập:
start - Trang chủ
admin - Quản trị (chỉ admin)
huy - Huỷ thao tác hiện tại
3. Tạo D1 Database
# 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
4. Cấu hình Environment
4.1. Local development (.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.
4.2. Production (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
4.3. Cấu hình runtime qua CMS (DB-first, fallback env)
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ả:
Deploy không bắt buộc 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).
CMS hiển thị giá trị hiệu lực: khi 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.
Fail-safe: nếu một giá trị trống ở cả DB lẫn env thì thao tác tương ứng bị từ chối (webhook Telegram/SePay trả 401, Mini App verify initData fail). Phải có giá trị ở ít nhất một nguồn.
Đổi 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).
5. Chạy Migration
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.
6. Tạo Admin CMS
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 ')
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')"
7. Development (Local)
# 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:
Worker: http://localhost:8787
CMS dev: http://localhost:5173/cms/
CMS từ Worker (sau khi build): http://localhost:8787/cms/
Mini App từ Worker (sau khi build): http://localhost:8787/app/
Health check: http://localhost:8787/health
Mini App cần chạy trong Telegram để có initData thậ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ệ).
8. Build & Deploy
# 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 deploy có hook predeploy = build:all nên tự build cả CMS lẫn Mini App trước khi wrangler deploy — không cần build thủ công trước. wrangler.toml dù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ẳng npx wrangler deploy (bỏ qua npm) thì KHÔNG có predeploy → phải tự npm run build:all trước.
9. Cấu hình Webhook
Telegram Webhook
# 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"
}'
SePay Webhook
Đăng nhập https://my.sepay.vn
Vào Webhook → Tạo webhook mới
URL: https://YOUR_WORKER_URL/webhook/sepay
Sự kiện: Có tiền vào
Bảo mật: API Key → paste key đã lưu trong SEPAY_API_KEY (Worker yêu cầu header Authorization: Apikey )
Key này có thể đặt ở secret SEPAY_API_KEY hoặc trong CMS → Cấu hình → SePay (system_config.sepay_api_key, ưu tiên DB). Mã chuyển khoản NAP… được nhận diện từ trường code của SePay trước, nếu không có thì dò trong content.
10. Chạy Tests
Unit / property-based (Vitest + fast-check)
npm test # Chạy tất cả tests
npm run test:watch # Watch mode
E2E full flow (dữ liệu thật qua HTTP)
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
Telegram Shop Bot
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.
1. Cài đặt
# Clone repo
git clone
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:miniapp tự chạy npm --prefix miniapp install trước khi build nên có thể bỏ qua bước cài thủ công cho Mini App.
2. Tạo Telegram Bot
Mở Telegram, chat với @BotFather
Gửi /newbot → đặt tên → nhận BOT_TOKEN
Gửi /setcommands → chọn bot → nhập:
start - Trang chủ
admin - Quản trị (chỉ admin)
huy - Huỷ thao tác hiện tại
3. Tạo D1 Database
# 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
4. Cấu hình Environment
4.1. Local development (.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.
4.2. Production (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
4.3. Cấu hình runtime qua CMS (DB-first, fallback env)
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ả:
Deploy không bắt buộc 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).
CMS hiển thị giá trị hiệu lực: khi 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.
Fail-safe: nếu một giá trị trống ở cả DB lẫn env thì thao tác tương ứng bị từ chối (webhook Telegram/SePay trả 401, Mini App verify initData fail). Phải có giá trị ở ít nhất một nguồn.
Đổi 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).
5. Chạy Migration
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.
6. Tạo Admin CMS
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 ')
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')"
7. Development (Local)
# 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:
Worker: http://localhost:8787
CMS dev: http://localhost:5173/cms/
CMS từ Worker (sau khi build): http://localhost:8787/cms/
Mini App từ Worker (sau khi build): http://localhost:8787/app/
Health check: http://localhost:8787/health
Mini App cần chạy trong Telegram để có initData thậ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ệ).
8. Build & Deploy
# 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 deploy có hook predeploy = build:all nên tự build cả CMS lẫn Mini App trước khi wrangler deploy — không cần build thủ công trước. wrangler.toml dù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ẳng npx wrangler deploy (bỏ qua npm) thì KHÔNG có predeploy → phải tự npm run build:all trước.
9. Cấu hình Webhook
Telegram Webhook
# 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"
}'
SePay Webhook
Đăng nhập https://my.sepay.vn
Vào Webhook → Tạo webhook mới
URL: https://YOUR_WORKER_URL/webhook/sepay
Sự kiện: Có tiền vào
Bảo mật: API Key → paste key đã lưu trong SEPAY_API_KEY (Worker yêu cầu header Authorization: Apikey )
Key này có thể đặt ở secret SEPAY_API_KEY hoặc trong CMS → Cấu hình → SePay (system_config.sepay_api_key, ưu tiên DB). Mã chuyển khoản NAP… được nhận diện từ trường code của SePay trước, nếu không có thì dò trong content.
10. Chạy Tests
Unit / property-based (Vitest + fast-check)
npm test # Chạy tất cả tests
npm run test:watch # Watch mode
E2E full flow (dữ liệu thật qua HTTP)
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
Thành viên
Nội dung đánh giá
Thành viên ẩn danh
13:05 28-05-2026
1 sao
Nam exercitationem ipsum quia asperiores possimus qui.