Làm bot lì xì cho nhóm Telegram chạy hoàn toàn trên gói miễn phí — ba chỗ khó hơn tưởng
Chào mọi người. Mình vừa làm xong một bot Telegram cho nhóm chat: thành viên tip điểm cho nhau bằng /lixi @ban 100, mở bao lì xì chia ngẫu nhiên bằng /lixi 1000 chia 10 (ai bấm nhanh thì nhận), và admin đặt luật tự thưởng điểm cho người hoạt động mỗi ngày. Bot chạy thật, mã nguồn mở, miễn phí.
Bài này không phải bài giới thiệu sản phẩm. Mình muốn kể ba chỗ tưởng dễ mà hoá ra không, vì mình tìm trên Viblo không thấy ai viết về chúng cho trường hợp bot Telegram.
1. Tip song song và bài toán âm số dư
Hai người cùng tip từ một tài khoản trong cùng một giây là chuyện xảy ra thật khi nhóm đông. Bản đầu mình đọc số dư, trừ, ghi lại — và test 10 lệnh tip 30 điểm chạy song song từ tài khoản có 100 điểm cho ra kết quả âm. Cách sửa không mới nhưng phải làm đúng: SELECT ... FOR UPDATE khoá đúng một dòng người gửi trong transaction, cộng thêm CHECK (balance >= 0) ở tầng database làm lưới cuối. Test đó giờ cho đúng 3 lệnh thành công, 7 lệnh bị từ chối, tổng điểm toàn hệ thống không đổi.
2. Cron trên gói miễn phí chỉ chạy một lần mỗi ngày, và không đúng phút
Vercel Hobby cho tối đa 2 cron, tần suất tối thiểu là một lần/ngày, chạy vào một lúc bất kỳ trong giờ đã đặt. Nghĩa là mọi việc theo lịch phải idempotent: chạy lại không gây hại. Thưởng hoạt động tính theo ngày UTC và ghi dấu (nhóm, ngày) vào bảng riêng trước khi phát. Bao lì xì hết giờ thì "dọn lười": đóng ngay khi nhóm có tin nhắn tiếp theo, cron chỉ là lưới an toàn cho nhóm im hẳn. Bài đăng lên kênh thì xí mã bài trong database trước rồi mới gửi, nên có chạy hai lần cũng không đăng trùng.
3. Hàm serverless không được ném lỗi vì chuyện phụ
Đăng bài kênh hỏng, token GitHub hết hạn — không cái nào được phép làm hỏng phần phát thưởng đã chạy xong trước đó. Mình tách rõ: việc động vào điểm của người dùng thì lỗi là HTTP 500 để có người vào xem; việc truyền thông và báo cáo thì tự nuốt lỗi và ghi lý do vào log.
Stack: Node.js 22, Telegraf v4 (webhook, không long-polling), PostgreSQL trên Neon gói miễn phí, Vercel Hobby. Không framework web, không ORM. 236 test bằng node:test có sẵn, có cả test chạy với Postgres thật.
Một điều nói rõ: repo có tài liệu kế hoạch cho một token trong tương lai. Nhưng chưa phát hành token nào, và bot không cần token để chạy. Điểm trong bot chỉ là con số trong database: không mua bán, không quy đổi được, admin đặt lại về 0 lúc nào cũng được.
- Mã nguồn: https://github.com/nirannguyen50/new-coin
- Thử trong nhóm demo: https://t.me/lixibot_demo
Mình đang muốn nghe góp ý về hai thứ: cách chống lạm dụng khi nhóm có người tạo nhiều tài khoản, và có nên chuyển bao lì xì sang cơ chế "bấm để mở" thay vì ai nhắn trước nhận trước. Ai từng làm bot cho nhóm đông xin chia sẻ.
All rights reserved