Pabal API
Pabal API (MTProto)
Khi xây dựng client kết nối đến máy chủ theo cùng cách với ứng dụng: thông tin kết nối, khóa công khai của máy chủ, luồng xác thực, update và phạm vi hỗ trợ.
Ứng dụng Pabal giao tiếp với máy chủ bằng MTProto 2.0. Hãy đọc tài liệu này khi bạn xây dựng chương trình kết nối theo cùng cách đó — một ứng dụng khác, công cụ tự động hóa chạy bằng tài khoản người dùng, hay client phục vụ nghiên cứu. Nếu bạn tạo bot, Bot API đơn giản hơn là đủ dùng.
Pabal tuân theo giao thức công khai của Telegram, nên định nghĩa chi tiết của giao thức và các phương thức lấy tài liệu MTProto và phương thức API làm chuẩn. Tài liệu này ghi lại những điểm khác biệt và phạm vi hỗ trợ khi kết nối đến máy chủ Pabal.
Thông tin kết nối
| Mục | Giá trị |
|---|---|
| Địa chỉ | 122.34.175.215 |
| Cổng | 8443 (TCP) |
| DC | Cả DC 1–5 đều cùng một địa chỉ. Kết nối vào DC nào cũng được, thường dùng DC 2 |
| Giao thức | MTProto 2.0, API layer 216 |
| Kiểu truyền tải | Abridged, Intermediate, Padded Intermediate, Full — mỗi kiểu đều có bản làm rối (obfuscated2) |
| Khóa công khai máy chủ | server-key.pem · fingerprint 8724853375441383205 |
| api_id · api_hash | Không được kiểm tra. Điền giá trị nào cũng được |
Hiện chưa có truyền tải qua HTTP, WebSocket, cũng như MTProxy. Đồng hồ trên thiết bị client phải chính xác — số hiệu tin nhắn MTProto được tạo từ thời gian, nên nếu đồng hồ lệch nhiều, máy chủ sẽ bỏ các tin nhắn đó.
Khóa công khai của máy chủ
Khi kết nối lần đầu, client MTProto dùng khóa công khai RSA của máy chủ để mã hóa quá trình trao đổi khóa xác thực. Client Telegram có sẵn khóa công khai của Telegram bên trong, nên muốn kết nối đến Pabal thì phải nhúng khóa này thay vào (hoặc thêm vào). Chính khóa này ngăn máy chủ khác giả làm máy chủ Pabal.
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA4hH74xPQsUwr/pyXPdF4tVicYr6QbfeDrKC7mUOVrPLSL4FtmgGn
w+O4u6lVvOf3Udd1KY6+OL4fUZdMBlLzwsoGLoniiVR09dnvyXHE8LhQSS+i1LmI
oJbhQwXplLnUJf272fLXkD23e7ppKLkjYk+jeYObueCy5HYMSThklVeXEzbZVGZv
47o/mjU2vyFoRpa6wCIE4rpj1UIPtOMpekMI/TocIlGVJ+ch6cAVNxIDro53a1eG
/1oZRLQH4oViEGxeMMjBMY5gk5HPkZvjbqy4h8TjXEz7O5o0BRsSqG/OPtP/dRQV
X4ewPhj2WCU4e6l5X59ZKIcv4sQLOwClqQIDAQAB
-----END RSA PUBLIC KEY-----
curl -s -o server-key.pem https://pabal.me/docs/server-key.pem
Khóa này được tạo một lần khi máy chủ chạy lần đầu và không thay đổi. Hãy kiểm tra giá trị Loaded RSA key … (fingerprint …) trong log máy chủ có khớp với fingerprint ở trên không.
Kết nối bằng Telethon
Ví dụ dùng Telethon của Python để đăng nhập bằng tài khoản người dùng và nhắn tin qua lại. Hãy đăng ký tài khoản trong ứng dụng trước (xem bên dưới).
# pabal_client.py — pip install telethon==1.42.0
# Đặt server-key.pem (khóa công khai máy chủ đã tải ở trên) trong cùng thư mục
import asyncio
from telethon import TelegramClient, events
from telethon.crypto import rsa
rsa.add_key(open("server-key.pem").read(), old=False) # khóa công khai của máy chủ Pabal
client = TelegramClient("pabal", api_id=1, api_hash="0" * 32) # lưu trạng thái đăng nhập vào pabal.session
client.session.set_dc(2, "122.34.175.215", 8443)
@client.on(events.NewMessage(incoming=True))
async def show(event):
sender = await event.get_sender()
print(f"{sender.first_name}: {event.raw_text}")
async def main():
await client.start(phone=lambda: input("Số điện thoại (+849…): ")) # nhập mã một lần đầu tiên
me = await client.get_me()
print(f"Đã đăng nhập: {me.first_name} (id {me.id})")
await client.send_message("BotFather", "/help")
await client.run_until_disconnected()
asyncio.run(main())
- Hãy dùng Telethon 1.42. Đây là bản dùng layer 216. Các bản mới hơn cố đọc phản hồi theo layer cao hơn nên thất bại với
TypeNotFoundError. - Telethon đã chặn việc đăng ký tài khoản mới (
sign_up()). Hãy đăng ký trong ứng dụng, hoặc tự gọiauth.signUp. - Trạng thái đăng nhập được lưu vào tệp
pabal.session, nên từ lần sau sẽ không hỏi mã nữa. Tệp này là chìa khóa của tài khoản, hãy giữ nó cẩn thận.
Luồng đăng nhập
Giải thích sơ đồ
- Hai giai đoạn: phía trên là giai đoạn tạo khóa xác thực dùng để mã hóa (giao thức), phía dưới là giai đoạn đăng nhập gắn tài khoản vào khóa đó (API). Thư viện sẽ tự lo giai đoạn phía trên.
- Trạng thái đăng nhập gắn với khóa xác thực: dù mở nhiều phiên bằng khóa đã đăng nhập, tất cả đều ở trạng thái đăng nhập. Nếu mất khóa (xóa tệp phiên) thì phải đăng nhập lại.
- Mã được gửi theo đường nào là do người vận hành máy chủ quyết định: nếu là SMS hoặc quản trị viên chuyển thì nhận
sentCodeTypeSms; nếu là email thì nhậnsentCodeTypeSetUpEmailRequired, khi đó client hỏi địa chỉ email rồi gọiaccount.sendVerifyEmailCode(hàng giữa). - Nét đứt màu đỏ là đường của số mới: nếu mã đúng nhưng chưa có tài khoản, bạn nhận
authorizationSignUpRequired; nhập tên và gọiauth.signUplà hoàn tất đăng ký. Chỉ đăng ký được sau khi đã nhập đúng mã. - Bot không đi qua giai đoạn phía dưới mà đăng nhập bằng một lần gọi
auth.importBotAuthorization(token bot).
| Lỗi | Khi nào |
|---|---|
PHONE_NUMBER_INVALID | Số sai, hoặc là số mới trong lúc máy chủ đang đóng đăng ký mới |
PHONE_NUMBER_BANNED | Số đã bị người vận hành chặn |
FLOOD_WAIT_n (420) | Yêu cầu mã quá thường xuyên. Thử lại sau n giây |
PHONE_CODE_INVALID | Mã sai (vượt quá số lần cho phép thì bị khóa) |
PHONE_CODE_EXPIRED | Mã đã hết hạn hoặc bị khóa, hoặc phone_code_hash không xác định — bắt đầu lại từ sendCode |
EMAIL_INVALID, EMAIL_NOT_ALLOWED | Địa chỉ email sai / tài khoản đã tồn tại nhưng đây không phải email đăng nhập đã đăng ký |
AUTH_KEY_UNREGISTERED (401) | Gọi phương thức cần đăng nhập bằng khóa chưa đăng nhập |
Trên máy chủ mà người vận hành bật số thử nghiệm, các số có dạng +99966XYYYY đăng nhập được bằng mã XXXXX (lặp X năm lần) mà không cần gửi mã thật. Tính năng này chỉ dùng cho máy chủ phát triển và bị tắt trên máy chủ vận hành thật.
Nhận update
- Thời gian thực: khi kết nối đang mở, máy chủ gửi ngay tin nhắn mới, sửa, xóa dưới dạng
updateShortMessage,updates. Phiên đã gửi request nhận kết quả qua phản hồi RPC, nên sẽ không nhận thêm một lần nữa qua thông báo đẩy. - pts: mỗi thay đổi của từng người dùng được gắn một số thứ tự (pts). Nếu pts nhận được có khoảng trống thì client đã bỏ lỡ điều gì đó.
- Bắt kịp: ghi nhớ pts hiện tại bằng
updates.getState, và khi kết nối lại thì dùngupdates.getDifference(pts, date, qts)để nhận tin nhắn mới, lượt xóa trong khoảng đó cùng người dùng và nhóm liên quan. Nếu pts mà client đang giữ vượt trước máy chủ (ví dụ khi dữ liệu máy chủ đã bị khởi tạo lại), bạn sẽ nhậndifferenceTooLong, khi đó hãy tải lại danh sách trò chuyện. - Các thư viện như Telethon tự lo toàn bộ quá trình này.
ID và peer
| Đối tượng | ID | Ghi chú |
|---|---|---|
| Người | Từ 100001 | peerUser. @BotFather là 100000 |
| Bot | Cùng hệ thống số với người | user.bot = true. Dãy số trước token là ID của bot |
| Nhóm thường | Từ 1000001 | peerChat. Trong Bot API hiển thị là số âm (-chat_id) |
| Tin nhắn | Từ 1 trong mỗi hộp thư | Trong trò chuyện 1:1, mỗi người tham gia có bản sao và số hiệu riêng. Cùng một tin nhắn có thể mang số khác nhau đối với hai người |
Hãy lưu nguyên giá trị access_hash mà máy chủ cấp để dùng về sau (nó đi kèm khi tra cứu tên người dùng, trong danh sách trò chuyện và trong update).
Tệp
- Tải lên: tải từng phần bằng
upload.saveFilePartvà tham chiếu bằnginputFileUploaded…. Chưa cóupload.saveBigFilePartcho tệp lớn, nên trên thực tế tối đa là 10MB. - Gửi: dùng
messages.sendMediavớiinputMediaUploadedPhoto(ảnh mới) hoặcinputMediaPhoto(ảnh đã có trên máy chủ). Các phương tiện khác trả vềMEDIA_INVALID. - Nhận: dùng
upload.getFilevớiinputPhotoFileLocation(ảnh trong tin nhắn),inputPeerPhotoFileLocation(ảnh đại diện). Tối đa 1MB mỗi lần. - Ảnh đại diện:
photos.uploadProfilePhoto,photos.updateProfilePhoto,photos.getUserPhotos,photos.deletePhotos. - Ảnh chỉ được lưu ở một kích thước gốc (không tạo ảnh thu nhỏ riêng).
Phạm vi hỗ trợ
Máy chủ có bộ xử lý cho 408 phương thức của layer 216 và tất cả đều đọc được request, nhưng những phương thức đã được kiểm chứng trọn vẹn bằng client thật là các phương thức dưới đây. Các phương thức còn lại trả lời đúng định dạng nhưng nội dung có thể rỗng hoặc không được ghi lại.
| Lĩnh vực | Phương thức đã kiểm chứng |
|---|---|
| Kết nối | initConnection, invokeWithLayer, help.getConfig, auth.bindTempAuthKey (khóa tạm thời PFS), auth.exportAuthorization/importAuthorization |
| Đăng nhập | auth.sendCode, auth.signIn, auth.signUp, auth.logOut, auth.importBotAuthorization, account.sendVerifyEmailCode |
| Người dùng, danh bạ | users.getUsers, users.getFullUser, contacts.resolveUsername, contacts.importContacts, contacts.search |
| Tin nhắn | messages.sendMessage, messages.sendMedia (ảnh), messages.getHistory, messages.getDialogs, messages.getMessages, messages.editMessage, messages.deleteMessages |
| Nhóm | messages.createChat, messages.deleteChatUser, messages.editChatTitle (messages.addChatUser chỉ mới kiểm chứng bằng ứng dụng chính thức) |
| Bot | messages.getBotCallbackAnswer, messages.setBotCallbackAnswer, tin nhắn có gắn nút (reply_markup) |
| Update | updates.getState, updates.getDifference, thông báo đẩy thời gian thực |
| Tệp, ảnh | upload.saveFilePart, upload.getFile, photos.* (ở trên) |
Chúng tôi cũng đã kiểm chứng Telegram Desktop chính thức 6.2.6 hoạt động không cần sửa đổi, từ đăng ký, đăng nhập, trò chuyện, ảnh, nhóm cho đến kết nối lại. Khoảng 60 phương thức mà ứng dụng gọi khi khởi động được kiểm tra định dạng phản hồi riêng.
Lỗi
Lỗi được trả về dưới dạng rpc_error chuẩn (error_code + error_message). error_message luôn có dạng chữ hoa, chữ số và dấu gạch dưới (PEER_ID_INVALID), và khi cần sẽ có thêm : mô tả phía sau.
| Mã | Ý nghĩa |
|---|---|
400 | Request sai — PEER_ID_INVALID, MESSAGE_ID_INVALID, MEDIA_INVALID, USERNAME_NOT_OCCUPIED … |
401 | Cần đăng nhập — AUTH_KEY_UNREGISTERED |
403 | Không có quyền — ví dụ nhóm mà bạn không phải thành viên |
420 | FLOOD_WAIT_n — chờ n giây |
500 | Lỗi nội bộ máy chủ |
Lỗi truyền tải -404 | Máy chủ không biết khóa xác thực này — tạo khóa mới rồi đăng nhập lại (khóa vĩnh viễn) hoặc gắn lại (khóa tạm thời) |
Những gì chưa có
- Kênh và siêu nhóm (
channels.*có trả lời nhưng không hiển thị đúng trong ứng dụng), trò chuyện bí mật, cuộc gọi - Phương tiện ngoài ảnh,
upload.saveBigFilePart, ảnh thu nhỏ - Xác minh hai bước (SRP) — không thể thiết lập, và các thao tác cần xác minh hai bước đều bị từ chối
- Truyền tải qua HTTP và WebSocket, MTProxy, gửi
msgs_ack, thaybad_server_salt - Chia ra nhiều máy chủ — một máy chủ đảm nhận cả DC 1–5
Để kết nối ứng dụng Telegram chính thức với Pabal
Ứng dụng Telegram nhúng địa chỉ máy chủ và khóa công khai vào bên trong lúc build. Vì vậy không đổi được trong màn hình cài đặt mà phải sửa mã nguồn rồi build lại. Ứng dụng Pabal (Pabal.app) chính là được làm như vậy. Nếu bạn là người vận hành máy chủ, hãy xem Cài đặt máy chủ — kết nối ứng dụng.