### Downloading and Running Telethon Examples Source: https://github.com/coddrago/heroku-tl/blob/main/telethon_examples/README.md This sequence of commands clones the Telethon repository from GitHub, navigates into the examples directory, and then launches a Python GUI application to interact with the examples. Git must be installed on the system as a prerequisite. ```Shell git clone https://github.com/LonamiWebs/Telethon.git cd Telethon cd telethon_examples python3 gui.py ``` -------------------------------- ### Installing Telethon Library with Pip Source: https://github.com/coddrago/heroku-tl/blob/main/telethon_examples/README.md This command installs or upgrades the Telethon library using pip, ensuring the necessary dependencies are met for running the examples. It's recommended to use `python3 -m pip` for portability to avoid conflicts with system-wide Python installations. ```Shell python3 -m pip install --upgrade telethon --user ``` -------------------------------- ### Verifying Telethon Installation - sh Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/installation.rst This command executes a short Python script to import the Telethon library and print its installed version number. It serves as a quick check to confirm that the library has been successfully installed and is accessible within the Python environment. ```sh python3 -c "import telethon; print(telethon.__version__)" ``` -------------------------------- ### Installing Optional Telethon Dependencies on apt-based Systems - sh Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/installation.rst This sequence of commands updates package lists, installs system-level development libraries required for certain Python modules (like cryptg and pillow), and then uses pip to install setuptools, telethon, cryptg, and pillow for the current user. These optional dependencies enhance performance and functionality, particularly for image handling and encryption. ```sh apt update apt install clang lib{jpeg-turbo,webp}-dev python{,-dev} zlib-dev pip install -U --user setuptools pip install -U --user telethon cryptg pillow ``` -------------------------------- ### Structuring Asynchronous Telethon Applications in Python Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/quick-start.rst This example illustrates the recommended structure for asynchronous Telethon applications, emphasizing the use of `async def` functions and `await` keywords. It shows how to define a `main` asynchronous function to encapsulate the primary application logic and how to run it using `client.loop.run_until_complete()`, which is crucial for handling the library's asynchronous nature. ```python client = ... async def do_something(me): ... async def main(): # Most of your code should go here. # You can of course make and use your own async def (do_something). # They only need to be async if they need to await things. me = await client.get_me() await do_something(me) with client: client.loop.run_until_complete(main()) ``` -------------------------------- ### Installing Telethon Development Version - sh Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/installation.rst This command installs the latest unreleased development version of the Telethon library directly from its GitHub repository. This version may contain new features or bug fixes not yet in a stable release but is not recommended for production use due to potential instability. ```sh python3 -m pip install --upgrade https://github.com/LonamiWebs/Telethon/archive/v1.zip ``` -------------------------------- ### Starting Client and Signing Up in Python Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst The `.start()` method has been enhanced to allow for direct user sign-up during the client initialization process, simplifying the onboarding flow. ```Python .start() ``` -------------------------------- ### Installing and Upgrading Telethon Library - sh Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/installation.rst This command sequence upgrades pip, the Python package installer, and then installs or upgrades the Telethon library to its latest stable version. It ensures that the environment is ready for Telethon and fetches the most recent stable release. ```sh python3 -m pip install --upgrade pip python3 -m pip install --upgrade telethon ``` -------------------------------- ### Initializing TelegramClient: Chaining Start Method with With Block (Python) Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst This example showcases chaining the `.start()` method directly after `TelegramClient` instantiation within a `with` block. This allows for immediate client startup with specific authentication parameters (like `bot_token`) while still benefiting from the automatic disconnection provided by the `with` statement. ```python with TelegramClient(name, api_id, api_hash).start(bot_token=token) as bot: bot.send_message(chat, 'Hello!') ``` -------------------------------- ### Importing Telethon Client for Documentation Examples Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/compatibility-and-convenience.rst This snippet demonstrates the common import statements assumed throughout the Telethon documentation. It shows two ways to import TelegramClient: either directly from telethon along with sync, or specifically from telethon.sync. These imports simplify examples by making the client and synchronous functionalities readily available. ```python from telethon import TelegramClient, sync # or from telethon.sync import TelegramClient ``` -------------------------------- ### Logging In Bot Account with Telethon (Python) Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/signing-in.rst This example illustrates how to log in a Telegram bot account. In addition to `api_id` and `api_hash`, a `bot_token` obtained from `@BotFather` is required. Unlike user accounts, the `start()` method must be explicitly called with `bot_token` when initializing the `TelegramClient` for bot authentication. ```python from telethon.sync import TelegramClient api_id = 12345 api_hash = '0123456789abcdef0123456789abcdef' bot_token = '12345:0123456789abcdef0123456789abcdef' # We have to manually call "start" if we want an explicit bot token bot = TelegramClient('bot', api_id, api_hash).start(bot_token=bot_token) # But then we can use the client instance as usual with bot: ... ``` -------------------------------- ### Automated TL Generation during Library Installation in Python Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst The `setup.py` script now automatically invokes `gen_tl` during library installation if necessary, ensuring that the Telegram Layer (TL) definitions are up-to-date. ```Python setup.py ``` ```Python gen_tl ``` -------------------------------- ### Installing Herokutl Library (Shell) Source: https://github.com/coddrago/heroku-tl/blob/main/README.rst This snippet demonstrates how to install the `heroku-tl-new` Python library using pip3. This command is a prerequisite for setting up your environment to use the library for Telegram API interactions. ```sh pip3 install heroku-tl-new ``` -------------------------------- ### Initializing TelegramClient (Python) Source: https://github.com/coddrago/heroku-tl/blob/main/README.rst This snippet shows how to create and start a `TelegramClient` instance using `herokutl`. It requires `api_id` and `api_hash` obtained from Telegram's API Development section, which are essential for authenticating your application with the Telegram API. ```python from herokutl import TelegramClient, events, sync # These example values won't work. You must get your own api_id and # api_hash from https://my.telegram.org, under API Development. api_id = 12345 api_hash = '0123456789abcdef0123456789abcdef' client = TelegramClient('session_name', api_id, api_hash) client.start() ``` -------------------------------- ### Implementing Echo Bot with pyTelegramBotAPI Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/botapi-vs-mtproto.rst This snippet demonstrates a basic echo bot using `pyTelegramBotAPI`. It initializes the bot with a token, defines handlers for the `/start` command and all other messages, and starts polling for updates. It showcases the `message_handler` decorator and `reply_to` method. ```Python import telebot bot = telebot.TeleBot("TOKEN") @bot.message_handler(commands=['start']) def send_welcome(message): bot.reply_to(message, "Howdy, how are you doing?") @bot.message_handler(func=lambda m: True) def echo_all(message): bot.reply_to(message, message.text) bot.polling() ``` -------------------------------- ### Implementing an Echo Bot with python-telegram-bot Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/botapi-vs-mtproto.rst This snippet demonstrates how to create a basic echo bot using the `python-telegram-bot` library. It initializes an `Updater` with a bot token, registers `CommandHandler` for `/start` and `MessageHandler` for text messages, and starts polling for updates. The `start` function replies with 'Hi!', and the `echo` function replies with the user's message. ```Python from telegram.ext import Updater, CommandHandler, MessageHandler, Filters def start(update, context): """Send a message when the command /start is issued.""" update.message.reply_text('Hi!') def echo(update, context): """Echo the user message.""" update.message.reply_text(update.message.text) def main(): """Start the bot.""" updater = Updater("TOKEN") dp = updater.dispatcher dp.add_handler(CommandHandler("start", start)) dp.add_handler(MessageHandler(Filters.text & ~Filters.command, echo)) updater.start_polling() updater.idle() if __name__ == '__main__': main() ``` -------------------------------- ### Concise TelegramClient Initialization with MTProto Proxy - Python Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/signing-in.rst This snippet provides a concise version of initializing a `TelegramClient` with an MTProto proxy, omitting comments for clarity. It demonstrates setting the `connection` to `ConnectionTcpMTProxyRandomizedIntermediate` and passing the proxy host, port, and secret as a tuple. This is a streamlined example of the previous snippet. ```python from telethon import TelegramClient, connection client = TelegramClient( 'anon', api_id, api_hash, connection=connection.ConnectionTcpMTProxyRandomizedIntermediate, proxy=('mtproxy.example.com', 2002, 'secret') ) ``` -------------------------------- ### Running Asynchronous Main Function with asyncio (Python) Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/compatibility-and-convenience.rst This snippet illustrates the standard way to execute an asynchronous `main` function in Python using `asyncio.run()`. It is a common pattern for starting an asyncio event loop and running the top-level coroutine. This is a prerequisite for any asyncio-based application. ```python asyncio.run(main()) ``` -------------------------------- ### Automating Replies with Telethon NewMessage Event in Python Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/updates.rst This example demonstrates how to set up a basic Telegram bot using Telethon to automatically reply to messages containing 'hello'. It initializes the client, defines an asynchronous event handler for new messages, and starts the client to listen for updates. ```Python from telethon import TelegramClient, events client = TelegramClient('anon', api_id, api_hash) @client.on(events.NewMessage) async def my_event_handler(event): if 'hello' in event.raw_text: await event.reply('hi!') client.start() client.run_until_disconnected() ``` -------------------------------- ### Performing Basic Operations with Telethon Client in Python Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/quick-start.rst This snippet demonstrates how to initialize a TelegramClient and perform various common operations using its 'friendly methods'. It covers retrieving user information, listing dialogs, sending messages to different recipients (including markdown and replies), sending files, and iterating through message history to download media. It highlights the asynchronous nature of the library. ```python from telethon import TelegramClient # Remember to use your own values from my.telegram.org! api_id = 12345 api_hash = '0123456789abcdef0123456789abcdef' client = TelegramClient('anon', api_id, api_hash) async def main(): # Getting information about yourself me = await client.get_me() # "me" is a user object. You can pretty-print # any Telegram object with the "stringify" method: print(me.stringify()) # When you print something, you see a representation of it. # You can access all attributes of Telegram objects with # the dot operator. For example, to get the username: username = me.username print(username) print(me.phone) # You can print all the dialogs/conversations that you are part of: async for dialog in client.iter_dialogs(): print(dialog.name, 'has ID', dialog.id) # You can send messages to yourself... await client.send_message('me', 'Hello, myself!') # ...to some chat ID await client.send_message(-100123456, 'Hello, group!') # ...to your contacts await client.send_message('+34600123123', 'Hello, friend!') # ...or even to any username await client.send_message('username', 'Testing Telethon!') # You can, of course, use markdown in your messages: message = await client.send_message( 'me', 'This message has **bold**, `code`, __italics__ and ' 'a [nice website](https://example.com)!', link_preview=False ) # Sending a message returns the sent message object, which you can use print(message.raw_text) # You can reply to messages directly if you have a message object await message.reply('Cool!') # Or send files, songs, documents, albums... await client.send_file('me', '/home/me/Pictures/holidays.jpg') # You can print the message history of any chat: async for message in client.iter_messages('me'): print(message.id, message.text) # You can download media from messages, too! # The method will return the path where the file was saved. if message.photo: path = await message.download_media() print('File saved to', path) # printed after download is done with client: client.loop.run_until_complete(main()) ``` -------------------------------- ### Getting Input Entity with Telethon Client Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/full-api.rst Shows an asynchronous way to obtain an `InputPeer` object using `client.get_input_entity()`. This method simplifies resolving various entity types (e.g., usernames, phone numbers) into the required `InputPeer` format for API calls. The example includes the necessary `async def` and `run_until_complete` for execution. ```python import telethon async def main(): peer = await client.get_input_entity('someone') client.loop.run_until_complete(main()) ``` -------------------------------- ### Configuring Proxy for TelegramClient (Dictionary Syntax, Python) Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/signing-in.rst This example demonstrates configuring a proxy for `TelegramClient` using a dictionary for the `proxy` argument. It allows specifying `proxy_type`, `addr`, `port`, and optional `username` and `password` for authenticated proxies. This is the preferred way to define proxy settings, requiring `python-socks[asyncio]` or `PySocks`. ```python proxy = { 'proxy_type': 'socks5', # (mandatory) protocol to use (see above) 'addr': '1.1.1.1', # (mandatory) proxy IP address 'port': 5555, # (mandatory) proxy port number 'username': 'foo', # (optional) username if the proxy requires auth 'password': 'bar', # (optional) password if the proxy requires auth } ``` -------------------------------- ### Initializing and Using TelegramClient in Python Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/modules/client.rst This snippet demonstrates how to initialize a TelegramClient instance using 'name', 'api_id', and 'api_hash' and then use it to send a message. It shows the basic asynchronous setup required for interacting with the Telegram API via Telethon, including running an asynchronous function within the client's context. ```python from telethon import TelegramClient client = TelegramClient(name, api_id, api_hash) async def main(): # Now you can use all client methods listed below, like for example... await client.send_message('me', 'Hello to myself!') with client: client.loop.run_until_complete(main()) ``` -------------------------------- ### Implementing Bot with dumbot Subclassing Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/botapi-vs-mtproto.rst This snippet demonstrates subclassing `dumbot.Bot` to create a custom bot. It overrides the `init` method to fetch bot information and `on_update` to handle incoming messages, replying with the bot's username. It uses synchronous `run()` to start the bot. ```Python from dumbot import Bot class Subbot(Bot): async def init(self): self.me = await self.getMe() async def on_update(self, update): await self.sendMessage( chat_id=update.message.chat.id, text='i am {}'.format(self.me.username) ) Subbot(token).run() ``` -------------------------------- ### Configuring Proxy for TelegramClient (Tuple Syntax, Python) Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/signing-in.rst This snippet shows how to configure a proxy for `TelegramClient` using a tuple for the `proxy` argument. It specifies the proxy type (e.g., 'socks5'), IP address, and port. This method is provided for backwards compatibility and requires `python-socks[asyncio]` (Python >= 3.6) or `PySocks` (Python <= 3.5) to be installed. ```python TelegramClient('anon', api_id, api_hash, proxy=("socks5", '127.0.0.1', 4444)) ``` -------------------------------- ### Conditional Phone Prompt on Client Start in Python Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst The `.start()` method has been improved to only prompt for the user's phone number when it is absolutely required, enhancing user experience for existing sessions. ```Python .start() ``` -------------------------------- ### Example of Pong Response Object Structure Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/full-api.rst Shows the typical structure of a `Pong` object, which is the expected response from a `PingRequest`. It includes `msg_id` and `ping_id` members, demonstrating how the API returns data. This is often seen via `stringify()`. ```python Pong( msg_id=781875678118, ping_id=48641868471 ) ``` -------------------------------- ### Using Telethon in Synchronous Mode with `telethon.sync` Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/compatibility-and-convenience.rst This snippet illustrates how to use Telethon in a synchronous manner for quick scripts or REPL usage, leveraging telethon.sync to manage the asyncio loop implicitly. It demonstrates performing actions like getting user info, sending messages, and even integrating asynchronous event handlers within a synchronous context, highlighting the convenience of not needing explicit 'await' calls for basic operations. ```python from telethon.sync import TelegramClient # ^~~~~ note this part; it will manage the asyncio loop for you with TelegramClient(...) as client: print(client.get_me().username) # ^ notice the lack of await, or loop.run_until_complete(). # Since there is no loop running, this is done behind the scenes. # message = client.send_message('me', 'Hi!') import time time.sleep(5) message.delete() # You can also have an hybrid between a synchronous # part and asynchronous event handlers. # from telethon import events @client.on(events.NewMessage(pattern='(?i)hi|hello')) async def handler(event): await event.reply('hey') client.run_until_disconnected() ``` -------------------------------- ### Handling Complex Inline Keyboard Input with Callback Query (Python) Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst This example illustrates how to create and handle a complex inline keyboard layout, simulating a phone number input. It uses the `events.CallbackQuery` handler to process button clicks, appending or removing digits from a global `phone` variable and updating the user with the current input. ```Python from telethon import events global phone = '' @bot.on(events.CallbackQuery) async def handler(event): global phone if event.data == b'<': phone = phone[:-1] else: phone += event.data.decode('utf-8') await event.answer('Phone is now {}'.format(phone)) markup = bot.build_reply_markup([ [Button.inline('1'), Button.inline('2'), Button.inline('3')], [Button.inline('4'), Button.inline('5'), Button.inline('6')], [Button.inline('7'), Button.inline('8'), Button.inline('9')], [Button.inline('+'), Button.inline('0'), Button.inline('<')], ]) bot.send_message(chat, 'Enter a phone', buttons=markup) ``` -------------------------------- ### Updating User Profile Photo with Telethon (Python) Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/examples/users.rst This example demonstrates how to update a user's profile photo. It first uploads a local file using `client.upload_file` and then uses the returned file object with `UploadProfilePhotoRequest` from Telethon's photos functions to set it as the new profile picture. ```python from telethon.tl.functions.photos import UploadProfilePhotoRequest await client(UploadProfilePhotoRequest( await client.upload_file('/path/to/some/file') )) ``` -------------------------------- ### Sending Messages: Asyncio vs. Telethon Sync Module (Python) Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst This example illustrates how to send a message using the Telethon client. It contrasts the traditional `asyncio` approach, requiring an `async def` function and `await`, with the new `telethon.sync` module, which allows for a more straightforward synchronous-looking call while still leveraging `asyncio` internally. ```python import asyncio async def main(): await client.send_message('me', 'Hello!') asyncio.run(main()) # ...can be rewritten as: from telethon import sync client.send_message('me', 'Hello!') ``` -------------------------------- ### Enabling Custom Languages in Preformatted HTML Blocks Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst This HTML snippet demonstrates how to embed code within a `
` block and specify a custom language using the `class` attribute. This allows for proper syntax highlighting when displaying code examples in web contexts.
```html
from telethon import TelegramClient
```
--------------------------------
### Configuring Telethon Client for HTTP Connection (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst
This snippet demonstrates how to configure the Telethon `TelegramClient` to use an HTTP connection, which is essential for environments requiring HTTP proxies. It involves importing `ConnectionHttp` from `telethon.network` and passing an instance of it to the `connection` parameter during client initialization. The example then shows a basic message sending operation to verify the connection.
```Python
from telethon import TelegramClient, sync
from telethon.network import ConnectionHttp
client = TelegramClient(..., connection=ConnectionHttp)
with client:
client.send_message('me', 'Hi!')
```
--------------------------------
### Scheduling Messages with Telethon Client (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst
This snippet demonstrates how to schedule messages to be sent at a later time using the 'schedule' parameter in 'client.send_message()'. It shows examples for scheduling a message in 10 minutes and another for 1 day later, utilizing 'datetime.timedelta'.
```python
from datetime import timedelta
# Remind yourself to walk the dog in 10 minutes (after you play with Telethon's update)
await client.send_message('me', 'Walk the dog',
schedule=timedelta(minutes=10))
# Remind your friend tomorrow to update Telethon
await client.send_message(friend, 'Update Telethon!',
schedule=timedelta(days=1))
```
--------------------------------
### Implementing Bot with Telethon Subclassing (dumbot Migration)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/botapi-vs-mtproto.rst
This snippet rewrites the `dumbot` subclassing example using Telethon. It subclasses `TelegramClient`, manually registers `on_update` as an event handler, and overrides `connect` to fetch bot info. It demonstrates Telethon's snake_case methods and event-driven approach.
```Python
from telethon import TelegramClient, events
class Subbot(TelegramClient):
def __init__(self, *a, **kw):
super().__init__(*a, **kw)
self.add_event_handler(self.on_update, events.NewMessage)
async def connect():
await super().connect()
self.me = await self.get_me()
async def on_update(event):
await event.reply('i am {}'.format(self.me.username))
bot = Subbot('bot', 11111, 'a1b2c3d4').start(bot_token='TOKEN')
bot.run_until_disconnected()
```
--------------------------------
### Updating User Name and Bio with Telethon (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/examples/users.rst
This example illustrates how to modify a user's first name, last name, and 'about' (bio) information using `UpdateProfileRequest` in Telethon. Fields not specified in the request will remain unchanged. This is useful for personalizing a user's profile.
```python
from telethon.tl.functions.account import UpdateProfileRequest
await client(UpdateProfileRequest(
about='This is a test from Telethon'
))
```
--------------------------------
### Creating Asynchronous Tasks with asyncio in Python
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/asyncio.rst
This snippet demonstrates how to schedule multiple asynchronous operations to run concurrently in the background using `loop.create_task()`. It shows examples of fetching messages, sending messages, and downloading profile photos, all managed by an `asyncio` event loop. These tasks will execute as long as the main event loop is active.
```python
loop.create_task(client.get_messages('telegram', 10))
loop.create_task(client.send_message('me', 'Using asyncio!'))
loop.create_task(client.download_profile_photo('telegram'))
```
--------------------------------
### Sending Message by Username with Inline Entity Retrieval (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/full-api.rst
This example shows a more concise way to send a message by directly resolving the input entity from a username within the `SendMessageRequest`. The `client.get_input_entity()` call is nested, allowing for a single-line operation to send a message to a user identified by their username.
```python
result = await client(SendMessageRequest(
await client.get_input_entity('username'), 'Hello there!'
))
```
--------------------------------
### Indicating Chat Action with client.action (Telethon Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst
This snippet demonstrates the new `client.action` method, introduced to easily indicate chat actions such as 'typing'. By using an `async with` statement, the action is automatically started upon entering the block and stopped upon exiting, providing a clean and efficient way to show user activity before sending a message or performing other operations.
```Python
async with client.action(chat, 'typing'):
await asyncio.sleep(2) # type for 2 seconds
await client.send_message(chat, 'Hello world! I type slow ^^')
```
--------------------------------
### Executing Multiple Requests in Parallel (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/full-api.rst
This example demonstrates two ways to send multiple requests concurrently. The first uses `asyncio.wait` with `client.send_message` for automatic batching by the library. The second manually provides a list of `SendMessageRequest` objects to the client for explicit parallel execution, which the library merges into a single container for efficiency.
```python
async def main():
# Letting the library do it behind the scenes
await asyncio.wait([
client.send_message('me', 'Hello'),
client.send_message('me', ','),
client.send_message('me', 'World'),
client.send_message('me', '.')
])
# Manually invoking many requests at once
await client([
SendMessageRequest('me', 'Hello'),
SendMessageRequest('me', ', '),
SendMessageRequest('me', 'World'),
SendMessageRequest('me', '.')
])
```
--------------------------------
### Keeping Telethon Client Alive with Awaiting client.disconnected (Asyncio Loop)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/updates.rst
This example shows an equivalent way to keep the Telethon client alive by explicitly awaiting the `client.disconnected` property within an `asyncio` event loop. This approach requires manual handling of the event loop and `KeyboardInterrupt`.
```python
import asyncio
from telethon import TelegramClient
client = TelegramClient(...)
async def main():
await client.disconnected
asyncio.run(main())
```
--------------------------------
### Defining Pytest Unit Tests with Asyncio Support - Python
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/developing/testing.rst
This snippet demonstrates how to define unit tests using Pytest in Python. It shows a synchronous test function accepting a fixture and an asynchronous test function marked with `@pytest.mark.asyncio` that requests an `event_loop` fixture, suitable for testing asyncio code. The tests use simple `assert` statements for validation.
```Python
from module import my_thing, my_other_thing
def test_my_thing(fixture):
assert my_thing(fixture) == 42
@pytest.mark.asyncio
async def test_my_thing(event_loop):
assert await my_other_thing(loop=event_loop) == 42
```
--------------------------------
### Correctly Accessing Chat and Sender Entities in Telethon Events
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/updates.rst
This example illustrates the correct and incorrect ways to retrieve chat and sender information from an event object. It emphasizes that for events, `get_chat()` and `get_sender()` (asynchronous methods) must be used to fetch complete entity data, rather than directly accessing properties like `event.chat` or `event.sender`, which may not contain full information.
```Python
async def handler(event):
# Good
chat = await event.get_chat()
sender = await event.get_sender()
chat_id = event.chat_id
sender_id = event.sender_id
# BAD. Don't do this
chat = event.chat
sender = event.sender
chat_id = event.chat.id
sender_id = event.sender.id
```
--------------------------------
### Retrieving Various Entity Types (Telethon, Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/entities.rst
This comprehensive snippet demonstrates various ways to retrieve entities using `client.get_entity()`. It covers fetching dialogs to populate the entity cache, getting entities by username (including different link formats), by channel invite links, by phone numbers, by raw IDs, and by explicit `Peer` types (User, Chat, Channel) for clarity and type safety.
```Python
# (These examples assume you are inside an "async def")
#
# Dialogs are the "conversations you have open".
# This method returns a list of Dialog, which
# has the .entity attribute and other information.
#
# This part is IMPORTANT, because it fills the entity cache.
dialogs = await client.get_dialogs()
# All of these work and do the same.
username = await client.get_entity('username')
username = await client.get_entity('t.me/username')
username = await client.get_entity('https://telegram.dog/username')
# Other kind of entities.
channel = await client.get_entity('telegram.me/joinchat/AAAAAEkk2WdoDrB4-Q8-gg')
contact = await client.get_entity('+34xxxxxxxxx')
friend = await client.get_entity(friend_id)
# Getting entities through their ID (User, Chat or Channel)
entity = await client.get_entity(some_id)
# You can be more explicit about the type for said ID by wrapping
# it inside a Peer instance. This is recommended but not necessary.
from telethon.tl.types import PeerUser, PeerChat, PeerChannel
my_user = await client.get_entity(PeerUser(some_id))
my_chat = await client.get_entity(PeerChat(some_id))
```
--------------------------------
### Simplified Client Initialization with New .start() Method in Python
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst
A new `.start()` method has been introduced to simplify client initialization, reducing boilerplate code required to connect and authenticate with the Telegram API.
```Python
.start()
```
--------------------------------
### Reliably Getting Input Sender for Message Sending (Telethon, Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/entities.rst
This code snippet shows how to reliably obtain an input sender using `event.get_input_sender()`. Unlike direct properties, this method explicitly handles potential network requests to ensure the entity is found, making it suitable for scenarios where certainty is crucial or when the sender entity will be reused multiple times.
```Python
async def handler(event):
# This method may make a network request to find the input sender.
# Properties can't make network requests, so we need a method.
sender = await event.get_input_sender()
await client.send_message(sender, 'Hi')
await client.send_message(sender, 'Hi')
```
--------------------------------
### Example of Unrecognized RPC Base Error in Telethon
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/errors.rst
This snippet shows an example of a `BadRequestError` (a base RPC error) that might be raised when the library doesn't have a specific class for a particular error. It highlights the error code (400) and the specific Telegram error message (`MESSAGE_POLL_CLOSED`), indicating a need to report such unhandled errors.
```text
telethon.errors.rpcbaseerrors.BadRequestError: RPCError 400: MESSAGE_POLL_CLOSED (caused by SendVoteRequest)
```
--------------------------------
### Using StringSession for TelegramClient Initialization (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/sessions.rst
This snippet demonstrates how to initialize a TelegramClient using StringSession, which allows session data to be stored in memory and easily saved as a string. It shows both creating a client with a StringSession and converting an existing session (e.g., SQLiteSession) into a string for portability and reuse without requiring a physical file.
```python
from telethon.sync import TelegramClient
from telethon.sessions import StringSession
with TelegramClient(StringSession(string), api_id, api_hash) as client:
... # use the client
# Save the string session as a string; you should decide how
# you want to save this information (over a socket, remote
# database, print it and then paste the string in the code,
# etc.); the advantage is that you don't need to save it
# on the current disk as a separate file, and can be reused
# anywhere else once you log in.
string = client.session.save()
# Note that it's also possible to save any other session type
# as a string by using ``StringSession.save(session_instance)``:
client = TelegramClient('sqlite-session', api_id, api_hash)
string = StringSession.save(client.session)
```
--------------------------------
### Implementing Echo Bot with aiogram
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/botapi-vs-mtproto.rst
This snippet shows an echo bot implementation using `aiogram`. It initializes a `Bot` and `Dispatcher`, defines handlers for `/start` and a regex pattern, and a general echo handler. It demonstrates `message.reply` and `bot.send_photo` for sending files.
```Python
from aiogram import Bot, Dispatcher, executor, types
API_TOKEN = 'BOT TOKEN HERE'
# Initialize bot and dispatcher
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)
@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
"""
This handler will be called when client send `/start` command.
"""
await message.reply("Hi!\nI'm EchoBot!\nPowered by aiogram.")
@dp.message_handler(regexp='(^cat[s]?$|puss)')
async def cats(message: types.Message):
with open('data/cats.jpg', 'rb') as photo:
await bot.send_photo(message.chat.id, photo, caption='Cats is here 😺',
reply_to_message_id=message.message_id)
@dp.message_handler()
async def echo(message: types.Message):
await bot.send_message(message.chat.id, message.text)
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
```
--------------------------------
### Handling FloodWaitError in Telethon Python
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/errors.rst
This example illustrates how to catch and handle a `FloodWaitError` (error code 420) in Telethon. This error occurs when too many requests are made, and the `e.seconds` attribute provides the required waiting period, which the code then uses with `time.sleep()`.
```python
...
from telethon import errors
try:
messages = await client.get_messages(chat)
print(messages[0].text)
except errors.FloodWaitError as e:
print('Have to sleep', e.seconds, 'seconds')
time.sleep(e.seconds)
```
--------------------------------
### Initializing Telethon Client and Handling Messages (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/index.rst
This snippet demonstrates how to initialize a Telethon `TelegramClient` in synchronous mode, send a message, download a profile photo, and set up an event handler for new messages. It requires `api_id` and `api_hash` for authentication and keeps the client running until disconnected, allowing it to respond to incoming messages.
```Python
from telethon.sync import TelegramClient, events
with TelegramClient('name', api_id, api_hash) as client:
client.send_message('me', 'Hello, myself!')
print(client.download_profile_photo('me'))
@client.on(events.NewMessage(pattern='(?i).*Hello'))
async def handler(event):
await event.reply('Hey!')
client.run_until_disconnected()
```
--------------------------------
### Converting Peer Objects to Marked IDs using Telethon
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/chats-vs-channels.rst
This example illustrates the use of `telethon.utils.get_peer_id` to convert a Telethon peer object (like `types.PeerChannel`) into its 'marked' identifier, which includes the appropriate prefix for channels or chats. This is the reverse operation of `resolve_id`.
```python
print(utils.get_peer_id(types.PeerChannel(456))) # -1000000000456
```
--------------------------------
### Enabling Logging in Python
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/quick-references/faq.rst
This snippet demonstrates how to enable basic logging in a Python application using the `logging` module. It configures the log format and sets the initial logging level to `WARNING`, allowing developers to see messages with medium severity.
```python
import logging
logging.basicConfig(format='[%(levelname) %(asctime)s] %(name)s: %(message)s',
level=logging.WARNING)
```
--------------------------------
### Obtaining Full Channel Details using Telethon Functions
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/chats-vs-channels.rst
This example demonstrates how to retrieve comprehensive details about a channel, including its `ChannelFull` object, using `telethon.functions.channels.GetFullChannelRequest`. This is useful for accessing properties like `migrated_from` which are not directly available on the basic `Channel` object.
```python
from telethon import functions
full = await client(functions.channels.GetFullChannelRequest(your_channel))
full_channel = full.full_chat
# full_channel is a ChannelFull
```
--------------------------------
### Initializing TelegramClient with MTProto Proxy - Python
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/basic/signing-in.rst
This snippet shows how to initialize a `TelegramClient` to use an MTProto proxy. It requires specifying a special `connection` mode, such as `ConnectionTcpMTProxyRandomizedIntermediate`, and providing proxy details (host, port, and secret) as a tuple. If the proxy has no secret, a specific all-zero string must be used.
```python
from telethon import TelegramClient, connection
# we need to change the connection ^^^^^^^^^^
client = TelegramClient(
'anon',
api_id,
api_hash,
# Use one of the available connection modes.
# Normally, this one works with most proxies.
connection=connection.ConnectionTcpMTProxyRandomizedIntermediate,
# Then, pass the proxy details as a tuple:
# (host name, port, proxy secret)
#
# If the proxy has no secret, the secret must be:
# '00000000000000000000000000000000'
proxy=('mtproxy.example.com', 2002, 'secret')
)
```
--------------------------------
### Initializing Telethon Client for Test Server (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/developing/test-servers.rst
This snippet initializes a Telethon client for connecting to a Telegram test server. It sets the session to `None` to ensure a new authorization key is generated and configures the data center (DC) with a specific test IP and port 80, as port 443 might not be reliable for test connections.
```python
client = TelegramClient(None, api_id, api_hash)
client.session.set_dc(dc_id, '149.154.167.40', 80)
```
--------------------------------
### Fetching Chat and Sender Information in Telethon Event Handlers (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/quick-references/faq.rst
Shows how to explicitly fetch `chat` and `sender` information using `await event.get_chat()` and `await event.get_sender()` when `event.chat` or `event.sender` might be `None` due to Telegram's bandwidth optimization, ensuring all necessary data is retrieved.
```Python
async def handler(event):
chat = await event.get_chat()
sender = await event.get_sender()
```
--------------------------------
### Manually Constructing a Pong Object in Telethon
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/full-api.rst
Demonstrates how to manually create an instance of the `Pong` type, similar to how `stringify()` would represent it. This is useful for understanding the object's constructor and its required parameters, `msg_id` and `ping_id`.
```python
my_pong = Pong(
msg_id=781875678118,
ping_id=48641868471
)
```
--------------------------------
### Retrieving Messages by ID in Telethon
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst
This example illustrates how to fetch messages using the get_messages method of TelegramClient by specifying their IDs. It shows how to retrieve a single message using an integer ID and multiple messages using a list of IDs. The chats parameter specifies the chat(s) from which to retrieve messages.
```python
message = client.get_messages(chats, ids=123) # Single message
message_list = client.get_messages(chats, ids=[777, 778]) # Multiple
```
--------------------------------
### Optimizing Telethon Usage with Pure Asyncio
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/compatibility-and-convenience.rst
This snippet shows how to use Telethon in a purely asynchronous context for performance optimization, by directly importing TelegramClient from telethon and operating within an async def function. It demonstrates the explicit use of 'await' for API calls, such as client.get_me(), emphasizing the need for proper asyncio patterns when telethon.sync is not used.
```python
import asyncio
from telethon import TelegramClient, events
async def main():
async with TelegramClient(...) as client:
print((await client.get_me()).username)
# ^_____________________^ notice these parenthesis
```
--------------------------------
### Accessing Sender Properties with Telethon Message (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/entities.rst
This snippet illustrates how `Message` objects, through inheritance from `SenderGetter`, can access sender-related properties and methods. It demonstrates retrieving the user ID, asynchronously getting the input sender entity, and accessing the user object. This functionality is provided because `Message` also acts as a `SenderGetter`.
```python
message.user_id
await message.get_input_sender()
message.user
# ...etc
```
--------------------------------
### Client-Side Theme Switching Initialization in JavaScript
Source: https://github.com/coddrago/heroku-tl/blob/main/telethon_generator/data/html/core.html
This JavaScript Immediately Invoked Function Expression (IIFE) handles the client-side theme management for the documentation page. It initializes the theme based on local storage or defaults to 'light', and sets up event listeners for 'light' and 'dark' theme buttons to allow users to toggle the display style.
```JavaScript
(function () { var style = document.getElementById('style'); function setTheme(theme) { localStorage.setItem('theme', theme); return style.href = 'css/docs.' + theme + '.css'; } function setThemeOnClick(theme, button) { return button.addEventListener('click', function (e) { setTheme(theme); e.preventDefault(); return false; }); } setTheme(localStorage.getItem('theme') || 'light'); document.addEventListener('DOMContentLoaded', function () { setThemeOnClick('light', document.getElementById('themeLight')); setThemeOnClick('dark', document.getElementById('themeDark')); }); })();
```
--------------------------------
### Manually Constructing InputPeerUser in Telethon
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/full-api.rst
Demonstrates how to manually create an `InputPeerUser` object, which is often required as a `peer` parameter for API requests. It requires `user_id` and `user_hash` to uniquely identify a user.
```python
from telethon.tl.types import InputPeerUser
peer = InputPeerUser(user_id, user_hash)
```
--------------------------------
### Accessing Chat Properties with Telethon Message (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/entities.rst
This snippet demonstrates how `Message` objects, by inheriting from `ChatGetter`, can directly access chat-related properties and methods. It shows how to check if a message is private, retrieve the chat ID, and asynchronously get the full chat object. This functionality is available because `Message` acts as a `ChatGetter`.
```python
message.is_private
message.chat_id
await message.get_chat()
# ...etc
```
--------------------------------
### Connecting and Authenticating to Telegram Test Server (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/developing/test-servers.rst
This code demonstrates connecting to a Telegram test server and authenticating using a specific test phone number and a hardcoded login code. It initializes the client, sets the data center to `dc_id = 2` with the test IP and port, and then calls `client.start()` with a test phone number (e.g., `9996621234`) and a `code_callback` that returns the expected test login code (e.g., `22222`).
```python
client = TelegramClient(None, api_id, api_hash)
client.session.set_dc(2, '149.154.167.40', 80)
client.start(
phone='9996621234', code_callback=lambda: '22222'
)
```
--------------------------------
### Adding Users to Chats and Channels with Telethon (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/examples/chats-and-channels.rst
This snippet shows how to add users to normal chats using `AddChatUserRequest` and to channels (including megagroups) using `InviteToChannelRequest`. `AddChatUserRequest` takes `chat_id`, `user_to_add`, and an optional `fwd_limit`, while `InviteToChannelRequest` takes the channel entity and a list of users. It's important to note that mass-adding users is not supported and can lead to account risks.
```python
# For normal chats
from telethon.tl.functions.messages import AddChatUserRequest
# Note that ``user_to_add`` is NOT the name of the parameter.
# It's the user you want to add (``user_id=user_to_add``).
await client(AddChatUserRequest(
chat_id,
user_to_add,
fwd_limit=10 # Allow the user to see the 10 last messages
))
# For channels (which includes megagroups)
from telethon.tl.functions.channels import InviteToChannelRequest
await client(InviteToChannelRequest(
channel,
[users_to_add]
))
```
--------------------------------
### Sending Message with Raw API Request in Telethon (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/entities.rst
This example illustrates sending a message using a raw `SendMessageRequest` directly with the Telethon client. Since version 0.16.2, the library automatically resolves the 'username' string to an `InputPeer` internally, simplifying direct API calls by handling entity resolution transparently.
```python
await client(SendMessageRequest('username', 'hello'))
```
--------------------------------
### Adding Telethon Event Handlers Without Decorators in Python
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/updates.rst
This example shows an alternative method for adding an event handler to a Telethon client without using the events.register decorator. The handler function and the specific event type (events.NewMessage) are directly passed as arguments to client.add_event_handler(), providing flexibility in how handlers are defined and attached.
```Python
from telethon import TelegramClient, events
async def handler(event):
...
with TelegramClient(...) as client:
client.add_event_handler(handler, events.NewMessage)
client.run_until_disconnected()
```
--------------------------------
### Sending Messages with Explicit Peer Types in Telethon
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/concepts/chats-vs-channels.rst
This example demonstrates how to explicitly specify the peer type (e.g., `types.PeerChannel`) when sending a message. This is crucial when Telethon might otherwise assume a `User` type for an identifier without a 'mark' (minus sign), ensuring the message is sent to the correct entity type.
```python
from telethon import types
await client.send_message(types.PeerChannel(456), 'hello')
# ^^^^^^^^^^^^^^^^^ explicit peer type
```
--------------------------------
### Managing TelegramClient: Using With Block for Auto Start/Disconnect (Python)
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst
This snippet demonstrates the new `with` block functionality for `TelegramClient`. When used in a `with` statement, the client automatically calls `client.start()` upon entering the block and `client.disconnect()` upon exiting, simplifying resource management and ensuring proper connection handling.
```python
from telethon import TelegramClient, sync
with TelegramClient(name, api_id, api_hash) as client:
client.send_message('me', 'Hello!')
```
--------------------------------
### Optimizing Input Entity Resolution for Early Return in Python
Source: https://github.com/coddrago/heroku-tl/blob/main/readthedocs/misc/changelog.rst
Internal optimizations have been applied to `.get_input_entity()` and similar methods to return results as early as possible, improving performance and reducing unnecessary processing.
```Python
.get_input_entity()
```