Multi-language Bot Example¶
A multilingual bot with language selection, custom locales, and dynamic content translation using PyKeyboard's built-in language support.
Tested Reference
For a fully tested, comprehensive example, see the Showcase Bot.
Overview¶
This example shows:
- Language selection using built-in locales via
languages() - Custom locale registration with
add_custom_locale() - Dynamic content translation
- Persistent language preferences
Code¶
from pyrogram import Client, filters
from pykeyboard import InlineKeyboard, InlineButton
app = Client("multilingual_bot")
# Language storage (in production, use a database)
user_languages: dict[int, str] = {}
# Translation dictionaries
TRANSLATIONS: dict[str, dict[str, str]] = {
"en_US": {
"welcome": "🏠 **Welcome!**\n\nChoose your language:",
"main_menu": "🏠 **Main Menu**\n\nWhat would you like to do?",
"settings": "⚙️ **Settings**",
"language": "🌐 **Language**\n\nSelect your preferred language:",
"help": "ℹ️ **Help**\n\n/start — Start the bot\n/lang — Change language",
"dashboard": "📊 **Dashboard**\n\nWelcome back!",
"change_language": "🌐 Change Language",
"back": "⬅️ Back",
},
"es_ES": {
"welcome": "🏠 **¡Bienvenido!**\n\nElige tu idioma:",
"main_menu": "🏠 **Menú Principal**\n\n¿Qué te gustaría hacer?",
"settings": "⚙️ **Configuración**",
"language": "🌐 **Idioma**\n\nSelecciona tu idioma preferido:",
"help": "ℹ️ **Ayuda**\n\n/start — Iniciar el bot\n/lang — Cambiar idioma",
"dashboard": "📊 **Panel**\n\n¡Bienvenido de vuelta!",
"change_language": "🌐 Cambiar Idioma",
"back": "⬅️ Atrás",
},
"fr_FR": {
"welcome": "🏠 **Bienvenue !**\n\nChoisissez votre langue :",
"main_menu": "🏠 **Menu Principal**\n\nQue souhaitez-vous faire ?",
"settings": "⚙️ **Paramètres**",
"language": "🌐 **Langue**\n\nSélectionnez votre langue :",
"help": "ℹ️ **Aide**\n\n/start — Démarrer le bot\n/lang — Changer de langue",
"dashboard": "📊 **Tableau de Bord**\n\nBienvenue !",
"change_language": "🌐 Changer de Langue",
"back": "⬅️ Retour",
},
"de_DE": {
"welcome": "🏠 **Willkommen!**\n\nWählen Sie Ihre Sprache:",
"main_menu": "🏠 **Hauptmenü**\n\nWas möchten Sie tun?",
"settings": "⚙️ **Einstellungen**",
"language": "🌐 **Sprache**\n\nWählen Sie Ihre bevorzugte Sprache:",
"help": "ℹ️ **Hilfe**\n\n/start — Bot starten\n/lang — Sprache ändern",
"dashboard": "📊 **Dashboard**\n\nWillkommen zurück!",
"change_language": "🌐 Sprache Ändern",
"back": "⬅️ Zurück",
},
}
SUPPORTED_LOCALES = ["en_US", "es_ES", "fr_FR", "de_DE"]
def t(user_id: int, key: str) -> str:
"""Translate a key for the user's language."""
lang = user_languages.get(user_id, "en_US")
return TRANSLATIONS.get(lang, TRANSLATIONS["en_US"]).get(key, f"[{key}]")
def create_language_keyboard() -> InlineKeyboard:
"""Create language selection keyboard using built-in locales."""
keyboard = InlineKeyboard()
keyboard.languages("set_lang:{locale}", SUPPORTED_LOCALES)
return keyboard
def create_main_menu(user_id: int) -> InlineKeyboard:
"""Create main menu keyboard in user's language."""
keyboard = InlineKeyboard(row_width=2)
keyboard.add(
InlineButton("📊 " + t(user_id, "dashboard").split("\n")[0].strip("* "),
callback_data="menu:dashboard"),
InlineButton("⚙️ " + t(user_id, "settings").split("\n")[0].strip("* "),
callback_data="menu:settings"),
InlineButton("ℹ️ " + t(user_id, "help").split("\n")[0].strip("* "),
callback_data="menu:help"),
)
return keyboard
@app.on_message(filters.command("start"))
async def start_command(client, message):
user_id = message.from_user.id
if user_id not in user_languages:
# First visit — show language selection
await message.reply_text(
t(user_id, "welcome"),
reply_markup=create_language_keyboard(),
)
else:
await message.reply_text(
t(user_id, "main_menu"),
reply_markup=create_main_menu(user_id),
)
@app.on_callback_query(filters.regex(r"^set_lang:"))
async def handle_language_selection(client, callback_query):
user_id = callback_query.from_user.id
locale = callback_query.data.split(":")[1]
user_languages[user_id] = locale
await callback_query.edit_message_text(
t(user_id, "main_menu"),
reply_markup=create_main_menu(user_id),
)
await callback_query.answer(f"Language set to {locale[:2].upper()}!")
@app.on_callback_query(filters.regex(r"^menu:"))
async def handle_menu(client, callback_query):
user_id = callback_query.from_user.id
action = callback_query.data.split(":")[1]
match action:
case "main":
text = t(user_id, "main_menu")
keyboard = create_main_menu(user_id)
case "settings":
text = t(user_id, "settings")
lang = user_languages.get(user_id, "en_US")[:2].upper()
keyboard = InlineKeyboard(row_width=1)
keyboard.add(
InlineButton(
f"{t(user_id, 'change_language')} ({lang})",
callback_data="settings:language",
),
InlineButton(t(user_id, "back"), callback_data="menu:main"),
)
case "dashboard":
text = t(user_id, "dashboard")
keyboard = create_main_menu(user_id)
case "help":
text = t(user_id, "help")
keyboard = create_main_menu(user_id)
case _:
await callback_query.answer(f"Unknown: {action}")
return
await callback_query.edit_message_text(text, reply_markup=keyboard)
await callback_query.answer()
@app.on_callback_query(filters.regex(r"^settings:language$"))
async def handle_change_language(client, callback_query):
user_id = callback_query.from_user.id
await callback_query.edit_message_text(
t(user_id, "language"),
reply_markup=create_language_keyboard(),
)
await callback_query.answer()
@app.on_message(filters.command("lang"))
async def change_language_command(client, message):
"""Allow users to change language via /lang command."""
await message.reply_text(
t(message.from_user.id, "welcome"),
reply_markup=create_language_keyboard(),
)
if __name__ == "__main__":
app.run()
Adding Custom Locales¶
You can register custom locales that appear alongside built-in ones:
keyboard = InlineKeyboard()
keyboard.add_custom_locale("en_PIRATE", "🏴☠️ Pirate English")
keyboard.languages("set_lang:{locale}", ["en_US", "en_PIRATE"])
Supported Languages¶
PyKeyboard supports 50+ built-in locales with native names and flag emojis. This example uses 4 of them, but you can pass any locale codes to languages().
Running¶
pip install pykeyboard-kurigram
export TELEGRAM_BOT_TOKEN="..."
export TELEGRAM_API_ID="..."
export TELEGRAM_API_HASH="..."
python multilingual_bot.py
Send /start to select your language. Use /lang to change it later.