Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

telegram-bot-framework

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.

Example conversation: a support-ticket bot walking through report an issue -> describe it -> pick a priority -> confirmation

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.

Problem

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).

Solution

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 (InMemoryStateStore for a single-process bot, SqliteStateStore when 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's MT5Client — it's what lets the whole example conversation in tests/test_support_bot.py be tested with no bot token and no network call anywhere near the suite.

Installation

git clone https://github.com/kestrelquant/telegram-bot-framework
cd telegram-bot-framework
pip install -r requirements.txt

Usage

from 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.

Running the example

export TG_BOT_TOKEN=...
python examples/support_bot.py

Tests

Fully 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.

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.

About

Command router and conversation-state machine for Telegram bots

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages