Telegram Bot PRD

x3 TàiChính — Challenge Bot Platform — Go + PostgreSQL + Redis + Cloudflare R2 + Webhook

01Tổng Quan & KPI

Bot Telegram tự động hóa 90% quy trình vận hành lớp 21 Ngày Thử Thách Tài Chính — onboarding học viên sau khi cọc, nhắc nhở nhiệm vụ hàng ngày/tuần, thu thập bằng chứng ảnh, tính điểm/streak, và hoàn tiền cọc cuối khóa.

Go (Gin/Fiber) PostgreSQL Redis Cloudflare R2 Telegram Webhook SePay
90%
Automation
Không cần admin can thiệp
<500ms
Response Time
User message → bot reply
0
Reminder bỏ sót
Mỗi lớp / khóa học
95%
Onboarding Rate
Cọc → join group <24h
80%
Daily Completion
Submit đúng ngày
02Kiến Trúc Hệ Thống

Ctrl/Cmd + scroll = zoom • Kéo = pan • Nút ↺ = fit

...
Key Decisions: 1 bot — multi-class routing qua telegram_group_id • Webhook, không polling • Session key = (user_id, bot_token) TTL 30ph • Snapshot reward_amount vào TaskLog ngay lúc tạo (immutable ledger)
03Bot Identity & Commands
Bot Identity
  • Username: @x3taichi_bot
  • Backup: @thuthachx3_bot
  • Display: "x3 TàiChính — Bot Thử Thách"
  • Avatar: logo 256×256px
  • Description: "Đồng hành 21 ngày tự do tài chính"
Callback Schema
  • daily_done:{tasklog_id}
  • daily_notyet:{tasklog_id}
  • confirm_link:{enrollment_id}
  • zoom_attend:{tasklog_id}
  • admin_approve:{tasklog_id}
  • HMAC signed — chống tamper
CommandMô TảAi Dùng
/start <code?>Khởi tạo / liên kết enrollment qua deep-linkHọc viên
/todayXem nhiệm vụ hôm nay + status + rewardHọc viên
/diemTổng hợp: streak, earned, level tích lũyHọc viên
/lopThông tin lớp: lịch zoom, group linkHọc viên
/helpHướng dẫn dùng botTất cả
/huyThoát flow hiện tại — reset sessionHọc viên
/adminMenu quản trị (chỉ admin lớp)Admin
/broadcast <msg>Gửi tin nhắn toàn lớpAdmin
04Onboarding Flow

State machine — liên kết tài khoản Telegram với enrollment

...
Câu hỏi mở #5: Invite link expire 24h. Học viên cọc sớm nhưng /start sau 3 ngày → link đã chết. Cần flow re-generate link on-demand khi user /start lại.
Deep-link format: t.me/x3taichi_bot?start=ENR_ABC123 — landing page tự động inject code vào URL sau khi payment callback.
05Daily Task Flow

Sequence — Luồng chính hàng ngày

...

Retry & Escalation Timeline

T+0
Initial
send_reminder
T+30m
Retry 1
PENDING → resend
T+60m
Retry 2
resend lần 2
T+20h
Phone Call
Vbee fallback
(Phase 2)
T+22h
Cutoff
MISSED nếu PENDING

Photo Proof — R2 Upload

1
getFile()
Download từ
Telegram CDN
2
Compress
→ WebP <50KB
max 600px
3
Upload R2
private bucket
key: class/enr/date
4
Save URL
proof_url → DB
TaskLog = DONE

Edge Cases

CaseXử Lý
User gửi text thay vì click nút"Vui lòng bấm nút ở trên 👆"
User gửi nhiều ảnhLấy ảnh đầu, ignore còn lại + reply confirm
User submit 2 lần cùng task"Bạn đã hoàn thành rồi! +50k đã ghi nhận"
Submit task ngày trướcReject: "Hôm nay là ngày X, bạn đang xem ngày Y"
Telegram ảnh fail downloadRetry 3 lần → admin queue
R2 upload failRetry 2 lần → lưu file_id tạm, re-upload async
Ảnh >20MB (Telegram limit)Telegram tự reject → bot catch MediaTooLarge
User gửi ảnh qua groupBot ignore — chỉ nhận proof trong private chat
06Weekly Task & Zoom Check-in

Weekly Task — Dispatch Thứ 5 12:00

Luồng chính
  • Bot gửi video bài học YouTube + link Google Form
  • Học viên nộp link bài viết Facebook (public)
  • Admin review queue (SLA 24h)
  • Auto-accept form khi Google webhook về (Phase 2)
  • Sau duyệt: +50k reward → thông báo học viên
Thời ĐiểmAction
deadline − 12hNhắc "Còn 12h, gửi gấp!"
deadline − 1hNhắc lần cuối
deadline + 0Status = LATE (cho nộp 24h)
deadline + 24hStatus = MISSED

Zoom Check-in Flow

Trước Zoom 11h (22:00 đêm trước)
  • Bot gửi nhắc nhở + nút "Tôi sẽ tham dự"
  • Click → xác nhận phone đã đăng ký
  • Confirm → nhận link Zoom lúc 04:00 sáng
  • Vắng mặt = −50k via PaymentLog
Sau Zoom: Đối chiếu participant_phoneenrollment.phone
Match → TaskLog DONE (reward = 0, không phạt)
Không match → TaskLog MISSED → trừ 50k
07Scheduler Jobs
JobCronHành Động
daily_reminder_dispatch08:00 mỗi ngàyTạo TaskLog(DAILY) + gửi reminder toàn lớp active
daily_reminder_retryMỗi 30ph (08:00–22:00)Resend cho TaskLog PENDING
daily_call_trigger20:00 mỗi ngàyTrigger Vbee phone call (Phase 2)
weekly_task_dispatch12:00 T5/T7/T3Gửi video bài học + link form
weekly_deadline_checkMỗi 1hMark LATE / MISSED khi quá deadline
zoom_reminder22:00 đêm trước + 04:00 sángNhắc + gửi link Zoom
group_celebrationMỗi 60ph (08:00–22:00)Group message tổng hợp hoàn thành — skip nếu 0 người mới
payment_reconcile23:59 mỗi ngàySync PaymentLog từ TaskLog DONE / MISSED
class_complete_check23:59 ngày cuối lớpAuto-trigger REFUND nếu đủ điều kiện
Implementation: Go ticker + time.AfterFunc, lưu state vào Redis. Distributed lock nếu scale nhiều instance.
08Session & State Redis

Redis Key Schema

session:{user_id}:{bot_token}
  state: WAITING_PHOTO
       | WAITING_FB_LINK
       | IDLE
  context: {task_log_id, retry_count,
            last_message_id}
  TTL: 30 phut

ratelimit:{user_id}        → max 30 msg/min
ratelimit:group:{group_id} → max 20 msg/min

queue:fb_review            → Redis list
celebration:lock:{class_id}→ TTL 60 phut

State Transitions

IDLE
  ├─ /start       → WAITING_LINK_CONFIRM
  │                 └─ IDLE (success)
  ├─ /today       → IDLE (info only)
  └─ click DA_LAM → WAITING_PHOTO
                    ├─ photo received → IDLE
                    ├─ /huy          → IDLE
                    └─ timeout 30m   → IDLE

WAITING_FB_LINK
  ├─ URL pasted   → IDLE (queue review)
  ├─ /huy         → IDLE
  └─ timeout 30m  → IDLE
Anti-spam group: Max 1 message/giờ/group • Skip nếu cùng nội dung trong 2h • Tag username (không tag full name) — privacy
09Bảo Mật & Reliability

Security

Mối NguyMitigation
Webhook spoofingVerify Telegram X-Telegram-Bot-Api-Secret-Token
Admin escalationBảng class_admins(class_id, telegram_id)
User impersonationMatch telegram_idenrollment.telegram_id
SQL injectionpgx parameterized queries 100%
Bot token leakLưu env var, rotate khi nghi ngờ
Callback tamperHMAC-SHA256 signature trên callback data
Group join unauthInvite link per-enrollment, expire 24h, single-use

Rate Limiting & Reliability

Limit / FailureStrategy
30 msg/sec/bot (Telegram)Token bucket golang.org/x/time/rate
20 msg/min/groupPer-group bucket
>30 msg/min/user floodAuto-ignore + warning một lần
Webhook 5xxTelegram retry exp, alert >100 fail/h
DB pool exhaustpgx max=20, queue timeout 5s
Redis downDegrade stateless — chấp nhận user gõ lại
Logging: Mọi message bot ↔ user → bot_message_log (Postgres) • Lỗi server → Sentry • Audit admin actions: ai review FB link nào
10Admin Panel
Dashboard Realtime
Tỷ lệ hoàn thành lớp, streak top, daily active enrollments
Queue Duyệt FB Link
Review từng bài với nút Duyệt / Reject / Xem. Counter hiển thị số chờ. SLA 24h.
Danh Sách Học Viên
Trạng thái, streak, số tiền tích lũy, link Telegram của từng học viên
Broadcast Cả Lớp
/broadcast <msg> — gửi tới toàn bộ active enrollment trong lớp
Can Thiệp Khẩn
Học viên không phản hồi >3 ngày liên tiếp, cần phone call thủ công
Config Lớp
reminder_interval_min, cutoff_hour, reward_amount, lịch zoom
Metrics Prometheus: bot_message_received_total, task_completion_rate{class,task_type}, reminder_response_time_seconds (histogram), admin_review_queue_depth — expose /metrics
11Phase Plan
P0 — MVP
Tuần 1–2
  • Webhook + /start onboarding
  • DAILY reminder + photo proof
  • Reward calc + streak
  • Group celebration
  • Admin /broadcast
P1 — Core
Tuần 3–4
  • WEEKLY flow + FB queue duyệt
  • ZOOM check-in
  • Admin dashboard web (read-only)
  • Prometheus + Grafana
P2 — Sau MVP
Khi có ROI
  • Phone call fallback (Vbee)
  • Google Form auto-accept
  • AI proof moderation (Gemini)
  • Multi-bot per class
12Testing Strategy
LayerScopeCông Cụ
UnitFSM transitions, reward calc, snapshot logic, HMAC verifyGo testing
IntegrationTelegram webhook → DB write end-to-endtestcontainers Postgres + Redis
Bot InteractionGửi message thật qua staging botgotgproto test client
Load1000 webhook/s — đo p99 latency <500msk6
ChaosKill Redis 30s, Postgres reconnect, Telegram 5xxManual / Chaos Monkey
ManualDaily/weekly/zoom full flow, edge cases, timeout, retryStaging environment
Câu hỏi mở: Bot down lúc 08:00 (giờ vàng) → cần backfill reminder? Queue persistent (Redis Streams) hay chấp nhận mất? Anti-cheat ảnh proof: perceptual hash so sánh 21 ngày?