Provide a default multilanguage suggestions module
This commit is contained in:
parent
ceef3103f4
commit
f17333ca42
@ -14,12 +14,12 @@ __author__ = "Davide Testa"
|
|||||||
__email__ = "davide@davte.it"
|
__email__ = "davide@davte.it"
|
||||||
__credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
|
__credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
|
||||||
__license__ = "GNU General Public License v3.0"
|
__license__ = "GNU General Public License v3.0"
|
||||||
__version__ = "2.3.30"
|
__version__ = "2.4.0"
|
||||||
__maintainer__ = "Davide Testa"
|
__maintainer__ = "Davide Testa"
|
||||||
__contact__ = "t.me/davte"
|
__contact__ = "t.me/davte"
|
||||||
|
|
||||||
# Legacy module; please use `from davtelepot.bot import Bot` from now on
|
# Legacy module; please use `from davtelepot.bot import Bot` from now on
|
||||||
from .custombot import Bot
|
from .custombot import Bot
|
||||||
from . import administration_tools, authorization, bot, helper, utilities
|
from . import administration_tools, authorization, bot, helper, suggestions, utilities
|
||||||
|
|
||||||
__all__ = [administration_tools, authorization, Bot, bot, helper, utilities]
|
__all__ = [administration_tools, authorization, Bot, bot, helper, suggestions, utilities]
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
# Project modules
|
# Project modules
|
||||||
|
from .bot import Bot
|
||||||
from .utilities import (
|
from .utilities import (
|
||||||
Confirmator, get_cleaned_text, get_user, make_button, make_inline_keyboard
|
Confirmator, get_cleaned_text, get_user, make_button, make_inline_keyboard
|
||||||
)
|
)
|
||||||
@ -132,12 +133,20 @@ class Role():
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by_role_id(cls, role_id=100):
|
def get_by_role_id(cls, role_id=100):
|
||||||
"""Give a `role_id`, return the corresponding `Role` instance."""
|
"""Given a `role_id`, return the corresponding `Role` instance."""
|
||||||
for code, role in cls.roles.items():
|
for code, role in cls.roles.items():
|
||||||
if code == role_id:
|
if code == role_id:
|
||||||
return role
|
return role
|
||||||
raise IndexError(f"Unknown role id: {role_id}")
|
raise IndexError(f"Unknown role id: {role_id}")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_role_by_name(cls, name='everybody'):
|
||||||
|
"""Given a `name`, return the corresponding `Role` instance."""
|
||||||
|
for role in cls.roles.values():
|
||||||
|
if role.name == name:
|
||||||
|
return role
|
||||||
|
raise IndexError(f"Unknown role name: {name}")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_user_role(cls, user_record=None, user_role_id=None):
|
def get_user_role(cls, user_record=None, user_role_id=None):
|
||||||
"""Given a `user_record`, return its `Role`.
|
"""Given a `user_record`, return its `Role`.
|
||||||
@ -488,7 +497,7 @@ async def _ban_command(bot, update, user_record):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def init(bot, roles=None, authorization_messages=None):
|
def init(bot: Bot, roles=None, authorization_messages=None):
|
||||||
"""Set bot roles and assign role-related commands.
|
"""Set bot roles and assign role-related commands.
|
||||||
|
|
||||||
Pass an OrderedDict of `roles` to get them set.
|
Pass an OrderedDict of `roles` to get them set.
|
||||||
@ -496,7 +505,7 @@ def init(bot, roles=None, authorization_messages=None):
|
|||||||
class _Role(Role):
|
class _Role(Role):
|
||||||
roles = OrderedDict()
|
roles = OrderedDict()
|
||||||
|
|
||||||
bot.Role = _Role
|
bot.set_role_class(_Role)
|
||||||
if roles is None:
|
if roles is None:
|
||||||
roles = DEFAULT_ROLES
|
roles = DEFAULT_ROLES
|
||||||
# Cast roles to OrderedDict
|
# Cast roles to OrderedDict
|
||||||
|
@ -219,6 +219,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
|||||||
self._errors_file_name = None
|
self._errors_file_name = None
|
||||||
self.placeholder_requests = dict()
|
self.placeholder_requests = dict()
|
||||||
self.shared_data = dict()
|
self.shared_data = dict()
|
||||||
|
self.Role = None
|
||||||
# Add `users` table with its fields if missing
|
# Add `users` table with its fields if missing
|
||||||
self.db['users'].upsert(
|
self.db['users'].upsert(
|
||||||
dict(
|
dict(
|
||||||
@ -2814,3 +2815,10 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
|
|||||||
finally:
|
finally:
|
||||||
cls.loop.run_until_complete(cls.stop_app())
|
cls.loop.run_until_complete(cls.stop_app())
|
||||||
return cls.final_state
|
return cls.final_state
|
||||||
|
|
||||||
|
def set_role_class(self, role):
|
||||||
|
"""Set a Role class for bot.
|
||||||
|
|
||||||
|
`role` must be an instance of `authorization.Role`.
|
||||||
|
"""
|
||||||
|
self.Role = role
|
||||||
|
@ -37,3 +37,140 @@ default_help_messages = {
|
|||||||
'it': "Comandi 🤖",
|
'it': "Comandi 🤖",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default_suggestion_messages = {
|
||||||
|
'suggestions_command': {
|
||||||
|
'command': "/suggestion",
|
||||||
|
'aliases': [
|
||||||
|
"/suggestions", "/ideas",
|
||||||
|
"/suggerimento", "/suggerimenti", "idee"
|
||||||
|
],
|
||||||
|
'reply_keyboard_button': {
|
||||||
|
'en': "Ideas 💡",
|
||||||
|
'it': "Idee 💡"
|
||||||
|
},
|
||||||
|
'description': {
|
||||||
|
'en': "Send a suggestion to help improve the bot",
|
||||||
|
'it': "Invia un suggerimento per aiutare a migliorare il bot"
|
||||||
|
},
|
||||||
|
'prompt_text': {
|
||||||
|
'en': (
|
||||||
|
"Send a suggestion to bot administrator.\n\n"
|
||||||
|
"Maximum 1500 characters (extra ones will be ignored).\n"
|
||||||
|
"If you need more space, you may create a telegra.ph topic and link it here.\n\n"
|
||||||
|
"/cancel if you misclicked."
|
||||||
|
),
|
||||||
|
'it': (
|
||||||
|
"Inserisci un suggerimento da inviare agli amministratori.\n\n"
|
||||||
|
"Massimo 1500 caratteri (quelli in più non verranno registrati).\n"
|
||||||
|
"Se ti serve maggiore libertà, puoi per esempio creare un topic "
|
||||||
|
"su telegra.ph e linkarlo qui!\n\n"
|
||||||
|
"/annulla se hai clickato per errore."
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'prompt_popup': {
|
||||||
|
'en': (
|
||||||
|
"Send a suggestion"
|
||||||
|
),
|
||||||
|
'it': (
|
||||||
|
"Inserisci un suggerimento"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'entered_suggestion': {
|
||||||
|
'text': {
|
||||||
|
'en': (
|
||||||
|
"Entered suggestions:\n\n"
|
||||||
|
"<code>{suggestion}</code>\n\n"
|
||||||
|
"Do you want to send it to bot administrators?"
|
||||||
|
),
|
||||||
|
'it': (
|
||||||
|
"Suggerimento inserito:\n\n"
|
||||||
|
"<code>{suggestion}</code>\n\n"
|
||||||
|
"Vuoi inviarlo agli amministratori?"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'buttons': {
|
||||||
|
'send': {
|
||||||
|
'en': "Send it! 📧",
|
||||||
|
'it': "Invia! 📧",
|
||||||
|
},
|
||||||
|
'cancel': {
|
||||||
|
'en': "Cancel ❌",
|
||||||
|
'it': "Annulla ❌",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'received_suggestion': {
|
||||||
|
'text': {
|
||||||
|
'en': (
|
||||||
|
"💡 We received a new suggestion! 💡\n\n"
|
||||||
|
"{user}\n\n"
|
||||||
|
"<code>{suggestion}</code>\n\n"
|
||||||
|
"#suggestions #{bot.name}"
|
||||||
|
),
|
||||||
|
'it': (
|
||||||
|
"💡 Abbiamo ricevuto un nuovo suggerimento! 💡\n\n"
|
||||||
|
"{user}\n\n"
|
||||||
|
"<code>{suggestion}</code>\n\n"
|
||||||
|
"#suggestions #{bot.name}"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
'buttons': {
|
||||||
|
'new': {
|
||||||
|
'en': "New suggestion 💡",
|
||||||
|
'it': "Nuovo suggerimento 💡",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'invalid_suggestion': {
|
||||||
|
'en': "Invalid suggestion.",
|
||||||
|
'it': "Suggerimento non valido."
|
||||||
|
},
|
||||||
|
'cancel_messages': {
|
||||||
|
'en': ['cancel'],
|
||||||
|
'it': ['annulla', 'cancella'],
|
||||||
|
},
|
||||||
|
'operation_cancelled': {
|
||||||
|
'en': "Operation cancelled.",
|
||||||
|
'it': "Operazione annullata con successo.",
|
||||||
|
},
|
||||||
|
'suggestion_sent': {
|
||||||
|
'popup': {
|
||||||
|
'en': "Thanks!",
|
||||||
|
'it': "Grazie!",
|
||||||
|
},
|
||||||
|
'text': {
|
||||||
|
'en': (
|
||||||
|
"💡 Suggestion sent, thank you! 💡\n\n"
|
||||||
|
"<code>{suggestion}</code>\n\n"
|
||||||
|
"#suggestions #{bot.name}"
|
||||||
|
),
|
||||||
|
'it': (
|
||||||
|
"💡 Suggerimento inviato, grazie! 💡\n\n"
|
||||||
|
"<code>{suggestion}</code>\n\n"
|
||||||
|
"#suggerimenti #{bot.name}"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'suggestions_button': {
|
||||||
|
'file_name': {
|
||||||
|
'en': "Suggestions.csv",
|
||||||
|
'it': "Suggerimenti.csv",
|
||||||
|
},
|
||||||
|
'file_caption': {
|
||||||
|
'en': "Here is the suggestions file.",
|
||||||
|
'it': "Ecco il file dei suggerimenti.",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'see_suggestions': {
|
||||||
|
'command': "/getsuggestions",
|
||||||
|
'aliases': [
|
||||||
|
"/vedisuggerimenti",
|
||||||
|
],
|
||||||
|
'description': {
|
||||||
|
'en': "Get a file containing all suggestions",
|
||||||
|
'it': "Richiedi un file con tutti i suggerimenti"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
286
davtelepot/suggestions.py
Normal file
286
davtelepot/suggestions.py
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
"""Receive structured suggestions from bot users."""
|
||||||
|
|
||||||
|
# Standard library modules
|
||||||
|
import asyncio
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
# Third party modules
|
||||||
|
import davtelepot
|
||||||
|
|
||||||
|
# Project modules
|
||||||
|
from .messages import default_suggestion_messages
|
||||||
|
from .utilities import (
|
||||||
|
async_wrapper, get_cleaned_text, make_button,
|
||||||
|
make_inline_keyboard, send_csv_file
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def _handle_suggestion_message(bot: davtelepot.bot.Bot, update, user_record, try_no=1,
|
||||||
|
suggestion_prefixes=None):
|
||||||
|
if suggestion_prefixes is None:
|
||||||
|
suggestion_prefixes = []
|
||||||
|
suggestion_prefixes = [prefix.strip('/') for prefix in suggestion_prefixes]
|
||||||
|
user_id = user_record['id']
|
||||||
|
telegram_id = user_record['telegram_id']
|
||||||
|
text = get_cleaned_text(
|
||||||
|
update,
|
||||||
|
bot,
|
||||||
|
suggestion_prefixes
|
||||||
|
)
|
||||||
|
text = text.strip(' /')[:1500]
|
||||||
|
if not text:
|
||||||
|
if try_no < 2:
|
||||||
|
bot.set_individual_text_message_handler(
|
||||||
|
await async_wrapper(
|
||||||
|
_handle_suggestion_message,
|
||||||
|
bot=bot,
|
||||||
|
update=update,
|
||||||
|
user_record=user_record,
|
||||||
|
try_no=(try_no + 1),
|
||||||
|
suggestion_prefixes=suggestion_prefixes
|
||||||
|
),
|
||||||
|
user_id=telegram_id
|
||||||
|
)
|
||||||
|
return dict(
|
||||||
|
chat_id=telegram_id,
|
||||||
|
reply_markup=dict(
|
||||||
|
force_reply=True
|
||||||
|
),
|
||||||
|
text=bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'prompt_text',
|
||||||
|
update=update, user_record=user_record
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'invalid_suggestion',
|
||||||
|
update=update, user_record=user_record
|
||||||
|
)
|
||||||
|
if text.lower() in bot.messages['suggestions']['suggestions_command']['cancel_messages']:
|
||||||
|
return bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'operation_cancelled',
|
||||||
|
update=update, user_record=user_record
|
||||||
|
)
|
||||||
|
created = datetime.datetime.now()
|
||||||
|
with bot.db as db:
|
||||||
|
db['suggestions'].insert(
|
||||||
|
dict(
|
||||||
|
user_id=user_id,
|
||||||
|
suggestion=text,
|
||||||
|
created=created
|
||||||
|
),
|
||||||
|
ensure=True
|
||||||
|
)
|
||||||
|
suggestion_id = db['suggestions'].find_one(
|
||||||
|
user_id=user_id,
|
||||||
|
created=created
|
||||||
|
)['id']
|
||||||
|
text = bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'entered_suggestion', 'text',
|
||||||
|
suggestion=text,
|
||||||
|
update=update, user_record=user_record
|
||||||
|
)
|
||||||
|
reply_markup = make_inline_keyboard(
|
||||||
|
[
|
||||||
|
make_button(
|
||||||
|
bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'entered_suggestion', 'buttons', 'send',
|
||||||
|
update=update, user_record=user_record
|
||||||
|
),
|
||||||
|
prefix='suggest:///',
|
||||||
|
delimiter='|',
|
||||||
|
data=['confirm', suggestion_id]
|
||||||
|
),
|
||||||
|
make_button(
|
||||||
|
bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'entered_suggestion', 'buttons', 'cancel',
|
||||||
|
update=update, user_record=user_record
|
||||||
|
),
|
||||||
|
prefix='suggest:///',
|
||||||
|
delimiter='|',
|
||||||
|
data=['cancel']
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return dict(
|
||||||
|
chat_id=telegram_id,
|
||||||
|
text=text,
|
||||||
|
parse_mode='HTML',
|
||||||
|
reply_markup=reply_markup
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def _suggestions_button(bot: davtelepot.bot.Bot, update, user_record, data):
|
||||||
|
command = data[0]
|
||||||
|
user_id = update['from']['id']
|
||||||
|
result, text, reply_markup = '', '', None
|
||||||
|
if command in ['new']:
|
||||||
|
bot.set_individual_text_message_handler(
|
||||||
|
_handle_suggestion_message,
|
||||||
|
user_id=user_id
|
||||||
|
)
|
||||||
|
asyncio.ensure_future(
|
||||||
|
bot.send_message(
|
||||||
|
chat_id=user_id,
|
||||||
|
reply_markup=dict(
|
||||||
|
force_reply=True
|
||||||
|
),
|
||||||
|
text=bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'prompt_text',
|
||||||
|
update=update, user_record=user_record
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result = bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'prompt_popup',
|
||||||
|
update=update, user_record=user_record
|
||||||
|
)
|
||||||
|
elif command in ['cancel']:
|
||||||
|
result = 'Operazione annullata'
|
||||||
|
text = 'Operazione annullata con successo.'
|
||||||
|
reply_markup = None
|
||||||
|
elif command in ['confirm'] and len(data) > 1:
|
||||||
|
suggestion_id = data[1]
|
||||||
|
when = datetime.datetime.now()
|
||||||
|
with bot.db as db:
|
||||||
|
registered_user = db['users'].find_one(telegram_id=user_id)
|
||||||
|
admins = [
|
||||||
|
x['telegram_id']
|
||||||
|
for x in db['users'].find(
|
||||||
|
privileges=[
|
||||||
|
bot.Role.get_role_by_name('admin').code,
|
||||||
|
bot.Role.get_role_by_name('founder').code
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
db['suggestions'].update(
|
||||||
|
dict(
|
||||||
|
id=suggestion_id,
|
||||||
|
sent=when
|
||||||
|
),
|
||||||
|
['id'],
|
||||||
|
ensure=True
|
||||||
|
)
|
||||||
|
suggestion_text = db['suggestions'].find_one(
|
||||||
|
id=suggestion_id
|
||||||
|
)['suggestion']
|
||||||
|
suggestion_message = bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'received_suggestion', 'text',
|
||||||
|
user=bot.Role.get_user_role_panel(registered_user)[0],
|
||||||
|
suggestion=suggestion_text,
|
||||||
|
bot=bot,
|
||||||
|
update=update, user_record=user_record,
|
||||||
|
)
|
||||||
|
for admin in admins:
|
||||||
|
when += datetime.timedelta(seconds=1)
|
||||||
|
asyncio.ensure_future(
|
||||||
|
bot.send_message(
|
||||||
|
chat_id=admin,
|
||||||
|
text=suggestion_message,
|
||||||
|
parse_mode='HTML'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
reply_markup = make_inline_keyboard(
|
||||||
|
[
|
||||||
|
make_button(
|
||||||
|
text=bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'received_suggestion', 'buttons', 'new',
|
||||||
|
bot=bot,
|
||||||
|
update=update, user_record=user_record,
|
||||||
|
),
|
||||||
|
prefix='suggest:///',
|
||||||
|
delimiter='|',
|
||||||
|
data=['new']
|
||||||
|
)
|
||||||
|
],
|
||||||
|
1
|
||||||
|
)
|
||||||
|
result = bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'suggestion_sent', 'popup',
|
||||||
|
suggestion=suggestion_text, bot=bot,
|
||||||
|
update=update, user_record=user_record,
|
||||||
|
)
|
||||||
|
text = bot.get_message(
|
||||||
|
'suggestions', 'suggestions_command', 'suggestion_sent', 'text',
|
||||||
|
suggestion=suggestion_text, bot=bot,
|
||||||
|
update=update, user_record=user_record,
|
||||||
|
)
|
||||||
|
if text:
|
||||||
|
return dict(
|
||||||
|
text=result,
|
||||||
|
edit=dict(
|
||||||
|
text=text,
|
||||||
|
reply_markup=reply_markup,
|
||||||
|
parse_mode='HTML'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
async def _see_suggestions(bot: davtelepot.bot.Bot, update, user_record):
|
||||||
|
chat_id = update['from']['id']
|
||||||
|
query = (
|
||||||
|
"SELECT u.username, u.privileges, s.created, s.sent, s.suggestion "
|
||||||
|
"FROM suggestions s "
|
||||||
|
"LEFT JOIN users u "
|
||||||
|
"ON u.id = s.user_id "
|
||||||
|
"ORDER BY s.created"
|
||||||
|
)
|
||||||
|
await send_csv_file(
|
||||||
|
bot=bot,
|
||||||
|
chat_id=chat_id,
|
||||||
|
query=query,
|
||||||
|
caption=bot.get_message(
|
||||||
|
'suggestions', 'suggestions_button', 'file_caption',
|
||||||
|
user_record=user_record, update=update
|
||||||
|
),
|
||||||
|
file_name=bot.get_message(
|
||||||
|
'suggestions', 'suggestions_button', 'file_name',
|
||||||
|
user_record=user_record, update=update
|
||||||
|
),
|
||||||
|
update=update,
|
||||||
|
user_record=user_record
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def init(telegram_bot: davtelepot.bot.Bot, suggestion_messages=default_suggestion_messages):
|
||||||
|
"""Set suggestion handling for `bot`."""
|
||||||
|
telegram_bot.messages['suggestions'] = suggestion_messages
|
||||||
|
suggestion_prefixes = (
|
||||||
|
list(suggestion_messages['suggestions_command']['reply_keyboard_button'].values())
|
||||||
|
+ [suggestion_messages['suggestions_command']['command']]
|
||||||
|
+ suggestion_messages['suggestions_command']['aliases']
|
||||||
|
)
|
||||||
|
|
||||||
|
@telegram_bot.command(command=suggestion_messages['suggestions_command']['command'],
|
||||||
|
aliases=suggestion_messages['suggestions_command']['aliases'],
|
||||||
|
reply_keyboard_button=(
|
||||||
|
suggestion_messages['suggestions_command']['reply_keyboard_button']
|
||||||
|
),
|
||||||
|
show_in_keyboard=True,
|
||||||
|
description=suggestion_messages['suggestions_command']['description'],
|
||||||
|
authorization_level='everybody')
|
||||||
|
async def suggestions_command(bot, update, user_record):
|
||||||
|
return await _handle_suggestion_message(
|
||||||
|
bot=bot,
|
||||||
|
update=update,
|
||||||
|
user_record=user_record,
|
||||||
|
try_no=1,
|
||||||
|
suggestion_prefixes=suggestion_prefixes
|
||||||
|
)
|
||||||
|
|
||||||
|
@telegram_bot.button(prefix='suggest:///', separator='|',
|
||||||
|
authorization_level='everybody')
|
||||||
|
async def suggestions_button(bot, update, user_record, data):
|
||||||
|
return await _suggestions_button(
|
||||||
|
bot=bot, update=update,
|
||||||
|
user_record=user_record, data=data
|
||||||
|
)
|
||||||
|
|
||||||
|
@telegram_bot.command(command=suggestion_messages['see_suggestions']['command'],
|
||||||
|
aliases=suggestion_messages['see_suggestions']['aliases'],
|
||||||
|
description=(
|
||||||
|
suggestion_messages['see_suggestions']['description']
|
||||||
|
),
|
||||||
|
authorization_level='admin')
|
||||||
|
async def see_suggestions(bot, update, user_record):
|
||||||
|
return await _see_suggestions(bot, update, user_record)
|
Loading…
x
Reference in New Issue
Block a user