Tài liệu dưới đây hướng dẫn tạo Telegram Bot, khai báo bot trong EzyOA, đăng ký webhook và kiểm tra luồng gửi/nhận tin nhắn.

Tổng quan

Luồng tích hợp hoạt động như sau:
Người dùng gửi tin nhắn
        |
        v
Telegram Bot API
        |
        | HTTPS POST webhook
        v
EzyOA
        |
        | Xử lý hội thoại / phản hồi
        v
Telegram Bot API
        |
        v
Người dùng nhận tin nhắn
EzyOA sử dụng:
  • Bot Token để gửi tin nhắn và truy vấn thông tin chat qua Telegram Bot API.
  • Webhook Secret Token để xác thực request webhook gửi từ Telegram.
  • Webhook URL để nhận tin nhắn và sự kiện thay đổi trạng thái của bot.
Telegram chỉ cho phép một webhook hoạt động trên mỗi bot. Khi webhook đã được thiết lập, bot không thể đồng thời nhận update bằng getUpdates. Xem thêm tại Telegram Bot API.

Chuẩn bị

Bạn cần có:
  • Một hệ thống EzyOA đang hoạt động.
  • Domain công khai có HTTPS hợp lệ.
  • Quyền truy cập trang quản trị EzyOA.
  • Tài khoản Telegram để tạo bot.
  • web url của EzyOA đã được cấu hình đúng theo domain công khai.
Ví dụ:
https://oa.example.com
Telegram Cloud Bot API yêu cầu webhook sử dụng HTTPS và hỗ trợ các cổng 443, 80, 88 hoặc 8443. Không nên sử dụng localhost làm webhook.

Tạo Telegram Bot

tich-hop-telegram-vao-ezyoa-1.jpg
Mở cuộc trò chuyện với @BotFather trên Telegram.
Gửi lệnh:
/newbot
BotFather sẽ yêu cầu:
  1. Nhập tên hiển thị của bot.
  2. Nhập username cho bot.
  3. Username thường phải kết thúc bằng bot, ví dụ:
ezyoa_support_bot
Sau khi tạo thành công, BotFather trả về Bot Token có dạng:
123456789:AAExampleTelegramBotToken
Bot Token cho phép toàn quyền điều khiển bot. Không đăng token lên Git, log, ảnh chụp màn hình hoặc gửi qua kênh công khai. Telegram cũng khuyến nghị coi token như mật khẩu; nếu bị lộ, hãy tạo lại token bằng BotFather. Xem hướng dẫn chính thức tại Telegram Bot Features.
Có thể kiểm tra token bằng API getMe:
curl "https://api.telegram.org/bot<BOT_TOKEN>/getMe"
Kết quả thành công có dạng:
{
  "ok": true,
  "result": {
    "id": 123456789,
    "is_bot": true,
    "first_name": "EzyOA Support",
    "username": "ezyoa_support_bot"
  }
}

Khai báo dịch vụ Telegram trong EzyOA

Trong trang quản trị EzyOA, vào:
OA Services → Thêm
Điền cấu hình như sau:
TrườngGiá trị
MãTELEGRAM_BOT
TênTên hiển thị, ví dụ Telegram Support
Phiên bảnĐể trống
Mã ứng dụngĐể trống
Mã UUID ứng dụngĐể trống
Đường dẫn dịch vụCó thể nhập https://t.me/<bot_username>
Đường dẫn API dịch vụĐể trống
Khoá máy kháchĐể trống
Khoá bí mậtBot Token nhận từ BotFather
Khoá bí mật webhookChuỗi bí mật dùng để xác thực webhook
Code challengeĐể trống
Code verifierĐể trống
Dịch vụ xử lýTELEGRAM_BOT
Trạng tháiACTIVATED
Nếu tích hợp nhiều bot, mỗi bot cần một mã riêng, ví dụ:
TELEGRAM_SUPPORT
TELEGRAM_SALES
Với các dịch vụ này, trường Dịch vụ xử lý vẫn chọn TELEGRAM_BOT.
Mã dịch vụ được sử dụng trong Webhook URL và không nên thay đổi sau khi đã đăng ký webhook.

Tạo Webhook Secret Token

Webhook Secret Token nên là chuỗi ngẫu nhiên đủ dài, ví dụ:
ezyoa_telegram_A7k9xP2mQ4vN8sR6
Token chỉ được chứa các ký tự:
A-Z
a-z
0-9
_
-
Telegram cho phép secret_token dài từ 1 đến 256 ký tự. Khi gửi webhook, Telegram đặt giá trị này vào header:
X-Telegram-Bot-Api-Secret-Token: <WEBHOOK_SECRET>
EzyOA sẽ so sánh header trên với trường Khoá bí mật webhook. Nếu giá trị không khớp, request bị từ chối.
Sau khi nhập đầy đủ thông tin, bấm Lưu.

Lấy Webhook URL

Mở trang chi tiết dịch vụ vừa tạo. EzyOA hiển thị Webhook URL theo cấu trúc:
https://<web-url>/api/v1/oa/<code>/webhook
Ví dụ:
https://oa.example.com/api/v1/oa/TELEGRAM_BOT/webhook
Webhook URL phải:
  • Truy cập được từ Internet.
  • Sử dụng HTTPS.
  • Không chuyển hướng sang URL khác.
  • Trỏ đúng mã dịch vụ.
  • Thuộc dịch vụ đang ở trạng thái ACTIVATED.

Đăng ký webhook với Telegram

Gọi phương thức setWebhook bằng Bot Token, Webhook URL và Webhook Secret Token.
Thay các giá trị sau:
  • <BOT_TOKEN>: Bot Token nhận từ BotFather.
  • <WEBHOOK_URL>: URL hiển thị trong EzyOA.
  • <WEBHOOK_SECRET>: giá trị đã nhập ở trường Khoá bí mật webhook.
curl --request POST \
  "https://api.telegram.org/bot<BOT_TOKEN>/setWebhook" \
  --header "Content-Type: application/json" \
  --data '{
    "url": "<WEBHOOK_URL>",
    "secret_token": "<WEBHOOK_SECRET>",
    "allowed_updates": [
      "message",
      "my_chat_member"
    ]
  }'
Ví dụ về cấu trúc request:
{
  "url": "https://oa.example.com/api/v1/oa/TELEGRAM_BOT/webhook",
  "secret_token": "ezyoa_telegram_A7k9xP2mQ4vN8sR6",
  "allowed_updates": [
    "message",
    "my_chat_member"
  ]
}
Không sử dụng Bot Token hoặc Webhook Secret thật trong tài liệu, ticket hỗ trợ hay source code.
Hai loại update được đăng ký có ý nghĩa:
  • message: nhận tin nhắn người dùng gửi cho bot.
  • my_chat_member: nhận sự kiện bot được thêm, gỡ, chặn hoặc bỏ chặn trong chat.
Kết quả thành công:
{
  "ok": true,
  "result": true,
  "description": "Webhook was set"
}
Tham số và giới hạn mới nhất được mô tả trong phần `setWebhook` của Telegram Bot API.

Kiểm tra trạng thái webhook

Gọi API:
curl "https://api.telegram.org/bot<BOT_TOKEN>/getWebhookInfo"
Kết quả cần kiểm tra:
{
  "ok": true,
  "result": {
    "url": "https://oa.example.com/api/v1/oa/TELEGRAM_BOT/webhook",
    "pending_update_count": 0,
    "allowed_updates": [
      "message",
      "my_chat_member"
    ]
  }
}
Các trường quan trọng:
TrườngÝ nghĩa
urlWebhook URL hiện tại
pending_update_countSố update Telegram đang chờ gửi
last_error_dateThời điểm gần nhất webhook gặp lỗi
last_error_messageMô tả lỗi gần nhất
allowed_updatesDanh sách loại update được gửi
Nếu url rỗng, webhook chưa được đăng ký.

Kiểm tra nhận và gửi tin nhắn

Kiểm tra nhận tin

tich-hop-telegram-vao-ezyoa-2.jpg
  1. Mở bot trên Telegram.
  2. Bấm Start hoặc gửi lệnh:
/start
  1. Gửi một tin nhắn văn bản.
  2. Mở danh sách OA Users hoặc màn hình tin nhắn trong EzyOA.
  3. Kiểm tra người dùng và nội dung tin nhắn đã xuất hiện.
Khi nhận tin nhắn lần đầu, EzyOA sử dụng Chat ID làm định danh người dùng và truy vấn thông tin chat để lấy tên hiển thị.

Kiểm tra trả lời

Từ giao diện quản trị EzyOA:
  1. Mở người dùng Telegram vừa gửi tin.
  2. Nhập nội dung trả lời.
  3. Bấm gửi.
  4. Kiểm tra tin nhắn xuất hiện trong Telegram.
Tin nhắn văn bản gửi từ EzyOA sử dụng chế độ định dạng HTML. Vì vậy, nội dung chứa ký tự hoặc thẻ HTML không hợp lệ có thể bị Telegram từ chối.

Kiểm tra trạng thái theo dõi

Trong cuộc trò chuyện riêng:
  • Khi người dùng bắt đầu hoặc bỏ chặn bot, Telegram có thể gửi update my_chat_member.
  • Khi người dùng chặn bot, Telegram gửi trạng thái tương ứng để EzyOA cập nhật người dùng sang trạng thái không còn theo dõi.

Các loại nội dung được hỗ trợ

EzyOA hiện xử lý các nội dung Telegram sau:
HướngLoại nội dung
Telegram → EzyOAVăn bản
Telegram → EzyOAẢnh
Telegram → EzyOATài liệu và tệp
Telegram → EzyOAVideo
Telegram → EzyOAVoice message
Telegram → EzyOAAudio
Telegram → EzyOASticker
EzyOA → TelegramVăn bản
EzyOA → TelegramẢnh
EzyOA → TelegramAudio
EzyOA → TelegramTài liệu
EzyOA → TelegramVideo
EzyOA → TelegramAnimation
EzyOA → TelegramVoice message
EzyOA → TelegramTrạng thái đang nhập
Khi gửi media:
  • Nếu tệp có URL HTTPS công khai, EzyOA gửi URL cho Telegram tải về.
  • Nếu URL không công khai, chẳng hạn hệ thống chạy bằng localhost hoặc HTTP, EzyOA tải trực tiếp tệp lên Telegram.
  • Các tệp không thuộc loại được nhận diện sẽ được xử lý như tài liệu.
Một số giới hạn hiện tại:
  • Caption của media không được xử lý như tin nhắn văn bản.
  • EzyOA không đồng bộ toàn bộ danh sách người dùng Telegram theo yêu cầu.
  • Không hỗ trợ Telegram notification template riêng.
  • Các update như callback_query, edited_message, reaction, poll hoặc location chưa nằm trong luồng xử lý mặc định.

Tích hợp bot vào nhóm

Nếu muốn sử dụng bot trong group:
  1. Mở BotFather.
  2. Chọn bot.
  3. Kiểm tra cấu hình cho phép thêm bot vào group.
  4. Thêm bot vào group cần sử dụng.
  5. Cấp quyền phù hợp nếu bot cần đọc hoặc gửi tin nhắn.
  6. Kiểm tra Privacy Mode.
Khi Privacy Mode được bật, bot trong group thường chỉ nhận:
  • Command gửi cho bot.
  • Tin nhắn trả lời trực tiếp bot.
  • Tin nhắn có nhắc tới bot.
  • Một số service message liên quan.
Nếu cần nhận nhiều tin nhắn hơn trong group, hãy cân nhắc thay đổi Privacy Mode trong BotFather. Chỉ tắt chế độ này khi nghiệp vụ thực sự cần, vì nó ảnh hưởng đến quyền riêng tư của thành viên.

Cập nhật cấu hình webhook

Sau khi thay đổi Webhook URL hoặc Webhook Secret Token trong EzyOA, phải gọi lại setWebhook với giá trị mới:
curl --request POST \
  "https://api.telegram.org/bot<BOT_TOKEN>/setWebhook" \
  --header "Content-Type: application/json" \
  --data '{
    "url": "<NEW_WEBHOOK_URL>",
    "secret_token": "<NEW_WEBHOOK_SECRET>",
    "allowed_updates": ["message", "my_chat_member"]
  }'
Nếu chỉ sửa cấu hình trong EzyOA mà không đăng ký lại trên Telegram, Telegram vẫn gửi request với URL hoặc secret cũ.

Xoá webhook

Để ngừng chuyển update về EzyOA:
curl --request POST \
  "https://api.telegram.org/bot<BOT_TOKEN>/deleteWebhook"
Nếu muốn xoá luôn các update đang chờ:
curl --request POST \
  "https://api.telegram.org/bot<BOT_TOKEN>/deleteWebhook" \
  --header "Content-Type: application/json" \
  --data '{
    "drop_pending_updates": true
  }'
Chỉ sử dụng drop_pending_updates khi chấp nhận mất các tin nhắn chưa được xử lý.

Xử lý lỗi thường gặp

Hiện tượngNguyên nhân thường gặpCách xử lý
getMe trả về 401 UnauthorizedBot Token sai hoặc đã bị thu hồiLấy hoặc tạo lại token trong BotFather
setWebhook trả lỗi URLDomain không có HTTPS hợp lệ hoặc URL không công khaiKiểm tra DNS, chứng chỉ SSL và firewall
Webhook trả 404Sai mã dịch vụ hoặc dịch vụ chưa kích hoạtKiểm tra <code>, Dịch vụ xử lý và trạng thái
Webhook trả lỗi secret tokenSecret Telegram gửi không trùng cấu hình EzyOAGọi lại setWebhook với đúng secret_token
pending_update_count tăng liên tụcEzyOA không trả mã HTTP 2xxKiểm tra log ứng dụng và last_error_message
Gửi được nhưng không nhận được tinWebhook chưa được đăng ký hoặc allowed_updates saiKiểm tra bằng getWebhookInfo
Không nhận sự kiện chặn/bỏ chặnThiếu my_chat_memberGọi lại setWebhook với loại update này
Không nhận tin nhắn groupPrivacy Mode hoặc quyền groupKiểm tra cấu hình bot trong BotFather
Telegram không tải được mediaURL media không công khai hoặc chứng chỉ không hợp lệDùng HTTPS công khai hoặc để EzyOA upload file
Gửi tin văn bản thất bạiNội dung HTML không hợp lệKiểm tra và escape các ký tự HTML
Bot không chủ động gửi được cho người dùngNgười dùng chưa bắt đầu chat hoặc đã chặn botYêu cầu người dùng mở bot và bấm Start
getUpdates không hoạt độngBot đang sử dụng webhookXoá webhook trước khi dùng long polling

Bảo mật

  • Không commit Bot Token hoặc Webhook Secret Token vào Git.
  • Không đặt token trực tiếp trong mã nguồn frontend.
  • Không ghi đầy đủ Bot Token vào log.
  • Sử dụng Webhook Secret Token ở mọi môi trường production.
  • Chỉ mở endpoint webhook qua HTTPS.
  • Giới hạn quyền truy cập trang quản trị EzyOA.
  • Khi nghi ngờ Bot Token bị lộ, tạo lại token trong BotFather và cập nhật ngay trường Khoá bí mật.
  • Sau khi đổi Webhook Secret Token, gọi lại setWebhook.
  • Tách bot development và production để tránh tin nhắn thử nghiệm đi vào dữ liệu thật.
Tài liệu này được viết theo hành vi tích hợp hiện có của EzyOA và đã tổng quát hóa tên lớp, package cùng các chi tiết triển khai nội bộ.