Initial commit
This commit is contained in:
373
handlers/admin_handlers.py
Normal file
373
handlers/admin_handlers.py
Normal file
@@ -0,0 +1,373 @@
|
||||
# handlers/admin_handlers.py
|
||||
|
||||
import sqlite3
|
||||
import asyncio
|
||||
from aiogram import Router, F, types, Bot
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.fsm.state import State, StatesGroup
|
||||
from aiogram.enums import ContentType
|
||||
from aiogram.exceptions import TelegramAPIError
|
||||
|
||||
from keyboards import (
|
||||
get_main_keyboard_by_role, get_users_keyboard, user_management_keyboard,
|
||||
get_users_for_configs_keyboard, get_user_configs_management_keyboard,
|
||||
get_tutorials_admin_keyboard, get_skip_media_keyboard, get_confirm_send_keyboard
|
||||
)
|
||||
from localization import get_text
|
||||
|
||||
router = Router()
|
||||
|
||||
# --- Helper function to get admin's language ---
|
||||
def get_admin_lang(user_id: int) -> str:
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT language_code FROM users WHERE telegram_id = ?", (user_id,))
|
||||
result = cursor.fetchone()
|
||||
conn.close()
|
||||
return result[0] if result else 'en'
|
||||
|
||||
# --- FSM States ---
|
||||
class AdminStates(StatesGroup):
|
||||
add_user_id = State()
|
||||
add_config_type = State()
|
||||
add_config_data = State()
|
||||
add_tutorial_title = State()
|
||||
add_tutorial_text = State()
|
||||
add_tutorial_media = State()
|
||||
mass_send_message = State()
|
||||
mass_send_confirm = State()
|
||||
|
||||
# --- Main Menu Handler ---
|
||||
@router.callback_query(F.data == "admin_menu")
|
||||
async def process_admin_menu(callback: types.CallbackQuery, state: FSMContext):
|
||||
await state.clear() # Clear any active state
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await callback.message.edit_text(
|
||||
get_text('welcome_admin', lang),
|
||||
reply_markup=get_main_keyboard_by_role(is_admin=True, lang=lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
# --- User Management Section ---
|
||||
|
||||
@router.callback_query(F.data.startswith("admin_users_page_"))
|
||||
async def process_users_list(callback: types.CallbackQuery):
|
||||
page = int(callback.data.split("_")[-1])
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await callback.message.edit_text(
|
||||
get_text('users_list', lang),
|
||||
reply_markup=get_users_keyboard(page, lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.callback_query(F.data.startswith("manage_user_"))
|
||||
async def process_manage_user(callback: types.CallbackQuery):
|
||||
user_id = int(callback.data.split("_")[-1])
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT username FROM users WHERE telegram_id = ?", (user_id,))
|
||||
user = cursor.fetchone()
|
||||
conn.close()
|
||||
username = user[0] if user and user[0] else "N/A"
|
||||
|
||||
text = get_text('manage_user_title', lang).format(user_id=user_id, username=username)
|
||||
await callback.message.edit_text(
|
||||
text,
|
||||
reply_markup=user_management_keyboard(user_id, lang),
|
||||
parse_mode="Markdown"
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.callback_query(F.data.startswith("delete_user_"))
|
||||
async def process_delete_user(callback: types.CallbackQuery):
|
||||
user_id = int(callback.data.split("_")[-1])
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM users WHERE telegram_id = ?", (user_id,))
|
||||
# Configs will be deleted automatically due to "ON DELETE CASCADE" in the new DB schema
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
await callback.answer(get_text('user_deleted_ok', lang))
|
||||
await callback.message.edit_text(
|
||||
get_text('users_list', lang),
|
||||
reply_markup=get_users_keyboard(0, lang)
|
||||
)
|
||||
|
||||
@router.callback_query(F.data == "add_user")
|
||||
async def process_add_user_start(callback: types.CallbackQuery, state: FSMContext):
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await callback.message.edit_text(get_text('ask_for_user_id', lang))
|
||||
await state.set_state(AdminStates.add_user_id)
|
||||
await callback.answer()
|
||||
|
||||
@router.message(AdminStates.add_user_id)
|
||||
async def process_add_user_id(message: types.Message, state: FSMContext):
|
||||
lang = get_admin_lang(message.from_user.id)
|
||||
try:
|
||||
user_id = int(message.text)
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT telegram_id FROM users WHERE telegram_id = ?", (user_id,))
|
||||
if cursor.fetchone():
|
||||
await message.answer(get_text('user_already_exists', lang))
|
||||
else:
|
||||
# Add user with default language 'en'
|
||||
cursor.execute("INSERT INTO users (telegram_id, language_code) VALUES (?, ?)", (user_id, 'en'))
|
||||
conn.commit()
|
||||
await message.answer(get_text('user_added_ok', lang))
|
||||
conn.close()
|
||||
|
||||
await state.clear()
|
||||
await message.answer(
|
||||
get_text('users_list', lang),
|
||||
reply_markup=get_users_keyboard(0, lang)
|
||||
)
|
||||
except (ValueError, TypeError):
|
||||
await message.answer(get_text('invalid_id_format', lang))
|
||||
|
||||
# --- Config Management Section ---
|
||||
# (This section is also refactored to use the lang parameter)
|
||||
|
||||
@router.callback_query(F.data.startswith("admin_configs_page_"))
|
||||
async def process_config_users_list(callback: types.CallbackQuery):
|
||||
page = int(callback.data.split("_")[-1])
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await callback.message.edit_text(
|
||||
get_text('choose_user_for_config', lang),
|
||||
reply_markup=get_users_for_configs_keyboard(page, lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.callback_query(F.data.startswith("user_configs_manage_"))
|
||||
async def process_user_configs_manage(callback: types.CallbackQuery):
|
||||
user_id = int(callback.data.split("_")[-1])
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await callback.message.edit_text(
|
||||
get_text('user_configs_title', lang),
|
||||
reply_markup=get_user_configs_management_keyboard(user_id, lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.callback_query(F.data.startswith("delete_config:"))
|
||||
async def process_delete_config(callback: types.CallbackQuery):
|
||||
_, config_id, user_id = callback.data.split(":")
|
||||
config_id, user_id = int(config_id), int(user_id)
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM configs WHERE id = ?", (config_id,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
await callback.answer(get_text('config_deleted_ok', lang))
|
||||
await callback.message.edit_text(
|
||||
get_text('user_configs_title', lang),
|
||||
reply_markup=get_user_configs_management_keyboard(user_id, lang)
|
||||
)
|
||||
|
||||
# ... (Add Config FSM flow refactored for localization)
|
||||
@router.callback_query(F.data.startswith("add_config_"))
|
||||
async def process_add_config_start(callback: types.CallbackQuery, state: FSMContext):
|
||||
user_id = int(callback.data.split("_")[-1])
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await state.update_data(current_user_id=user_id)
|
||||
await state.set_state(AdminStates.add_config_type)
|
||||
await callback.message.edit_text(get_text('add_config_step1', lang))
|
||||
await callback.answer()
|
||||
|
||||
@router.message(AdminStates.add_config_type)
|
||||
async def process_add_config_type(message: types.Message, state: FSMContext):
|
||||
lang = get_admin_lang(message.from_user.id)
|
||||
await state.update_data(config_type=message.text)
|
||||
await state.set_state(AdminStates.add_config_data)
|
||||
await message.answer(get_text('add_config_step2', lang))
|
||||
|
||||
@router.message(AdminStates.add_config_data, F.content_type.in_({ContentType.TEXT, ContentType.DOCUMENT}))
|
||||
async def process_add_config_data(message: types.Message, state: FSMContext):
|
||||
lang = get_admin_lang(message.from_user.id)
|
||||
data = await state.get_data()
|
||||
user_id = data['current_user_id']
|
||||
|
||||
# ... (logic for handling file/text remains the same)
|
||||
if message.document:
|
||||
file_id = message.document.file_id
|
||||
file_name = message.document.file_name
|
||||
config_type = f"file:{file_name}"
|
||||
config_data = file_id
|
||||
else:
|
||||
config_type = data['config_type']
|
||||
config_data = message.text
|
||||
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("INSERT INTO configs (user_id, config_type, config_data) VALUES (?, ?, ?)",
|
||||
(user_id, config_type, config_data))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
await state.clear()
|
||||
await message.answer(get_text('config_added_ok', lang))
|
||||
await message.answer(
|
||||
get_text('user_configs_title', lang),
|
||||
reply_markup=get_user_configs_management_keyboard(user_id, lang)
|
||||
)
|
||||
|
||||
# --- Tutorial Management Section ---
|
||||
@router.callback_query(F.data == "admin_tutorials_menu")
|
||||
async def process_tutorials_menu(callback: types.CallbackQuery):
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await callback.message.edit_text(
|
||||
get_text('tutorials_menu_title', lang),
|
||||
reply_markup=get_tutorials_admin_keyboard(lang)
|
||||
)
|
||||
await callback.answer()
|
||||
# ... (rest of the tutorial management refactored similarly)
|
||||
|
||||
@router.callback_query(F.data.startswith("delete_tutorial_"))
|
||||
async def process_delete_tutorial(callback: types.CallbackQuery):
|
||||
tutorial_id = int(callback.data.split("_")[-1])
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("DELETE FROM tutorials WHERE id = ?", (tutorial_id,))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
await callback.answer(get_text('tutorial_deleted_ok', lang))
|
||||
await callback.message.edit_text(
|
||||
get_text('tutorials_menu_title', lang),
|
||||
reply_markup=get_tutorials_admin_keyboard(lang)
|
||||
)
|
||||
|
||||
@router.callback_query(F.data == "add_tutorial")
|
||||
async def process_add_tutorial_start(callback: types.CallbackQuery, state: FSMContext):
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await state.set_state(AdminStates.add_tutorial_title)
|
||||
await callback.message.edit_text(get_text('add_tutorial_step1', lang))
|
||||
await callback.answer()
|
||||
|
||||
@router.message(AdminStates.add_tutorial_title)
|
||||
async def process_add_tutorial_title(message: types.Message, state: FSMContext):
|
||||
lang = get_admin_lang(message.from_user.id)
|
||||
await state.update_data(title=message.text)
|
||||
await state.set_state(AdminStates.add_tutorial_text)
|
||||
await message.answer(get_text('add_tutorial_step2', lang))
|
||||
|
||||
@router.message(AdminStates.add_tutorial_text)
|
||||
async def process_add_tutorial_text(message: types.Message, state: FSMContext):
|
||||
lang = get_admin_lang(message.from_user.id)
|
||||
await state.update_data(text=message.text)
|
||||
await state.set_state(AdminStates.add_tutorial_media)
|
||||
await message.answer(
|
||||
get_text('add_tutorial_step3', lang),
|
||||
reply_markup=get_skip_media_keyboard(lang)
|
||||
)
|
||||
|
||||
@router.callback_query(F.data == "skip_media", AdminStates.add_tutorial_media)
|
||||
async def process_skip_media(callback: types.CallbackQuery, state: FSMContext):
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
data = await state.get_data()
|
||||
# ... (DB logic is the same)
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("INSERT INTO tutorials (title, content_text) VALUES (?, ?)", (data['title'], data['text']))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
await state.clear()
|
||||
await callback.message.edit_text(get_text('tutorial_added_ok_no_media', lang))
|
||||
await callback.message.answer(
|
||||
get_text('tutorials_menu_title', lang),
|
||||
reply_markup=get_tutorials_admin_keyboard(lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.message(AdminStates.add_tutorial_media, F.content_type.in_({ContentType.PHOTO, ContentType.VIDEO}))
|
||||
async def process_add_tutorial_media(message: types.Message, state: FSMContext):
|
||||
lang = get_admin_lang(message.from_user.id)
|
||||
# ... (DB and file_id logic is the same)
|
||||
file_id = ""
|
||||
if message.photo:
|
||||
file_id = message.photo[-1].file_id
|
||||
elif message.video:
|
||||
file_id = message.video.file_id
|
||||
data = await state.get_data()
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("INSERT INTO tutorials (title, content_text, file_id) VALUES (?, ?, ?)",
|
||||
(data['title'], data['text'], file_id))
|
||||
conn.commit()
|
||||
conn.close()
|
||||
await state.clear()
|
||||
await message.answer(get_text('tutorial_added_ok_with_media', lang))
|
||||
await message.answer(
|
||||
get_text('tutorials_menu_title', lang),
|
||||
reply_markup=get_tutorials_admin_keyboard(lang)
|
||||
)
|
||||
|
||||
# --- Mass Messaging Section ---
|
||||
@router.callback_query(F.data == "mass_send_start")
|
||||
async def process_mass_send_start(callback: types.CallbackQuery, state: FSMContext):
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await state.set_state(AdminStates.mass_send_message)
|
||||
await callback.message.edit_text(get_text('mass_send_ask_message', lang))
|
||||
await callback.answer()
|
||||
|
||||
@router.message(AdminStates.mass_send_message)
|
||||
async def process_mass_send_message(message: types.Message, state: FSMContext):
|
||||
lang = get_admin_lang(message.from_user.id)
|
||||
await state.update_data(message_to_send=message)
|
||||
await state.set_state(AdminStates.mass_send_confirm)
|
||||
await message.answer(
|
||||
get_text('mass_send_confirm_message', lang),
|
||||
reply_markup=get_confirm_send_keyboard(lang)
|
||||
)
|
||||
|
||||
@router.callback_query(F.data == "send_cancelled", AdminStates.mass_send_confirm)
|
||||
async def process_send_cancelled(callback: types.CallbackQuery, state: FSMContext):
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
await state.clear()
|
||||
await callback.message.edit_text(
|
||||
get_text('mass_send_cancelled', lang),
|
||||
reply_markup=get_main_keyboard_by_role(is_admin=True, lang=lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.callback_query(F.data == "send_confirmed", AdminStates.mass_send_confirm)
|
||||
async def process_send_confirmed(callback: types.CallbackQuery, state: FSMContext, bot: Bot):
|
||||
lang = get_admin_lang(callback.from_user.id)
|
||||
data = await state.get_data()
|
||||
message_to_send = data['message_to_send']
|
||||
await state.clear()
|
||||
|
||||
await callback.message.edit_text(get_text('mass_send_started', lang), reply_markup=None)
|
||||
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT telegram_id FROM users WHERE is_admin = 0")
|
||||
user_ids = cursor.fetchall()
|
||||
conn.close()
|
||||
|
||||
success_count = 0
|
||||
fail_count = 0
|
||||
for (user_id,) in user_ids:
|
||||
try:
|
||||
await message_to_send.copy_to(chat_id=user_id)
|
||||
success_count += 1
|
||||
except TelegramAPIError as e:
|
||||
print(f"Failed to send to {user_id}: {e}")
|
||||
fail_count += 1
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
result_text = get_text('mass_send_finished', lang).format(
|
||||
success_count=success_count,
|
||||
fail_count=fail_count
|
||||
)
|
||||
await callback.message.answer(
|
||||
result_text,
|
||||
reply_markup=get_main_keyboard_by_role(is_admin=True, lang=lang)
|
||||
)
|
||||
48
handlers/settings_handlers.py
Normal file
48
handlers/settings_handlers.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# handlers/settings_handlers.py
|
||||
|
||||
import sqlite3
|
||||
from aiogram import Router, F, types
|
||||
|
||||
from keyboards import get_language_choice_keyboard, get_main_keyboard_by_role
|
||||
from localization import get_text
|
||||
|
||||
router = Router()
|
||||
|
||||
@router.callback_query(F.data == "settings")
|
||||
async def process_settings(callback: types.CallbackQuery):
|
||||
# Получаем язык пользователя для корректного отображения меню
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT language_code FROM users WHERE telegram_id = ?", (callback.from_user.id,))
|
||||
lang = cursor.fetchone()[0]
|
||||
conn.close()
|
||||
|
||||
await callback.message.edit_text(
|
||||
get_text('choose_language', lang),
|
||||
reply_markup=get_language_choice_keyboard()
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data.startswith("set_lang_"))
|
||||
async def process_set_language(callback: types.CallbackQuery):
|
||||
lang_code = callback.data.split("_")[-1]
|
||||
user_id = callback.from_user.id
|
||||
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("UPDATE users SET language_code = ? WHERE telegram_id = ?", (lang_code, user_id))
|
||||
cursor.execute("SELECT is_admin FROM users WHERE telegram_id = ?", (user_id,))
|
||||
is_admin = cursor.fetchone()[0]
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
await callback.message.edit_text(get_text('language_changed', lang_code))
|
||||
|
||||
# Показываем главное меню на новом языке
|
||||
main_menu_text = get_text('welcome_admin' if is_admin else 'welcome', lang_code)
|
||||
await callback.message.answer(
|
||||
main_menu_text,
|
||||
reply_markup=get_main_keyboard_by_role(is_admin, lang_code)
|
||||
)
|
||||
await callback.answer()
|
||||
98
handlers/user_handlers.py
Normal file
98
handlers/user_handlers.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# handlers/user_handlers.py
|
||||
|
||||
import sqlite3
|
||||
from aiogram import Router, F, types, Bot
|
||||
from keyboards import get_main_keyboard_by_role, get_tutorials_user_keyboard
|
||||
from localization import get_text
|
||||
|
||||
router = Router()
|
||||
|
||||
# Вспомогательная функция для получения языка пользователя
|
||||
def get_user_lang(user_id: int) -> str:
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT language_code FROM users WHERE telegram_id = ?", (user_id,))
|
||||
result = cursor.fetchone()
|
||||
conn.close()
|
||||
return result[0] if result else 'en'
|
||||
|
||||
# Новый обработчик для кнопки "Назад в меню" из раздела помощи
|
||||
@router.callback_query(F.data == "user_main_menu")
|
||||
async def process_back_to_main_menu(callback: types.CallbackQuery):
|
||||
lang = get_user_lang(callback.from_user.id)
|
||||
await callback.message.edit_text(
|
||||
get_text('welcome', lang),
|
||||
reply_markup=get_main_keyboard_by_role(is_admin=False, lang=lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.callback_query(F.data == "user_configs")
|
||||
async def process_user_configs(callback: types.CallbackQuery, bot: Bot):
|
||||
user_id = callback.from_user.id
|
||||
lang = get_user_lang(user_id)
|
||||
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT config_type, config_data FROM configs WHERE user_id = ?", (user_id,))
|
||||
user_configs = cursor.fetchall()
|
||||
conn.close()
|
||||
|
||||
if not user_configs:
|
||||
await callback.message.answer(get_text('no_configs_yet', lang))
|
||||
else:
|
||||
await callback.message.answer(get_text('your_configs', lang))
|
||||
for config_type, config_data in user_configs:
|
||||
if config_type.startswith("file:"):
|
||||
file_id = config_data
|
||||
caption = f"{get_text('config_type', lang)}: {config_type.split(':', 1)[1]}"
|
||||
await bot.send_document(chat_id=user_id, document=file_id, caption=caption)
|
||||
else:
|
||||
await callback.message.answer(f"{get_text('config_type', lang)}: `{config_type}`\n\n`{config_data}`", parse_mode="Markdown")
|
||||
|
||||
await callback.message.answer(
|
||||
get_text('next_action', lang),
|
||||
reply_markup=get_main_keyboard_by_role(is_admin=False, lang=lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.callback_query(F.data == "user_help")
|
||||
async def process_user_help(callback: types.CallbackQuery):
|
||||
lang = get_user_lang(callback.from_user.id)
|
||||
await callback.message.edit_text(
|
||||
get_text('choose_tutorial', lang),
|
||||
reply_markup=get_tutorials_user_keyboard(lang)
|
||||
)
|
||||
await callback.answer()
|
||||
|
||||
@router.callback_query(F.data.startswith("view_tutorial_"))
|
||||
async def process_view_tutorial(callback: types.CallbackQuery, bot: Bot):
|
||||
user_id = callback.from_user.id
|
||||
lang = get_user_lang(user_id)
|
||||
tutorial_id = int(callback.data.split("_")[-1])
|
||||
|
||||
conn = sqlite3.connect('bot.db')
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT content_text, file_id FROM tutorials WHERE id = ?", (tutorial_id,))
|
||||
tutorial = cursor.fetchone()
|
||||
conn.close()
|
||||
|
||||
if tutorial:
|
||||
content_text, file_id = tutorial
|
||||
# Сначала удаляем предыдущее сообщение с кнопками
|
||||
await callback.message.delete()
|
||||
if file_id:
|
||||
try:
|
||||
await bot.send_photo(chat_id=user_id, photo=file_id, caption=content_text)
|
||||
except:
|
||||
await bot.send_video(chat_id=user_id, video=file_id, caption=content_text)
|
||||
else:
|
||||
await callback.message.answer(content_text)
|
||||
|
||||
await callback.message.answer(
|
||||
get_text('next_action', lang),
|
||||
reply_markup=get_main_keyboard_by_role(is_admin=False, lang=lang)
|
||||
)
|
||||
else:
|
||||
await callback.answer(get_text('error_not_found', lang), show_alert=True)
|
||||
|
||||
await callback.answer()
|
||||
Reference in New Issue
Block a user