A command router and conversation-state machine for Telegram bots — for any bot that needs to ask more than one question in a row, not a specific use case.
Illustration of the exact conversation tests/test_support_bot.py
exercises — not a live screenshot, but the dialogue text is copied
verbatim from what the example bot actually sends.
Past the first /start command, most bot deliveries turn into a single
large if/elif chain keyed on whatever the user typed last. That works
until two things happen at once: two users mid-conversation
simultaneously (whose state collides in a global variable), or a user
abandoning one flow to start a different command (which the if/elif
chain usually doesn't handle at all).
Three pieces, each independently testable:
Router— commands, per-state message handlers, and callback-query (inline button) handlers are registered with decorators and dispatched by precedence, not one hand-written conditional.StateStore— per-user conversation state (InMemoryStateStorefor a single-process bot,SqliteStateStorewhen state needs to survive a restart), so two users' conversations never collide.TelegramClient— a thin Bot API wrapper that takes its HTTP call as a constructor argument, the same pattern used in mt5-python-bridge'sMT5Client— it's what lets the whole example conversation intests/test_support_bot.pybe tested with no bot token and no network call anywhere near the suite.
git clone https://github.com/kestrelquant/telegram-bot-framework
cd telegram-bot-framework
pip install -r requirements.txtfrom bot import Router, TelegramClient, InMemoryStateStore, inline_keyboard, run_polling
router = Router()
@router.command("start")
def start(ctx):
ctx.reply("Hi! Type /help to see what I can do.")
@router.state_handler("awaiting_name")
def collect_name(ctx):
ctx.set_state(None, name=ctx.text)
ctx.reply(f"Nice to meet you, {ctx.text}.")
client = TelegramClient(token="...")
run_polling(client, router, InMemoryStateStore())See examples/support_bot.py for the full
support-ticket bot shown above — command menu, a two-step conversation,
inline keyboards, and completion.
export TG_BOT_TOKEN=...
python examples/support_bot.pyFully offline — tests/fake_client.py records calls instead of hitting
the Telegram API.
pip install -r requirements-dev.txt
python -m pytest tests/CI (.github/workflows/ci.yml) runs the suite on every push.
See CONTRIBUTING.md.
MIT — see LICENSE.
