obabot: Universal Library for Telegram and Max Bots
The obabot library lets you deploy a single asynchronous Python bot across both Telegram and Max simultaneously. Its API is fully compatible with aiogram 3.x: it uses native aiogram for Telegram and an adapter for Max that converts events into compatible objects. Installation is a one-liner: pip install obabot aiogram>=3.0.0 umaxbot>=0.1.7.
The core create_bot() function takes platform tokens and returns a tuple (bot, dispatcher, router). Message handlers are written uniformly, regardless of the platform.
Initialization Examples
For Telegram:
from obabot import create_bot
from obabot.filters import Command
bot, dp, router = create_bot(tg_token="YOUR_TG_TOKEN")
@router.message(Command("start"))
async def start(message):
await message.answer(f"Hi from {message.platform}!")
await dp.start_polling(bot)
For Max:
from obabot import create_bot
from obabot.filters import Command
bot, dp, router = create_bot(max_token="YOUR_MAX_TOKEN")
@router.message(Command("start"))
async def start(message):
await message.answer(f"Hi from {message.platform}!")
await dp.start_polling(bot)
For both platforms in parallel:
from obabot import create_bot
from obabot.filters import Command
bot, dp, router = create_bot(
tg_token="YOUR_TG_TOKEN",
max_token="YOUR_MAX_TOKEN"
)
@router.message(Command("start"))
async def start(message):
await message.answer(f"Hi from {message.platform}!")
await dp.start_polling(bot)
The message.platform attribute returns "telegram" or "max" for platform-specific logic.
Migration from aiogram
Switching from pure aiogram 3.x requires minimal changes: just swap imports and use create_bot() instead of separate Bot, Dispatcher, and Router.
Original aiogram code:
from aiogram import Bot, Dispatcher, Router
from aiogram.filters import Command
from aiogram.fsm.state import State, StatesGroup
from aiogram.fsm.context import FSMContext
bot = Bot(token="TOKEN")
dp = Dispatcher()
router = Router()
dp.include_router(router)
@router.message(Command("start"))
async def start(message):
await message.answer("Hi!")
await dp.start_polling(bot)
After migration:
from obabot import create_bot
from obabot.filters import Command
from obabot.fsm import State, StatesGroup, FSMContext
bot, dp, router = create_bot(tg_token="TOKEN")
@router.message(Command("start"))
async def start(message):
await message.answer("Hi!")
await dp.start_polling(bot)
The rest of your code—including FSM, filters, and keyboards—stays exactly the same.
Message Interface and Basic Methods
All Message objects share a unified interface:
message.text— textmessage.from_user— sendermessage.chat— chatmessage.message_id— IDmessage.platform— platform
Methods:
await message.answer("Reply")await message.reply("Reply to message")await message.delete()await message.edit_text("New text")
FSM: State Machine
FSM works just like aiogram:
from obabot.fsm import State, StatesGroup, FSMContext
class Form(StatesGroup):
name = State()
age = State()
@router.message(Command("start"))
async def start(message, state: FSMContext):
await state.set_state(Form.name)
await message.answer("What's your name?")
@router.message(Form.name)
async def process_name(message, state: FSMContext):
await state.update_data(name=message.text)
await state.set_state(Form.age)
await message.answer("How old are you?")
Inline Keyboards and Filters
Creating a keyboard:
from obabot.types import InlineKeyboardMarkup, InlineKeyboardButton
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[
InlineKeyboardButton(text="Button 1", callback_data="btn1"),
InlineKeyboardButton(text="Button 2", callback_data="btn2"),
]
])
await message.answer("Pick one:", reply_markup=keyboard)
Filters:
@router.message(Command("start", "help"))— multiple commands@router.message(F.text.startswith("!"))— prefix@router.message(F.photo)— photos@router.callback_query(F.data == "click")— callbacks
Testing Without Tokens
test_mode=True skips all network calls:
bot, dp, router = create_bot(test_mode=True)
Supports Python 3.10–3.14, aiogram 3.0.0–3.24. Full unit test coverage.
What's Important
- Single codebase: One handler for Telegram and Max—no adapters needed.
- Full compatibility: 100% aiogram 3.x API +
platformattribute. - FSM and filters: Complete support for states, inline keyboards, magic filters
F. - Easy migration: Swap 2 import lines and initialization.
- Testing: Isolated mode with no API calls.
— Editorial Team
No comments yet.