Skip to main content

A simple and convenient library for creating Telegram bots.

Project description

Extergram — Asynchronous Telegram Bot Framework

Disclaimer: This project is an independent open-source library and is not affiliated with, associated with, authorized by, endorsed by, or in any way officially connected with Telegram FZ-LLC or any of its subsidiaries or its affiliates.

Extergram is a simple, modern, and fully asynchronous library for creating Telegram bots in Python.

Quick Start

Installation

pip install extergram```

## Simple Echo Bot Example

```python
import asyncio
from extergram import Bot, Message
from extergram.ext import CommandHandler, MessageHandler

# Initialize the bot with your token
bot = Bot('YOUR_BOT_TOKEN')

async def start_handler(bot_instance: Bot, message: Message):
    """
    Handles the /start command and sends a welcome message.
    """
    await bot_instance.send_message(
        chat_id=message.chat.id,
        text="Extergram v0.7.0 is working! 🐾\nAsync polling is now stable."
    )

async def echo_handler(bot_instance: Bot, message: Message):
    """
    Simple echo handler to verify that message processing works.
    """
    if message.text:
        await bot_instance.send_message(
            chat_id=message.chat.id,
            text=message.text
        )

async def main():
    # Registering handlers using the ext module
    bot.add_handler(CommandHandler("start", start_handler))
    bot.add_handler(MessageHandler(echo_handler))
    
    print("Starting Extergram v0.7.0 bot...")
    
    # Polling is an async coroutine in v0.7.0
    await bot.polling()

if __name__ == '__main__':
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nStopping the bot...")```


## Complete Example (Classic Style)

This example demonstrates the original handler style, which remains fully supported for backward compatibility.

```python
# main.py
import asyncio
import datetime
from extergram import Bot, ButtonsDesign, Message, CallbackQuery, errors, Markdown
from extergram.ext import CommandHandler, CallbackQueryHandler

# Initialize the bot with your token
bot = Bot('YOUR_BOT_TOKEN', default_parse_mode="MarkdownV2")

# Create an inline keyboard
main_menu = ButtonsDesign().add_row(
    ButtonsDesign.create_button("Show time", "show_time"),
    ButtonsDesign.create_button("About", "about")
).add_row(
    ButtonsDesign.create_url_button("GitHub", "https://github.com/AAVTIBI1/extergram"),
    ButtonsDesign.create_button("Delete", "delete")
)

async def start(bot_instance: Bot, message: Message):
    user_name = message.from_user.first_name
    
    # Используем Markdown для автоматического экранирования точек и спецсимволов
    text = Markdown(f"Hello, {user_name}! I am running on Extergram v0.7.0.")
    
    await bot_instance.send_message(
        chat_id=message.chat.id,
        text=str(text),
        reply_markup=main_menu
    )

async def handle_callbacks(bot_instance: Bot, callback: CallbackQuery):
    await bot_instance.answer_callback_query(callback.id)
    
    if callback.data == 'show_time':
        now = datetime.datetime.now().strftime("%H:%M:%S")
        # Экранируем время, так как там есть двоеточия
        text = Markdown(f"The current time is: `{now}`")
        await bot_instance.edit_message_text(
            chat_id=callback.message.chat.id,
            message_id=callback.message.message_id,
            text=str(text),
            reply_markup=main_menu
        )
    
    elif callback.data == 'about':
        text = Markdown("Extergram is a simple and modern async library for Telegram bots.")
        await bot_instance.edit_message_text(
            chat_id=callback.message.chat.id,
            message_id=callback.message.message_id,
            text=str(text),
            reply_markup=main_menu
        )

    elif callback.data == 'delete':
        try:
            await bot_instance.delete_message(callback.message.chat.id, callback.message.message_id)
        except errors.BadRequestError:
            await bot_instance.answer_callback_query(callback.id, "Error: Message is too old to delete.", show_alert=True)

async def main():
    bot.add_handler(CommandHandler("start", start))
    bot.add_handler(CallbackQueryHandler(handle_callbacks))
    
    print("Bot is starting...")
    await bot.polling()

if __name__ == '__main__':
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("Bot stopped.")```

## Complete Example (Using ContextTypes)

This example shows the new, recommended approach using the ContextTypes object, which simplifies handler function signatures.

```python
# main_context_style.py
import asyncio
import datetime
from extergram import Bot, ButtonsDesign, ContextTypes, errors, Markdown
from extergram.ext import CommandHandler, CallbackQueryHandler, MessageHandler

# Инициализируем бота, MarkdownV2 включен по умолчанию для всех сообщений
bot = Bot('YOUR_BOT_TOKEN', default_parse_mode='MarkdownV2')

# Создаем меню
main_menu = ButtonsDesign().add_row(
    ButtonsDesign.create_button("Show time", "show_time"),
    ButtonsDesign.create_button("About", "about")
).add_row(
    ButtonsDesign.create_url_button("GitHub", "https://github.com/AAVTIBI1/extergram"),
    ButtonsDesign.create_button("Delete", "delete")
)

async def start(context: ContextTypes):
    user_name = context.message.from_user.first_name
    # Markdown автоматически экранирует точку в версии v0.7.0
    text = Markdown(f"Hello, {user_name}! I am running on Extergram v0.7.0.")
    
    await context.bot.send_message(
        chat_id=context.message.chat.id,
        text=str(text),
        reply_markup=main_menu
    )

async def handle_callbacks(context: ContextTypes):
    callback = context.callback_query
    await context.bot.answer_callback_query(callback.id)
    
    if callback.data == 'show_time':
        now = datetime.datetime.now().strftime("%H:%M:%S")
        # Экранируем время через Markdown
        text = Markdown(f"The current time is: `{now}`")
        await context.bot.edit_message_text(
            chat_id=callback.message.chat.id,
            message_id=callback.message.message_id,
            text=str(text),
            reply_markup=main_menu
        )
    
    elif callback.data == 'about':
        text = Markdown("Extergram is a simple and modern async library for Telegram bots.")
        await context.bot.edit_message_text(
            chat_id=callback.message.chat.id,
            message_id=callback.message.message_id,
            text=str(text),
            reply_markup=main_menu
        )

    elif callback.data == 'delete':
        try:
            await context.bot.delete_message(callback.message.chat.id, callback.message.message_id)
        except errors.BadRequestError:
            await context.bot.answer_callback_query(callback.id, "Error: Message is too old.", show_alert=True)

async def echo_handler(context: ContextTypes):
    # Безопасное эхо: любые символы пользователя будут экранированы
    response = Markdown(f"Echo: {context.message.text}")
    await context.bot.send_message(chat_id=context.message.chat.id, text=str(response))

async def main():
    # Регистрация хендлеров из extergram.ext
    bot.add_handler(CommandHandler("start", start))
    bot.add_handler(CallbackQueryHandler(handle_callbacks))
    bot.add_handler(MessageHandler(echo_handler))
    
    print("Context-style bot is starting...")
    await bot.polling()

if __name__ == '__main__':
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("Bot stopped.")```

## Features & Core Concepts

* Fully Async: High-performance non-blocking operations using httpx.

* Handler System: Manage updates with CommandHandler, MessageHandler, and CallbackQueryHandler. Backward compatibility is fully maintained.

* Context System: An optional ContextTypes object can be used in handlers to bundle the bot instance and update object, leading to cleaner code.

* Admin Functionality: A comprehensive set of methods for chat administration is now available:

ban_chat_member, unban_chat_member

restrict_chat_member (used with the ChatPermissions object)

promote_chat_member

approve_chat_join_request, decline_chat_join_request

* Safe Markdown Builder: The Markdown helper class in utils now automatically escapes special characters to prevent common API errors (Bad Request: can't parse entities).

* Type Hinting: Comprehensive api_types for better IDE support and code clarity.

* Error Handling:

errors.NetworkError: Connection issues.

errors.BadRequestError: Invalid API requests.

errors.ForbiddenError: Bot blocked by user.

errors.UnauthorizedError: Invalid token.

errors.TelegramAdminError: A new specific error raised when the bot lacks the necessary administrative rights to perform an action.

* Local Documentation

You can access the full documentation directly from your terminal:

```python
from extergram import Docs
Docs.print_docs()
## License

MIT License. Copyright (c) 2024-2025.

code
Code
download
content_copy
expand_less
---

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

extergram-0.7.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

extergram-0.7.0-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

File details

Details for the file extergram-0.7.0.tar.gz.

File metadata

  • Download URL: extergram-0.7.0.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for extergram-0.7.0.tar.gz
Algorithm Hash digest
SHA256 dd2e6de3d4d57fc7da986ac5356804545c2cb255a00004a01dd3be037ec00168
MD5 68408175cd2f5dfae65a8e8cf1211d02
BLAKE2b-256 3bc365e979b983d818a4b9d0a7c086c6c41388724f4f59e7c612017a37f0e949

See more details on using hashes here.

File details

Details for the file extergram-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: extergram-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 14.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for extergram-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a6c7109d77a0afe97c8dbaf4f531a3603427e1649dbbf3f480eaa5a141d66e6a
MD5 d08aa30dca9e5b138931cdd0bbb3fa63
BLAKE2b-256 5d01e421d3a78b49e4e7a97316844ff254a2a1c18d818d155d1b27425de99c66

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page