Telegram are două API-uri. Bot API, castrat, restricționat, limitat la ce a decis Telegram că au voie să facă boții. Și MTProto, protocolul propriu-zis pe care îl folosește telefonul tău, cu acces complet la cont, fără restricții. Boții nu pot citi istoricul mesajelor de dinainte să intre într-un chat. Boții nu pot vedea cine e într-un grup privat în care nu sunt. Boții nu pot acționa în numele tău. MTProto poate.
Telethon e un client MTProto în Python. telethon-plus îl împachetează într-un container Docker, cu un API REST peste HTTP și un server MCP. Dai POST cu niște JSON, sau îndrepți un agent AI spre /mcp/, iar chestia vorbește cu Telegram în numele tău, cu acces complet la cont. Un singur login. Un singur session string. Nu mai scrii niciodată un cod.
Userbot, Nu Bot
Ăsta e un userbot, nu un bot. Distincția contează.
Un bot e ce îți dă BotFather. Acces de scriere limitat, fără istoric de mesaje, fără apartenență la grupuri fără invitație explicită, nu poate reacționa la majoritatea evenimentelor. Bot API e în regulă pentru trimis notificări. E inutil pentru orice cere citirea a ce se întâmplă de fapt în chaturile tale.
Un userbot e contul tău, controlat programatic. Același acces pe care îl ai când deschizi Telegram pe telefon. Citești fiecare mesaj din fiecare chat în care ești. Trimiți mesaje ca tine însuți. Forwardezi, ștergi, editezi. Intri în grupuri. Creezi canale. Acționezi cu identitatea ta reală, cu istoric complet, cu vizibilitate completă.
Dezavantajul: e contul tău. Dacă abuzezi de el, îți ia contul ban. Telegram te limitează agresiv (FloodWaitError). Nu da spam. Folosește-l pentru ce e făcut: acces programatic la Telegramul tău, nu mesagerie în masă.
Pornire Rapidă
services:
telethon-plus:
image: psyb0t/telethon-plus
ports:
- "8080:8080"
environment:
TELETHON_API_ID: "123456"
TELETHON_API_HASH: "your-api-hash"
TELETHON_SESSION: "1Aa...long-string-from-login..."
TELETHON_AUTH_KEY: "your-bearer-token"
restart: unless-stoppedIei API_ID și API_HASH de la my.telegram.org/apps. Session stringul îl iei de la ajutorul de login.
Primul Login
Telegram te pune o dată să dovedești că ești om: număr de telefon, cod prin SMS, opțional 2FA. Containerul are un mod de login interactiv care te plimbă prin toată treaba și scuipă un session string la final:
docker run --rm -it
-e TELETHON_API_ID=123456
-e TELETHON_API_HASH=your-api-hash
psyb0t/telethon-plus loginSau, dacă ai clonat repo-ul: cp .env.example .env, completezi TELETHON_API_ID și TELETHON_API_HASH, apoi make login, care construiește imaginea, rulează fluxul și scrie TELETHON_SESSION direct în .env-ul tău.
Session stringul înseamnă acces complet la cont. Cine îl are, ăla ești tu. Nu îl comite. Nu îl lipi pe Slack. Nu ți-l tatua nicăieri.
Uneltele
Același registru de unelte, două suprafețe. Fiecare unealtă funcționează și ca endpoint REST, și ca unealtă MCP: JSON la intrare, JSON la ieșire, validat pe schemă de pydantic. Trimiți gunoi, primești înapoi 400 cu exact ce e greșit.
- get_me: întoarce profilul contului autorizat
- get_entity: rezolvă un username, ID sau link într-un profil complet
- send_message: trimite un mesaj text (Markdown/HTML, reply, silențios, previzualizare de link)
- get_messages: citește mesajele recente dintr-un chat (cele noi primele, căutare, paginare)
- get_dialogs: listează chaturile, grupurile și canalele tale
- forward_messages: forwardează mesaje între chaturi
- delete_messages: șterge mesaje după ID (revocă pentru toți sau doar pentru tine)
- edit_message: editează un mesaj trimis de tine
- mark_read: marchează mesajele dintr-un chat ca citite
- send_file: descarcă un fișier de la un URL HTTPS și îl trimite într-un chat
- get_participants: listează membrii unui grup sau canal
- create_group: creează un supergrup nou sau un canal de difuzare
- delete_chat: șterge un supergrup sau canal pe care îl deții
- join_chat: intră într-un canal public sau supergrup
- leave_chat: părăsește un canal sau supergrup
- get_message: aduce un singur mesaj după ID
- download_media: trage înapoi media unui mesaj ca base64
- bulk_resolve: rezolvă multe username-uri sau ID-uri într-un singur apel, în loc de N dus-întorsuri
- set_reaction / remove_reaction: reacționează la mesaje
- pin_message / unpin_message: administrare de mesaje fixate
- create_poll, vote_poll, get_poll_results: sondaje cap-coadă
- promote_user, demote_user, ban_user, unban_user, kick_user: administrare de canal
- join_via_invite: intră printr-un link de invitație privat
- get_linked_chat: grupul de discuții din spatele unui canal, sau invers
- account_health: e contul ăsta în belea cu Telegram chiar acum
- throttle_status: ce crede limitatorul de rată în momentul de față
Treizeci și patru de unelte în total, și fiecare dintre ele funcționează identic prin REST și prin MCP.
Referințele de chat acceptă ce acceptă Telethon: @username, numere de telefon, linkuri t.me/..., ID-uri numerice ca string-uri, ID-uri de supergrup sau canal (numere negative de genul -1001234567890), sau me pentru propriile tale Mesaje Salvate.
API HTTP
REST standard. /api/me, /api/messages, /api/dialogs și așa mai departe. De la v0.4.0, un 2xx întoarce resursa direct, vechiul plic {"result": ...} a dispărut. Dacă ți-ai scris un client pe v0.3.x, despachetează cu un nivel mai puțin.
# who am I
curl https://ciprian.51k.eu80/api/me
-H "Authorization: Bearer $TELETHON_AUTH_KEY"
# send a message with Markdown
curl -X POST https://ciprian.51k.eu80/api/messages
-H "Authorization: Bearer $TELETHON_AUTH_KEY"
-H "Content-Type: application/json"
-d '{"chat": "@somebody", "text": "**hello** from a container", "parse_mode": "md"}'
# read recent messages with full-text search
curl "https://ciprian.51k.eu80/api/messages?chat=me&limit=5&search=hello"
-H "Authorization: Bearer $TELETHON_AUTH_KEY"
# send a file from an HTTPS URL — never touches your disk
# (v0.4.0 folded /api/files into /api/messages; `caption` is now `text`)
curl -X POST https://ciprian.51k.eu80/api/messages
-H "Authorization: Bearer $TELETHON_AUTH_KEY"
-H "Content-Type: application/json"
-d '{"chat": "@psyb0t", "file_url": "https://example.com/photo.jpg", "text": "look at this"}'Telegram detectează automat tipul de media din extensia fișierului. .jpg devine poză, .mp4 video, .mp3 audio. Folosește force_document: true ca să suprascrii.
Validarea e strictă, schemele pydantic resping câmpurile în plus și tipurile greșite cu 400 și un corp de eroare detaliat. Erorile RPC de la Telegram (FloodWaitError, ChatWriteForbiddenError) vin înapoi ca 502, cu clasa erorii și mesajul păstrate.
Verificarea de sănătate la /healthz e mereu publică, fără autentificare. Întoarce {"status": "ok", "authorized": true}, iar authorized: false înseamnă că sesiunea e futută (string greșit, revocat, sau Telegram inaccesibil).
Server MCP
Montat la /mcp/, folosind transportul HTTP streamable. Fiecare unealtă din lista de mai sus apare automat ca unealtă MCP, cu același nume și aceeași schemă. Fără stare, fiecare cerere e independentă, fără jonglat cu sesiuni.
http://your-host:8080/mcp/Îl bagi în Claude Desktop, într-un agent propriu, într-un gateway de LLM-uri, în orice vorbește MCP peste HTTP streamable. Merge din prima.
Asta e partea care contează. Orice model cu function calling îți poate citi acum Telegramul, îi poate scrie, poate administra grupuri, poate forwarda conținut. Modelul decide când. Agentul acționează. Vrei ca Claude să îți rezume ultimele 50 de mesaje dintr-un chat într-un rezumat zilnic? Bagi endpointul MCP, ceri. Vrei un model care să forwardeze întrebările de suport dintr-un canal public în chatul echipei tale? La fel. Vrei un agent care monitorizează un grup pentru mențiuni și răspunde în numele tău? Gata.
Cum Să Nu Îți Ia Contul Ban
Asta e partea care contează când îndrepți automatizare spre propriul tău cont de Telegram: Telegram observă. Bați în API și primești FLOOD_WAIT, apoi restricții, apoi un cont mort.
Deci acum există un limitator de rată adevărat. Token buckets per metodă, intervale de trimitere și citire per chat, și backoff adaptiv când Telegram chiar întoarce un FLOOD_WAIT. Valorile implicite sunt calibrate să stea confortabil sub limitele blânde observate ale Telegramului, fără să reglezi tu nimic. throttle_status îți zice unde stai, iar account_health îți zice dacă deja contul e în belea.
Două comutatoare de siguranță pentru când cablezi ceva nou: TELETHON_READ_ONLY refuză orice apel care modifică ceva, iar TELETHON_DRY_RUN mimează mișcările fără să trimită efectiv. Îndreaptă un LLM spre contul tău prima dată cu unul dintre astea pornit.
Cache de entități. Rezolvarea unui username costă un apel de API real, iar rezolvarea repetată a aceluiași username e felul în care îți arzi cota degeaba. Cache-ul persistă peste reporniri de container, deci căutările repetate devin gratuite. v0.4.1 a reparat un bug urât pe calea aia: reîmprospătarea chema get_entity cu un int gol, pe care Telethon îl tratează ca PeerUser, deci canalele și grupurile din cache aruncau eroare, se invalidau și ardeau de fiecare dată un slot de ResolveUsername. Exact operația pe care cache-ul exista ca să o evite. Acum împachetează tipul corect de Peer.
Observabilitate
/metrics expune format Prometheus. /ws/updates e un websocket care streamează actualizările pe măsură ce sosesc. Setezi TELETHON_POST_TO_URL și fiecare actualizare pleacă și ca webhook de ieșire, ceea ce e modul simplu de a-l lega la n8n sau la serviciul tău, fără să ții un socket deschis.
Există o suită de 44 de teste unitare care rulează fără să atingă deloc Telegramul (make test-unit), separată de testele de integrare care merg pe un cont real.
Skill și Plugin
Repo-ul livrează un skill de agent plus un plugin OpenClaw sub .agents/, publicate pe ClawHub de CI la push-uri de tag. Un agent îl instalează și cunoaște toată suprafața de unelte fără să lipești tu lista într-un prompt.
Autentificare
Setezi TELETHON_AUTH_KEY ca să activezi autentificarea cu bearer token pe fiecare endpoint în afară de /healthz. Dacă nu îl setezi, API-ul rulează neautentificat, ceea ce e în regulă pe localhost și sinucidere expus pe o rețea. Setează-l mereu.
Authorization: Bearer your-secret-keySession stringul e secretul adevărat, dacă îl pierzi îți pierzi contul. Nici măcar nu îl pune într-un YAML de compose comis într-un repo. Fișier .env, în gitignore, încărcat la rulare.
Configurare
Totul prin variabile de mediu.
TELETHON_API_ID,TELETHON_API_HASH,TELETHON_SESSION: obligatorii, de la my.telegram.org și de la ajutorul de loginTELETHON_AUTH_KEY: bearer token pentru REST și MCP. Gol înseamnă fără autentificare. Setează-l.TELETHON_HTTP_LISTEN_ADDRESS: implicit0.0.0.0:8080TELETHON_REQUEST_TIMEOUT: timeout per cerere (implicit 60 de secunde)TELETHON_FLOOD_SLEEP_THRESHOLD: doarme automat peste erorile de FloodWait sub atâtea secunde (implicit 60). Supapa de siguranță.TELETHON_DEVICE_MODEL,TELETHON_SYSTEM_VERSION,TELETHON_APP_VERSION: ce crede Telegram că e clientul tăuTELETHON_DOWNLOAD_DIR: spațiu de lucru pentru încărcărilesend_file(implicit/tmp/telethon-plus)TELETHON_PROXY: proxy SOCKS5 opțional (socks5://user:pass@host:port)
Pragul de flood sleep e supapa de siguranță, Telegram o să te limiteze când împingi prea tare. Sub prag, clientul doarme transparent și reîncearcă. Peste el, primești un 502 înapoi. Reglează-l după cazul tău de utilizare.
Testele Merg pe Telegramul Real
Fără mock-uri. Suita de teste rulează containerul pe contul tău propriu, cu mesaje trimise și șterse într-un chat pe care îl specifici tu (TEST_CHAT, folosește me pentru Mesaje Salvate, ca să nu vadă nimeni altcineva zgomotul).
cp .env.example .env
$EDITOR .env # TELETHON_API_ID, TELETHON_API_HASH, TELETHON_SESSION, TEST_CHAT
make testTestele acoperă erorile de validare, dus-întorsurile de trimis-editat-adus-șters, listarea de dialoguri, rezolvarea de entități, citirile din canale publice, crearea și ștergerea de grupuri, listele de participanți, descoperirea și invocarea uneltelor MCP, middleware-ul de autentificare (401 la tokenuri lipsă sau greșite, healthz mereu public). Dacă nu sunt setate credențialele, suita sare peste teste curat.
Securitate
Session stringul e egal cu contul tău. Tratează-l ca pe un număr de card bancar care e și buletinul tău. Concret:
- Setează mereu
TELETHON_AUTH_KEY, nu rula niciodată neautentificat, în afară de un localhost izolat - Nu comite niciodată
TELETHON_SESSIONîn git, folosește fișier.env, în gitignore - Dacă bănuiești o scurgere, intră în Telegram pe telefon și revocă imediat sesiunile active
- Nu expune portul
8080pe internetul public, pune-l în spatele unui reverse proxy cu TLS, sau al unui Cloudflare Tunnel - Rotește cheia de autentificare dacă scapă vreodată ceva
Containerul în sine e mic: Python 3.12, Telethon, FastAPI, SDK-ul de MCP. /healthz e singurul endpoint public. Tot restul are nevoie de bearer token dacă e setat TELETHON_AUTH_KEY.
Băgat în aigate
Chestia asta e legată la aigate ca unul dintre serverele lui MCP. Pui TELETHON=1 în .env-ul de aigate, setezi credențialele, iar orice model cu function calling care trece prin gateway poate vorbi acum cu Telegramul tău. Groq cheamă o unealtă, unealta se duce la Telegram, tu primești un mesaj. Modelul decide când.
Un model Groq de pe planul gratuit care caută pe web, scrapează o pagină, generează o imagine și îți trimite rezultatul în Mesaje Salvate, zero tokeni plătiți, o singură conversație, mai multe apeluri de unelte. Ăsta e tot rostul.
Pe Scurt
Bot API e în regulă dacă tot ce îți trebuie e să trimiți notificări. Userboții sunt ce vrei când chiar ai nevoie să faci lucruri pe Telegram: să citești mesaje, să administrezi grupuri, să acționezi ca tine însuți programatic. telethon-plus pune un client MTProto adevărat în spatele HTTP și MCP, deci orice unealtă care vorbește JSON sau orice agent care știe MCP îți poate conduce contul.
Ia-l de aici: github.com/psyb0t/docker-telethon-plus
Licențiat sub WTFPL, fă ce mama dracului vrei cu el.
Cum Îl Instalezi în Agentul Tău
Skillul se instalează acum direct în Claude Code și în Codex. Tot ce e sub .agents/ e catalogat într-un singur marketplace, deci sunt două comenzi:
claude plugin marketplace add psyb0t/agents
claude plugin install telethon-plus@psyb0tCodex folosește același marketplace cu alt verb, codex plugin add telethon-plus@psyb0t, pentru că nu există codex plugin install. Găsește singur și skillul într-un checkout al repo-ului, pentru că scanează .agents/skills/ nativ, fără să fie instalat absolut nimic. E listat acum și pe MCP Registry-ul oficial, deci un client care rezolvă servere de acolo îl poate găsi fără să i se dea un URL.