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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd2e6de3d4d57fc7da986ac5356804545c2cb255a00004a01dd3be037ec00168
|
|
| MD5 |
68408175cd2f5dfae65a8e8cf1211d02
|
|
| BLAKE2b-256 |
3bc365e979b983d818a4b9d0a7c086c6c41388724f4f59e7c612017a37f0e949
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6c7109d77a0afe97c8dbaf4f531a3603427e1649dbbf3f480eaa5a141d66e6a
|
|
| MD5 |
d08aa30dca9e5b138931cdd0bbb3fa63
|
|
| BLAKE2b-256 |
5d01e421d3a78b49e4e7a97316844ff254a2a1c18d818d155d1b27425de99c66
|