TATrương Tuấn AnhTuna / truongtuananh.vn
Tất cả bài viết
ngày ghi
phút đọc
6
nguồn dẫn
10

Sửa website bằng tin nhắn Telegram mà không mất kiểm soát

Bot Telegram sửa giá và cấu hình web qua nhánh bot/<id>, cổng kiểm chạy trên GitHub Actions, tôi bấm Chốt mới lên web. Ba lớp chặn, tám lệnh whitelist, một bẫy thứ tự.

Chủ đề: cổng kiểm, ai có người duyệt, vận hành

Website bán cửa chống cháy của tôi có đơn giá, VAT, tỷ lệ cọc, hotline, và chúng thỉnh thoảng phải đổi. Mỗi lần đổi mà phải mở máy tính, mở Claude Code, chạy flyctl thì việc bị hoãn. Nên tôi dựng một bot Telegram: nhắn cho bot, bot sửa, GitHub Actions chạy cổng kiểm, tôi bấm Chốt, bản mới lên web.

Cái đáng kể lại là ba quyết định phía sau, vì cái nào cũng có phương án khác trông gọn hơn nhưng sai.

Ba quyết định

1. Bot đi qua repo, không sửa file trong container. Container trên Fly sinh ra từ repo. Sửa thẳng trong container thì lần deploy sau ghi đè mất, và không có gì để revert. Đi qua repo thì mỗi thay đổi là một commit mang tên người bấm Chốt, đúng cách data/pricing.jsonconfig/company.json vẫn giữ lịch sử. Bot đọc file từ main, sửa đúng một giá trị, đẩy lên nhánh bot/<id> trên GitHub, không chạm vào main.

2. Bot không tự chạy cổng kiểm. Cổng kiểm của site sống trong repo và chạy trên Actions. Đó là cùng một cổng tôi phải đi qua khi sửa tay. Cho bot một đường kiểm riêng là tạo cổng thứ hai, và hai cổng thì sớm muộn lệch nhau. Workflow bot-kiem.yml kích khi có push lên bot/**: test, build site, ba cổng kiểm nội dung, stylelint CSS, rồi gửi diff về Telegram kèm trạng thái XANH hay ĐỎ.

Sau khi gộp vào main, cổng kiểm chạy lần nữa trước deploy: lần đầu kiểm nhánh, lần sau kiểm kết quả gộp. Hai bên xanh mà gộp lại đỏ là chuyện thường.

3. Có nút Chốt. Site này bán hàng có quy định pháp lý: cấp EI, QCVN 06:2022, giá. Một con số sai không phải lỗi chính tả mà là rủi ro pháp lý. Cổng kiểm bắt được lỗi kỹ thuật. Nó không bắt được "1,9tr gõ thành 19tr", vì cả hai đều là số hợp lệ. Cái bắt được lỗi đó là mắt người, một lần bấm.

Nút "Chốt & deploy" chỉ hiện khi cổng kiểm xanh; đỏ thì chỉ có link log. Dải giá cố tình rộng, 500k đến 20tr cho đơn giá cửa, vì nó chặn lỗi chữ số chứ không chặn quyền đổi giá. 19tr vẫn trong dải. Cái tóm được nó là dòng cảnh báo trên màn hình chốt:

Đơn giá EI60 sơn 1 cánh: 1.900.000 → 19.000.000 đ/m²
   ‼️ lệch +900% (10.00× - kiểm lại số chữ số)

Tôi đọc dòng đó rồi mới bấm.

Ba lớp chặn ở cửa vào

Endpoint webhook là quyền ghi lên một website thương mại đang chạy, mở bằng một chuỗi token Telegram. Ba lớp chặn:

  1. Biến BOT_TELEGRAM_ADMINS rỗng thì endpoint trả 404. Mặc định là tắt. Trả 404 chứ không 403, để người dò không được xác nhận rằng đường này tồn tại.
  2. secret_token của Telegram được so sánh timing-safe. Sai là 401.
  3. ID người gửi được kiểm lại ở tầng nghiệp vụ. Người lạ bị im lặng bỏ qua, chỉ ghi log, vì trả lời là tự khai bot làm được gì. Phải là ID số, không phải @username, vì username đổi được còn ID thì không.

Tắt khẩn cấp là gỡ một biến môi trường, endpoint về 404 ngay khi máy khởi động lại. Thông báo đơn hàng không bị ảnh hưởng vì module đó tách riêng.

Một chi tiết bắt buộc: endpoint trả 200 ngay rồi mới làm việc. Telegram retry nếu không nhận 200 trong khoảng 60 giây, mà gọi Claude rồi đọc ghi GitHub có thể lâu hơn thế. Chậm một nhịp là một câu lệnh tạo hai nhánh.

Bẫy thứ tự: merge workflow trước, bật bot sau

Không đảo được, do cách GitHub Actions nạp workflow: sự kiện push dùng file workflow có trong chính commit được push. Nhánh bot/** do bot tạo từ main. Nếu main chưa có bot-kiem.yml thì nhánh bot cũng không có, cổng kiểm không chạy, và không có nút Chốt nào hiện ra. Bot vẫn tạo được nhánh, chỉ là sau đó im lặng.

workflow_dispatch, tức lệnh /deploy, chỉ gọi được workflow đã nằm trên nhánh mặc định. Chưa merge thì deploy.yml chưa tồn tại để kích.

Nên thứ tự đúng là: merge PR vào main trước, rồi mới chạy script bật bot.

Bot sửa được gì, và không sửa được gì

Bot chỉ sửa trường có trong danh sách trắng. Tám lệnh sửa dữ liệu:

LệnhSửa gìDải cho phép
/giađơn giá cửa theo cấp EI, bề mặt, số cánh500k - 20tr
/phukiengói phụ kiện100k - 10tr
/hosophí hồ sơ0 - 5tr
/vatthuế suất0 - 0,2
/coctỷ lệ cọc0,1 - 1
/hotlinehotlinedạng số Việt Nam
/emailemail liên hệdạng email
/flagcờ tính năngdanh sách cờ cố định

Thêm /sua cho AI soạn câu chữ mô tả, và /xem, /deploy, /giupdo không sửa gì. Nhập số ngoài dải thì bot nói thẳng: dải này chặn lỗi thiếu thừa chữ số, không chặn bạn đổi giá; giá thật ngoài dải thì sửa file bằng tay kèm evidence.

Bot không sửa được:

  • Bất cứ gì ngoài data/config/. Không mã nguồn, không template, không CSS. Phạm vi hẹp là thứ giữ cho token bị lộ không thành mất cả site.
  • Khoá chưa tồn tại. Tạo khoá lạ là cách âm thầm nhất làm hỏng file mà cổng kiểm vẫn xanh.
  • SALES_MODE=full_salesPAYMENTS_ENABLED=true. Hai cờ này gọi lại launch-gate.mjs, nơi bộ điều kiện mở bán viết một lần: giấy phép, evidence, compliance profile, quyền ảnh. Chưa đạt toàn bộ thì bot từ chối và liệt kê còn thiếu gì. Đây là cổng pháp lý, không phải cấu hình; bot không mở được, phải làm tay.
  • Tên hay vị trí nhà máy đối tác, kể cả khi AI tự viết ra trong /sua. Chặn hai tầng: trước khi tạo nhánh, và ở cổng kiểm nội dung trước deploy.

Điều tôi rút ra

  • "AI đề xuất, người duyệt" không phải khẩu hiệu. Nó là một nhánh git, một workflow, và một nút. Bỏ một trong ba thì quy tắc chỉ còn trên giấy.
  • Cổng kiểm tự động bắt lỗi kỹ thuật. Lỗi nghiệp vụ, kiểu số hợp lệ nhưng sai, chỉ có mắt người bắt được. Đừng cho AI đường kiểm riêng, để nó đi cùng cổng với bạn.
  • Phạm vi hẹp là lớp bảo vệ rẻ nhất. Token có lộ thì thiệt hại cũng chỉ trong vài trường của danh sách trắng, và mỗi thay đổi vẫn qua tay tôi bấm.
  • Thứ tự bật sai có thể làm cả hệ thống im lặng mà không báo lỗi. Ghi lại thứ tự.

Nếu công ty bạn muốn một kênh sửa dữ liệu có cổng duyệt như thế này, ta nói chuyện 15 phút.

Bài này chạm đúng việc bạn đang làm? Mười lăm phút nói chuyện không mất gì.