Telegram Bot API
🌐 Tiếng Việt

API gửi tin nhắn Telegram: hướng dẫn sendMessage với curl, Python và JavaScript

· 7 phút đọc

Để dùng API gửi tin nhắn Telegram, bạn gọi method sendMessage tại https://api.telegram.org/bot<token>/sendMessage với hai tham số bắt buộc: chat_id và text. Bài này có ví dụ copy-paste bằng curl, Python và JavaScript, cách định dạng HTML/MarkdownV2, thêm nút inline, gửi vào group, kênh và xử lý các lỗi hay gặp.

Cấu trúc request sendMessage

Bot API nhận cả GET và POST; tham số có thể truyền qua query string, application/x-www-form-urlencoded, application/json hoặc multipart/form-data. Phản hồi luôn là JSON: thành công có "ok": true và đối tượng Message trong result; thất bại có "ok": false, error_code và description.

Tham sốÝ nghĩa
chat_idID dạng số hoặc @tenkenh (bắt buộc)
textNội dung, 1–4096 ký tự sau khi xử lý định dạng (bắt buộc)
parse_modeHTML, MarkdownV2 hoặc Markdown (kiểu cũ)
reply_markupBàn phím inline hoặc bàn phím trả lời
message_thread_idID topic trong group có topic
disable_notification, protect_content, link_preview_options, reply_parametersGửi im lặng, chặn chuyển tiếp và lưu, tùy chỉnh xem trước link, trả lời một tin cụ thể

Gửi tin nhắn bằng curl

export TOKEN="123456789:AAEexampleTokenReplaceWithYours"

curl -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{"chat_id": 123456789, "text": "Đơn hàng #1024 đã được giao thành công."}'

Telegram bot Python: send message với requests

import os
import requests

API = f"https://api.telegram.org/bot{os.environ['TOKEN']}"

def send_message(chat_id, text, **params):
    resp = requests.post(f"{API}/sendMessage",
                         json={"chat_id": chat_id, "text": text, **params},
                         timeout=10)
    data = resp.json()
    if not data["ok"]:
        raise RuntimeError(f"{data['error_code']}: {data['description']}")
    return data["result"]

msg = send_message(123456789, "Xin chào từ Python!")
print(msg["message_id"])

Các thư viện như python-telegram-bot hay aiogram bọc sẵn method này thành send_message(), nhưng tham số vẫn y hệt Bot API.

JavaScript với fetch (Node.js 18+)

// lưu thành file .mjs để dùng await ở cấp cao nhất
const API = `https://api.telegram.org/bot${process.env.TOKEN}`;

const res = await fetch(`${API}/sendMessage`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ chat_id: 123456789, text: "Xin chào từ Node.js!" }),
});
const data = await res.json();
if (!data.ok) throw new Error(`${data.error_code}: ${data.description}`);

Chỉ chạy đoạn này ở backend: đặt token trong JavaScript của trình duyệt đồng nghĩa với việc công khai nó.

Định dạng: parse_mode HTML và MarkdownV2

HTML hỗ trợ các thẻ <b>, <strong>, <i>, <em>, <u>, <ins>, <s>, <strike>, <del>, <tg-spoiler>, <a href>, <code>, <pre>, <blockquote> (kể cả <blockquote expandable>). Ký tự <, >, & trong nội dung phải viết thành &lt;, &gt;, &amp;:

import html

name = "Tôm & Cua <Bình Thạnh>"
send_message(123456789,
             f"<b>Đơn mới</b> từ {html.escape(name, quote=False)}\n"
             "<a href=\"https://example.com/don/1024\">Xem chi tiết</a>",
             parse_mode="HTML")

MarkdownV2 bắt buộc escape bằng dấu \ các ký tự _ * [ ] ( ) ~ ` > # + - = | { } . ! (và chính dấu \). Quên một ký tự, Telegram trả lỗi Bad Request: can't parse entities: Character '.' is reserved and must be escaped with the preceding '\'. Hàm escape cho nội dung động:

import re

def escape_md(text):
    return re.sub(r"([_*\[\]()~`>#+\-=|{}.!\\])", r"\\\1", text)

send_message(123456789, f"*Tổng tiền:* {escape_md('1.250.000đ (đã gồm VAT)')}",
             parse_mode="MarkdownV2")

Thêm nút bấm inline với reply_markup

{
  "chat_id": 123456789,
  "text": "Bạn muốn làm gì tiếp?",
  "reply_markup": {
    "inline_keyboard": [[
      {"text": "Mở website", "url": "https://example.com"},
      {"text": "Xác nhận", "callback_data": "confirm:1024"}
    ]]
  }
}

callback_data dài 1–64 byte, không phải 64 ký tự: chữ tiếng Việt có dấu chiếm 2–3 byte trong UTF-8, nên chỉ nên lưu mã ngắn không dấu. Khi người dùng bấm, bot nhận update callback_query và cần gọi answerCallbackQuery để kết thúc trạng thái chờ trên nút.

Gửi vào group, kênh và topic

Chưa có ID? Xem bài chat id Telegram lấy ở đâu.

Gửi im lặng, tắt xem trước link

{
  "chat_id": 123456789,
  "text": "Bản tin tối: https://example.com/ban-tin",
  "disable_notification": true,
  "protect_content": true,
  "link_preview_options": {"is_disabled": true}
}

Lỗi thường gặp khi gửi tin nhắn

LỗiNguyên nhân và cách xử lý
400 Bad Request: chat not foundSai chat_id, thiếu tiền tố -100, người dùng chưa bấm Start hoặc bot không ở trong group.
400 Bad Request: can't parse entitiesSai cú pháp HTML hoặc chưa escape ký tự MarkdownV2.
400 Bad Request: message is too longVượt 4096 ký tự; tách tin nhắn.
403 Forbidden: bot was blocked by the userNgười dùng đã chặn bot; ngừng gửi cho chat này.
429 Too Many Requests: retry after NGửi quá nhanh; chờ đúng parameters.retry_after giây rồi thử lại.

Nên giữ nhịp khoảng 1 tin mỗi giây trong một chat, không quá 20 tin mỗi phút trong group và khoảng 30 tin mỗi giây khi gửi hàng loạt. Xử lý 429 trong Python:

import time

def send_with_retry(payload, attempts=3):
    for _ in range(attempts):
        data = requests.post(f"{API}/sendMessage", json=payload, timeout=10).json()
        if data["ok"]:
            return data["result"]
        retry = data.get("parameters", {}).get("retry_after")
        if data["error_code"] != 429 or not retry:
            raise RuntimeError(data["description"])
        time.sleep(retry)
    raise RuntimeError("Vẫn bị giới hạn tốc độ sau nhiều lần thử")

Thử ngay trên trình duyệt

Mở sendMessage trong Bot API Tester, dán token, điền chat_id, text, parse_mode rồi bấm chạy để xem JSON phản hồi. Danh sách tham số đầy đủ có ở trang tham chiếu sendMessage. Mới bắt đầu? Đọc bài cách tạo bot Telegram; muốn bot tự trả lời khi chạy trên server, xem bài webhook Telegram bot.

Câu hỏi thường gặp

Tin nhắn Telegram gửi qua bot dài tối đa bao nhiêu ký tự?

Tham số text của sendMessage nhận 1–4096 ký tự sau khi xử lý định dạng. Dài hơn sẽ gặp lỗi message is too long, hãy tách thành nhiều tin.

Nên dùng parse_mode HTML hay MarkdownV2?

Với nội dung động, HTML dễ hơn vì chỉ cần escape <, > và &. MarkdownV2 yêu cầu escape 18 ký tự đặc biệt, quên một ký tự là gặp lỗi can't parse entities.

Bot có tự nhắn tin trước cho người dùng được không?

Không. Người dùng phải bấm Start hoặc nhắn cho bot trước. Nếu chưa, sendMessage trả về lỗi như chat not found hoặc bot can't initiate conversation with a user.

Làm sao gửi tin nhắn không có âm báo?

Thêm "disable_notification": true. Người nhận vẫn thấy tin nhắn, chỉ là thông báo không phát âm thanh.

Bot gửi được bao nhiêu tin nhắn mỗi giây?

Khoảng 1 tin mỗi giây trong một chat, tối đa 20 tin mỗi phút trong một group và khoảng 30 tin mỗi giây khi gửi hàng loạt. Vượt giới hạn sẽ nhận lỗi 429 kèm retry_after.

Cách tạo bot Telegram từ A đến Z: BotFather, token và tin nhắn đầu tiên

Tạo bot Telegram miễn phí với @BotFather: chọn username, lấy token, kiểm tra bằng getMe, tìm chat id và gửi tin nhắn đầu tiên bằng curl, Python.

Cách lấy token bot Telegram: tìm lại, kiểm tra bằng getMe và thu hồi khi bị lộ

Cách lấy token bot Telegram từ @BotFather, xem lại token của bot cũ, kiểm tra bằng getMe, sửa lỗi 401 Unauthorized và thu hồi token khi bị lộ.

Webhook Telegram bot: cài setWebhook, bảo mật bằng secret_token và dùng với n8n

Cài webhook Telegram bot từng bước: yêu cầu HTTPS và cổng, setWebhook với secret_token, kiểm tra getWebhookInfo, sửa lỗi 409 Conflict và webhook n8n.

Chat id Telegram lấy ở đâu? Cách lấy chat id cho người dùng, group, kênh và topic

Chat id Telegram lấy ở đâu: cách lấy chat id bot cho chat riêng, group, supergroup, kênh và topic bằng getUpdates, kèm cách sửa lỗi result rỗng, 409.