Metadata-Version: 2.4
Name: ScoloTeleuser
Version: 0.1.0.post1
Summary: Typed asynchronous TDLib client for Telegram user accounts.
Author: G3tFun
License-Expression: MIT
Project-URL: Homepage, https://github.com/G3tFun/ScoloTeleuser
Project-URL: Repository, https://github.com/G3tFun/ScoloTeleuser
Project-URL: Issues, https://github.com/G3tFun/ScoloTeleuser/issues
Keywords: telegram,tdlib,mtproto,asyncio,client
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: tdjson
Requires-Dist: tdjson<2,>=1.8.66; extra == "tdjson"
Provides-Extra: logging
Requires-Dist: ScoloLogger>=0.1.0; extra == "logging"
Dynamic: license-file

# 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:

```bash
pip install ScoloTeleuser
```

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

```bash
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](https://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`.

```python
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.

```python
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](docs/DANGEROUS_FUNCTIONS.md) 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.

```python
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.

```python
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.

```python
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.

```python
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]

```python
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.

```python
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](https://core.telegram.org/tdlib/docs/). 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

[1]: https://core.telegram.org/tdlib/getting-started "Telegram: Getting started with TDLib"
[2]: https://core.telegram.org/tdlib "Telegram Database Library"
[3]: https://core.telegram.org/api/terms "Telegram API Terms of Service"
[4]: https://core.telegram.org/api/obtaining_api_id "Telegram: Creating your Telegram Application"
