Multilanguage support for reply keyboard buttons
This commit is contained in:
parent
02ce581ced
commit
62b390b7b9
@ -14,7 +14,7 @@ __author__ = "Davide Testa"
|
||||
__email__ = "davide@davte.it"
|
||||
__credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
|
||||
__license__ = "GNU General Public License v3.0"
|
||||
__version__ = "2.1.36"
|
||||
__version__ = "2.2.0"
|
||||
__maintainer__ = "Davide Testa"
|
||||
__contact__ = "t.me/davte"
|
||||
|
||||
|
@ -176,6 +176,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
self.commands = OrderedDict()
|
||||
self.command_aliases = OrderedDict()
|
||||
self.messages['commands'] = dict()
|
||||
self.messages['reply_keyboard_buttons'] = dict()
|
||||
self._unknown_command_message = None
|
||||
self.text_message_parsers = OrderedDict()
|
||||
# Handle location messages
|
||||
@ -206,7 +207,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
lambda update, user_record=None, authorization_level='user': True
|
||||
)
|
||||
self.default_reply_keyboard_elements = []
|
||||
self._default_keyboard = dict()
|
||||
self.recent_users = OrderedDict()
|
||||
self._log_file_name = None
|
||||
self._errors_file_name = None
|
||||
@ -411,13 +411,32 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
return self._authorization_denied_message
|
||||
return self.__class__._authorization_denied_message
|
||||
|
||||
@property
|
||||
def default_keyboard(self):
|
||||
"""Get the default keyboard.
|
||||
|
||||
It is sent when reply_markup is left blank and chat is private.
|
||||
"""
|
||||
return self._default_keyboard
|
||||
def get_keyboard(self, user_record=dict(), update=dict(),
|
||||
telegram_id=None):
|
||||
"""Return a reply keyboard translated into user language."""
|
||||
if (not user_record) and telegram_id:
|
||||
with self.db as db:
|
||||
user_record = db['users'].find_one(telegram_id=telegram_id)
|
||||
buttons = [
|
||||
dict(
|
||||
text=self.get_message(
|
||||
'reply_keyboard_buttons', command,
|
||||
user_record=user_record, update=update,
|
||||
default_message=element['reply_keyboard_button']
|
||||
)
|
||||
)
|
||||
for command, element in self.commands.items()
|
||||
if 'reply_keyboard_button' in element
|
||||
]
|
||||
if len(buttons) == 0:
|
||||
return
|
||||
return dict(
|
||||
keyboard=make_lines_of_buttons(
|
||||
buttons,
|
||||
(2 if len(buttons) < 4 else 3) # Row length
|
||||
),
|
||||
resize_keyboard=True
|
||||
)
|
||||
|
||||
@property
|
||||
def unknown_command_message(self):
|
||||
@ -1025,7 +1044,10 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
and chat_id > 0
|
||||
and text != self.authorization_denied_message
|
||||
):
|
||||
reply_markup = self.default_keyboard
|
||||
reply_markup = self.get_keyboard(
|
||||
update=update,
|
||||
telegram_id=chat_id
|
||||
)
|
||||
if not text:
|
||||
return
|
||||
parse_mode = str(parse_mode)
|
||||
@ -1176,7 +1198,10 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
and chat_id > 0
|
||||
and caption != self.authorization_denied_message
|
||||
):
|
||||
reply_markup = self.default_keyboard
|
||||
reply_markup = self.get_keyboard(
|
||||
update=update,
|
||||
telegram_id=chat_id
|
||||
)
|
||||
if type(photo) is str:
|
||||
photo_path = photo
|
||||
with self.db as db:
|
||||
@ -1296,7 +1321,10 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
and chat_id > 0
|
||||
and caption != self.authorization_denied_message
|
||||
):
|
||||
reply_markup = self.default_keyboard
|
||||
reply_markup = self.get_keyboard(
|
||||
update=update,
|
||||
telegram_id=chat_id,
|
||||
)
|
||||
if document_path is not None:
|
||||
with self.db as db:
|
||||
already_sent = db['sent_documents'].find_one(
|
||||
@ -1544,8 +1572,9 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
"""
|
||||
self._unknown_command_message = unknown_command_message
|
||||
|
||||
def command(self, command, aliases=None, show_in_keyboard=False,
|
||||
description="", authorization_level='admin'):
|
||||
def command(self, command, aliases=None, reply_keyboard_button=None,
|
||||
show_in_keyboard=False, description="",
|
||||
authorization_level='admin'):
|
||||
"""Associate a bot command with a custom handler function.
|
||||
|
||||
Decorate command handlers like this:
|
||||
@ -1559,9 +1588,11 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
`command` is the command name (with or without /).
|
||||
`aliases` is a list of aliases; each will call the command handler
|
||||
function; the first alias will appear as button in
|
||||
default_keyboard.
|
||||
`show_in_keyboard`, if True, makes first alias appear in
|
||||
default_keyboard.
|
||||
reply keyboard if `reply_keyboard_button` is not set.
|
||||
`reply_keyboard_button` is a str or better dict of language-specific
|
||||
strings to be shown in default keyboard.
|
||||
`show_in_keyboard`, if True, makes a button for this command appear in
|
||||
default keyboard.
|
||||
`description` can be used to help users understand what `/command`
|
||||
does.
|
||||
`authorization_level` is the lowest authorization level needed to run
|
||||
@ -1623,8 +1654,13 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
if aliases:
|
||||
for alias in aliases:
|
||||
self.command_aliases[alias] = decorated_command_handler
|
||||
if show_in_keyboard:
|
||||
self.default_reply_keyboard_elements.append(aliases[0])
|
||||
if show_in_keyboard and (aliases or reply_keyboard_button):
|
||||
_reply_keyboard_button = reply_keyboard_button or aliases[0]
|
||||
self.messages[
|
||||
'reply_keyboard_buttons'][
|
||||
command] = _reply_keyboard_button
|
||||
self.commands[command][
|
||||
'reply_keyboard_button'] = _reply_keyboard_button
|
||||
return command_decorator
|
||||
|
||||
def parser(self, condition, description='', authorization_level='admin',
|
||||
@ -1690,7 +1726,8 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
return parser_decorator
|
||||
|
||||
def set_command(self, command, handler, aliases=None,
|
||||
show_in_keyboard=False, description="",
|
||||
reply_keyboard_button=None, show_in_keyboard=False,
|
||||
description="",
|
||||
authorization_level='admin'):
|
||||
"""Associate a `command` with a `handler`.
|
||||
|
||||
@ -1700,9 +1737,11 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
`handler` is the function to be called on update objects.
|
||||
`aliases` is a list of aliases; each will call the command handler
|
||||
function; the first alias will appear as button in
|
||||
default_keyboard.
|
||||
`show_in_keyboard`, if True, makes first alias appear in
|
||||
default_keyboard.
|
||||
reply keyboard if `reply_keyboard_button` is not set.
|
||||
`reply_keyboard_button` is a str or better dict of language-specific
|
||||
strings to be shown in default keyboard.
|
||||
`show_in_keyboard`, if True, makes a button for this command appear in
|
||||
default keyboard.
|
||||
`description` is a description and can be used to help users understand
|
||||
what `/command` does.
|
||||
`authorization_level` is the lowest authorization level needed to run
|
||||
@ -1712,6 +1751,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
raise TypeError(f'Handler `{handler}` is not callable.')
|
||||
return self.command(
|
||||
command=command, aliases=aliases,
|
||||
reply_keyboard_button=reply_keyboard_button,
|
||||
show_in_keyboard=show_in_keyboard, description=description,
|
||||
authorization_level=authorization_level
|
||||
)(handler)
|
||||
@ -1944,33 +1984,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
del self.individual_location_handlers[identifier]
|
||||
return
|
||||
|
||||
def set_default_keyboard(self, keyboard='set_default'):
|
||||
"""Set a default keyboard for the bot.
|
||||
|
||||
If a keyboard is not passed as argument, a default one is generated,
|
||||
based on aliases of commands.
|
||||
"""
|
||||
if keyboard == 'set_default':
|
||||
buttons = [
|
||||
dict(
|
||||
text=x
|
||||
)
|
||||
for x in self.default_reply_keyboard_elements
|
||||
]
|
||||
if len(buttons) == 0:
|
||||
self._default_keyboard = None
|
||||
else:
|
||||
self._default_keyboard = dict(
|
||||
keyboard=make_lines_of_buttons(
|
||||
buttons,
|
||||
(2 if len(buttons) < 4 else 3) # Row length
|
||||
),
|
||||
resize_keyboard=True
|
||||
)
|
||||
else:
|
||||
self._default_keyboard = keyboard
|
||||
return
|
||||
|
||||
async def webhook_feeder(self, request):
|
||||
"""Handle incoming HTTP `request`s.
|
||||
|
||||
@ -2012,7 +2025,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
||||
|
||||
def setup(self):
|
||||
"""Make bot ask for updates and handle responses."""
|
||||
self.set_default_keyboard()
|
||||
if not self.webhook_url:
|
||||
asyncio.ensure_future(self.get_updates())
|
||||
else:
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""Bot support for multiple languages."""
|
||||
|
||||
# Standard library modules
|
||||
import asyncio
|
||||
from collections import OrderedDict
|
||||
import logging
|
||||
|
||||
@ -17,6 +18,10 @@ default_language_messages = {
|
||||
'en': "Language 🗣",
|
||||
'it': "Lingua 🗣"
|
||||
},
|
||||
'reply_keyboard_button': {
|
||||
'en': "Language 🗣",
|
||||
'it': "Lingua 🗣"
|
||||
},
|
||||
'description': {
|
||||
'en': "Change language settings",
|
||||
'it': "Cambia le impostazioni della lingua"
|
||||
@ -26,6 +31,10 @@ default_language_messages = {
|
||||
'description': {
|
||||
'en': "Change language settings",
|
||||
'it': "Cambia le impostazioni della lingua"
|
||||
},
|
||||
'language_set': {
|
||||
'en': "Selected language: English 🇬🇧",
|
||||
'it': "Lingua selezionata: Italiano 🇮🇹"
|
||||
}
|
||||
},
|
||||
'language_panel': {
|
||||
@ -265,6 +274,16 @@ async def _language_button(bot, update, user_record, data):
|
||||
ensure=True
|
||||
)
|
||||
user_record['selected_language_code'] = data[1]
|
||||
if 'chat' in update['message'] and update['message']['chat']['id'] > 0:
|
||||
asyncio.ensure_future(
|
||||
bot.send_message(
|
||||
text=bot.get_message(
|
||||
'language', 'language_button', 'language_set',
|
||||
update=update['message'], user_record=user_record
|
||||
),
|
||||
chat_id=update['message']['chat']['id']
|
||||
)
|
||||
)
|
||||
if len(data) == 0 or data[0] in ('show', 'set'):
|
||||
text, reply_markup = get_language_panel(bot, user_record)
|
||||
if text:
|
||||
@ -292,18 +311,17 @@ def init(
|
||||
bot.messages['language'] = language_messages
|
||||
bot.add_supported_languages(supported_languages)
|
||||
|
||||
language_command_alias = bot.get_message(
|
||||
'language', 'language_command', 'alias',
|
||||
language='en', default_message=None
|
||||
)
|
||||
if language_command_alias is None:
|
||||
aliases = []
|
||||
else:
|
||||
aliases = [language_command_alias]
|
||||
aliases = [
|
||||
alias
|
||||
for alias in language_messages[
|
||||
'language_command']['alias'].values()
|
||||
]
|
||||
|
||||
@bot.command(
|
||||
command='/language',
|
||||
aliases=aliases,
|
||||
reply_keyboard_button=language_messages['language_command'][
|
||||
'reply_keyboard_button'],
|
||||
show_in_keyboard=show_in_keyboard,
|
||||
description=language_messages['language_command']['description'],
|
||||
authorization_level='everybody'
|
||||
|
Loading…
x
Reference in New Issue
Block a user