From d844ce42e83a0672d33648f3b53903275c42e3b9 Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Sun, 15 Dec 2024 23:49:30 +0300 Subject: [PATCH 01/10] =?UTF-8?q?fix:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D1=82=D1=8C=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20message=5Fthread=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Заменен вызов свойства c `message` на `effective_message` для корректного получения `message_thread_id`. Исправление предотвращает возможные ошибки в обработке и обеспечивает стабильную работу функции ответа. --- src/middleware/throttling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/throttling.py b/src/middleware/throttling.py index 70a2809..5b327b9 100644 --- a/src/middleware/throttling.py +++ b/src/middleware/throttling.py @@ -33,7 +33,7 @@ async def check_ttl(update: Update, context: ContextTypes.DEFAULT_TYPE): text = ('При необходимости повторной обработки ' 'вызови /start в ЛС бота, иначе игнорируй ' 'данное сообщение') - message_thread_id = update.message.message_thread_id + message_thread_id = update.effective_message.message_thread_id try: await update.effective_message.reply_text( text=text, From bbc9729bc3b9408dd6a371521b59decd960da46c Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:33:47 +0300 Subject: [PATCH 02/10] =?UTF-8?q?refactor:=20=D1=83=D0=B4=D0=B0=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9?= =?UTF-8?q?=D0=BA=D0=B8=20get=5Fupdates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Удалены параметры настроек get_updates, которые больше не используются. Не ясно влияли ли эти настройки на стабильность или качество соединения --- src/bot.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/bot.py b/src/bot.py index fdca338..114b79f 100644 --- a/src/bot.py +++ b/src/bot.py @@ -25,11 +25,6 @@ .token(config.bot.token.get_secret_value()) .persistence(pickle_persistence) .defaults(Defaults(parse_mode=ParseMode.HTML)) - .get_updates_pool_timeout(3) - .get_updates_write_timeout(7) - .get_updates_connect_timeout(7) - .get_updates_read_timeout(7) - .get_updates_connection_pool_size(2) .rate_limiter(AIORateLimiter()) .build() From ff9e6ea183f3631fbad681bd21c2efc8715dd893 Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:34:12 +0300 Subject: [PATCH 03/10] =?UTF-8?q?feat:=20=D1=83=D0=BB=D1=83=D1=87=D1=88?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA=20=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=81?= =?UTF-8?q?=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена обработка ошибки удаления сообщения и обновлены сообщения для пользователя при сетевых ошибках. Теперь бот дает более понятные инструкции для повторения действий в случае возникновения проблем --- src/handlers/error_hl.py | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/handlers/error_hl.py b/src/handlers/error_hl.py index fc67d84..da12b61 100644 --- a/src/handlers/error_hl.py +++ b/src/handlers/error_hl.py @@ -30,6 +30,7 @@ async def error_handler(update: Update, chat_id = context.config.bot.developer_chat_id outdated_err_msg = ( 'Query is too old and response timeout expired or query id is invalid') + del_err_msg = "Message can't be deleted for everyone" if isinstance(context.error, HTTPError): await context.bot.send_message( chat_id=chat_id, @@ -39,15 +40,48 @@ async def error_handler(update: Update, (context.error.message == outdated_err_msg)): error_hl_logger.error(context.error.message) raise ApplicationHandlerStop + elif (hasattr(context.error, 'message') and + (context.error.message == del_err_msg)): + error_hl_logger.error(context.error.message) + text = 'Пожалуйста, выполните команду /start и повторите операцию заново' + message_thread_id = update.effective_message.message_thread_id + try: + await update.effective_message.reply_text( + text=text, + message_thread_id=message_thread_id, + ) + except BadRequest as e: + error_hl_logger.error(e) + await update.effective_chat.send_message( + text=text, + message_thread_id=message_thread_id, + ) elif (isinstance(context.error, TimedOut) or - isinstance(context.error, NetworkError)): + isinstance(context.error, NetworkError) and + not isinstance(context.error, BadRequest)): error_hl_logger.error(context.error.message) error_hl_logger.error('Выполнение запроса занимает много времени') context.user_data['last_update'] = None + text = ('Пожалуйста, подождите 3 секунды и повторите последнее ' + 'действие, если проблема остается, вызовите /start и ' + 'повторите запрос заново.') + message_thread_id = update.effective_message.message_thread_id + try: + await update.effective_message.reply_text( + text=text, + message_thread_id=message_thread_id, + ) + except BadRequest as e: + error_hl_logger.error(e) + await update.effective_chat.send_message( + text=text, + message_thread_id=message_thread_id, + ) raise ApplicationHandlerStop else: text = ('Произошла не предвиденная ошибка\n' - 'Пожалуйста, выполните команду /start и повторите операцию заново') + 'Пожалуйста, пробуйте повторить последнее действие, ' + 'или выполните команду /start и повторите операцию заново') message_thread_id = update.effective_message.message_thread_id try: await update.effective_message.reply_text( @@ -74,11 +108,9 @@ async def error_handler(update: Update, message = ( "An exception was raised while handling an update\n" - f"
"
             f"update = {html.escape(json.dumps(update_str,
                                                indent=2,
                                                ensure_ascii=False))}"
-            f"
" ) try: await split_message(context, message) From 32ecd42499210b1048a227ff020fbf6fc2adf7a8 Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:35:27 +0300 Subject: [PATCH 04/10] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BF=D0=BE=D0=BB=D0=B5=20last=5Fup?= =?UTF-8?q?date=20=D0=B2=20user=5Fdata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлено новое поле last_update в user_data для хранения информации о последнем обновлении. На случай, если необходимо сбросить информацию о последнем update --- src/handlers/main_hl.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/handlers/main_hl.py b/src/handlers/main_hl.py index 9bd6b08..e17bfe4 100644 --- a/src/handlers/main_hl.py +++ b/src/handlers/main_hl.py @@ -41,6 +41,8 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): context.user_data['user'] = update.effective_user context.user_data['common_data'] = {} + context.user_data['last_update'] = None + start_text = 'Вас приветствует Бот Бэби-театра «Домик»\n\n' description = context.bot_data['texts']['description'] address = context.bot_data['texts']['address'] From bdb2493cba5150b0007973eaac7e78628c68d951 Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:36:23 +0300 Subject: [PATCH 05/10] =?UTF-8?q?fix:=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B0=20=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B9=20TimedOut=20=D0=B8=20NetworkError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена обработка исключений TimedOut и NetworkError для предотвращения сбоев при работе с методами telegram. Логирование дополнено для упрощения диагностики ошибок --- src/handlers/reserve_hl.py | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/handlers/reserve_hl.py b/src/handlers/reserve_hl.py index a43e52f..c3ec506 100644 --- a/src/handlers/reserve_hl.py +++ b/src/handlers/reserve_hl.py @@ -8,7 +8,7 @@ InlineKeyboardButton, ReplyKeyboardRemove, ) -from telegram.error import TimedOut +from telegram.error import TimedOut, NetworkError from telegram.ext import ContextTypes, ConversationHandler, TypeHandler from telegram.constants import ChatType, ChatAction @@ -750,19 +750,28 @@ async def get_name_children( await update.effective_chat.send_action(ChatAction.TYPING) text = 'Создаю новые билеты в бд...' + reserve_hl_logger.info(text) message = await update.effective_chat.send_message(text) ticket_ids = await create_tickets_and_people( update, context, TicketStatus.CREATED) text += '\nЗаписываю новый билет в клиентскую базу...' - await message.edit_text(text) + try: + await message.edit_text(text) + except TimedOut as e: + reserve_hl_logger.error(e) + reserve_hl_logger.info(text) await write_client_reserve(context, update.effective_chat.id, chose_base_ticket, TicketStatus.CREATED.value) text += '\nУменьшаю кол-во свободных мест...' - await message.edit_text(text) + try: + await message.edit_text(text) + except TimedOut as e: + reserve_hl_logger.error(e) + reserve_hl_logger.info(text) result = await decrease_free_seat( context, schedule_event_id, chose_base_ticket_id) if not result: @@ -773,7 +782,11 @@ async def get_name_children( text += ('\nНе уменьшились свободные места' '\nНовый билет отменен' '\nНеобходимо повторить резервирование заново') - await message.edit_text(text) + try: + await message.edit_text(text) + except TimedOut as e: + reserve_hl_logger.error(e) + reserve_hl_logger.info(text) context.user_data['conv_hl_run'] = False await clean_context_on_end_handler(reserve_hl_logger, context) return ConversationHandler.END @@ -783,6 +796,7 @@ async def get_name_children( await message.edit_text(text) except TimedOut as e: reserve_hl_logger.error(e) + reserve_hl_logger.info(text) await processing_successful_payment(update, context) state = ConversationHandler.END @@ -900,7 +914,10 @@ async def send_clients_data( if not is_skip_ticket(ticket.status): base_ticket_and_tickets.append((base_ticket, ticket)) - await query.edit_message_text('Загружаю данные покупателей') + try: + await query.edit_message_text('Загружаю данные покупателей') + except TimedOut as e: + reserve_hl_logger.error(e) text = f'#Мероприятие {event_id}\n' text += (f'Список людей на\n' @@ -916,7 +933,10 @@ async def send_clients_data( state = ConversationHandler.END context.user_data['STATE'] = state - await query.answer() + try: + await query.answer() + except NetworkError as e: + reserve_hl_logger.error(e) context.user_data['conv_hl_run'] = False return state From d28d01bc4a3d3c678d83dccc08721b6201959190 Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:36:48 +0300 Subject: [PATCH 06/10] =?UTF-8?q?fix:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=D1=81=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20messag?= =?UTF-8?q?e=5Fthread=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлено обращение к message_thread_id для корректной работы функции. Теперь метод использует update.effective_message вместо update.callback_query.message --- src/handlers/reserve_hl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers/reserve_hl.py b/src/handlers/reserve_hl.py index c3ec506..7530dd9 100644 --- a/src/handlers/reserve_hl.py +++ b/src/handlers/reserve_hl.py @@ -357,7 +357,7 @@ async def choice_time(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.effective_chat.send_message( text=text, reply_markup=reply_markup, - message_thread_id=update.callback_query.message.message_thread_id + message_thread_id=update.effective_message.message_thread_id ) reserve_user_data = context.user_data['reserve_user_data'] From 29c1de6a9e86e009bd08f3bf8c4108ad0a8f56af Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:36:58 +0300 Subject: [PATCH 07/10] =?UTF-8?q?style:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82?= =?UTF-8?q?=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=20=D0=B2=20reserve=5Fhl.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Изменен стиль записи многострочного текста для повышения читаемости и соответствия PEP-8. Функциональность кода не изменена --- src/handlers/reserve_hl.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/handlers/reserve_hl.py b/src/handlers/reserve_hl.py index 7530dd9..88bb41b 100644 --- a/src/handlers/reserve_hl.py +++ b/src/handlers/reserve_hl.py @@ -974,9 +974,9 @@ async def get_phone_for_waiting( user = context.user_data['user'] thread_id = (context.bot_data['dict_topics_name'] .get('Лист ожидания', None)) - text = f'#Лист_ожидания\n' \ - f'Пользователь @{user.username} {user.full_name}\n' \ - f'Запросил добавление в лист ожидания\n' + text + text = (f'#Лист_ожидания\n' + f'Пользователь @{user.username} {user.full_name}\n' + f'Запросил добавление в лист ожидания\n' + text) await context.bot.send_message( chat_id=ADMIN_GROUP, text=text, From 6b305dc84effc0f806c30de933e93b2e64febb20 Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:37:24 +0300 Subject: [PATCH 08/10] =?UTF-8?q?fix:=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B0=20=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20NetworkError=20=D0=B2=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=87=D0=B8=D0=BA=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BB=D0=B0=D1=82=D0=B5=D0=B6=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена обработка исключения NetworkError при ответе на запрос. Это улучшает устойчивость к сетевым ошибкам и предотвращает возможные сбои при работе с платежами --- src/handlers/sub_hl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handlers/sub_hl.py b/src/handlers/sub_hl.py index 7f0597d..a99918e 100644 --- a/src/handlers/sub_hl.py +++ b/src/handlers/sub_hl.py @@ -8,7 +8,7 @@ ReplyKeyboardMarkup, KeyboardButton, Message ) from telegram.constants import ChatAction -from telegram.error import BadRequest, TimedOut +from telegram.error import BadRequest, TimedOut, NetworkError from telegram.ext import ContextTypes, ConversationHandler from yookassa import Payment @@ -397,7 +397,7 @@ async def processing_successful_payment( if query: try: await query.answer() - except BadRequest as e: + except NetworkError as e: sub_hl_logger.error(e) await query.edit_message_text('Платеж успешно обработан') From b910aa26bb41be71511804022443964abadf41b5 Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:37:47 +0300 Subject: [PATCH 09/10] =?UTF-8?q?fix:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=BF=D0=BE=D0=B2=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=BD=D1=8B=D1=85=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B9=20=D0=B2=20throttling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена проверка потока сообщений и уточнены тексты ответов для разных случаев. Устранено дублирование кода и исправлены возможные ошибки отправки сообщений при обработке запросов. --- src/middleware/throttling.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/middleware/throttling.py b/src/middleware/throttling.py index 5b327b9..60142e3 100644 --- a/src/middleware/throttling.py +++ b/src/middleware/throttling.py @@ -29,22 +29,27 @@ async def check_ttl(update: Update, context: ContextTypes.DEFAULT_TYPE): last_query_data = last_query.data if last_query_data == query_data: logger_ttl.warning(f'Update уже обработан: {update}') + message_thread_id = update.effective_message.message_thread_id if chat_id in ADMIN_GROUP_ID: text = ('При необходимости повторной обработки ' 'вызови /start в ЛС бота, иначе игнорируй ' 'данное сообщение') - message_thread_id = update.effective_message.message_thread_id - try: - await update.effective_message.reply_text( - text=text, - message_thread_id=message_thread_id, - ) - except BadRequest as e: - logger_ttl.error(e) - await update.effective_chat.send_message( - text=text, - message_thread_id=message_thread_id, - ) + else: + text = ('Подождите 3 секунды и повторите последнее ' + 'действие, в случае многократного повтора ' + 'данного сообщения, вызовите /start и ' + 'повторите запрос заново.') + try: + await update.effective_message.reply_text( + text=text, + message_thread_id=message_thread_id, + ) + except BadRequest as e: + logger_ttl.error(e) + await update.effective_chat.send_message( + text=text, + message_thread_id=message_thread_id, + ) raise ApplicationHandlerStop context.user_data['last_update'] = update From 6decdc23e34184ae8dbeacc03ec07a20080f921d Mon Sep 17 00:00:00 2001 From: MikiEremiki Date: Mon, 16 Dec 2024 02:38:11 +0300 Subject: [PATCH 10/10] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B0=D1=80=D1=85=D0=B8=D0=B2=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2=20=D1=81=20=D0=BD=D0=BE=D0=BC?= =?UTF-8?q?=D0=B5=D1=80=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена функциональность передачи номера архивного лога через аргумент. При неправильном формате аргумента действие игнорируется --- src/utilities/utl_func.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/utilities/utl_func.py b/src/utilities/utl_func.py index 32a0c0c..c708fce 100644 --- a/src/utilities/utl_func.py +++ b/src/utilities/utl_func.py @@ -4,7 +4,7 @@ import re from datetime import time from pprint import pformat -from typing import List, Sequence, Tuple +from typing import List, Sequence, Tuple, cast import pytz from telegram import ( @@ -199,11 +199,26 @@ async def set_description(bot: ExtBot) -> None: async def send_log(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + caption = [0] + i = 1 + while os.path.exists(f'log/archive/log.txt.{i}'): + caption.append(i) + i += 1 await context.bot.send_document( chat_id=update.effective_chat.id, - document='log/archive/log.txt' + document='log/archive/log.txt', + caption=caption ) if context.args: + try: + num = int(context.args[0]) + if os.path.exists(f'log/archive/log.txt.{num}'): + await context.bot.send_document( + chat_id=update.effective_chat.id, + document=f'log/archive/log.txt.{num}' + ) + except ValueError: + pass if context.args[0] == 'all': i = 1 while os.path.exists(f'log/archive/log.txt.{i}'):