Skip to main content

A modular, multi-client library for aiogram to handle user response waiting in Telegram bots.

Project description

aiogram-input

aiogram-input is a lightweight and flexible library for aiogram
that simplifies waiting for user responses without FSMs.

With aiogram-input, you can easily implement interactive flows where your bot waits for a specific user's reply in a specific chat, with full support for multiple bot instances (multi-client) to avoid conflicts.


✨ Key Features

  • Simple API – Replace FSM with a single input() call.
  • Filters – Use filter= to capture only the messages you want.
  • Timeout Handling – Gracefully handle unresponsive users.
  • Multi-Client – Each bot instance has its own isolated state.
  • Race Condition Safe – Built for concurrency.
  • Logging Integration – Debug and monitor with ease.
  • Quick Setup - Just add one line to your project: asker = InputManager(DP_OR_ROUTER)

📦 Installation

From PyPI:

pip install aiogram-input

From GitHub (latest):

pip install git+https://github.com/mamahoos/aiogram-input.git

💡 Usage Examples

Below are real scenarios where aiogram-input shines.


1. ✅ Confirm Before Action

Ask users to confirm actions before executing them.

from aiogram         import Bot, Dispatcher, Router, F
from aiogram.types   import Message
from aiogram.filters import Command
from aiogram.enums   import ChatType
from aiogram_input   import InputManager

TOKEN = "YOUR_BOT_TOKEN"

bot   = Bot(TOKEN)
dp    = Dispatcher()
asker = InputManager(dp)

@dp.message(Command("delete"), F.chat.type == ChatType.PRIVATE)
async def delete_command(message: Message):
    await message.answer("⚠️ Are you sure you want to delete your data? (yes/no)")

    response = await asker.input(message.chat.id, timeout=20)

    if response is None:
        return await message.answer("⏳ Timeout. Action canceled.")

    text = (response.text or "").lower().strip()
    if text in {"yes", "y"}:
        # Perform deletion here
        await message.answer("✅ Your data has been deleted.")
    else:
        await message.answer("❌ Action canceled.")

2. 👥 Per-User Flow Inside a Group

Capture responses only from the command initiator in busy group chats.

from aiogram         import Bot, Dispatcher, Router, F
from aiogram.types   import Message
from aiogram.enums   import ChatType
from aiogram.filters import Command
from aiogram_input   import InputManager

TOKEN = "YOUR_BOT_TOKEN"

bot   = Bot(TOKEN)
dp    = Dispatcher()
asker = InputManager(dp)

@dp.message(Command("register"), F.chat.type == ChatType.PRIVATE)
async def group_registration(message: Message):
    user_id = message.from_user.id
    chat_id = message.chat.id

    await message.answer(f"👋 {message.from_user.first_name}, please enter your email:")

    response = await asker.input(chat_id, timeout=40)

    if response is None:
        return await message.answer(f"⏳ {message.from_user.first_name}, you ran out of time!")

    await message.answer(f"✅ Email saved: {response.text}")

3. 🔐 Admin-Only Confirmation

Restrict input handling to administrators using custom filters.

from aiogram import Bot, Dispatcher, Router
from aiogram.types import Message
from aiogram.filters import Filter, Command
from aiogram_input import InputManager

TOKEN = "YOUR_BOT_TOKEN"
ADMIN_ID = 123456789

bot    = Bot(TOKEN)
dp     = Dispatcher()
router = Router(name="admin")
asker  = InputManager(router)

class AdminFilter(Filter):
    async def __call__(self, message: Message) -> bool:
        return message.from_user and message.from_user.id == ADMIN_ID

@router.message(AdminFilter(), Command("admin"))
async def secure_command(message: Message):
    await message.answer("🔐 Admin check passed! Please confirm action:")

    response = await asker.input(
        message.chat.id,
        timeout=20,
        filter=AdminFilter()
    )

    if not response:
        return await message.answer("⏳ No confirmation received.")

    text = response.text
    if text.strip().lower() in {'y', 'yes'}:
        await message.answer(f"✅ Action confirmed")
    else:
        await message.answer("❌ Action canceled.")
        
dp.include_router(router)

4. 📊 Multi-Step Data Collection (Form)

Build forms or registration flows without FSMs.

from aiogram         import Bot, Dispatcher, Router, F
from aiogram.enums   import ChatType
from aiogram.types   import Message
from aiogram.filters import Command
from aiogram_input   import InputManager

TOKEN = "YOUR_BOT_TOKEN"

bot   = Bot(TOKEN)
dp    = Dispatcher()
asker = InputManager(dp)

@dp.message(Command("form"), F.chat.type == ChatType.PRIVATE)
async def form_command(message: Message):
    user_id = message.from_user.id
    chat_id = message.chat.id

    await message.answer("👤 What is your name?")
    name = await asker.input(chat_id, timeout=30)
    if not name:
        return await message.answer("⏳ Timeout on name.")

    await message.answer("📧 What is your email?")
    email = await asker.input(chat_id, timeout=30)
    if not email:
        return await message.answer("⏳ Timeout on email.")

    await message.answer(f"✅ Registration complete!
Name: {name.text}
Email: {email.text}")

5. ⏳ Timeout with Fallback Action

Provide fallback behavior when the user doesn’t respond in time.

from aiogram import Bot, Dispatcher, Router, F
from aiogram.types import Message
from aiogram.filters import Command
from aiogram_input import InputManager

TOKEN = "YOUR_BOT_TOKEN"

bot   = Bot(TOKEN)
dp    = Dispatcher()
asker = InputManager(dp)

router = Router(name="timeout")

@dp.message(Command("quiz"))
async def quiz_command(message: Message):
    await message.answer("❓ What is 2 + 2?")

    response = await asker.input(
        message.chat.id,
        timeout=15,
        filter=(F.from_user.id == message.from_user.id)
    )

    if response is None:
        return await message.answer("⏳ Time’s up! The correct answer is 4.")

    if response.text.strip() == "4":
        await message.answer("🎉 Correct!")
    else:
        await message.answer("❌ Wrong. The correct answer is 4.")

📖 Summary

  • Use asker.input(chat_id, timeout, filter=...) to capture user input seamlessly.
  • Combine with filters for per-user targeting.
  • Production-ready: async, safe, and minimal boilerplate.

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

aiogram_input-3.1.0.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

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

aiogram_input-3.1.0-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file aiogram_input-3.1.0.tar.gz.

File metadata

  • Download URL: aiogram_input-3.1.0.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for aiogram_input-3.1.0.tar.gz
Algorithm Hash digest
SHA256 7b547c217c3f4b021aac2e31a8ababed36334292733bc48aa7c500bed92d39e4
MD5 983e378f3b1438b77fc27687a14d8d1c
BLAKE2b-256 5d3a68d391ecc1ed33fc7e6504316bdf9905821753f4385bc22cbfcf3bcbb0c7

See more details on using hashes here.

File details

Details for the file aiogram_input-3.1.0-py3-none-any.whl.

File metadata

  • Download URL: aiogram_input-3.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for aiogram_input-3.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f996b1da13f062358e95d0bc838679d40d64422c827746b5f7896876d3018987
MD5 1ade4d853e31814d13297c4ea3d6993c
BLAKE2b-256 081603a055a730429dfd45011f0bf3a5ea342e33a90a506604ebfe949dff6b00

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