exteraGram

Client Utilities

This module provides utility functions and classes for asynchronous tasks, making API requests, sending messages, and displaying UI notifications like bulletins.

This module contains helpers for interacting with Telegram's core functionalities, managing background tasks, and providing user feedback.

Queues (Background Threads)

For performing long-running or blocking operations (like network requests or heavy computations) without freezing the UI, you should run your functions on a background thread. client_utils provides run_on_queue for this.

import time
from client_utils import run_on_queue
from android_utils import log
 
def my_long_task(parameter: str):
    log(f"Task started with: {parameter}")
    time.sleep(5) # Simulate a long operation
    log(f"Task finished for: {parameter}")
    # If you need to update UI after this, use run_on_ui_thread here
 
# Run on the default PLUGINS_QUEUE
run_on_queue(lambda: my_long_task("some_data"))

You can specify which queue to use and add a delay (in milliseconds):

from client_utils import GLOBAL_QUEUE
 
# Run on GLOBAL_QUEUE after a 2.5 second delay
run_on_queue(lambda: my_long_task("other_data"), GLOBAL_QUEUE, 2500)

Available Queues (as string constants): These allow you to target specific Telegram dispatch queues.

STAGE_QUEUE = "stageQueue"                # For critical, sequential operations
GLOBAL_QUEUE = "globalQueue"              # General purpose background tasks
CACHE_CLEAR_QUEUE = "cacheClearQueue"    # Cache management tasks
SEARCH_QUEUE = "searchQueue"              # Search operations
PHONE_BOOK_QUEUE = "phoneBookQueue"      # Phone book and contact sync
THEME_QUEUE = "themeQueue"                # Theme application and processing
EXTERNAL_NETWORK_QUEUE = "externalNetworkQueue" # Network requests not related to Telegram API
PLUGINS_QUEUE = "pluginsQueue"            # **Default queue for `run_on_queue` if not specified.** Recommended for most plugin background tasks.

To get a direct Java org.telegram.messenger.DispatchQueue instance:

from client_utils import get_queue_by_name
 
plugins_dispatch_queue = get_queue_by_name(PLUGINS_QUEUE)
if plugins_dispatch_queue:
    # You can use methods of DispatchQueue directly, e.g., plugins_dispatch_queue.postRunnable(...)
    pass

Utilities

Sending Telegram API Requests

To send raw Telegram API requests (TLObjects), use send_request. This function handles sending the request via the current account's connection manager and invoking your callback upon response or error.

RequestCallback is a dynamic_proxy for org.telegram.tgnet.RequestDelegate, simplifying callback implementation in Python.

from org.telegram.tgnet import TLRPC
from client_utils import send_request, RequestCallback, get_messages_controller
from android_utils import log
from java.lang import Integer
 
def handle_read_contents_response(response: TLRPC.TLObject, error: TLRPC.TL_error):
    if error:
        log(f"Error reading message contents: {error.text}")
        return
    if response and isinstance(response, TLRPC.TL_messages_affectedMessages): # Or other expected type
        log(f"Successfully read contents. PTS: {response.pts}, Count: {response.pts_count}")
    else:
        log(f"Unexpected response type for readMessageContents: {type(response)}")
 
# Create the request object
req = TLRPC.TL_messages_readMessageContents()
req.id.add(Integer(12345))
 
# Create the callback proxy
callback_proxy = RequestCallback(handle_read_contents_response)
 
# Send the request
connection_request_id = send_request(req, callback_proxy)
log(f"Sent TL_messages_readMessageContents, request ID: {connection_request_id}")

Sending Messages and Media

This module provides several high-level functions to easily send text, photos, videos, and other files. These functions handle file processing and sending on the appropriate threads.

send_text

Sends a simple text message.

from client_utils import send_text
 
# Send a text message to a user or chat
peer_id = 123456789
send_text(peer_id, "Hello from my plugin!")
 
# Send a reply to a message
send_text(peer_id, "This is a reply.", replyToMsg=9876)

send_photo

Uploads and sends a photo from a local file path.

from client_utils import send_photo
 
peer_id = 123456789
photo_path = "/path/to/your/image.jpg"
 
# Send a photo with a caption
send_photo(peer_id, photo_path, caption="Here is a photo!")
 
# Send a high-quality photo
send_photo(peer_id, photo_path, caption="High quality.", high_quality=True)

send_document

Uploads and sends a generic file/document.

from client_utils import send_document
 
peer_id = 123456789
file_path = "/path/to/your/file.zip"
 
send_document(peer_id, file_path, caption="Here is the zip file.")

send_video

Uploads and sends a video file, automatically extracting metadata like duration and dimensions.

from client_utils import send_video
 
peer_id = 123456789
video_path = "/path/to/your/video.mp4"
 
send_video(peer_id, video_path, caption="Check out this video!")

send_audio

Uploads and sends an audio file as a music track, automatically extracting metadata.

from client_utils import send_audio
 
peer_id = 123456789
audio_path = "/path/to/your/song.mp3"
 
send_audio(peer_id, audio_path, caption="Listen to this!")

All send_* functions also accept any additional keyword arguments (**kwargs) that will be passed along to the underlying SendMessageParams object, such as replyToMsg, scheduleDate, etc.

Editing Messages

You can edit existing messages using the edit_message function.

from client_utils import edit_message
 
# Assume 'message_obj' is a valid MessageObject instance you have obtained
# For example, from a hook or by fetching it from storage.
 
# Edit the text of a message
edit_message(message_obj, text="This is the new, edited text.")
 
# Replace the media in a message (and optionally edit the caption)
new_photo_path = "/path/to/another/image.jpg"
edit_message(message_obj, file_path=new_photo_path, text="Here is a new photo instead.")

The edit_message function can also be used to add a media spoiler by passing with_spoiler=True.

Displaying Bulletins (Bottom Notifications)

Bulletins are small, non-intrusive notifications shown at the bottom of the screen. The BulletinHelper class provides an easy way to show them.

For detailed information and examples on how to use various types of bulletins, please refer to the Bulletin Helper documentation.

from ui.bulletin import BulletinHelper
 
# Example:
BulletinHelper.show_info("This is an informational message.")

Accessing Controllers and Managers

client_utils.py provides convenient getter functions for accessing various core Telegram controllers, managers, and configurations for the currently selected account.

from client_utils import (
    get_account_instance, get_messages_controller, get_contacts_controller,
    get_media_data_controller, get_connections_manager, get_location_controller,
    get_notifications_controller, get_messages_storage, get_send_messages_helper,
    get_file_loader, get_secret_chat_helper, get_download_controller,
    get_notifications_settings, get_notification_center, get_media_controller,
    get_user_config
)
 
# Examples:
account_instance = get_account_instance() # Current AccountInstance
messages_controller = get_messages_controller() # MessagesController
connections_manager = get_connections_manager() # ConnectionsManager
send_helper = get_send_messages_helper() # SendMessagesHelper
user_cfg = get_user_config() # UserConfig
 
# Use these instances to interact with Telegram's internal systems.
if user_cfg.getCurrentUser():
  user_name = user_cfg.getCurrentUser().first_name
 
messages_controller.loadDialogs(0, 50, True) # Example method call

These functions simplify access to key components of the Telegram client.

On this page