3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger
3 horizontal lines, burger

3 horizontal lines, burger
Remove all
LOADING ...

Content



    How to add translations(localisation) for your telegram bot in aiogram/python + i18n

    Clock
    14.01.2025
    /
    Clock
    02.10.2025
    /
    Clock
    4 minutes
    An eye
    1009
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0

    Introduction

    Our bot example will consist of 2 *.py files, main.py and config.py. The first will contain the entry point and the corresponding handlers, and the second will contain the settings for translations. The code for the example was taken from the Bot-example for connecting the Inline mode.

    Necessary code and setup

    As I promised, we do translations. Firstly, create a locales directory in the project folder. Then add the following imports to the main.py file:
    import asyncio import logging import sys import uuid from aiogram import F from aiogram.types import Message, InlineQuery, InlineQueryResultArticle, InputTextMessageContent, InlineQueryResultPhoto from aiogram.utils.i18n import gettext as _ from aiogram.filters import Command from config import bot_dispatcher, bot @bot_dispatcher.inline_query(F.query == "greeting") async def send_greetings(inline_query: InlineQuery): results = [] results.append(InlineQueryResultArticle( id=str(uuid.uuid4()), title="Обычное приветствие", input_message_content=InputTextMessageContent( disable_web_page_preview=True, message_text="Приветствую я вас сегодня." ) )) results.append(InlineQueryResultArticle( id=str(uuid.uuid4()), title="Жёсткое приветствие", input_message_content=InputTextMessageContent( disable_web_page_preview=True, message_text="Ну чё, как дела" ) )) results.append(InlineQueryResultArticle( id=str(uuid.uuid4()), title="Спокойное приветствие", input_message_content=InputTextMessageContent( disable_web_page_preview=True, message_text="Привет" ) )) await inline_query.answer(results) @bot_dispatcher.inline_query(F.query == "memes") async def send_user_images(inline_query: InlineQuery): results = [] results.append(InlineQueryResultPhoto( id=str(uuid.uuid4()), photo_url="https://wisconsinskydivingcenter.com/wp-content/uploads/2024/05/you-dont-need-a-parachute-to-go-skydiving-meme.jpeg", thumbnail_url="https://wisconsinskydivingcenter.com/wp-content/uploads/2024/05/you-dont-need-a-parachute-to-go-skydiving-meme.jpeg" )) results.append(InlineQueryResultPhoto( id=str(uuid.uuid4()), photo_url="https://jungleroots.com/wp-content/uploads/2022/11/1_OkVxoXBTygSKB8K-zbB7uQ-300x176.jpeg", thumbnail_url="https://jungleroots.com/wp-content/uploads/2022/11/1_OkVxoXBTygSKB8K-zbB7uQ-300x176.jpeg" )) results.append(InlineQueryResultPhoto( id=str(uuid.uuid4()), photo_url="https://livestorm.imgix.net/1127/1651607695-obi-wan-alarm-work-meme.jpeg?h=auto&w=730&fm=jpeg&auto=format&q=90&dpr=1", thumbnail_url="https://livestorm.imgix.net/1127/1651607695-obi-wan-alarm-work-meme.jpeg?h=auto&w=730&fm=jpeg&auto=format&q=90&dpr=1" )) await inline_query.answer(results) @bot_dispatcher.message(Command('help')) async def help(message: Message): await message.answer("Этот бот является примером того, как можно реализовать inline функционал для него.") await message.answer("/startapp - запустить приложение") await message.answer("@joker_gut_bot memes - запросить мемы для показа") await message.answer("@joker_gut_bot greeting - запросить ответы по умолчанию") @bot_dispatcher.message(Command("startapp")) async def start_app(message: Message): await message.answer("Этот бот является примером того, как можно реализовать inline функционал для него.") async def main() -> None: await bot_dispatcher.start_polling(bot) if __name__ == "__main__": logging.basicConfig(level=logging.INFO, stream=sys.stdout) asyncio.run(main())
    In the config.py file, we will set up a directory for storing translations and middleware, respectively.
    from aiogram import Bot, Dispatcher from aiogram.utils.i18n import I18n, SimpleI18nMiddleware with open(".env", "r") as file: buffer = file.read() line_pos = buffer.find("BOT_TOKEN") TOKEN = buffer[buffer.find("=", line_pos) + 1:] bot = Bot(TOKEN) bot_dispatcher = Dispatcher(bot=bot) # Set up translation i18n = I18n(path="locales", domain="messages") i18n_handler = SimpleI18nMiddleware(i18n) i18n_handler.setup(bot_dispatcher)

    Marking strings for translation

    After we have connected the relevant modules and set up the environment, we need to mark which strings we are going to translate. In main.py I created an alias.
    ... from aiogram.utils.i18n import gettext as _ ...
    Each line will need to be wrapped around the alias of gettext. The end result will look something like this:
    import asyncio import logging import sys import uuid from aiogram import F from aiogram.types import Message, InlineQuery, InlineQueryResultArticle, InputTextMessageContent, InlineQueryResultPhoto from aiogram.filters import Command from aiogram.utils.i18n import gettext as _ from config import bot_dispatcher, bot @bot_dispatcher.inline_query(F.query == "greeting") async def send_greetings(inline_query: InlineQuery): results = [] results.append(InlineQueryResultArticle( id=str(uuid.uuid4()), title=_("Обычное приветствие"), input_message_content=InputTextMessageContent( disable_web_page_preview=True, message_text=_("Приветствую я вас сегодня.") ) )) results.append(InlineQueryResultArticle( id=str(uuid.uuid4()), title=_("Жёсткое приветствие"), input_message_content=InputTextMessageContent( disable_web_page_preview=True, message_text=_("Ну чё, как дела") ) )) results.append(InlineQueryResultArticle( id=str(uuid.uuid4()), title=_("Спокойное приветствие"), input_message_content=InputTextMessageContent( disable_web_page_preview=True, message_text=_("Привет") ) )) await inline_query.answer(results) @bot_dispatcher.inline_query(F.query == "memes") async def send_user_images(inline_query: InlineQuery): results = [] results.append(InlineQueryResultPhoto( id=str(uuid.uuid4()), photo_url="https://wisconsinskydivingcenter.com/wp-content/uploads/2024/05/you-dont-need-a-parachute-to-go-skydiving-meme.jpeg", thumbnail_url="https://wisconsinskydivingcenter.com/wp-content/uploads/2024/05/you-dont-need-a-parachute-to-go-skydiving-meme.jpeg" )) results.append(InlineQueryResultPhoto( id=str(uuid.uuid4()), photo_url="https://jungleroots.com/wp-content/uploads/2022/11/1_OkVxoXBTygSKB8K-zbB7uQ-300x176.jpeg", thumbnail_url="https://jungleroots.com/wp-content/uploads/2022/11/1_OkVxoXBTygSKB8K-zbB7uQ-300x176.jpeg" )) results.append(InlineQueryResultPhoto( id=str(uuid.uuid4()), photo_url="https://livestorm.imgix.net/1127/1651607695-obi-wan-alarm-work-meme.jpeg?h=auto&w=730&fm=jpeg&auto=format&q=90&dpr=1", thumbnail_url="https://livestorm.imgix.net/1127/1651607695-obi-wan-alarm-work-meme.jpeg?h=auto&w=730&fm=jpeg&auto=format&q=90&dpr=1" )) await inline_query.answer(results) @bot_dispatcher.message(Command('help')) async def help(message: Message): await message.answer(_("Этот бот является примером того, как можно реализовать inline функционал для него.")) await message.answer(_("/startapp - запустить приложение")) await message.answer(_("@joker_gut_bot memes - запросить мемы для показа")) await message.answer(_("@joker_gut_bot greeting - запросить ответы по умолчанию")) @bot_dispatcher.message(Command("startapp")) async def start_app(message: Message): await message.answer(_("Этот бот является примером того, как можно реализовать inline функционал для него.")) async def main() -> None: await bot_dispatcher.start_polling(bot) if __name__ == "__main__": logging.basicConfig(level=logging.INFO, stream=sys.stdout) asyncio.run(main())

    Extracting strings

    Finally, you can start extracting strings to the locales folder. All strings and their data will be saved in the messages.pot file.
    pybabel extract --input-dirs=. -o locales/messages.pot

    Initializing locales and translated languages

    You will need to make exactly as many locales as languages ​​​​you are going to use. In my case, there are 2, and they are made like this:
    pybabel init -i locales/messages.pot -d locales -D messages -l en; pybabel init -i locales/messages.pot -d locales -D messages -l ru;

    Translate

    The first is English, the second is Russian. In the first case, after generation, you will need to write a translation. You will need to find the messages.po file in locales\en\LC_MESSAGES and write translations. In the second case, this is the original language. No need to do translations.

    Compiling translations

    Now let's compile the translations
    pybabel compile -d locales -D messages

    Updating translations

    The translations are ready. But what if you wanted to make changes to the translations or added another text? In this case, you need to update the translations. And to do this, you will have to perform slightly different steps than when initializing in the first steps.
    It is important to remember that we initialize only once. Then, unless you want to lose all the translations, you will need to update them in a special way. First, extract the changes from all files with translation strings.
    pybabel extract --input-dirs=. -o locales/messages.pot
    Afterward, we update all locales
    pybabel update -d locales -D messages -i locales/messages.pot
    And finally compile the translations.
    pybabel compile -d locales -D messages
    That's it, the translations have been updated and will be shown depending on the user's Telegram client settings.

    Conclusion

    Translations for bots in Telegram are not so easy and can cause quite a headache for those who do it for the first time. The most difficult step, in my opinion, is finding and wrapping the lines you need for translation. Because not all lines can be wrapped, but if you follow the basic rules, everything should work out. ( ̄︶ ̄)↗ 


    Do not forget to share, like and leave a comment :)

    Comments

    (0)

    captcha
    Send
    LOADING ...
    It's empty now. Be the first (o゚v゚)ノ

    Other

    Similar articles


    How to get a telegram bot token and initial setup for telegram bot

    Clock
    14.01.2025
    /
    Clock
    02.10.2025
    An eye
    2002
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    In this article you will see how I get the telegram bot token (via bot father), where I store the token and how I set it up

    How to implement localization and translation for django website (python, js, templates and models) p. 5

    Clock
    06.02.2025
    /
    Clock
    02.10.2025
    An eye
    2627
    Hearts
    0
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    In this article, I will show how you can add localization and translations to a Django website(i18n). We will translate Python, JS code, as well as templates and Django-models. Plus, …

    How to implement yourown API using Django rest framework

    Clock
    24.02.2025
    /
    Clock
    02.10.2025
    An eye
    588
    Hearts
    1
    Connected dots
    0
    Connected dots
    0
    Connected dots
    0
    This article describes the process of setting up and adding a REST framework to a site written in Django. It is added in order to build an API for access …

    Used termins


    Related questions