Back to Home

UX Telegram Bots: Buttons and FSM on aiogram

Article Breaks Down UX Telegram Bots: Message Structure, Colored Buttons Bot API 9.4, Scenarios Instead of Commands, FSM for States. Code Examples on aiogram for Senior Developers.

Colored Buttons and FSM: UX for Telegram Bots
Advertisement 728x90

UX Design for Telegram Bots: Buttons, Scenarios, and FSM with aiogram

User experience determines Telegram bot retention. Without a clear sequence of messages and buttons, functionality is useless. In Telegram, UX boils down to a chain: message → button → response. Minimize user decisions—guide them step-by-step without hesitation.

The first message on /start is critical: within 3 seconds, users decide whether to stay. Avoid long texts—state the essence, benefit, and main button.

Start screen structure:

Google AdInline article slot
  • Title with the bot's purpose
  • 1–2 lines of explanation
  • 1 main action button
  • Optional: help button

Buttons as the Primary Interface

Buttons replace screens and menus. Inline buttons are preferred: attached to messages, they don't clutter the chat. Use reply buttons for a fixed set of options.

Optimal number of buttons:

  • 1–2 buttons: instant choice
  • 3–4: 2–3 second pause
  • 5+: stress and drop-off

Button text rules:

Google AdInline article slot
  • Verbs: "Create," "Send," "Back"
  • Instead of "Yes/No"—"Confirm/Cancel"
  • Unique text in the message
  • For dangerous actions: clear warning

Colored Buttons in Bot API 9.4

Bot API 9.4 introduced styles for inline buttons: primary (blue), success (green), danger (red). Requires aiogram 3.20+. Custom emojis are available with Telegram Premium for the owner or an additional username on Fragment.

Example keyboard in aiogram:

from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton

def get_colored_keyboard() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup(inline_keyboard=[
        # 🔵 Blue button
        [InlineKeyboardButton(
            text="Subscribe to channel",
            url="https://t.me/example",
            icon_custom_emoji_id="6039422865189638057",  # 📣 megaphone
            style="primary",
        )],
        # 🟢 Green button
        [InlineKeyboardButton(
            text="Check subscription",
            callback_data="check_subscribe",
            icon_custom_emoji_id="5870633910337015697",  # ✅ checkmark
            style="success",
        )],
        # 🔴 Red button
        [InlineKeyboardButton(
            text="Delete account",
            callback_data="delete_account",
            icon_custom_emoji_id="5870657884844462243",  # ❌ cross
            style="danger",
        )],
        # Two buttons in a row
        [
            InlineKeyboardButton(
                text="Cancel",
                callback_data="cancel",
                icon_custom_emoji_id="5870657884844462243",
                style="danger",
            ),
            InlineKeyboardButton(
                text="Done",
                callback_data="confirm",
                icon_custom_emoji_id="5870633910337015697",
                style="success",
            ),
        ],
        # Button without style
        [InlineKeyboardButton(
            text="Settings",
            callback_data="settings",
            icon_custom_emoji_id="5870982283724328568",  # ⚙️
        )],
    ])

Call: await message.answer("Text", reply_markup=get_colored_keyboard()). Get emoji IDs from @ShowJsonBot.

Google AdInline article slot

Limitations:

  • Styles—Bot API 9.4+
  • Custom emojis—Premium
  • Without Premium: squares for users without subscription

Custom Emojis for a Modern Look

Premium emojis enhance perception: branded icons in buttons, titles, confirmations. Don't overload—1–2 accents per message.

Applications:

  • Checkmark instead of ✅ in buttons
  • Unique emoji as bot brand
  • Animation on success

Scenarios Instead of Commands

Commands (/create, /edit) force users to remember logic. Scenarios guide them hand-in-hand: the bot dictates steps, the user follows.

Example post creation scenario:

| Step | User Action | Bot Response |

|------|-------------|--------------|

| 1 | "Create post" | "Send a photo or GIF" |

| 2 | Sends photo | "Now the text" |

| 3 | Sends text | "Add a button?" |

| 4 | "Yes" | "Button text and link" |

| 5 | Enters data | Preview |

| 6 | "Send" | "✅ Published" |

When to use scenarios:

  • Multiple steps
  • Data input
  • Option selection

Commands: /start, /help, /cancel.

FSM for State Management

Without Finite State Machine, scenarios break: users send text instead of photos, the bot gets confused.

States solve:

  • Tracking stage for each user_id
  • Error handling: "Waiting for photo, ignoring text"
  • Support for "Back"

Example state class:

class States:
    START = "start"
    WAITING_PHOTO = "waiting_photo"
    WAITING_TEXT = "waiting_text"
    WAITING_BUTTON = "waiting_button"

In handlers: check FSMContext.state, transition await state.set_state(States.WAITING_TEXT).

Key Takeaways

  • First message: essence + 1 button, no command lists.
  • Buttons: max 2–4, verbs, colors from Bot API 9.4.
  • Scenarios > commands: guide users step-by-step.
  • FSM is essential: for sequences >1 step.
  • Emojis carefully: Premium icons only as accents.

— Editorial Team

Advertisement 728x90

Read Next