Keyboard buttons in Telegram bot Using Python
Last Updated :
26 Sep, 2025
Telegram bots can be made more interactive by using keyboard buttons instead of requiring users to type commands. Buttons provide predefined options that make navigation faster, clearer, and more user-friendly. In this article, we will use Python’s Aiogram framework to build interactive menus with InlineKeyboardButton and ReplyKeyboardButton.
Aiogram Framework in Python
Aiogram is an asynchronous Python framework for building Telegram bots using asyncio and aiohttp. It simplifies bot development and allows you to:
- Send and receive messages, photos, and other content.
- Handle user interactions with keyboard buttons.
- Work with inline queries, callback queries, and more.
Install aiogram using the following command in the terminal:
pip install -U aiogram
Note: Aiogram requires Python 3.7+. Check your version using python --version.
Telegram bots support two types of keyboard buttons:
- Displays a set of options in a reply keyboard.
- When clicked, sends the button text as a message to the bot.
- Useful for guiding users through choices.
- Displays buttons within the message itself.
- Sends a callback query to the bot when clicked.
- Allows performing specific actions without sending messages.
Getting a Telegram Bot Token
Before creating buttons, you need a bot token:
1. Search for @BotFather on Telegram.
2. Click on it to open the chat with BotFather. Then, click the "Start" button to interact with the BotFather.
3. Enter the command "/newbot" to create a new bot. Then BotFather bot will guide you through the process of creating your bot, including giving your bot a name and a username.
Note: The Username should always be unique and ends with "bot".
Getting a telegram bot token4. The above token shown in the image is going to use as a bot token and a key to access Telegram API. Make sure to copy the token and keep it safe.
Note: The minimum version of Python required for using aiogram is Python 3.7 or later.
Step 1: Importing required libraries
Python
from aiogram import Bot, Dispatcher, executor, types
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
- Bot: This class represents a Telegram bot and allows you to send messages, photos, videos, documents, and other types of content to Telegram users.
- Dispatcher: This class is the central part of the aiogram library and handles incoming messages and updates from Telegram users.
- executor: This module contains the functions that run the bot and handle incoming updates from Telegram.
- types: This module contains all the types used in the aiogram library, such as Message, User, Chat, and CallbackQuery.
- InlineKeyboardMarkup: This class is used to create inline keyboards in Telegram.
- InlineKeyboardButton: This class represents a single button in an inline keyboard.
Step 2: Initialize Bot and Dispatcher
Python
TOKEN = "YOUR_BOT_TOKEN" # Replace with your BotFather token
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)
- The bot token is required to connect to the Telegram API.
- The dispatcher handles updates and connects them to your handlers.
Python
button1 = InlineKeyboardButton(text="Button 1", callback_data="btn1")
button2 = InlineKeyboardButton(text="Button 2", callback_data="btn2")
keyboard_inline = InlineKeyboardMarkup(row_width=2).add(button1, button2)
- text: The label shown on the button.
- callback_data: Data sent to the bot when the button is clicked.
- row_width=2: Number of buttons per row.
Step 4: Handle /start Command
Python
@dp.message_handler(commands=['start'])
async def start_command(message: types.Message):
await message.reply("Hi! How are you?", reply_markup=keyboard_inline)
- Sends a message with the inline keyboard attached.
- Users can click the buttons instead of typing a response.
Python
@dp.callback_query_handler(text=["btn1", "btn2"])
async def handle_button_click(call: types.CallbackQuery):
if call.data == "btn1":
await call.message.answer("You clicked Button 1!")
elif call.data == "btn2":
await call.message.answer("You clicked Button 2!")
await call.answer() # Stops the loading animation on the button
- Callback query handler receives button clicks.
- call.answer() is required to stop the Telegram “loading” animation.
Step 6: Start the Bot
Python
executor.start_polling(dp)
- Starts an infinite loop that listens for updates.
- The bot will keep running until manually stopped.
Here is the entire code for InlineKeyboardButtons in Telegram Bot:
Python
import asyncio
from aiogram import Bot, Dispatcher
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram import F
from aiogram.types import Message, CallbackQuery
from aiogram import Router
from aiogram.fsm.storage.memory import MemoryStorage
TOKEN = "YOUR_BOT_TOKEN"
bot = Bot(token=TOKEN)
dp = Dispatcher(storage=MemoryStorage())
router = Router()
# Create inline keyboard
keyboard_builder = InlineKeyboardBuilder()
keyboard_builder.button(text="Button 1", callback_data="btn1")
keyboard_builder.button(text="Button 2", callback_data="btn2")
keyboard = keyboard_builder.as_markup(row_width=2)
# /start handler
@router.message(F.text == "/start")
async def start_command(message: Message):
await message.answer("Hi! How are you?", reply_markup=keyboard)
# Button clicks
@router.callback_query(F.data.in_(["btn1", "btn2"]))
async def callback_handler(callback: CallbackQuery):
if callback.data == "btn1":
await callback.message.answer("You pressed Button 1!")
elif callback.data == "btn2":
await callback.message.answer("You pressed Button 2!")
await callback.answer()
dp.include_router(router)
async def main():
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
Output:
Output for Inline Keyboard ButtonStep 1: Importing the required libraries
from aiogram import Bot, Dispatcher, types, executor
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
- Bot: Connects to the Telegram bot API.
- Dispatcher: Handles incoming updates.
- types: Contains Message, ReplyKeyboardMarkup, KeyboardButton, etc.
- executor: Starts the bot.
Step 2: Initialize Bot and Dispatcher
Python
TOKEN = "YOUR_BOT_TOKEN"
bot = Bot(token=TOKEN)
dp = Dispatcher(bot)
Replace "YOUR_BOT_TOKEN" with the token from BotFather.
Step 3: Create Reply Keyboard
Python
keyboard_reply = ReplyKeyboardMarkup(
resize_keyboard=True, # Adjusts keyboard size for the device
one_time_keyboard=True # Hides keyboard after user selects a button
).add(
KeyboardButton("Button 1"),
KeyboardButton("Button 2"))
- KeyboardButton("…"): Creates individual buttons.
- add(): Adds buttons to the keyboard.
Step 4: Handle /start and /help Commands
Python
@dp.message_handler(commands=['start', 'help'])
async def welcome(message: types.Message):
await message.reply("Hello! How are you?", reply_markup=keyboard_reply)
Sends a greeting message with the reply keyboard attached.
Step 5: Handle User Responses
Python
@dp.message_handler()
async def handle_reply(message: types.Message):
if message.text == "Button 1":
await message.reply("You pressed Button 1!")
elif message.text == "Button 2":
await message.reply("You pressed Button 2!")
else:
await message.reply(f"You said: {message.text}")
- Checks which button the user pressed and responds accordingly.
- Any other text input is echoed back.
Step 6: Start the Bot
Python
executor.start_polling(dp)
Runs the bot in an infinite loop to listen for updates.
Here is the entire code for ReplyKeyboardButtons in Telegram Bot:
Python
from aiogram import Bot, Dispatcher, F
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, Message
from aiogram import Router
from aiogram.fsm.storage.memory import MemoryStorage
import asyncio
TOKEN = "YOUR_BOT_TOKEN"
bot = Bot(token=TOKEN)
dp = Dispatcher(storage=MemoryStorage())
router = Router()
# Create reply keyboard
keyboard = ReplyKeyboardMarkup(
keyboard=[
[KeyboardButton(text="Button 1"), KeyboardButton(text="Button 2")]
],
resize_keyboard=True,
one_time_keyboard=True
)
# /start command handler
@router.message(F.text.in_(["/start", "/help"]))
async def start(message: Message):
await message.answer("Hello! How are you?", reply_markup=keyboard)
# Handle user reply
@router.message()
async def handle_reply(message: Message):
if message.text == "Button 1":
await message.answer("You pressed Button 1!")
elif message.text == "Button 2":
await message.answer("You pressed Button 2!")
else:
await message.answer(f"You said: {message.text}")
# Register router
dp.include_router(router)
# Run bot
async def main():
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
Output
The output of Reply Keyboard ButtonRelated Articles:
Explore
Python Fundamentals
Python Data Structures
Advanced Python
Data Science with Python
Web Development with Python
Python Practice