Add voice bot welcome tracking functionality

- Implemented methods to check and mark if a user has received a welcome message from the voice bot in both async and synchronous database classes.
- Updated database schema to include a new field for tracking welcome message status.
- Enhanced voice handler to utilize the new tracking methods, improving user interaction flow and engagement metrics.
This commit is contained in:
2025-09-01 19:43:46 +03:00
parent 2d40f4496e
commit 3a7b0f6219
5 changed files with 158 additions and 13 deletions

View File

@@ -977,3 +977,63 @@ class AsyncBotDB:
"""Закрытие соединений.""" """Закрытие соединений."""
# Соединения закрываются в каждом методе # Соединения закрываются в каждом методе
pass pass
# Методы для voice bot welcome tracking
async def check_voice_bot_welcome_received(self, user_id: int) -> bool:
"""
Проверяет, получал ли пользователь приветственное сообщение от voice_bot.
Args:
user_id (int): Идентификатор пользователя в Telegram.
Returns:
bool: True, если пользователь получал приветствие, False - иначе.
"""
conn = None
try:
conn = await self._get_connection()
async with conn.execute(
"SELECT voice_bot_welcome_received FROM our_users WHERE user_id = ?",
(user_id,)
) as cursor:
result = await cursor.fetchone()
if result:
welcome_received = bool(result[0])
self.logger.info(f"Пользователь {user_id} получал приветствие: {welcome_received}")
return welcome_received
else:
self.logger.info(f"Пользователь {user_id} не найден в базе")
return False
except Exception as e:
self.logger.error(f"Ошибка при проверке получения приветствия: {e}")
return False
finally:
if conn:
await conn.close()
async def mark_voice_bot_welcome_received(self, user_id: int) -> bool:
"""
Отмечает, что пользователь получил приветственное сообщение от voice_bot.
Args:
user_id (int): Идентификатор пользователя в Telegram.
Returns:
bool: True, если обновление прошло успешно, False - в случае ошибки.
"""
conn = None
try:
conn = await self._get_connection()
await conn.execute(
"UPDATE our_users SET voice_bot_welcome_received = 1 WHERE user_id = ?",
(user_id,)
)
await conn.commit()
self.logger.info(f"Пользователь {user_id} отмечен как получивший приветствие")
return True
except Exception as e:
self.logger.error(f"Ошибка при отметке получения приветствия: {e}")
return False
finally:
if conn:
await conn.close()

View File

@@ -1492,3 +1492,60 @@ class BotDB:
raise raise
finally: finally:
self.close() self.close()
def check_voice_bot_welcome_received(self, user_id: int) -> bool:
"""
Проверяет, получал ли пользователь приветственное сообщение от voice_bot.
Args:
user_id (int): Идентификатор пользователя в Telegram.
Returns:
bool: True, если пользователь получал приветствие, False - иначе.
"""
self.logger.info(f"Запуск функции check_voice_bot_welcome_received. user_id={user_id}")
try:
self.connect()
self.cursor.execute(
"SELECT voice_bot_welcome_received FROM our_users WHERE user_id = ?",
(user_id,)
)
result = self.cursor.fetchone()
if result:
welcome_received = bool(result[0])
self.logger.info(f"Пользователь {user_id} получал приветствие: {welcome_received}")
return welcome_received
else:
self.logger.info(f"Пользователь {user_id} не найден в базе")
return False
except sqlite3.Error as error:
self.logger.error(f"Ошибка при проверке получения приветствия: {error}")
return False
finally:
self.close()
def mark_voice_bot_welcome_received(self, user_id: int) -> bool:
"""
Отмечает, что пользователь получил приветственное сообщение от voice_bot.
Args:
user_id (int): Идентификатор пользователя в Telegram.
Returns:
bool: True, если обновление прошло успешно, False - в случае ошибки.
"""
self.logger.info(f"Запуск функции mark_voice_bot_welcome_received. user_id={user_id}")
try:
self.connect()
self.cursor.execute(
"UPDATE our_users SET voice_bot_welcome_received = 1 WHERE user_id = ?",
(user_id,)
)
self.conn.commit()
self.logger.info(f"Пользователь {user_id} отмечен как получивший приветствие")
return True
except sqlite3.Error as error:
self.logger.error(f"Ошибка при отметке получения приветствия: {error}")
return False
finally:
self.close()

View File

@@ -86,7 +86,8 @@ CREATE TABLE IF NOT EXISTS our_users (
has_stickers INTEGER DEFAULT 0 NOT NULL, has_stickers INTEGER DEFAULT 0 NOT NULL,
emoji TEXT, emoji TEXT,
date_added DATE NOT NULL, date_added DATE NOT NULL,
date_changed DATE NOT NULL date_changed DATE NOT NULL,
voice_bot_welcome_received BOOLEAN DEFAULT 0
); );
-- Audio moderation tracking -- Audio moderation tracking

View File

@@ -200,7 +200,8 @@ async def change_page(
@callback_router.callback_query(F.data == CALLBACK_SAVE) @callback_router.callback_query(F.data == CALLBACK_SAVE)
async def save_voice_message( async def save_voice_message(
call: CallbackQuery, call: CallbackQuery,
bot_db: MagicData("bot_db") bot_db: MagicData("bot_db"),
settings: MagicData("settings")
): ):
try: try:
# Создаем сервис для работы с аудио файлами # Создаем сервис для работы с аудио файлами
@@ -224,7 +225,7 @@ async def save_voice_message(
# Удаляем сообщение из предложки # Удаляем сообщение из предложки
await call.bot.delete_message( await call.bot.delete_message(
chat_id=bot_db.settings['Telegram']['group_for_posts'], chat_id=settings['Telegram']['group_for_posts'],
message_id=call.message.message_id message_id=call.message.message_id
) )
@@ -238,12 +239,13 @@ async def save_voice_message(
@callback_router.callback_query(F.data == CALLBACK_DELETE) @callback_router.callback_query(F.data == CALLBACK_DELETE)
async def delete_voice_message( async def delete_voice_message(
call: CallbackQuery, call: CallbackQuery,
bot_db: MagicData("bot_db") bot_db: MagicData("bot_db"),
settings: MagicData("settings")
): ):
try: try:
# Удаляем сообщение из предложки # Удаляем сообщение из предложки
await call.bot.delete_message( await call.bot.delete_message(
chat_id=bot_db.settings['Telegram']['group_for_posts'], chat_id=settings['Telegram']['group_for_posts'],
message_id=call.message.message_id message_id=call.message.message_id
) )

View File

@@ -96,28 +96,46 @@ class VoiceHandlers:
async def voice_bot_button_handler(self, message: types.Message, state: FSMContext, bot_db: MagicData("bot_db"), settings: MagicData("settings")): async def voice_bot_button_handler(self, message: types.Message, state: FSMContext, bot_db: MagicData("bot_db"), settings: MagicData("settings")):
"""Обработчик кнопки 'Голосовой бот' из основной клавиатуры""" """Обработчик кнопки 'Голосовой бот' из основной клавиатуры"""
await self.start(message, state, bot_db, settings) try:
# Проверяем, получал ли пользователь приветственное сообщение
welcome_received = bot_db.check_voice_bot_welcome_received(message.from_user.id)
logger.info(f"Пользователь {message.from_user.id}: welcome_received = {welcome_received}")
if welcome_received:
# Если уже получал приветствие, вызываем restart_function
logger.info(f"Пользователь {message.from_user.id}: вызываем restart_function")
await self.restart_function(message, state, bot_db, settings)
else:
# Если не получал, вызываем start
logger.info(f"Пользователь {message.from_user.id}: вызываем start")
await self.start(message, state, bot_db, settings)
except Exception as e:
logger.error(f"Ошибка при проверке приветственного сообщения: {e}")
# В случае ошибки вызываем start
await self.start(message, state, bot_db, settings)
async def restart_function( async def restart_function(
self, self,
message: types.Message, message: types.Message,
state: FSMContext, state: FSMContext,
bot_db: MagicData("bot_db") bot_db: MagicData("bot_db"),
settings: MagicData("settings")
): ):
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs']) logger.info(f"Пользователь {message.from_user.id}: вызывается функция restart_function")
await message.forward(chat_id=settings['Telegram']['group_for_logs'])
await update_user_info(VOICE_BOT_NAME, message) await update_user_info(VOICE_BOT_NAME, message)
check_user_emoji(message) check_user_emoji(message)
markup = get_main_keyboard() markup = get_main_keyboard()
await message.answer(text='Я перезапущен!', reply_markup=markup) await message.answer(text='🎤 Записывайся или слушай!', reply_markup=markup)
await state.set_state(STATE_START) await state.set_state(STATE_START)
async def handle_emoji_message( async def handle_emoji_message(
self, self,
message: types.Message, message: types.Message,
state: FSMContext, state: FSMContext,
bot_db: MagicData("bot_db") settings: MagicData("settings")
): ):
await message.forward(chat_id=bot_db.settings['Telegram']['group_for_logs']) await message.forward(chat_id=settings['Telegram']['group_for_logs'])
user_emoji = check_user_emoji(message) user_emoji = check_user_emoji(message)
await state.set_state(STATE_START) await state.set_state(STATE_START)
if user_emoji is not None: if user_emoji is not None:
@@ -127,7 +145,6 @@ class VoiceHandlers:
self, self,
message: types.Message, message: types.Message,
state: FSMContext, state: FSMContext,
bot_db: MagicData("bot_db"),
settings: MagicData("settings") settings: MagicData("settings")
): ):
await message.forward(chat_id=settings['Telegram']['group_for_logs']) await message.forward(chat_id=settings['Telegram']['group_for_logs'])
@@ -135,7 +152,7 @@ class VoiceHandlers:
help_message = messages.get_message(get_first_name(message), 'HELP_MESSAGE') help_message = messages.get_message(get_first_name(message), 'HELP_MESSAGE')
await message.answer( await message.answer(
text=help_message, text=help_message,
disable_web_page_preview=not bot_db.settings['Telegram']['preview_link'] disable_web_page_preview=not settings['Telegram']['preview_link']
) )
await state.set_state(STATE_START) await state.set_state(STATE_START)
@@ -146,6 +163,7 @@ class VoiceHandlers:
bot_db: MagicData("bot_db"), bot_db: MagicData("bot_db"),
settings: MagicData("settings") settings: MagicData("settings")
): ):
logger.info(f"Пользователь {message.from_user.id}: вызывается функция start")
await state.set_state(STATE_START) await state.set_state(STATE_START)
await message.forward(chat_id=settings['Telegram']['group_for_logs']) await message.forward(chat_id=settings['Telegram']['group_for_logs'])
await update_user_info(VOICE_BOT_NAME, message) await update_user_info(VOICE_BOT_NAME, message)
@@ -154,6 +172,13 @@ class VoiceHandlers:
# Создаем сервис и отправляем приветственные сообщения # Создаем сервис и отправляем приветственные сообщения
voice_service = VoiceBotService(bot_db, settings) voice_service = VoiceBotService(bot_db, settings)
await voice_service.send_welcome_messages(message, user_emoji) await voice_service.send_welcome_messages(message, user_emoji)
# Отмечаем, что пользователь получил приветственное сообщение
try:
bot_db.mark_voice_bot_welcome_received(message.from_user.id)
logger.info(f"Пользователь {message.from_user.id}: отмечен как получивший приветствие")
except Exception as e:
logger.error(f"Ошибка при отметке получения приветствия: {e}")
async def refresh_listen_function( async def refresh_listen_function(