CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-python-telegram-bot

A pure Python, asynchronous interface for the Telegram Bot API with comprehensive wrapper and high-level framework for building sophisticated Telegram bots

Pending
Overview
Eval results
Files

files.mddocs/

File Operations

Complete file handling system supporting uploads, downloads, and media processing for all Telegram file types including photos, videos, documents, audio, stickers, and voice messages.

Capabilities

Input Files

Upload files to Telegram from various sources.

class InputFile:
    def __init__(
        self,
        obj: BinaryIO | bytes | str,
        filename: str = None,
        attach: bool = None
    ): ...
    
    def __enter__(self) -> 'InputFile': ...
    def __exit__(self, exc_type, exc_val, exc_tb) -> None: ...
    
    @property
    def field_tuple(self) -> tuple: ...

Usage examples:

from telegram import InputFile

# From file path
photo = InputFile("/path/to/photo.jpg")
await bot.send_photo(chat_id, photo)

# From bytes
with open("/path/to/document.pdf", "rb") as f:
    document_bytes = f.read()
    
document = InputFile(document_bytes, filename="document.pdf")
await bot.send_document(chat_id, document)

# From file-like object
import io

buffer = io.BytesIO()
# ... write data to buffer
buffer.seek(0)

file_obj = InputFile(buffer, filename="generated.txt")
await bot.send_document(chat_id, file_obj)

# From URL (string)
await bot.send_photo(chat_id, "https://example.com/photo.jpg")

# From file_id (string)
await bot.send_photo(chat_id, "AgACAgIAAxkDAAIC...")

File Downloads

Download files from Telegram servers.

class File:
    file_id: str
    file_unique_id: str
    file_size: int | None
    file_path: str | None
    
    async def download_to_drive(
        self,
        custom_path: str = None,
        block: bool = True
    ) -> str: ...
    
    async def download_as_bytearray(self, block: bool = True) -> bytearray: ...
    async def download_to_memory(self, out: BinaryIO = None, block: bool = True) -> BinaryIO: ...

Usage examples:

# Get file object from message
if update.message.photo:
    # Get largest photo size
    photo = update.message.photo[-1]
    file = await bot.get_file(photo.file_id)
    
    # Download to specific path
    file_path = await file.download_to_drive("downloads/photo.jpg")
    print(f"Downloaded to: {file_path}")
    
    # Download to default path (uses file_id as filename)
    file_path = await file.download_to_drive()
    
    # Download as bytes
    file_bytes = await file.download_as_bytearray()
    
    # Download to memory stream
    import io
    buffer = io.BytesIO()
    await file.download_to_memory(buffer)
    buffer.seek(0)
    data = buffer.read()

# Handle document downloads
if update.message.document:
    file = await bot.get_file(update.message.document.file_id)
    filename = update.message.document.file_name or "unknown"
    await file.download_to_drive(f"downloads/{filename}")

Media Groups

Send multiple media files as a grouped message.

class InputMediaPhoto:
    def __init__(
        self,
        media: str | InputFile,
        caption: str = None,
        parse_mode: str = None,
        caption_entities: list[MessageEntity] = None,
        show_caption_above_media: bool = None,
        has_spoiler: bool = None
    ): ...

class InputMediaVideo:
    def __init__(
        self,
        media: str | InputFile,
        thumbnail: str | InputFile = None,
        caption: str = None,
        parse_mode: str = None,
        caption_entities: list[MessageEntity] = None,
        show_caption_above_media: bool = None,
        width: int = None,
        height: int = None,
        duration: int = None,
        supports_streaming: bool = None,
        has_spoiler: bool = None
    ): ...

class InputMediaAnimation:
    def __init__(
        self,
        media: str | InputFile,
        thumbnail: str | InputFile = None,
        caption: str = None,
        parse_mode: str = None,
        caption_entities: list[MessageEntity] = None,
        show_caption_above_media: bool = None,
        width: int = None,
        height: int = None,
        duration: int = None,
        has_spoiler: bool = None
    ): ...

class InputMediaAudio:
    def __init__(
        self,
        media: str | InputFile,
        thumbnail: str | InputFile = None,
        caption: str = None,
        parse_mode: str = None,
        caption_entities: list[MessageEntity] = None,
        duration: int = None,
        performer: str = None,
        title: str = None
    ): ...

class InputMediaDocument:
    def __init__(
        self,
        media: str | InputFile,
        thumbnail: str | InputFile = None,
        caption: str = None,
        parse_mode: str = None,
        caption_entities: list[MessageEntity] = None,
        disable_content_type_detection: bool = None
    ): ...

Usage example:

from telegram import InputMediaPhoto, InputMediaVideo

# Send media group
media_group = [
    InputMediaPhoto("photo1.jpg", caption="First photo"),
    InputMediaPhoto("photo2.jpg", caption="Second photo"),
    InputMediaVideo("video.mp4", caption="A video")
]

messages = await bot.send_media_group(chat_id, media_group)

Paid Media

Handle paid media content with star payments.

class InputPaidMediaPhoto:
    def __init__(self, media: str | InputFile): ...
    
    media: str | InputFile

class InputPaidMediaVideo:
    def __init__(
        self,
        media: str | InputFile,
        thumbnail: str | InputFile = None,
        width: int = None,
        height: int = None,
        duration: int = None,
        supports_streaming: bool = None
    ): ...
    
    media: str | InputFile
    thumbnail: str | InputFile | None
    width: int | None
    height: int | None
    duration: int | None
    supports_streaming: bool | None

class PaidMediaInfo:
    star_count: int
    paid_media: list[PaidMedia]

class PaidMediaPhoto:
    type: str = "photo"
    photo: list[PhotoSize]

class PaidMediaVideo:
    type: str = "video"
    video: Video

class PaidMediaPreview:
    type: str = "preview"
    width: int | None
    height: int | None
    duration: int | None

Usage example:

from telegram import InputPaidMediaPhoto, InputPaidMediaVideo

# Send paid media
paid_media = [
    InputPaidMediaPhoto("exclusive_photo.jpg"),
    InputPaidMediaVideo("exclusive_video.mp4")
]

message = await bot.send_paid_media(
    chat_id=chat_id,
    star_count=10,  # Cost in Telegram Stars
    media=paid_media,
    caption="Exclusive content for 10 stars!"
)

Stickers

Handle sticker uploads and sticker set management.

class InputSticker:
    def __init__(
        self,
        sticker: str | InputFile,
        format: str,
        emoji_list: list[str],
        mask_position: MaskPosition = None,
        keywords: list[str] = None
    ): ...
    
    sticker: str | InputFile
    format: str  # "static", "animated", "video"
    emoji_list: list[str]
    mask_position: MaskPosition | None
    keywords: list[str] | None

class MaskPosition:
    def __init__(
        self,
        point: str,
        x_shift: float,
        y_shift: float,
        scale: float
    ): ...
    
    point: str  # "forehead", "eyes", "mouth", "chin"
    x_shift: float
    y_shift: float
    scale: float

class Sticker:
    file_id: str
    file_unique_id: str
    type: str  # "regular", "mask", "custom_emoji"
    width: int
    height: int
    is_animated: bool
    is_video: bool
    thumbnail: PhotoSize | None
    emoji: str | None
    set_name: str | None
    premium_animation: File | None
    mask_position: MaskPosition | None
    custom_emoji_id: str | None
    needs_repainting: bool | None
    file_size: int | None
    
    async def get_file(self, **kwargs) -> File: ...

class StickerSet:
    name: str
    title: str
    sticker_type: str
    stickers: list[Sticker]
    thumbnail: PhotoSize | None

Usage examples:

# Send existing sticker
await bot.send_sticker(chat_id, sticker_file_id)

# Create new sticker set
from telegram import InputSticker, MaskPosition

stickers = [
    InputSticker(
        sticker="sticker1.png",
        format="static",
        emoji_list=["😀", "😃"]
    ),
    InputSticker(
        sticker="sticker2.png", 
        format="static",
        emoji_list=["😎"],
        keywords=["cool", "sunglasses"]
    )
]

success = await bot.create_new_sticker_set(
    user_id=user_id,
    name="my_sticker_set_by_mybot",
    title="My Sticker Set",
    stickers=stickers
)

# Add sticker to existing set
new_sticker = InputSticker(
    sticker="new_sticker.png",
    format="static", 
    emoji_list=["🎉"]
)

await bot.add_sticker_to_set(
    user_id=user_id,
    name="my_sticker_set_by_mybot",
    sticker=new_sticker
)

# Get sticker set
sticker_set = await bot.get_sticker_set("my_sticker_set_by_mybot")
for sticker in sticker_set.stickers:
    print(f"Sticker: {sticker.emoji} - {sticker.file_id}")

File Type Detection

Utilities for working with different file types.

# Check file types in messages
async def handle_media(update, context):
    message = update.message
    
    if message.photo:
        # Handle photo
        photo = message.photo[-1]  # Get largest size
        file = await bot.get_file(photo.file_id)
        await file.download_to_drive(f"photos/{photo.file_id}.jpg")
        
    elif message.video:
        # Handle video
        video = message.video
        file = await bot.get_file(video.file_id)
        filename = f"videos/{video.file_id}.mp4"
        await file.download_to_drive(filename)
        
    elif message.document:
        # Handle document
        document = message.document
        file = await bot.get_file(document.file_id)
        filename = document.file_name or f"document_{document.file_id}"
        await file.download_to_drive(f"documents/{filename}")
        
    elif message.audio:
        # Handle audio
        audio = message.audio
        file = await bot.get_file(audio.file_id)
        filename = f"{audio.performer or 'Unknown'} - {audio.title or 'Untitled'}.mp3"
        await file.download_to_drive(f"audio/{filename}")
        
    elif message.voice:
        # Handle voice message
        voice = message.voice
        file = await bot.get_file(voice.file_id)
        await file.download_to_drive(f"voice/{voice.file_id}.ogg")
        
    elif message.video_note:
        # Handle video note (circle video)
        video_note = message.video_note
        file = await bot.get_file(video_note.file_id)
        await file.download_to_drive(f"video_notes/{video_note.file_id}.mp4")
        
    elif message.sticker:
        # Handle sticker
        sticker = message.sticker
        file = await bot.get_file(sticker.file_id)
        extension = "tgs" if sticker.is_animated else "webm" if sticker.is_video else "webp"
        await file.download_to_drive(f"stickers/{sticker.file_id}.{extension}")

File Size and Limits

Understanding Telegram file limitations.

from telegram.constants import FileSizeLimit

# File size limits (in bytes)
max_photo_size = FileSizeLimit.FILESIZE_UPLOAD  # 50 MB for bots
max_file_size = FileSizeLimit.FILESIZE_UPLOAD   # 50 MB for bots
max_thumb_size = FileSizeLimit.FILESIZE_DOWNLOAD  # 20 MB for downloads

# Check file size before upload
import os

def check_file_size(file_path):
    size = os.path.getsize(file_path)
    if size > FileSizeLimit.FILESIZE_UPLOAD:
        raise ValueError(f"File too large: {size} bytes (max: {FileSizeLimit.FILESIZE_UPLOAD})")
    return size

# Handle large files
async def send_large_file(bot, chat_id, file_path):
    try:
        check_file_size(file_path)
        with open(file_path, 'rb') as f:
            await bot.send_document(chat_id, InputFile(f))
    except ValueError as e:
        await bot.send_message(chat_id, f"Cannot send file: {e}")

Thumbnails

Generate and use thumbnails for media files.

# Send video with custom thumbnail
video_file = InputFile("video.mp4")
thumbnail_file = InputFile("thumbnail.jpg")

await bot.send_video(
    chat_id=chat_id,
    video=video_file,
    thumbnail=thumbnail_file,
    duration=120,
    width=1920,
    height=1080,
    caption="Video with custom thumbnail"
)

# Send document with thumbnail
document_file = InputFile("document.pdf")
thumbnail_file = InputFile("doc_preview.jpg")

await bot.send_document(
    chat_id=chat_id,
    document=document_file,
    thumbnail=thumbnail_file,
    caption="PDF document with preview"
)

File Processing Utilities

Helper functions for common file operations.

import mimetypes
import os
from pathlib import Path

def get_file_info(file_path):
    """Get comprehensive file information."""
    path = Path(file_path)
    return {
        'name': path.name,
        'stem': path.stem,
        'suffix': path.suffix,
        'size': path.stat().st_size,
        'mime_type': mimetypes.guess_type(str(path))[0],
        'is_image': path.suffix.lower() in ['.jpg', '.jpeg', '.png', '.gif', '.webp'],
        'is_video': path.suffix.lower() in ['.mp4', '.avi', '.mov', '.mkv'],
        'is_audio': path.suffix.lower() in ['.mp3', '.wav', '.ogg', '.m4a']
    }

async def process_uploaded_file(bot, message):
    """Process any type of uploaded file."""
    file_obj = None
    file_info = {}
    
    if message.document:
        file_obj = message.document
        file_info = {
            'type': 'document',
            'name': file_obj.file_name,
            'mime_type': file_obj.mime_type,
            'size': file_obj.file_size
        }
    elif message.photo:
        file_obj = message.photo[-1]  # Largest size
        file_info = {
            'type': 'photo',
            'width': file_obj.width,
            'height': file_obj.height,
            'size': file_obj.file_size
        }
    elif message.video:
        file_obj = message.video
        file_info = {
            'type': 'video',
            'duration': file_obj.duration,
            'width': file_obj.width,
            'height': file_obj.height,
            'size': file_obj.file_size
        }
    # ... handle other types
    
    if file_obj:
        # Download file
        file = await bot.get_file(file_obj.file_id)
        local_path = await file.download_to_drive()
        
        # Process file as needed
        return {
            'telegram_file': file_obj,
            'local_path': local_path,
            'info': file_info
        }
    
    return None

Types

from typing import BinaryIO, Union
from pathlib import Path

FileInput = Union[str, InputFile, BinaryIO, Path]

Install with Tessl CLI

npx tessl i tessl/pypi-python-telegram-bot

docs

advanced-features.md

application-framework.md

bot-api.md

files.md

filters.md

handlers.md

index.md

keyboards.md

telegram-types.md

tile.json