API Pabal
API Pabal (MTProto)
Pour créer un client qui se connecte au serveur comme l'application : informations de connexion, clé publique du serveur, flux d'authentification, mises à jour, périmètre pris en charge.
L'application Pabal communique avec le serveur en MTProto 2.0. Consultez cette page si vous créez un programme qui se connecte de la même façon : une autre application, une automatisation qui tourne avec un compte utilisateur, un client de recherche. Pour créer un bot, la Bot API, plus simple, suffit.
Pabal suit le protocole public de Telegram : pour la définition détaillée du protocole et des méthodes, la référence reste la documentation MTProto et celle des méthodes de l'API. Cette page décrit ce qui diffère et ce qui est pris en charge quand vous vous connectez à un serveur Pabal.
Informations de connexion
| Élément | Valeur |
|---|---|
| Adresse | 122.34.175.215 |
| Port | 8443 (TCP) |
| DC | De 1 à 5, tous à la même adresse. Vous pouvez vous connecter à n'importe quel DC ; on utilise généralement le 2 |
| Protocole | MTProto 2.0, layer d'API 216 |
| Transports | Abridged, Intermediate, Padded Intermediate, Full — chacun aussi en version obfusquée (obfuscated2) |
| Clé publique du serveur | server-key.pem · empreinte (fingerprint) 8724853375441383205 |
| api_id · api_hash | Non vérifiés. Mettez n'importe quelle valeur |
Les transports HTTP et WebSocket ainsi que MTProxy ne sont pas encore disponibles. L'horloge de l'appareil client doit être à l'heure : les numéros de message MTProto sont dérivés de l'heure, et si l'horloge est très décalée, le serveur rejette les messages.
Clé publique du serveur
Lors de sa première connexion, un client MTProto chiffre l'échange de clé d'autorisation avec la clé publique RSA du serveur. Les clients Telegram intègrent la clé publique de Telegram : pour se connecter à Pabal, ils doivent intégrer cette clé à la place (ou en plus). C'est elle qui empêche un autre serveur de se faire passer pour le serveur 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
Cette clé est générée une seule fois, au premier démarrage du serveur, et ne change plus. Vérifiez que la valeur Loaded RSA key … (fingerprint …) des journaux du serveur correspond à l'empreinte ci-dessus.
Se connecter avec Telethon
Exemple avec Telethon en Python : connexion à un compte utilisateur, puis envoi et réception de messages. Créez d'abord le compte en vous inscrivant depuis l'application (voir plus bas).
# pabal_client.py — pip install telethon==1.42.0
# server-key.pem (la clé publique du serveur téléchargée plus haut) dans le même dossier
import asyncio
from telethon import TelegramClient, events
from telethon.crypto import rsa
rsa.add_key(open("server-key.pem").read(), old=False) # clé publique du serveur Pabal
client = TelegramClient("pabal", api_id=1, api_hash="0" * 32) # connexion enregistrée dans 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("Numéro de téléphone (+336…) : ")) # code à saisir la première fois seulement
me = await client.get_me()
print(f"Connecté : {me.first_name} (id {me.id})")
await client.send_message("BotFather", "/help")
await client.run_until_disconnected()
asyncio.run(main())
- Utilisez Telethon 1.42 : c'est la version qui parle la layer 216. Les versions plus récentes tentent de lire les réponses avec une layer plus élevée et échouent avec
TypeNotFoundError. - Telethon bloque l'inscription de nouveaux comptes (
sign_up()). Inscrivez-vous depuis l'application, ou appelez vous-mêmeauth.signUp. - La connexion est enregistrée dans le fichier
pabal.session: le code ne vous sera plus demandé les fois suivantes. Ce fichier est la clé de votre compte : protégez-le.
Flux de connexion
Explication du diagramme
- Deux étapes : en haut, la création de la clé d'autorisation qui servira au chiffrement (protocole) ; en bas, la connexion qui rattache un compte à cette clé (API). Les bibliothèques se chargent de l'étape du haut à votre place.
- La connexion est rattachée à la clé d'autorisation : toutes les sessions ouvertes avec une clé déjà connectée sont connectées. Si vous perdez la clé (fichier de session supprimé), vous devez vous reconnecter.
- C'est l'opérateur du serveur qui décide par où passe le code : pour les SMS ou la remise par l'administrateur, vous recevez
sentCodeTypeSms; pour l'e-mail,sentCodeTypeSetUpEmailRequired, et le client demande alors une adresse e-mail puis appelleaccount.sendVerifyEmailCode(rangée du milieu). - Les pointillés rouges sont le chemin d'un nouveau numéro : si le code est correct mais qu'aucun compte n'existe, vous recevez
authorizationSignUpRequired; appelez alorsauth.signUpavec un nom, et l'inscription est terminée. L'inscription n'est possible qu'après avoir saisi le bon code. - Les bots se connectent en un seul appel à
auth.importBotAuthorization(jeton du bot), au lieu de l'étape du bas.
| Erreur | Quand |
|---|---|
PHONE_NUMBER_INVALID | Numéro incorrect, ou nouveau numéro alors que le serveur a fermé les inscriptions |
PHONE_NUMBER_BANNED | Numéro bloqué par l'opérateur |
FLOOD_WAIT_n (420) | Codes demandés trop souvent. Réessayez dans n secondes |
PHONE_CODE_INVALID | Code incorrect (verrouillé au-delà du nombre d'essais autorisé) |
PHONE_CODE_EXPIRED | Code expiré ou verrouillé, ou phone_code_hash inconnu — recommencez à partir de sendCode |
EMAIL_INVALID, EMAIL_NOT_ALLOWED | Adresse e-mail incorrecte / compte existant, mais ce n'est pas l'e-mail de connexion enregistré |
AUTH_KEY_UNREGISTERED (401) | Appel, avec une clé non connectée, d'une méthode qui exige une connexion |
Sur un serveur où l'opérateur a activé les numéros de test, les numéros de la forme +99966XYYYY se connectent sans aucun envoi réel de code, avec le code XXXXX (X répété cinq fois). Cette fonction est réservée aux serveurs de développement ; elle est désactivée sur les serveurs de production.
Recevoir les mises à jour
- Temps réel : tant que la connexion est ouverte, le serveur envoie aussitôt les nouveaux messages, modifications et suppressions sous forme de
updateShortMessageetupdates. La session qui a envoyé une requête en reçoit le résultat dans la réponse RPC : elle ne reçoit donc pas la même chose une seconde fois en push. - pts : chaque changement reçoit un numéro d'ordre (pts), propre à chaque utilisateur. Si les pts reçus par le client présentent un trou, c'est qu'il a manqué quelque chose.
- Rattrapage : mémorisez le pts actuel avec
updates.getState; à la reconnexion,updates.getDifference(pts, date, qts)renvoie les nouveaux messages et suppressions survenus entre-temps, avec les utilisateurs et groupes concernés. Si le pts du client est en avance sur celui du serveur (par exemple parce que les données du serveur ont été réinitialisées), vous recevezdifferenceTooLong: rechargez alors la liste des discussions. - Les bibliothèques comme Telethon gèrent tout cela automatiquement.
ID et pairs
| Cible | ID | Remarque |
|---|---|---|
| Personne | À partir de 100001 | peerUser. @BotFather a l'ID 100000 |
| Bot | Même numérotation que les personnes | user.bot = true. Le nombre au début du jeton est l'ID du bot |
| Groupe simple | À partir de 1000001 | peerChat. Dans la Bot API, il apparaît en négatif (-chat_id) |
| Message | À partir de 1 dans chaque boîte de messages | Dans une conversation 1:1, chaque participant possède sa propre copie avec sa propre numérotation. Un même message peut donc porter un numéro différent pour chacune des deux personnes |
Enregistrez tel quel l'access_hash fourni par le serveur et réutilisez-le (il accompagne les résolutions de nom d'utilisateur, la liste des discussions et les mises à jour).
Fichiers
- Téléversement : envoyez les morceaux avec
upload.saveFilePart, puis référencez-les avecinputFileUploaded… Quant àupload.saveBigFilePart, destiné aux gros fichiers, il n'existe pas encore : la limite est donc en pratique de 10 Mo. - Envoi :
messages.sendMediaavecinputMediaUploadedPhoto(nouvelle photo) ouinputMediaPhoto(photo déjà présente sur le serveur). Les autres médias renvoientMEDIA_INVALID. - Réception :
upload.getFileavecinputPhotoFileLocation(photo d'un message) ouinputPeerPhotoFileLocation(photo de profil). 1 Mo au maximum par appel. - Photo de profil :
photos.uploadProfilePhoto,photos.updateProfilePhoto,photos.getUserPhotos,photos.deletePhotos. - Les photos ne sont stockées qu'en une seule taille, celle de l'original (aucune miniature n'est générée).
Périmètre pris en charge
Le serveur dispose de gestionnaires pour 408 méthodes de la layer 216, et tous savent lire les requêtes ; mais seules les méthodes ci-dessous ont été vérifiées de bout en bout avec de vrais clients. Les autres répondent dans le bon format, mais leur contenu peut être vide ou ne pas être enregistré.
| Domaine | Méthodes vérifiées |
|---|---|
| Connexion | initConnection, invokeWithLayer, help.getConfig, auth.bindTempAuthKey (clé temporaire PFS), auth.exportAuthorization/importAuthorization |
| Authentification | auth.sendCode, auth.signIn, auth.signUp, auth.logOut, auth.importBotAuthorization, account.sendVerifyEmailCode |
| Utilisateurs et contacts | users.getUsers, users.getFullUser, contacts.resolveUsername, contacts.importContacts, contacts.search |
| Messages | messages.sendMessage, messages.sendMedia (photos), messages.getHistory, messages.getDialogs, messages.getMessages, messages.editMessage, messages.deleteMessages |
| Groupes | messages.createChat, messages.deleteChatUser, messages.editChatTitle (messages.addChatUser vérifié uniquement avec l'application officielle) |
| Bots | messages.getBotCallbackAnswer, messages.setBotCallbackAnswer, messages portant des boutons (reply_markup) |
| Mises à jour | updates.getState, updates.getDifference, push en temps réel |
| Fichiers et photos | upload.saveFilePart, upload.getFile, photos.* (ci-dessus) |
Nous avons aussi vérifié que Telegram Desktop 6.2.6 officiel fonctionne sans modification pour l'inscription, la connexion, les conversations, les photos, les groupes et la reconnexion. Le format de réponse des quelque 60 méthodes que l'application appelle au démarrage fait l'objet d'une vérification spécifique.
Erreurs
Les erreurs arrivent sous la forme standard rpc_error (error_code + error_message). error_message est toujours composé de majuscules, de chiffres et de tirets bas (PEER_ID_INVALID), suivi si nécessaire de : explication.
| Code | Signification |
|---|---|
400 | Requête incorrecte — PEER_ID_INVALID, MESSAGE_ID_INVALID, MEDIA_INVALID, USERNAME_NOT_OCCUPIED … |
401 | Connexion requise — AUTH_KEY_UNREGISTERED |
403 | Pas d'autorisation — par exemple, un groupe dont vous n'êtes pas membre |
420 | FLOOD_WAIT_n — attendre n secondes |
500 | Erreur interne du serveur |
Erreur de transport -404 | Le serveur ne connaît pas cette clé d'autorisation — créez une nouvelle clé et reconnectez-vous (clé permanente), ou refaites la liaison (clé temporaire) |
Ce qui n'existe pas encore
- Canaux et supergroupes (
channels.*répond, mais ils ne s'affichent pas correctement dans l'application), conversations secrètes, appels - Médias autres que les photos,
upload.saveBigFilePart, miniatures - Validation en deux étapes (SRP) — impossible à configurer, et les opérations qui l'exigent sont refusées
- Transports HTTP et WebSocket, MTProxy, envoi de
msgs_ack, remplacement debad_server_salt - Répartition sur plusieurs serveurs — un seul serveur assure tous les DC de 1 à 5
Connecter l'application Telegram officielle à Pabal
L'application Telegram intègre l'adresse du serveur et la clé publique au moment de la compilation. Il faut donc modifier le code source et recompiler : un écran de réglages ne suffit pas. C'est ainsi qu'a été créée l'application Pabal (Pabal.app). Si vous êtes opérateur de serveur, consultez Installation du serveur — connecter l'application.