Keyboards, Button Styles, Mini Apps & Reply Controls
Telegram 8.0 button styles (primary, success, danger), custom emoji icons, inline buttons, hardware data pickers, and reply controls.
Inline Keyboards vs. Reply Keyboards
Telegram supports two distinct interactive interface paradigms:
- Inline Keyboards (
InlineKeyboardMarkup): Attached directly underneath specific message bubbles. Tapping a button triggers a backgroundcallback_query, opens an external URL, launches a full-screen Telegram Mini App, copies text to clipboard, or executes seamless OAuth authentication. - Reply Keyboards (
ReplyKeyboardMarkup): Replace the user's on-screen virtual keyboard with fixed or persistent command tiles, contact/GPS hardware requests, or native user/chat pickers.
Telegram 8.0 Button Colors (style parameter)
In Telegram Bot API 8.0+, both
In Telegram Bot API 8.0+, both
InlineKeyboardButton and KeyboardButton support the style parameter:
"primary"— Dark Blue color for highlighted actions and primary calls-to-action."success"— Emerald Green color for approvals, confirmations, and successful purchases."danger"— Crimson Red color for destructive actions, deletions, bans, and cancellations.
1. Complete Telegram 8.0 Styled Inline Keyboard Example
Demonstrating colored buttons (primary, success, danger), custom emoji prefixes (icon_custom_emoji_id), and one-tap clipboard copy:
PHP — Styled Inline Buttons (API 8.0+)
<?php
// ── Botlify Cloud .env — auto-injected, never hardcode secrets ──
$BOT_TOKEN = getenv('BOT_TOKEN'); // Telegram bot token from @BotFather
$ADMIN_CHAT_ID = getenv('ADMIN_CHAT_ID'); // Your numeric admin Telegram user ID
$BOT_USERNAME = getenv('BOT_USERNAME'); // Bot username without @
declare(strict_types=1);
function send_styled_action_card(string|int $chatId): void {
$keyboard = [
'inline_keyboard' => [
// Row 1: Positive Confirmation (Green) & Destructive Action (Red)
[
[
'text' => '✅ Confirm Payment',
'callback_data' => 'order_confirm_492',
'style' => 'success' // Emerald Green button
],
[
'text' => '🗑️ Cancel Order',
'callback_data' => 'order_cancel_492',
'style' => 'danger' // Crimson Red button
]
],
// Row 2: Primary Call-to-Action (Blue) with Custom Emoji Icon
[
[
'text' => '⚡ Upgrade to Enterprise',
'callback_data' => 'upgrade_enterprise',
'style' => 'primary', // Dark Blue button
'icon_custom_emoji_id' => '5368324170671202286' // Verified custom emoji prefix
]
],
// Row 3: Telegram Mini App & One-Tap Clipboard Copy
[
[
'text' => '🚀 Open Cloud Studio',
'web_app' => ['url' => 'https://app.botlify.cloud/studio'],
'style' => 'primary'
],
[
'text' => '📋 Copy API Secret',
'copy_text' => ['text' => 'sk_live_botlify_982347102']
]
],
// Row 4: External Web Link
[
[
'text' => '🌐 View Documentation',
'url' => 'https://docs.botlify.cloud'
]
]
]
];
bot('sendMessage', [
'chat_id' => $chatId,
'text' => "⚡ Botlify Cloud Styled Action Center\n\nChoose an action below using Telegram 8.0 styled buttons:",
'parse_mode' => 'HTML',
'reply_markup' => $keyboard
]);
}
Always Answer Callback Queries Promptly!
Whenever a user taps an inline callback button, Telegram displays a spinning loader on the button. You must immediately call
Whenever a user taps an inline callback button, Telegram displays a spinning loader on the button. You must immediately call
bot('answerCallbackQuery', ['callback_query_id' => $cbId]) to dismiss the spinner and provide optional haptic/toast notifications.
2. The 9 Inline Button Types Matrix
| Button Type | Key Payload Property | Behavior & Capabilities |
|---|---|---|
| Callback Button | callback_data => 'act_1' |
Dispatches background webhook update (1 to 64 bytes). Supports style and icon_custom_emoji_id. |
| URL Button | url => 'https://...' |
Opens external web link in user's browser or in-app browser. |
| Mini App Button | web_app => ['url' => '...'] |
Launches Telegram Web App directly inside the messenger with full JavaScript bridge. |
| Copy Text Button | copy_text => ['text' => '...'] |
Copies specified string directly into device clipboard with single tap (API 7.10+). |
| Switch Inline Query | switch_inline_query => 'query' |
Prompts user to select a chat and enters bot's inline query. |
| Switch Chosen Chat | switch_inline_query_chosen_chat |
Filters destination chats (e.g. channel-only, group-only, user-only) before forwarding query. |
| Telegram Web OAuth | login_url => ['url' => '...'] |
One-tap seamless web login passing verified Telegram auth token to your website. |
| Invoice Pay Button | pay => true |
Must be the first button in the first row of an invoice message to trigger payment sheet. |
| HTML5 Game Button | callback_game => [] |
Launches interactive canvas/HTML5 game configured via @BotFather. |
PHP — Advanced Inline Button Types Implementation
<?php
// ── Botlify Cloud .env — auto-injected, never hardcode secrets ──
$BOT_TOKEN = getenv('BOT_TOKEN'); // Telegram bot token from @BotFather
$ADMIN_CHAT_ID = getenv('ADMIN_CHAT_ID'); // Your numeric admin Telegram user ID
$BOT_USERNAME = getenv('BOT_USERNAME'); // Bot username without @
declare(strict_types=1);
$advancedInlineKeyboard = [
'inline_keyboard' => [
// 1. Target Channel Sharing Only
[
[
'text' => '📢 Post Announcement to Channel',
'switch_inline_query_chosen_chat' => [
'query' => 'flash_sale_active',
'allow_channel_chats' => true,
'allow_group_chats' => false,
'allow_user_chats' => false
]
]
],
// 2. Seamless Telegram Web OAuth Login
[
[
'text' => '🔐 Login to Botlify Cloud Web Dashboard',
'login_url' => [
'url' => 'https://botlify.cloud/auth/telegram_callback.php',
'request_write_access'=> true
]
]
]
]
];
3. Reply Keyboards with Button Styles & Data Pickers
Reply keyboards also support modern button styles (primary, danger, success), hardware data sharing, and native Telegram pickers for selecting specific users or channels:
PHP — Styled Reply Keyboards & Advanced Pickers
<?php
// ── Botlify Cloud .env — auto-injected, never hardcode secrets ──
$BOT_TOKEN = getenv('BOT_TOKEN'); // Telegram bot token from @BotFather
$ADMIN_CHAT_ID = getenv('ADMIN_CHAT_ID'); // Your numeric admin Telegram user ID
$BOT_USERNAME = getenv('BOT_USERNAME'); // Bot username without @
declare(strict_types=1);
function send_styled_reply_picker_menu(string|int $chatId): void {
$keyboard = [
'keyboard' => [
// Row 1: Hardware Access Requests
[
[
'text' => '📱 Share Verified Phone',
'request_contact' => true
],
[
'text' => '📍 Share GPS Location',
'request_location' => true
]
],
// Row 2: Modern User & Chat Pickers with Filters (API 6.5+)
[
[
'text' => '👤 Pick Premium User',
'request_users' => [
'request_id' => 201,
'user_is_bot' => false,
'user_is_premium' => true, // Filter Premium users only
'max_quantity' => 1,
'request_name' => true,
'request_username' => true
]
],
[
'text' => '📢 Pick Channel with Admin Rights',
'request_chat' => [
'request_id' => 202,
'chat_is_channel' => true,
'bot_is_member' => true,
'bot_administrator_rights' => [
'can_post_messages' => true
]
]
]
],
// Row 3: Styled Reply Action Tiles (Telegram 8.0+)
[
[
'text' => '🟢 Start Cloud Sync',
'style' => 'success' // Green Reply Button
],
[
'text' => '🔴 Emergency Stop',
'style' => 'danger' // Red Reply Button
]
],
// Row 4: Primary Hub Action
[
[
'text' => '🔵 Open Admin Console',
'style' => 'primary' // Blue Reply Button
]
]
],
'resize_keyboard' => true, // Dynamic compact sizing
'one_time_keyboard' => false, // Remains visible
'is_persistent' => true, // Visible even when device keyboard toggles
'input_field_placeholder' => 'Select an action or pick a user/channel...'
];
bot('sendMessage', [
'chat_id' => $chatId,
'text' => 'Please select an option or pick data from the control board below:',
'reply_markup' => $keyboard
]);
}
4. Keyboard Dismissal & Force Reply Controls
PHP — ReplyKeyboardRemove & ForceReply
<?php
// ── Botlify Cloud .env — auto-injected, never hardcode secrets ──
$BOT_TOKEN = getenv('BOT_TOKEN'); // Telegram bot token from @BotFather
$ADMIN_CHAT_ID = getenv('ADMIN_CHAT_ID'); // Your numeric admin Telegram user ID
$BOT_USERNAME = getenv('BOT_USERNAME'); // Bot username without @
declare(strict_types=1);
// 1. Remove Custom Reply Keyboard (Restores standard system keyboard)
bot('sendMessage', [
'chat_id' => $chatId,
'text' => 'Custom keyboard closed.',
'reply_markup' => ['remove_keyboard' => true]
]);
// 2. Force Reply (Opens user keyboard and auto-quotes this prompt)
bot('sendMessage', [
'chat_id' => $chatId,
'text' => '📝 Please enter your Database Backup Password:',
'parse_mode' => 'HTML',
'reply_markup' => [
'force_reply' => true,
'input_field_placeholder' => 'Enter password...'
]
]);
Botlify Cloud Runtime
Credentials are auto-injected in
Credentials are auto-injected in
.env — always load them with getenv(): BOT_TOKEN, ADMIN_CHAT_ID, BOT_USERNAME. Main database: database.db (SQLite, WAL mode). Runtime errors: error.log. Quick test: send to $ADMIN_CHAT_ID. Full details: Runtime Reference.