Skip to main content

ScoloTeleuser

ScoloTeleuser is a typed asynchronous Python client for a Telegram user account. It uses TDLib’s official JSON interface for MTProto networking, encryption, local storage, reconnection and ordered updates, while exposing a concise asyncio API for authorization, chats, messages and updates.1 2

The package is intended for transparent personal-account integrations. It does not provide bulk messaging, data extraction, artificial counter manipulation, ghost-mode behaviour, bypasses for disappearing content, or AI dataset features. Telegram requires third-party clients to act with the user’s knowledge and consent, preserve normal Telegram behaviour, and not use platform data for AI/ML development.3

Installation

The base package has no mandatory Python dependencies:

pip install ScoloTeleuser

For the default prebuilt TDLib runtime on supported Linux, macOS and Windows systems:

pip install "ScoloTeleuser[tdjson]"

You may instead build TDLib yourself and set TDJSON_LIBRARY_PATH to libtdjson (tdjson.dll on Windows), or pass tdjson_library_path= to Client.2

Credentials and session storage

Create an application at my.telegram.org/apps and provide your own api_id and api_hash. Telegram requires application-specific credentials and monitors unofficial clients for abuse.4

The session configuration requires a non-empty local database encryption key. Store api_hash and this key in a secret manager or environment variables; do not commit them, print them, or place them in a public session file. On POSIX systems ScoloTeleuser creates the session directories with 0700 permissions and tightens created database-file permissions to 0600.

import os
from pathlib import Path

from scoloteleuser import SessionConfig

config = SessionConfig(
    api_id=int(os.environ["TELEGRAM_API_ID"]),
    api_hash=os.environ["TELEGRAM_API_HASH"],
    database_directory=Path.home() / ".local" / "share" / "my-app" / "telegram",
    database_encryption_key=os.environ["TELEGRAM_DATABASE_KEY"],
)

Explicit opt-in for dangerous account operations

ScoloTeleuser follows a secure-by-default model. Operations that can immediately and destructively affect the logged-in account are blocked by default, and Client.start() emits DangerousFunctionWarning. The caller must make the decision visible in source code before enabling them.

from scoloteleuser import Client

AllowDangerousFunctions = True  # Explicitly reviewed by the application owner.
client = Client(config, allow_dangerous_functions=AllowDangerousFunctions)

With the flag disabled, selected message deletion, chat-history deletion, logout, termination of other sessions, and known destructive raw TDLib methods raise DangerousFunctionBlockedError before a request is sent to TDLib. The flag enables only these permitted account-management operations; it is not a bypass for Telegram rules.

AS IS and responsibility notice. ScoloTeleuser is provided under the MIT License, without warranty. Your code sends requests for the account configured in SessionConfig, and may affect that account immediately. You are responsible for your credentials, local session storage, selected targets, operation volume, consent, and compliance with Telegram rules.

The package does not add helpers for bulk unsolicited messaging, flood automation, fake counters, automatic outreach joins, ghost mode, status suppression, disappearing-message circumvention, personal-data scraping/export, or AI dataset collection. See Dangerous functions policy for the exact boundary.

Interactive login

ScoloTeleuser never reads a login code or 2FA password by itself. The application presents the current authorization state and obtains each value directly from the account owner.

from scoloteleuser import Client

async with Client(config) as telegram:
    state = telegram.authorization_state

    if state and state.kind == "WaitPhoneNumber":
        state = await telegram.send_phone_number("+15551234567")

    if state and state.kind == "WaitCode":
        state = await telegram.check_code(input("Telegram code: "))

    if state and state.kind == "WaitPassword":
        state = await telegram.check_password(input("2FA password: "))

    await telegram.wait_until_ready()
    me = await telegram.get_me()
    print(me.first_name)

TDLib’s authorization flow can also request email verification or registration. These states remain visible through authorization_state; call the corresponding TDLib method via invoke() until a typed helper is added.

Do not reuse the sample API ID embedded in Telegram’s open-source applications. Telegram documents that it is not suitable for released end-user applications.4

Chats and messages

Use a long-lived client and close it through the async context manager. send_text sends one ordinary message to a chat that the application has explicitly selected.

async with Client(config) as telegram:
    await telegram.wait_until_ready()

    chat = await telegram.search_public_chat("telegram")
    message = await telegram.send_text(chat.id, "Hello from my account")
    print(message.id)

    history = await telegram.get_chat_history(chat.id, limit=20)
    for item in history:
        print(item.date, item.text)

The ergonomic client exposes get_me, get_chat, search_public_chat, get_chat_history, send_text, delete_messages, and mark_chat_read. Each helper checks that TDLib is authorized before sending the request.

Complete TDLib schema API

ScoloTeleuser vendors the current TDLib schema and generates an async method for every function in that schema. The generated client.api namespace currently exposes 1,010 methods using predictable snake_case names. It also ships PEP 561 type stubs, so editors can discover the generated methods and their TDLib result type.

async with Client(config) as telegram:
    await telegram.wait_until_ready()

    # TDLib getMe -> generated snake_case method get_me.
    raw_user = await telegram.api.get_me()

    # Inspect the complete generated registry.
    for function in telegram.api.functions:
        print(function.python_name, function.result_type, function.dangerous)

    # The same operation is available when the name is dynamic.
    raw_user = await telegram.api.call("get_me")

Generated calls accept the original TDLib JSON parameter names as keyword arguments and return the unmodified TDLib JSON response as a dictionary. The existing ergonomic helpers remain available when a Python model or validation is more convenient.

D — Dangerous methods

A method with dangerous=True in the registry is displayed as [D] Dangerous in its generated documentation and is also present under client.api.dangerous. There are currently 59 reviewed D methods. They cover destructive, privacy-sensitive or access-changing account operations such as deletion, logout, session termination, account/profile changes, reporting, proxy changes and group membership changes.

AllowDangerousFunctions = True

async with Client(config, allow_dangerous_functions=AllowDangerousFunctions) as telegram:
    await telegram.wait_until_ready()

    # [D] — explicit opt-in remains required.
    await telegram.api.dangerous.delete_messages(
        chat_id=chat_id,
        message_ids=[message_id],
        revoke=True,
    )

Without the explicit opt-in, a D call raises DangerousFunctionBlockedError before it is sent to TDLib. The complete D registry is inspectable through client.api.dangerous.functions.

Updates and handlers

TDLib receives responses and updates asynchronously. ScoloTeleuser serializes them through one receiver task, preserves TDLib receive order, correlates method responses with private @extra IDs, and delivers all other objects as Update instances.1

from scoloteleuser import Update

async def observe(update: Update) -> None:
    if update.kind == "updateNewMessage":
        print(update.raw)

async with Client(config) as telegram:
    telegram.add_handler(observe)
    await telegram.wait_until_ready()

    async for update in telegram.updates():
        if update.kind == "updateNewMessage":
            break

Handler exceptions are isolated and written through Python logging; they do not stop TDLib’s receive loop. Never log update.raw blindly in production because it can contain private message content and metadata.

Raw TDLib methods

invoke() supports manually composed current TDLib schema methods. It requires a non-empty @type and owns @extra internally. For ordinary use, prefer the generated client.api surface, which covers the whole vendored schema. Known destructive methods are subject to the explicit opt-in policy described above.

async with Client(config) as telegram:
    await telegram.wait_until_ready()
    result = await telegram.invoke({"@type": "getOption", "name": "version"})

Use raw methods only after consulting the current TDLib API documentation. ScoloTeleuser validates lifecycle and errors but cannot make an arbitrary raw method safe for a particular product.

Safety boundaries

Included Deliberately excluded
Explicit account login, chats, normal read state, messages, events, encrypted local session storage. Bulk messaging, spam/flood automation, scraping/export API, automatic group joining, counter manipulation, ghost mode, typing/read-state bypasses, disappearing-message circumvention, AI dataset collection.

Telegram states that flooding, spam, and fake subscriber or channel-view counters can result in permanent bans.4 Treat the account session like a password: anyone with access to it can act as the account owner.

Compatibility

ScoloTeleuser requires Python 3.10+ and TDLib major version 1. The tdjson extra currently pins a compatible prebuilt runtime range; use await client.tdlib_version() for an explicit runtime check.

License

MIT.

References

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scoloteleuser-0.1.0.post1.tar.gz (294.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scoloteleuser-0.1.0.post1-py3-none-any.whl (45.3 kB view details)

Uploaded Python 3

File details

Details for the file scoloteleuser-0.1.0.post1.tar.gz.

File metadata

  • Download URL: scoloteleuser-0.1.0.post1.tar.gz
  • Upload date:
  • Size: 294.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for scoloteleuser-0.1.0.post1.tar.gz
Algorithm Hash digest
SHA256 92c9e333c0cdea8195edf468f552c86ef47f079a5d881d8b8ab7b2b6bdaa6774
MD5 4632375964202a437f141d432839e56a
BLAKE2b-256 6e62fabee66453e67ae289f2c4c43d61ad2bddbea4a5482f8b2201aefb61fac3

See more details on using hashes here.

File details

Details for the file scoloteleuser-0.1.0.post1-py3-none-any.whl.

File metadata

File hashes

Hashes for scoloteleuser-0.1.0.post1-py3-none-any.whl
Algorithm Hash digest
SHA256 8bb79a26335312bf345a7e19b7839a90cf411090f90be0e280b5806d1211982a
MD5 a879876a659f371b5e080b5990fb1451
BLAKE2b-256 ecdff2288a4bae48c94356c260f41c48d30712deaf4fe08df319cbabf5cd16f6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page