### Install python-telegram Library Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/tutorial.md Use this command to install the python-telegram library. ```bash python3 -m pip install python-telegram ``` -------------------------------- ### Install tdlib Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/tdlib.md Install the tdlib library after building it. This command is typically run after a successful build process. ```bash make install ``` -------------------------------- ### Install python-telegram Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/README.md Install the library using pip. Requires Python 3.9+ and Linux or MacOS. ```shell pip install python-telegram ``` -------------------------------- ### Run All Tests with Tox Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CONTRIBUTING.md Execute all defined test environments using tox. Ensure tox is installed before running. ```shell tox ``` -------------------------------- ### Initialize and Connect Telegram Client Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Instantiate a Telegram client for user or bot accounts. The client starts background threads immediately. Ensure you have your API ID and hash from my.telegram.org. ```python from telegram.client import Telegram # User account login tg = Telegram( api_id=12345678, # from https://my.telegram.org/apps api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="my-secret-key", files_directory="/tmp/.tdlib_files/", # optional; defaults to /tmp/.tdlib_files/ use_test_dc=False, use_message_database=True, use_secret_chats=True, tdlib_verbosity=1, # 0=minimal, 5=verbose TDLib logs login=True, # call login() automatically ) tg.stop() # Bot account login tg_bot = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", bot_token="110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw", database_encryption_key="my-secret-key", login=True, ) tg_bot.stop() ``` -------------------------------- ### Run python-telegram examples via Docker Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Shows how to execute python-telegram scripts, such as sending a message or running the echo bot, within an isolated Docker container. This requires mounting a volume for temporary data. ```sh # Send a message via Docker docker run -i -t --rm \ -v /tmp/docker-python-telegram/:/tmp/ \ akhmetov/python-telegram \ python3 /app/examples/send_message.py \ 12345678 \ "0123456789abcdef0123456789abcdef" \ "+15551234567" \ "-1001234567890" \ "Hello from Docker!" # Run the echo bot via Docker docker run -i -t --rm \ -v /tmp/docker-python-telegram/:/tmp/ \ akhmetov/python-telegram \ python3 /app/examples/echo_bot.py \ 12345678 \ "0123456789abcdef0123456789abcdef" \ "+15551234567" ``` -------------------------------- ### Telegram.__init__ Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Initializes a Telegram client instance and connects to the TDLib JSON interface. It can optionally perform the full login flow upon instantiation. Requires either a phone number or a bot token for authentication. The client starts background threads immediately. ```APIDOC ## Telegram.__init__ — Initialize and connect the client Creates a `Telegram` client instance, initializes the TDLib JSON interface, and optionally performs the full login flow in one step. Either `phone` or `bot_token` must be provided. The client starts background threads immediately upon instantiation. ```python from telegram.client import Telegram # User account login tg = Telegram( api_id=12345678, # from https://my.telegram.org/apps api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="my-secret-key", files_directory="/tmp/.tdlib_files/", # optional; defaults to /tmp/.tdlib_files/ use_test_dc=False, use_message_database=True, use_secret_chats=True, tdlib_verbosity=1, # 0=minimal, 5=verbose TDLib logs login=True, # call login() automatically ) tg.stop() # Bot account login tg_bot = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", bot_token="110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw", database_encryption_key="my-secret-key", login=True, ) tg_bot.stop() ``` ``` -------------------------------- ### Login to Telegram Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/tutorial.md Call the login method to authenticate your Telegram client. This example uses a blocking login. You will receive a code via SMS or Telegram message, and potentially be asked for a 2FA password. ```python tg.login() ``` -------------------------------- ### Get Supergroup Full Info and Create Basic Group Chat Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Retrieves extended information about a supergroup, including its basic group predecessor. If a basic group ID is found, a chat object is created from it to access its history. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) SUPERGROUP_ID = 1234567890 r = tg.get_supergroup_full_info(SUPERGROUP_ID) r.wait(raise_exc=True) basic_group_id = r.update.get("upgraded_from_basic_group_id", 0) print(f"Supergroup full info: member_count={r.update['member_count']}") if basic_group_id: r2 = tg.create_basic_group_chat(basic_group_id) r2.wait(raise_exc=True) print(f"Basic group chat ID: {r2.update['id']}") tg.stop() ``` -------------------------------- ### Telegram.get_chat_history Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Fetches a batch of messages from a chat in reverse chronological order. Use `from_message_id=0` to start from the latest and paginate using the last received message ID. ```APIDOC ## Telegram.get_chat_history — Fetch messages from a chat Retrieves a batch of messages from a chat in reverse chronological order. Use `from_message_id=0` to start from the latest, then paginate using the last received message ID. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) CHAT_ID = -1001234567890 from_msg_id = 0 # Paginate through entire chat history while True: result = tg.get_chat_history( chat_id=CHAT_ID, limit=100, from_message_id=from_msg_id, offset=0, only_local=False, ) result.wait(raise_exc=True) messages = result.update.get("messages", []) if not messages: break for msg in messages: if msg["content"]["@type"] == "messageText": print(msg["id"], msg["content"]["text"]["text"]) from_msg_id = messages[-1]["id"] tg.stop() ``` ``` -------------------------------- ### Fetch Chat History with Telegram Client Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Use `get_chat_history` to retrieve messages in reverse chronological order. Set `from_message_id=0` to start from the latest message and paginate using the last received message ID. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) CHAT_ID = -1001234567890 from_msg_id = 0 # Paginate through entire chat history while True: result = tg.get_chat_history( chat_id=CHAT_ID, limit=100, from_message_id=from_msg_id, offset=0, only_local=False, ) result.wait(raise_exc=True) messages = result.update.get("messages", []) if not messages: break for msg in messages: if msg["content"]["@type"] == "messageText": print(msg["id"], msg["content"]["text"]["text"]) from_msg_id = messages[-1]["id"] tg.stop() ``` -------------------------------- ### Build Docker Image Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CLAUDE.md Build the Docker image for the project. This command assumes a `Makefile` with a `docker/build` target is present. ```bash make docker/build ``` -------------------------------- ### Initialize Telegram Client Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/tutorial.md Initialize a new Telegram client with your API credentials and phone number. Ensure you replace the placeholder values with your actual information. ```python from telegram.client import Telegram tg = Telegram( api_id=123456, api_hash='api_hash', phone='+31611111111', database_encryption_key='changeme1234', ) ``` -------------------------------- ### Fetch Telegram Instant View for a URL Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Requests an Instant View preview of a webpage. Returns a 404 error if the page has no Instant View template. The `force_full` parameter can be used to attempt fetching the full content. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) result = tg.get_web_page_instant_view( url="https://telegram.org/blog/100-million", force_full=True, ) result.wait() if result.error: print(f"Error: {result.error_info}") else: title_block = result.update["page_blocks"][0] print(title_block["title"]["text"]) tg.stop() ``` -------------------------------- ### Telegram.get_web_page_instant_view Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Requests an Instant View preview of a webpage via Telegram's servers. Returns a 404 error if the page has no Instant View template. ```APIDOC ## `Telegram.get_web_page_instant_view` — Fetch Telegram Instant View for a URL Requests an Instant View preview of a webpage via Telegram's servers. Returns `404` if the page has no Instant View template. ### Parameters #### Query Parameters - **url** (string) - Required - The URL of the webpage to fetch the Instant View for. - **force_full** (boolean) - Optional - If true, attempts to fetch the full Instant View even if a preview is available. ### Request Example ```python tg.get_web_page_instant_view( url="https://telegram.org/blog/100-million", force_full=True, ) ``` ### Response #### Success Response (200) - **page_blocks** (list) - A list of blocks representing the content of the Instant View. - **title** (dict) - Contains the title of the page. - **text** (string) - The title text. ### Response Example ```json { "page_blocks": [ { "title": { "text": "100 Million Active Users!" } } ] } ``` ``` -------------------------------- ### Build PyPI Package Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CLAUDE.md Build the Python package for distribution on PyPI. This command relies on a `Makefile` with a `build-pypi` target. ```bash make build-pypi ``` -------------------------------- ### Initialize Telegram Client Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/non_blocking_login.md Initialize the Telegram client with your API credentials and phone number. This sets up the client for non-blocking operations. ```python from telegram.client import Telegram, AuthorizationState tg = Telegram( api_id='api_id', api_hash='api_hash', phone='+31611111111', database_encryption_key='changeme1234', ) ``` -------------------------------- ### Basic Telegram Client Usage Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/README.md Initialize the Telegram client, log in, preload chats, send a message with spoiler text, and wait for the result. Ensure to call `tg.stop()` at the end. ```python from telegram.client import Telegram from telegram.text import Spoiler tg = Telegram( api_id='api_id', api_hash='api_hash', phone='+31611111111', # you can pass 'bot_token' instead database_encryption_key='changekey123', files_directory='/tmp/.tdlib_files/', ) tg.login() # If this is the first run, the library needs to preload all chats. # Otherwise, the message will not be sent. result = tg.get_chats() result.wait() chat_id: int result = tg.send_message(chat_id, Spoiler('Hello world!')) # `tdlib` is asynchronous, so `python-telegram` always returns an `AsyncResult` object. # You can receive a result with the `wait` method of this object. result.wait() print(result.update) tg.stop() # You must call `stop` at the end of the script. ``` -------------------------------- ### Run Format Check with Tox Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CLAUDE.md Check code formatting using Tox. This command verifies if the code adheres to the project's formatting standards, usually managed by Ruff. ```bash tox -e ruff-format ``` -------------------------------- ### Fetch User Information with Telegram Client Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Use `get_user` for basic info or `get_user_full_info` for extended details like bio. Ensure the client is logged in before calling. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) USER_ID = 123456789 result = tg.get_user(USER_ID) result.wait(raise_exc=True) print(result.update["first_name"], result.update["username"]) result_full = tg.get_user_full_info(USER_ID) result_full.wait(raise_exc=True) print(result_full.update) # {'@type': 'userFullInfo', 'bio': {'@type': 'formattedText', 'text': '...', ...}, ...} tg.stop() ``` -------------------------------- ### Configure Proxy for Telegram Client Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/proxy.md Define proxy parameters and pass them to the Telegram class constructor to establish a proxied connection. Supports MTProto, SOCKS5, and HTTP proxies. ```python from telegram.client import Telegram proxy_type = { '@type': 'proxyTypeMtproto', # 'proxyTypeSocks5', 'proxyTypeHttp' } proxy_port = 1234 proxy_server = 'localhost' tg = Telegram( api_id='api_id', api_hash='api_hash', phone='+31611111111', database_encryption_key='changeme1234', proxy_server=proxy_server, proxy_port=proxy_port, proxy_type=proxy_type, ) ``` -------------------------------- ### Run Linting with Tox Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CLAUDE.md Perform linting checks using Tox. This command runs the configured linter, typically Ruff. ```bash tox -e ruff ``` -------------------------------- ### Configure Proxy Connection Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Proxy settings are passed to the Telegram constructor before authentication. Supports MTProto, SOCKS5, and HTTP proxy types. Ensure the correct proxy type and credentials are provided for a successful connection. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", proxy_server="proxy.example.com", proxy_port=1080, proxy_type={"@type": "proxyTypeSocks5", "username": "user", "password": "pass"}, login=True, ) result = tg.get_me() result.wait(raise_exc=True) print(result.update["username"]) tg.stop() # MTProto proxy (no username/password) tg_mtproto = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", proxy_server="mtproto.example.com", proxy_port=443, proxy_type={"@type": "proxyTypeMtproto"}, ) ``` -------------------------------- ### Full Echo Bot Code Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/tutorial.md This is the complete code for the simple echo-bot, combining client initialization, login, message handling for 'ping'/'pong', and the idle call to keep the bot running. ```python from telegram.client import Telegram tg = Telegram( api_id=123456, api_hash='api_hash', phone='+31611111111', database_encryption_key='changeme1234', ) tg.login() def new_message_handler(update): # We want to process only text messages. message_content = update['message']['content'].get('text', {}) message_text = message_content.get('text', '').lower() is_outgoing = update['message']['is_outgoing'] if not is_outgoing and message_text == 'ping': chat_id = update['message']['chat_id'] print(f'Ping has been received from {chat_id}') tg.send_message( chat_id=chat_id, text='pong', ) tg.add_message_handler(new_message_handler) tg.idle() ``` -------------------------------- ### Retrieve Current User Profile Information Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Fetches information about the authenticated user or bot account by mapping to TDLib's `getMe` method. Requires successful login. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) result = tg.get_me() result.wait(raise_exc=True) print(result.update) # { # '@type': 'user', # 'id': 987654321, ``` -------------------------------- ### Run Single Test with Tox Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CLAUDE.md Execute a specific test case within a given Python environment using Tox. Use the `-k` flag followed by the test name or pattern. ```bash tox -e py312 -- -k test_send_message ``` -------------------------------- ### Proxy Configuration Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Configures network connections to use a proxy server. Supported proxy types include MTProto, SOCKS5, and HTTP. Proxy settings are applied during the `Telegram` client initialization. ```APIDOC ## Proxy configuration — Connect through MTProto, SOCKS5, or HTTP proxy Proxy settings are passed to the `Telegram` constructor and applied before authentication. Supported types are `proxyTypeMtproto`, `proxyTypeSocks5`, and `proxyTypeHttp`. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", proxy_server="proxy.example.com", proxy_port=1080, proxy_type={ "@type": "proxyTypeSocks5", "username": "user", "password": "pass" }, login=True, ) result = tg.get_me() result.wait(raise_exc=True) print(result.update["username"]) tg.stop() # MTProto proxy (no username/password) tg_mtproto = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", proxy_server="mtproto.example.com", proxy_port=443, proxy_type={ "@type": "proxyTypeMtproto" }, ) ``` ``` -------------------------------- ### Run python-telegram via Docker Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/README.md Execute a Python script using the python-telegram Docker image. Mounts a volume for temporary files and passes necessary arguments. ```sh docker run -i -t --rm \ -v /tmp/docker-python-telegram/:/tmp/ \ akhmetov/python-telegram \ python3 /app/examples/send_message.py $(API_ID) $(API_HASH) $(PHONE) $(CHAT_ID) $(TEXT) ``` -------------------------------- ### Authenticate with Telegram using Login Flow Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Handles the TDLib authorization state machine. In blocking mode, it prompts for credentials via stdin. In non-blocking mode, it returns the current state for programmatic credential supply. ```python from telegram.client import Telegram, AuthorizationState tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", ) # Non-blocking login — useful for web apps or custom UI flows state = tg.login(blocking=False) if state == AuthorizationState.WAIT_CODE: code = input("Enter the Telegram code you received: ") tg.send_code(code) state = tg.login(blocking=False) if state == AuthorizationState.WAIT_PASSWORD: import getpass pwd = getpass.getpass("Enter your 2FA password: ") tg.send_password(pwd) state = tg.login(blocking=False) if state == AuthorizationState.WAIT_REGISTRATION: tg.register_user("Jane", "Doe") state = tg.login(blocking=False) assert state == AuthorizationState.READY print("Logged in successfully") tg.stop() ``` -------------------------------- ### Run Type Checking with Tox Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CLAUDE.md Perform strict type checking using Tox and Mypy. Ensure Mypy is configured in your `tox.ini`. ```bash tox -e mypy ``` -------------------------------- ### Telegram.get_user / get_user_full_info Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Fetches user information. `get_user` retrieves basic details by ID, while `get_user_full_info` provides extended profile information. ```APIDOC ## Telegram.get_user / get_user_full_info — Fetch user information `get_user` returns basic info for a user by ID; `get_user_full_info` returns extended profile details including bio, linked chat, etc. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) USER_ID = 123456789 result = tg.get_user(USER_ID) result.wait(raise_exc=True) print(result.update["first_name"], result.update["username"]) result_full = tg.get_user_full_info(USER_ID) result_full.wait(raise_exc=True) print(result_full.update) # {'@type': 'userFullInfo', 'bio': {'@type': 'formattedText', 'text': '...', ...}, ...} tg.stop() ``` ``` -------------------------------- ### Call tdlib Method Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/README.md Use `call_method` to invoke any tdlib function with specified parameters. Refer to tdlib documentation for available functions and parameters. ```python tg.call_method('getUser', params={'user_id': user_id}) ``` -------------------------------- ### Telegram.login Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Authenticates the client with Telegram by running the TDLib authorization state machine. In blocking mode, it interactively prompts for the SMS code and 2FA password. In non-blocking mode, it returns the current `AuthorizationState` for programmatic credential supply. ```APIDOC ## Telegram.login — Authenticate with Telegram Runs the full TDLib authorization state machine. In blocking mode (default), prompts interactively for SMS code and 2FA password via stdin. In non-blocking mode, returns the current `AuthorizationState` so the caller can supply credentials programmatically. ```python from telegram.client import Telegram, AuthorizationState tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", ) # Non-blocking login — useful for web apps or custom UI flows state = tg.login(blocking=False) if state == AuthorizationState.WAIT_CODE: code = input("Enter the Telegram code you received: ") tg.send_code(code) state = tg.login(blocking=False) if state == AuthorizationState.WAIT_PASSWORD: import getpass pwd = getpass.getpass("Enter your 2FA password: ") tg.send_password(pwd) state = tg.login(blocking=False) if state == AuthorizationState.WAIT_REGISTRATION: tg.register_user("Jane", "Doe") state = tg.login(blocking=False) assert state == AuthorizationState.READY print("Logged in successfully") tg.stop() ``` ``` -------------------------------- ### Call Any TDLib Method Directly Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt A low-level method to invoke any TDLib function by name. The `params` argument accepts a dictionary of parameters for the TDLib function. An optional `block=True` parameter can be used to wait synchronously for the result. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) # Search for public chats result = tg.call_method("searchPublicChat", params={"username": "telegram"}) result.wait(raise_exc=True) print(result.update["title"]) # Get current network type result = tg.call_method("getNetworkStatistics", block=True) print(result.update) # Forward a message result = tg.call_method("forwardMessages", params={ "chat_id": -1001111111111, "from_chat_id": -1001234567890, "message_ids": [1234567890123], "send_copy": False, "remove_caption": False, }) result.wait(raise_exc=True) tg.stop() ``` -------------------------------- ### Auto-fix Linting and Formatting Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CLAUDE.md Automatically fix linting and formatting issues in the codebase. This command uses Ruff to check and fix code style problems. ```bash ruff check --fix && ruff format ``` -------------------------------- ### Non-blocking Login Flow Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/non_blocking_login.md Perform a non-blocking login by checking the authorization state and providing the necessary code or password when prompted. This method allows the application to continue running while waiting for user input. ```python code = 'some-code' password = 'secret-password' state = tg.login(blocking=False) if state == AuthorizationState.WAIT_CODE: # Telegram expects a pin code tg.send_code(code) state = tg.login(blocking=False) # continue the login process if state == AuthorizationState.WAIT_PASSWORD: tg.send_password(password) state = tg.login(blocking=False) # continue the login process # Logged in. # You can also check that tg.authorization state is AuthorizationState.READY. ``` -------------------------------- ### Send Rich Text Messages with python-telegram Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Demonstrates how to compose and send messages with rich text formatting using the `telegram.text` module. Ensure you have initialized the `Telegram` client and have a valid `CHAT_ID`. ```python from telegram.client import Telegram from telegram.text import ( Bold, Italic, Underline, Strikethrough, Spoiler, Code, InlineCode, Link, Chain, PlainText, OrderedList, UnorderedList, ) tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) CHAT_ID = -1001234567890 # Compose a mixed-format message message = Chain( Bold("Status Update\n"), PlainText("Server "), Code("prod-01"), PlainText(" is "), Italic("currently "), Spoiler("offline"), PlainText(". See "), Link("dashboard", "https://example.com/dashboard"), PlainText(" for details."), ) tg.send_message(chat_id=CHAT_ID, text=message).wait(raise_exc=True) # Ordered list todo = OrderedList([ PlainText("Deploy hotfix"), PlainText("Notify on-call team"), PlainText("Update status page"), ]) tg.send_message(chat_id=CHAT_ID, text=todo).wait(raise_exc=True) tg.stop() ``` -------------------------------- ### Run Specific Test with Tox (Python 3.12) Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CONTRIBUTING.md Run a specific test case, identified by '-k test_add_message_handler', within the Python 3.12 tox environment. This is useful for targeted testing. ```shell tox -e py312 -- -k test_add_message_handler ``` -------------------------------- ### Run Tox Tests for Specific Python Version Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/CLAUDE.md Execute Tox tests for a particular Python version. Replace `py312` with the desired Python environment name. ```bash tox -e py312 ``` -------------------------------- ### Keep Client Alive and Clean Shutdown Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt The idle() method blocks until a POSIX signal is received, then calls stop(). The stop() method ensures a clean shutdown by sending TDLib's close command and joining background threads. This is crucial for proper resource management before the process exits. ```python import signal from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) def on_message(update): print("New message:", update["message"]["content"]) tg.add_message_handler(on_message) # Block until Ctrl-C or kill signal; handles shutdown automatically tg.idle(stop_signals=(signal.SIGINT, signal.SIGTERM)) # For script-style usage without idle(): # result = tg.get_me() # result.wait() # tg.stop() ``` -------------------------------- ### Send Text Messages with Formatting Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Sends messages to a chat using either plain text or rich-text elements from `telegram.text`. The chat must exist in TDLib's local database. Use `get_chats()` first for new sessions. ```python from telegram.client import Telegram from telegram.text import Bold, Italic, Spoiler, Chain, Link tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) CHAT_ID = -1001234567890 # Plain text result = tg.send_message(chat_id=CHAT_ID, text="Hello, world!") result.wait(raise_exc=True) print(result.update) # {'@type': 'message', 'id': 123456, 'chat_id': -1001234567890, ...} # Rich text using telegram.text elements formatted = Chain(Bold("Alert: "), Italic("server is "), Spoiler("down")) result = tg.send_message(chat_id=CHAT_ID, text=formatted) result.wait(raise_exc=True) # Link result = tg.send_message(chat_id=CHAT_ID, text=Link("Click here", "https://example.com")) result.wait(raise_exc=True) tg.stop() ``` -------------------------------- ### Call tdlib Method with python-telegram Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/tdlib.md Use the call_method function from the python-telegram library to interact with tdlib. This requires initializing a Telegram object and providing the method name and parameters. ```python tg = Telegram(...) params = {'user_id': 1} result = tg.call_method('getUser', params) ``` -------------------------------- ### AsyncResult Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Handles asynchronous responses from TDLib methods. Each method call returns an `AsyncResult` object, which allows blocking until a result is available using `.wait()`, inspecting the response via `.update`, and checking for errors using `.error` or `.error_info`. Timeouts are supported. ```APIDOC ## `AsyncResult` — Handle asynchronous TDLib responses Every `Telegram` method returns an `AsyncResult`. Call `.wait()` to block until the result arrives, inspect `.update` for the response dict, and check `.error` / `.error_info` for failures. Supports an optional timeout. ```python from telegram.client import Telegram from telegram.utils import AsyncResult tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) result: AsyncResult = tg.get_me() try: result.wait(timeout=10, raise_exc=True) # raises RuntimeError on TDLib error except TimeoutError: print("Request timed out") except RuntimeError as e: print(f"TDLib error: {e}") else: if result.error: print("Error:", result.error_info) else: print("Success:", result.update) tg.stop() ``` ``` -------------------------------- ### Import Contacts by Phone Number Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Adds or updates contacts in the user's address book using their phone numbers. The result contains a list of Telegram user IDs matched to the provided numbers. A user ID of 0 indicates the phone number is not registered on Telegram. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) contacts = [ {"phone_number": "+15559876543", "first_name": "Alice", "last_name": "Smith"}, {"phone_number": "+15551112222", "first_name": "Bob", "last_name": "Jones"}, ] result = tg.import_contacts(contacts) result.wait(raise_exc=True) print(result.update) # {'@type': 'importedContacts', 'user_ids': [111111111, 0], 'importer_count': [3, 0]} # user_id == 0 means that phone number is not registered on Telegram tg.stop() ``` -------------------------------- ### Telegram.idle / stop Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Manages the client's lifecycle by blocking the main thread until a termination signal is received (using `idle()`) and then performing a clean shutdown (using `stop()`). `stop()` ensures all pending operations are completed and the TDLib client is properly closed. ```APIDOC ## `Telegram.idle` / `stop` — Keep alive and clean shutdown `idle()` blocks the calling thread until a POSIX signal (SIGINT, SIGTERM, or SIGABRT) is received, then calls `stop()`. `stop()` sends TDLib's `close` command, waits for the `CLOSED` authorization state, joins background threads, and destroys the TDLib client. Always call `stop()` before the process exits. ```python import signal from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) def on_message(update): print("New message:", update["message"]["content"]) tg.add_message_handler(on_message) # Block until Ctrl-C or kill signal; handles shutdown automatically tg.idle(stop_signals=(signal.SIGINT, signal.SIGTERM)) # For script-style usage without idle(): # result = tg.get_me() # result.wait() # tg.stop() ``` ``` -------------------------------- ### Add Message Handler and Idle Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/tutorial.md Add a message handler function to process incoming messages and then call tg.idle() to keep the bot running and responsive. tg.idle() is a blocking call that waits for an exit signal (e.g., CTRL+C). ```python # This function will be called for each received message. def new_message_handler(update): print('New message!') tg.add_message_handler(new_message_handler) tg.idle() # Blocking, waiting for CTRL+C. ``` -------------------------------- ### Track Message Confirmation with Event Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Use threading.Event to wait for server confirmation of a sent message. Remove the handler when no longer needed. Blocks until SIGINT/SIGTERM/SIGABRT is received. ```python import threading # Track when a sent message is confirmed by the server sent_event = threading.Event() def on_send_succeeded(update): print(f"Message confirmed. New ID: {update['message']['id']}") sent_event.set() tg.add_update_handler("updateMessageSendSucceeded", on_send_succeeded) result = tg.send_message(chat_id=-1001234567890, text="Hello") result.wait() sent_event.wait(timeout=30) # Remove a handler when no longer needed tg.remove_update_handler("updateMessageSendSucceeded", on_send_succeeded) tg.idle() # blocks until SIGINT/SIGTERM/SIGABRT tg.stop() ``` -------------------------------- ### Retrieve Chat List with Telegram Client Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Call `get_chats` to fetch a page of chat IDs. This populates the local cache, which is necessary before sending messages. Use `get_chat` to fetch details for a specific chat. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) # Fetch up to 200 chats from the beginning of the list result = tg.get_chats(offset_order=9223372036854775807, offset_chat_id=0, limit=200) result.wait(raise_exc=True) print(result.update) # {'@type': 'chats', 'chat_ids': [-1001234567890, 987654321, ...], '@extra': {...}} # Then fetch details for a specific chat chat_result = tg.get_chat(-1001234567890) chat_result.wait(raise_exc=True) print(chat_result.update["title"]) tg.stop() ``` -------------------------------- ### Register Update Callbacks Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Registers a callback function to be executed when a specific TDLib update type is received. `add_message_handler` is a shortcut for `add_update_handler('updateNewMessage', func)`. Handlers are processed in a worker thread with a default queue size of 1000. ```python import threading from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) # Echo bot: reply "pong" to every "ping" def on_message(update): content = update["message"]["content"] if content["@type"] != "messageText": return text = content["text"]["text"].strip().lower() if not update["message"]["is_outgoing"] and text == "ping": tg.send_message(chat_id=update["message"]["chat_id"], text="pong") tg.add_message_handler(on_message) ``` -------------------------------- ### Telegram.get_me Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Retrieves profile information for the currently authenticated user or bot. This method corresponds to TDLib's `getMe` function. ```APIDOC ## Telegram.get_me — Get the current user's profile Returns information about the authenticated account (user or bot). Maps to TDLib's `getMe` method. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) result = tg.get_me() result.wait(raise_exc=True) print(result.update) # { # '@type': 'user', # 'id': 987654321, ``` -------------------------------- ### Telegram.get_supergroup_full_info / Telegram.create_basic_group_chat Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Retrieves extended information about a supergroup, including its basic group predecessor. `create_basic_group_chat` opens or creates a chat object from a basic group ID for accessing its history. ```APIDOC ## `Telegram.get_supergroup_full_info` / `create_basic_group_chat` — Supergroup and group utilities `get_supergroup_full_info` retrieves extended information about a supergroup including its basic group predecessor. `create_basic_group_chat` opens/creates a chat object from a basic group ID so its history can be accessed. ### Parameters #### `get_supergroup_full_info` - **supergroup_id** (int) - Required - The ID of the supergroup. #### `create_basic_group_chat` - **basic_group_id** (int) - Required - The ID of the basic group. ### Request Example ```python SUPERGROUP_ID = 1234567890 r = tg.get_supergroup_full_info(SUPERGROUP_ID) r.wait(raise_exc=True) basic_group_id = r.update.get("upgraded_from_basic_group_id", 0) if basic_group_id: r2 = tg.create_basic_group_chat(basic_group_id) r2.wait(raise_exc=True) ``` ### Response #### `get_supergroup_full_info` Success Response (200) - **member_count** (int) - The number of members in the supergroup. - **upgraded_from_basic_group_id** (int) - The ID of the basic group from which this supergroup was upgraded, if applicable. #### `create_basic_group_chat` Success Response (200) - **id** (int) - The ID of the created basic group chat. ``` -------------------------------- ### Echo Ping Pong Logic Source: https://github.com/alexander-akhmetov/python-telegram/blob/main/docs/source/tutorial.md Enhance the message handler to specifically respond to 'ping' messages with 'pong'. This code checks if the message is not outgoing and its text content is 'ping', then sends 'pong' back to the same chat. ```python def new_message_handler(update): # We want to process only text messages. message_content = update['message']['content'].get('text', {}) message_text = message_content.get('text', '').lower() is_outgoing = update['message']['is_outgoing'] if not is_outgoing and message_text == 'ping': chat_id = update['message']['chat_id'] print(f'Ping has been received from {chat_id}') tg.send_message( chat_id=chat_id, text='pong', ) ``` -------------------------------- ### Telegram.call_method Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt A low-level method to invoke any TDLib function directly by its name. Supports an optional `block` parameter for synchronous waiting. ```APIDOC ## `Telegram.call_method` — Call any TDLib method directly Low-level escape hatch to invoke any [TDLib function](https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1_function.html) by name. Supports an optional `block=True` parameter to wait synchronously for the result. ### Parameters - **method_name** (string) - Required - The name of the TDLib function to call. - **params** (dict) - Optional - A dictionary of parameters for the TDLib function. - **block** (boolean) - Optional - If true, waits synchronously for the result. Defaults to false. ### Request Example ```python # Search for public chats result = tg.call_method("searchPublicChat", params={"username": "telegram"}) result.wait(raise_exc=True) # Get current network type (synchronously) result = tg.call_method("getNetworkStatistics", block=True) # Forward a message result = tg.call_method("forwardMessages", params={ "chat_id": -1001111111111, "from_chat_id": -1001234567890, "message_ids": [1234567890123], "send_copy": False, "remove_caption": False, }) result.wait(raise_exc=True) ``` ### Response #### Success Response (200) - **update** (dict) - The result of the TDLib function call. The structure depends on the specific function invoked. ### Response Example ```json { "update": { "@type": "chat", "id": 123456789012345, "title": "Telegram" } } ``` ``` -------------------------------- ### Handle Asynchronous TDLib Responses Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Every Telegram method returns an AsyncResult. Use .wait() to block for the result, inspect .update for the response, and check .error/.error_info for failures. Supports optional timeouts and exception raising for TDLib errors. ```python from telegram.client import Telegram from telegram.utils import AsyncResult tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) result: AsyncResult = tg.get_me() try: result.wait(timeout=10, raise_exc=True) # raises RuntimeError on TDLib error except TimeoutError: print("Request timed out") except RuntimeError as e: print(f"TDLib error: {e}") else: if result.error: print("Error:", result.error_info) else: print("Success:", result.update) tg.stop() ``` -------------------------------- ### Fetch Single Message by ID with Telegram Client Source: https://context7.com/alexander-akhmetov/python-telegram/llms.txt Use `get_message` to retrieve a specific message using its `chat_id` and `message_id`. This is useful for looking up a known message after receiving a notification. ```python from telegram.client import Telegram tg = Telegram( api_id=12345678, api_hash="0123456789abcdef0123456789abcdef", phone="+15551234567", database_encryption_key="changeme1234", login=True, ) result = tg.get_message(chat_id=-1001234567890, message_id=1234567890123) result.wait(raise_exc=True) print(result.update) # { # '@type': 'message', # 'id': 1234567890123, # 'sender_user_id': 987654321, # 'chat_id': -1001234567890, # 'content': {'@type': 'messageText', 'text': {'text': 'Hello'}}, # ... # } tg.stop() ```