Tài liệu nhà phát triển
Tiếng Việt

Phát triển bot

Tạo bot

Tạo bot bằng @BotFather, nhận và trả lời tin nhắn, rồi đến nút bấm, lệnh, ảnh và nhóm — hướng dẫn làm theo từ đầu đến cuối.

Khi hoàn thành hướng dẫn này, bạn sẽ có một con bot biết trả lời tin nhắn, gắn nút bấm, dùng menu lệnh và ảnh, và làm việc được cả trong nhóm. Bạn cần ứng dụng Pabal, một máy tính để chạy chương trình bot, và một trong hai: Python 3.10 trở lên hoặc Node.js 18 trở lên.

Bot hoạt động như thế nào

Bot của Pabal là một tài khoản do chương trình điều khiển. Tin nhắn gửi cho bot được xếp vào hộp thư của bot; chương trình bot hỏi máy chủ "Có gì mới không?" (getUpdates) để lấy về, rồi gửi câu trả lời (sendMessage). Chương trình bot chạy bên ngoài máy chủ, trên máy tính của bạn.

Người (app) Máy chủ Pabal Bot của bạn ① getUpdates?offset=0&timeout=30 Chờ tối đa 30 giây cho đến khi có tin mới ② Gửi "Xin chào" ③ [{update_id: 1, message: "Xin chào"}] ④ sendMessage(chat_id, "Chào bạn!") ⑤ Câu trả lời đến app (tức thì) ⑥ getUpdates?offset=2 — đã nhận số 1, lấy tiếp
Trình tự cơ bản: nhận bằng getUpdates, trả lời bằng sendMessage

Giải thích sơ đồ

  • Ba trục: bên trái là người dùng ứng dụng, ở giữa là máy chủ Pabal, bên phải là chương trình bot của bạn. Các đường chấm dọc là chiều thời gian trôi.
  • Mũi tên xám là request do bot chủ động gửi, mũi tên xanh là tin nhắn được chuyển đi như kết quả của các request đó. Chương trình bot chỉ gửi request; máy chủ không chủ động liên lạc với bot trước (trừ khi dùng webhook).
  • Việc chờ ở bước ① (long polling) là điểm mấu chốt: với timeout=30, khi chưa có tin mới, máy chủ không trả về kết quả rỗng ngay mà giữ request tối đa 30 giây, và trả về (③) ngay khi có tin nhắn đến (②). Nhờ vậy bot phản hồi nhanh mà số request lại ít.
  • offset ở bước ⑥ là dấu "đã nhận": gửi update_id cuối cùng đã xử lý cộng thêm 1 thì mọi update từ số đó trở xuống sẽ bị xóa khỏi máy chủ. Nếu không tăng offset, bạn sẽ nhận đi nhận lại cùng một update.
  • Bước ⑤ đi cùng đường với tin nhắn do người gửi: câu trả lời của bot được đẩy đến mọi thiết bị của người dùng và cũng hiện lên trong danh sách trò chuyện.

1. Tạo bot bằng @BotFather

Bot được tạo bằng cách trò chuyện với @BotFather trong ứng dụng Pabal. BotFather là một bot có sẵn bên trong máy chủ Pabal.

  1. Nhập BotFather vào ô tìm kiếm của ứng dụng rồi mở BotFather. Bấm Bắt đầu, bạn sẽ nhận được danh sách lệnh.
  2. Gửi /newbot.
  3. Gửi tên của bot. Đây là tên hiển thị trong danh sách trò chuyện nên có thể dùng tiếng Việt có dấu.
  4. Gửi tên người dùng của bot: dài 5–32 ký tự gồm chữ cái Latin, chữ số và dấu gạch dưới, bắt đầu bằng chữ cái, và bắt buộc phải kết thúc bằng bot.
  5. Khi nhận được câu trả lời có chứa token là xong. Hãy sao chép và giữ lại token.
/newbot
BotFather새 봇을 만듭니다. 봇의 이름을 알려 주세요. (대화 목록에 보이는 이름이에요)
Bot Xin Chào
BotFather좋아요. 이제 봇의 사용자명을 정해 주세요. …
hello_test_bot
BotFather완료! 새 봇 @hello_test_bot 를 만들었어요. 검색해서 대화를 시작할 수 있어요. 봇 토큰: 100003:AbCdEfGhIjKlMnOpQrStUvWxYz0123456789 토큰은 비밀번호처럼 안전하게 보관하세요. …

Hiện tại BotFather trả lời bằng tiếng Hàn. Trong đoạn hội thoại trên, BotFather lần lượt hỏi tên của bot (tên hiển thị trong danh sách trò chuyện), rồi hỏi tên người dùng của bot, và cuối cùng báo đã tạo xong @hello_test_bot, gửi kèm token bot cùng lời nhắc hãy giữ token an toàn như mật khẩu.

Lệnh BotFatherTác dụng
/newbotTạo bot mới (tên → tên người dùng → token)
/mybotsDanh sách bot bạn đã tạo
/tokenXem lại token của bot
/revokeCấp lại token — token cũ mất hiệu lực ngay, các kết nối đang dùng token cũ cũng bị ngắt
/setcommandsThiết lập menu lệnh (mỗi dòng một mục lệnh - mô tả)
/deletebotXóa bot — xác nhận bằng cách gửi 네, 삭제합니다 (nghĩa là "Vâng, xóa đi"). Tên người dùng được giải phóng để có thể dùng lại
/cancelHủy thao tác đang làm dở

Nếu gửi kèm tên người dùng như /token @hello_test_bot, bạn sẽ bỏ qua bước BotFather hỏi "Bot nào?" (어느 봇인가요?).

2. Xử lý token

Token có dạng <ID-bot>:<bí-mật>. Dãy số phía trước là ID người dùng của bot, phần phía sau là bí mật. Chỉ một token là đủ để điều khiển bot hoàn toàn, vì vậy hãy xử lý nó như một mật khẩu.

  • Đừng viết token vào mã nguồn; hãy để trong biến môi trường (BOT_TOKEN) hoặc kho bí mật. Đừng đẩy nó lên kho mã công khai.
  • Nếu bị lộ, gửi /revoke cho BotFather. Token cũ bị từ chối ngay (401 Unauthorized), và phiên bot đang kết nối MTProto bằng token cũ cũng bị ngắt.
  • Token nằm trong địa chỉ (URL), nên đừng để chương trình bot ghi địa chỉ request vào log. Máy chủ Pabal cũng không ghi địa chỉ Bot API vào log.

3. Request đầu tiên — getMe

Địa chỉ của mọi request là https://pabal.me/bot<token>/<phương-thức>. Hãy dùng getMe để kiểm tra token có đúng không.

export BOT_TOKEN='100003:AbCdEf…'
curl -s "https://pabal.me/bot$BOT_TOKEN/getMe"
# pip install requests
import os
import requests

r = requests.get(f"https://pabal.me/bot{os.environ['BOT_TOKEN']}/getMe", timeout=10)
print(r.json())
// Node.js 18 trở lên — có sẵn fetch
const res = await fetch(`https://pabal.me/bot${process.env.BOT_TOKEN}/getMe`);
console.log(await res.json());

Nếu thành công, kết quả trông như sau. Mọi phản hồi đều là JSON chứa okresult (khi thành công) hoặc error_codedescription (khi thất bại).

{
  "ok": true,
  "result": {
    "id": 100003,
    "is_bot": true,
    "first_name": "Bot Xin Chào",
    "username": "hello_test_bot",
    "can_join_groups": true,
    "can_read_all_group_messages": true,
    "supports_inline_queries": false,
    "can_connect_to_business": false,
    "has_main_web_app": false
  }
}

Nếu token sai, bạn nhận HTTP 401 kèm {"ok": false, "error_code": 401, "description": "Unauthorized"}.

4. Nhận tin nhắn — getUpdates

Mở bot trong ứng dụng, bấm Bắt đầu hoặc gửi một tin bất kỳ, rồi lấy tin mới về.

curl -s "https://pabal.me/bot$BOT_TOKEN/getUpdates?timeout=30"
{
  "ok": true,
  "result": [
    {
      "update_id": 1,
      "message": {
        "message_id": 1,
        "from": { "id": 100001, "is_bot": false, "first_name": "Mai" },
        "chat": { "id": 100001, "first_name": "Mai", "type": "private" },
        "date": 1789805661,
        "text": "/start",
        "entities": [ { "type": "bot_command", "offset": 0, "length": 6 } ]
      }
    }
  ]
}
  • update_id: số thứ tự tăng thêm 1 sau mỗi update. Sau khi xử lý, truyền offset=update_id+1 ở request tiếp theo thì mọi update từ số đó trở xuống được coi là "đã nhận" và bị xóa.
  • timeout: số giây chờ khi chưa có tin mới (0–50). Nếu là 0 thì trả về danh sách rỗng ngay lập tức. Nên dùng 25–30.
  • chat.id: nơi gửi câu trả lời. Với trò chuyện 1:1 đó là ID của người dùng (số dương), với nhóm là số âm.
  • Có ba loại update có thể nhận: message (tin nhắn mới), edited_message (tin nhắn đã sửa), callback_query (bấm nút).
Hàng đợi nằm trong bộ nhớ máy chủ

Các update chưa được lấy về được giữ trong bộ nhớ máy chủ, tối đa 1.000 update gần nhất cho mỗi bot. Khi máy chủ khởi động lại, những update chưa lấy sẽ mất (bản thân tin nhắn vẫn còn trong cuộc trò chuyện). Đừng để bot tắt quá lâu.

5. Gửi câu trả lời — sendMessage

curl -s "https://pabal.me/bot$BOT_TOKEN/sendMessage" \
  -H 'Content-Type: application/json' \
  -d '{"chat_id": 100001, "text": "Chào bạn!"}'
requests.post(f"https://pabal.me/bot{os.environ['BOT_TOKEN']}/sendMessage",
              json={"chat_id": 100001, "text": "Chào bạn!"}, timeout=10)
await fetch(`https://pabal.me/bot${process.env.BOT_TOKEN}/sendMessage`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ chat_id: 100001, text: 'Chào bạn!' }),
});

Bạn có thể gửi tham số theo cách nào tiện nhất: phần thân JSON, form (application/x-www-form-urlencoded), multipart/form-data khi tải tệp lên, hoặc chuỗi truy vấn sau địa chỉ. Kết quả là tin nhắn đã gửi (Message).

Bot không thể bắt chuyện trước

Bot chỉ gửi được cho một người sau khi người đó đã gửi cho bot ít nhất một tin nhắn. Nếu không, bạn sẽ nhận 403 Forbidden: bot can't initiate conversation with a user. Quy tắc này giống Telegram.

6. Hoàn thành bot lặp lại lời bạn

Lặp đi lặp lại việc nhận và gửi là bạn đã có một con bot. Đây là toàn bộ mã, viết không cần thư viện.

# echo.py — pip install requests
# Chạy: BOT_TOKEN='100003:…' python3 echo.py
import os
import requests

API = f"https://pabal.me/bot{os.environ['BOT_TOKEN']}"


def call(method, **params):
    r = requests.post(f"{API}/{method}", json=params, timeout=60)
    data = r.json()
    if not data["ok"]:
        raise RuntimeError(f"{method}: {data['description']}")
    return data["result"]


offset = 0
print("Bot đã chạy. Nhấn Ctrl+C để dừng")
while True:
    for update in call("getUpdates", offset=offset, timeout=30):
        offset = update["update_id"] + 1          # đánh dấu đã nhận
        message = update.get("message")
        if message and "text" in message:
            call("sendMessage", chat_id=message["chat"]["id"], text=message["text"])
// echo.mjs — Node.js 18 trở lên, không cần thư viện
// Chạy: BOT_TOKEN='100003:…' node echo.mjs
const API = `https://pabal.me/bot${process.env.BOT_TOKEN}`;

async function call(method, params = {}) {
  const res = await fetch(`${API}/${method}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(params),
  });
  const data = await res.json();
  if (!data.ok) throw new Error(`${method}: ${data.description}`);
  return data.result;
}

let offset = 0;
console.log('Bot đã chạy. Nhấn Ctrl+C để dừng');
for (;;) {
  const updates = await call('getUpdates', { offset, timeout: 30 });
  for (const update of updates) {
    offset = update.update_id + 1;              // đánh dấu đã nhận
    const message = update.message;
    if (message?.text) {
      await call('sendMessage', { chat_id: message.chat.id, text: message.text });
    }
  }
}

7. Xây dựng bằng thư viện

Các thư viện bot cho Telegram đều có tùy chọn đổi địa chỉ máy chủ. Chỉ với tùy chọn đó, bot chạy được nguyên vẹn trên Pabal. Khi chuyển một bot viết cho Telegram sang, bạn cũng chỉ cần đổi mỗi thiết lập này, rồi lấy token mới từ BotFather của Pabal.

Thư việnThiết lập cần đổiPhiên bản đã kiểm tra
python-telegram-bot.base_url("https://pabal.me/bot"), .base_file_url("https://pabal.me/file/bot")22.8
aiogramAiohttpSession(api=TelegramAPIServer.from_base("https://pabal.me"))3.31
Không dùng thư viện (HTTP)Phần đầu địa chỉ https://api.telegram.orghttps://pabal.me
# hello_bot.py — pip install python-telegram-bot
# Chạy: BOT_TOKEN='100003:…' python3 hello_bot.py
import os

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import (Application, CallbackQueryHandler, CommandHandler, ContextTypes,
                          MessageHandler, filters)

SERVER = "https://pabal.me"


def buttons():
    return InlineKeyboardMarkup([[InlineKeyboardButton("👍 Thích", callback_data="like"),
                                  InlineKeyboardButton("🔢 Tăng số", callback_data="count")]])


async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("Xin chào! Hãy thử bấm nút.", reply_markup=buttons())


async def button(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    if query.data == "like":
        await query.answer("Cảm ơn bạn!")                  # dòng chữ hiện thoáng qua trên màn hình người bấm
    else:
        n = context.chat_data.get("n", 0) + 1
        context.chat_data["n"] = n
        await query.answer()                             # trả lời trước
        await query.edit_message_text(f"Số: {n}", reply_markup=buttons())   # rồi sửa tin nhắn


async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text(f"Bạn vừa nói '{update.message.text}'.")


def main():
    app = (Application.builder().token(os.environ["BOT_TOKEN"])
           .base_url(f"{SERVER}/bot")                   # Pabal thay cho api.telegram.org
           .base_file_url(f"{SERVER}/file/bot")
           .build())
    app.add_handler(CommandHandler("start", start))
    app.add_handler(CallbackQueryHandler(button))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
    print("Bot đã chạy. Nhấn Ctrl+C để dừng")
    app.run_polling()


if __name__ == "__main__":
    main()
# echo_aiogram.py — pip install aiogram
# Chạy: BOT_TOKEN='100003:…' python3 echo_aiogram.py
import asyncio
import os

from aiogram import Bot, Dispatcher
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer
from aiogram.filters import CommandStart

dp = Dispatcher()


@dp.message(CommandStart())
async def start(message):
    await message.answer("Xin chào! Hãy gửi cho tôi bất cứ điều gì.")


@dp.message()
async def echo(message):
    if message.text:
        await message.answer(message.text)


async def main():
    session = AiohttpSession(api=TelegramAPIServer.from_base("https://pabal.me"))   # Pabal
    bot = Bot(os.environ["BOT_TOKEN"], session=session)
    print("Bot đã chạy. Nhấn Ctrl+C để dừng")
    await dp.start_polling(bot)


asyncio.run(main())

8. Nút bấm và callback

Để gắn nút inline vào tin nhắn, truyền inline_keyboard (mảng các hàng, mỗi hàng là mảng các nút) vào reply_markup. Có hai loại nút: nút callback_data báo cho bot biết khi được bấm, và nút url mở một liên kết.

curl -s "https://pabal.me/bot$BOT_TOKEN/sendMessage" -H 'Content-Type: application/json' -d '{
  "chat_id": 100001,
  "text": "Hãy chọn một",
  "reply_markup": {
    "inline_keyboard": [
      [ {"text": "👍 Thích", "callback_data": "like"}, {"text": "👎 Không thích", "callback_data": "dislike"} ],
      [ {"text": "Mở tài liệu Pabal", "url": "https://pabal.me/docs/"} ]
    ]
  }
}'

Khi người dùng bấm nút callback_data, bot nhận được update callback_query.

{
  "update_id": 7,
  "callback_query": {
    "id": "5812039457730125441",
    "from": { "id": 100001, "is_bot": false, "first_name": "Mai" },
    "message": { "message_id": 4, "chat": { "id": 100001, "type": "private", "first_name": "Mai" }, "text": "Hãy chọn một", … },
    "chat_instance": "8413962145072395171",
    "data": "like"
  }
}

Bot phải trả lời bằng answerCallbackQuery trong vòng 10 giây. Trong lúc đó, ứng dụng hiện biểu tượng đồng hồ trên nút và chờ.

# Dòng chữ hiện thoáng qua ở đầu màn hình (show_alert: true thì là hộp thoại xác nhận)
curl -s "https://pabal.me/bot$BOT_TOKEN/answerCallbackQuery" -H 'Content-Type: application/json' \
  -d '{"callback_query_id": "5812039457730125441", "text": "Cảm ơn bạn!"}'

# Đổi nội dung và nút của tin nhắn vừa được bấm
curl -s "https://pabal.me/bot$BOT_TOKEN/editMessageText" -H 'Content-Type: application/json' \
  -d '{"chat_id": 100001, "message_id": 4, "text": "Bạn đã bấm Thích 👍"}'
  • callback_data dài 1–64 byte. Mỗi tin nhắn có tối đa 100 nút.
  • Nếu bot không trả lời callback, ứng dụng ngừng chờ sau 10 giây. Nếu bot đang tắt, máy chủ kết thúc ngay.
  • Chỉ câu trả lời đầu tiên có hiệu lực. Có thư viện gửi trước một câu trả lời rỗng khi sửa tin nhắn, nên hãy gửi câu trả lời có nội dung trước.
  • Sửa mà nội dung và nút không đổi sẽ nhận 400 Bad Request: message is not modified (giống Telegram).

Bàn phím dưới ô nhập

Truyền keyboard thì một bảng nút hiện ra thay cho ô nhập, bấm nút nào thì chữ trên nút đó được gửi đi thành tin nhắn. Dùng remove_keyboard để ẩn, và force_reply để bật chế độ trả lời.

{
  "chat_id": 100001,
  "text": "Bạn chọn bên nào?",
  "reply_markup": {
    "keyboard": [ [ {"text": "Có"}, {"text": "Không"} ], [ {"text": "Gửi vị trí của tôi", "request_location": true} ] ],
    "resize_keyboard": true,
    "one_time_keyboard": true
  }
}

9. Menu lệnh

Đây là danh sách hiện ra khi bạn gõ / trong khung trò chuyện hoặc bấm nút Menu. Bạn thiết lập bằng mã hoặc bằng lệnh /setcommands của BotFather.

curl -s "https://pabal.me/bot$BOT_TOKEN/setMyCommands" -H 'Content-Type: application/json' -d '{
  "commands": [
    {"command": "start", "description": "Bắt đầu"},
    {"command": "help",  "description": "Trợ giúp"}
  ]
}'

Lệnh dài 1–32 ký tự gồm chữ Latin thường, chữ số và dấu gạch dưới; mô tả dài 1–256 ký tự; tối đa 100 lệnh. Nếu truyền language_code, danh sách riêng cho từng ngôn ngữ sẽ được lưu, nhưng hiện ứng dụng chỉ hiển thị danh sách mặc định (được đặt không kèm mã ngôn ngữ). Lệnh do người dùng gửi, như /start, được đánh dấu là bot_command trong entities của tin nhắn.

10. Gửi và nhận ảnh

Gửi

Tải tệp lên bằng multipart/form-data, hoặc dùng lại file_id của ảnh đã nhận trước đó. Ảnh tối đa 10MB, chú thích (caption) tối đa 1.024 ký tự. Gửi ảnh bằng URL hiện chưa được hỗ trợ.

curl -s "https://pabal.me/bot$BOT_TOKEN/sendPhoto" \
  -F chat_id=100001 -F caption='Ảnh hôm nay' -F photo=@sunset.jpg
with open("sunset.jpg", "rb") as f:
    requests.post(f"{API}/sendPhoto", data={"chat_id": 100001, "caption": "Ảnh hôm nay"},
                  files={"photo": f}, timeout=60)

Nhận

Ảnh người dùng gửi đến nằm trong trường photo của tin nhắn (danh sách theo kích thước; Pabal chỉ có một ảnh gốc). Dùng getFile để lấy đường dẫn rồi tải xuống.

# 1) file_id → file_path
curl -s "https://pabal.me/bot$BOT_TOKEN/getFile?file_id=AQAAAAAAAAB7…"
# {"ok":true,"result":{"file_id":"AQAA…","file_unique_id":"AQAA…","file_size":48213,"file_path":"photos/AQAA….jpg"}}

# 2) Tải xuống — địa chỉ có thêm /file/
curl -s -o photo.jpg "https://pabal.me/file/bot$BOT_TOKEN/photos/AQAA….jpg"

11. Trong nhóm

  • Khi tạo nhóm trong ứng dụng, hoặc ở Thông tin nhóm → Thêm thành viên, hãy tìm tên người dùng của bot và thêm vào.
  • Bot trong nhóm nhận mọi tin nhắn của nhóm (giống "tắt chế độ riêng tư" trên Telegram). chat.type"group", chat.id là số âm.
  • Gọi sendMessage với chat.id đó là tin nhắn được gửi vào nhóm. Nút bấm, ảnh và sửa tin nhắn cũng hoạt động y như trò chuyện 1:1.
  • Khi bot đã rời nhóm, gửi vào nhóm đó sẽ nhận 403 Forbidden: bot is not a member of the group chat.

12. Chuyển sang webhook

Nếu bot chạy trên máy chủ có địa chỉ HTTPS công khai, thay vì hỏi bằng getUpdates, bạn có thể để máy chủ Pabal tự gửi tin mới đến địa chỉ đó.

curl -s "https://pabal.me/bot$BOT_TOKEN/setWebhook" -H 'Content-Type: application/json' \
  -d '{"url": "https://bot.example.com/pabal-webhook", "secret_token": "chuỗi-ngẫu-nhiên-dài"}'

Thiết lập, xác minh, gửi lại và trả lời ngay trong phản hồi được trình bày trong tài liệu Webhook.

Bot kết nối qua MTProto (Telethon)

Bot cũng có thể kết nối qua MTProto giống ứng dụng. Cách này tiện nếu bạn đã dùng công cụ cho tài khoản người dùng (như Telethon). Vì vẫn là cùng một tài khoản bot, bạn có thể dùng xen kẽ với HTTP.

# pip install telethon==1.42.0   ← hãy dùng 1.42 (giải thích bên dưới)
# Khóa công khai máy chủ: tải https://pabal.me/docs/server-key.pem về cùng thư mục
import asyncio
import os

from telethon import TelegramClient, events
from telethon.crypto import rsa
from telethon.sessions import StringSession

rsa.add_key(open("server-key.pem").read(), old=False)        # khóa công khai của máy chủ Pabal
client = TelegramClient(StringSession(), api_id=1, api_hash="0" * 32)
client.session.set_dc(2, "122.34.175.215", 8443)


@client.on(events.NewMessage(incoming=True))
async def echo(event):
    await event.reply(event.raw_text)


async def main():
    await client.start(bot_token=os.environ["BOT_TOKEN"])      # auth.importBotAuthorization
    print("Bot đã chạy. Nhấn Ctrl+C để dừng")
    await client.run_until_disconnected()


asyncio.run(main())
  • Hãy dùng Telethon 1.42. Pabal dùng layer 216, còn các bản Telethon mới hơn cố đọc phản hồi theo layer cao hơn nên thất bại ngay từ bước đăng nhập (TypeNotFoundError).
  • api_idapi_hash không được Pabal kiểm tra, nên dùng giá trị nào cũng được.
  • Với bot MTProto, máy chủ đẩy tin nhắn mới đến theo thời gian thực (không cần getUpdates hay webhook). Khi trả lời callback, hãy gọi event.answer("…") trước event.edit(…).

Quy tắc và giới hạn

MụcGiá trị
Số ký tự tin nhắn / chú thích ảnh4.096 ký tự / 1.024 ký tự
Kích thước ảnh (tải lên bằng sendPhoto)10MB
Kích thước phần thân request12MB
timeout · limit của getUpdates0–50 giây · 1–100 update
Lưu giữ update chưa lấy1.000 update gần nhất cho mỗi bot, trong bộ nhớ máy chủ (mất khi khởi động lại)
Thời gian chờ trả lời callback10 giây
callback_data · số nút1–64 byte · 100 nút mỗi tin nhắn
Lệnh1–32 ký tự gồm chữ Latin thường, chữ số, dấu gạch dưới; mô tả 1–256 ký tự; tối đa 100 lệnh
Bắt chuyện trướcKhông được — người dùng phải gửi cho bot trước

Xử lý sự cố

Triệu chứngNguyên nhân và cách xử lý
401 UnauthorizedToken sai hoặc đã bị đổi bằng /revoke. Gửi /token cho BotFather để kiểm tra.
404 Not Found: method not foundPhương thức mà Pabal chưa hỗ trợ. Hãy xem danh sách phương thức.
403 Forbidden: bot can't initiate conversation with a userNgười đó chưa từng nhắn cho bot. Hãy nhờ họ mở bot trong ứng dụng và bấm Bắt đầu.
409 Conflict: can't use getUpdates method while webhook is activeĐang có webhook được thiết lập. Hãy gọi deleteWebhook, hoặc nhận qua webhook.
Bấm nút mà không thấy phản ứngBot đang tắt hoặc chưa gọi answerCallbackQuery.
Nhận đi nhận lại cùng một tin nhắnBạn chưa tăng offset. Hãy truyền update_id + 1 của update đã xử lý vào request tiếp theo.
Định dạng in đậm hay liên kết không có tác dụngparse_mode chưa được hỗ trợ nên văn bản được gửi nguyên văn. Lệnh, lượt nhắc (@tên-người-dùng), URL và #hashtag được tự động hiển thị để bấm được.
Bot im lặng trong nhómBot chưa phải là thành viên nhóm. Hãy thêm vào qua Thông tin nhóm → Thêm thành viên.