[ВОЛК] коррекция бота под повторные попытки
This commit is contained in:
+137
-49
@@ -4,6 +4,7 @@ import time
|
||||
import errno
|
||||
from dotenv import load_dotenv
|
||||
import telebot
|
||||
from telebot import apihelper
|
||||
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
|
||||
import pymysql
|
||||
from datetime import datetime, timezone
|
||||
@@ -159,6 +160,11 @@ for name, value in required_vars.items():
|
||||
logger.error(f"Требуется переменная окружения {name}")
|
||||
exit(1)
|
||||
|
||||
# Настройка таймаутов для Telegram API
|
||||
apihelper.READ_TIMEOUT = 120 # Таймаут на чтение ответа (увеличен для больших сообщений)
|
||||
apihelper.CONNECT_TIMEOUT = 30 # Таймаут на подключение
|
||||
apihelper.RETRY_ON_TIMEOUT = True # Автоматические повторные попытки при таймауте
|
||||
|
||||
# Создаем экземпляр бота
|
||||
bot = telebot.TeleBot(RESPONDER_BOT_TOKEN)
|
||||
|
||||
@@ -802,44 +808,89 @@ def download_image(image_url):
|
||||
return None
|
||||
|
||||
def send_post_message(chat_id, text, image_url=None, reply_markup=None):
|
||||
"""Отправляет сообщение с изображением или текстом"""
|
||||
"""Отправляет сообщение с изображением или текстом с повторными попытками при таймауте"""
|
||||
logger.info(f"starting send_post_message")
|
||||
try:
|
||||
# Дополнительная обрезка текста
|
||||
if len(text) > UNIFIED_MAX_LENGTH:
|
||||
text = text[:UNIFIED_MAX_LENGTH - 3] + "..."
|
||||
|
||||
# Параметры для повторных попыток при таймауте
|
||||
max_retries = 5
|
||||
retry_interval = 2
|
||||
|
||||
# Дополнительная обрезка текста
|
||||
if len(text) > UNIFIED_MAX_LENGTH:
|
||||
text = text[:UNIFIED_MAX_LENGTH - 3] + "..."
|
||||
|
||||
if image_url:
|
||||
# Загружаем изображение
|
||||
image = download_image(image_url)
|
||||
if image:
|
||||
# Отправляем фото с подписью
|
||||
bot.send_photo(
|
||||
chat_id,
|
||||
photo=image,
|
||||
caption=text,
|
||||
reply_markup=reply_markup,
|
||||
parse_mode='HTML'
|
||||
)
|
||||
return True
|
||||
if image_url:
|
||||
# Загружаем изображение
|
||||
image = download_image(image_url)
|
||||
if image:
|
||||
# Отправляем фото с подписью с повторными попытками
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
bot.send_photo(
|
||||
chat_id,
|
||||
photo=image,
|
||||
caption=text,
|
||||
reply_markup=reply_markup,
|
||||
parse_mode='HTML'
|
||||
)
|
||||
logger.info(f"Сообщение с изображением успешно отправлено (попытка {attempt})")
|
||||
return True
|
||||
except Exception as e:
|
||||
error_str = str(e)
|
||||
# Проверяем, является ли это таймаутом
|
||||
if 'timeout' in error_str.lower() or 'timed out' in error_str.lower():
|
||||
if attempt < max_retries:
|
||||
logger.warning(f"Таймаут при отправке фото (попытка {attempt}/{max_retries}), повтор через {retry_interval} сек...")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Таймаут при отправке фото после {max_retries} попыток: {e}")
|
||||
return False
|
||||
else:
|
||||
# Для других ошибок не повторяем
|
||||
logger.error(f"Ошибка отправки фото: {e}")
|
||||
return False
|
||||
return False
|
||||
else:
|
||||
logger.warning(f"Не удалось загрузить изображение: {image_url}")
|
||||
|
||||
# Если изображение отсутствует или не загружено, отправляем текст с повторными попытками
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
bot.send_message(
|
||||
chat_id,
|
||||
text,
|
||||
reply_markup=reply_markup,
|
||||
parse_mode='HTML'
|
||||
)
|
||||
logger.info(f"Текстовое сообщение успешно отправлено (попытка {attempt})")
|
||||
return True
|
||||
except Exception as e:
|
||||
error_str = str(e)
|
||||
# Проверяем, является ли это таймаутом
|
||||
if 'timeout' in error_str.lower() or 'timed out' in error_str.lower():
|
||||
if attempt < max_retries:
|
||||
logger.warning(f"Таймаут при отправке сообщения (попытка {attempt}/{max_retries}), повтор через {retry_interval} сек...")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Таймаут при отправке сообщения после {max_retries} попыток: {e}")
|
||||
return False
|
||||
else:
|
||||
logger.warning(f"Не удалось загрузить изображение: {image_url}")
|
||||
|
||||
# Если изображение отсутствует или не загружено, отправляем текст
|
||||
bot.send_message(
|
||||
chat_id,
|
||||
text,
|
||||
reply_markup=reply_markup,
|
||||
parse_mode='HTML'
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка отправки сообщения: {e}")
|
||||
return False
|
||||
# Для других ошибок не повторяем
|
||||
logger.error(f"Ошибка отправки сообщения: {e}")
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def send_direct_message(user_id, message_text):
|
||||
"""Отправляет сообщение пользователю по ID с обработкой ошибок"""
|
||||
"""Отправляет сообщение пользователю по ID с обработкой ошибок и повторными попытками при таймауте"""
|
||||
logger.info(f"starting send_direct_message")
|
||||
|
||||
# Параметры для повторных попыток при таймауте
|
||||
max_retries = 5
|
||||
retry_interval = 2
|
||||
|
||||
try:
|
||||
# Проверяем, что сообщение не пустое
|
||||
if not message_text or not message_text.strip():
|
||||
@@ -848,17 +899,35 @@ def send_direct_message(user_id, message_text):
|
||||
log_event("error", f"user_{user_id}", message=error_msg)
|
||||
return False, error_msg
|
||||
|
||||
# Отправляем сообщение
|
||||
bot.send_message(
|
||||
user_id,
|
||||
message_text,
|
||||
parse_mode='HTML'
|
||||
)
|
||||
|
||||
# Логируем успешную отправку
|
||||
log_event("info", f"user_{user_id}", message=f"Сообщение отправлено: {message_text[:50]}...")
|
||||
logger.info(f"Сообщение успешно отправлено пользователю {user_id}")
|
||||
return True, "Сообщение отправлено успешно"
|
||||
# Отправляем сообщение с повторными попытками
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
bot.send_message(
|
||||
user_id,
|
||||
message_text,
|
||||
parse_mode='HTML'
|
||||
)
|
||||
|
||||
# Логируем успешную отправку
|
||||
log_event("info", f"user_{user_id}", message=f"Сообщение отправлено: {message_text[:50]}...")
|
||||
logger.info(f"Сообщение успешно отправлено пользователю {user_id} (попытка {attempt})")
|
||||
return True, "Сообщение отправлено успешно"
|
||||
except Exception as e:
|
||||
error_str = str(e)
|
||||
# Проверяем, является ли это таймаутом
|
||||
if 'timeout' in error_str.lower() or 'timed out' in error_str.lower():
|
||||
if attempt < max_retries:
|
||||
logger.warning(f"Таймаут при отправке сообщения пользователю {user_id} (попытка {attempt}/{max_retries}), повтор через {retry_interval} сек...")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
else:
|
||||
error_msg = f"Таймаут при отправке сообщения после {max_retries} попыток: {e}"
|
||||
logger.error(error_msg)
|
||||
log_event("error", f"user_{user_id}", message=error_msg)
|
||||
return False, f"Таймаут при отправке сообщения. Попробуйте позже."
|
||||
else:
|
||||
# Для других ошибок выходим из цикла и обрабатываем дальше
|
||||
break
|
||||
|
||||
except telebot.apihelper.ApiTelegramException as e:
|
||||
error_msg = f"Ошибка Telegram API: {e}"
|
||||
@@ -963,12 +1032,31 @@ def handle_start(message):
|
||||
# Команда /start без параметров
|
||||
welcome_text = get_welcome_text()
|
||||
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
welcome_text,
|
||||
reply_markup=create_main_keyboard(),
|
||||
parse_mode='HTML'
|
||||
)
|
||||
# Отправляем приветственное сообщение с повторными попытками при таймауте
|
||||
max_retries = 5
|
||||
retry_interval = 2
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
bot.send_message(
|
||||
message.chat.id,
|
||||
welcome_text,
|
||||
reply_markup=create_main_keyboard(),
|
||||
parse_mode='HTML'
|
||||
)
|
||||
logger.info(f"Приветственное сообщение отправлено (попытка {attempt})")
|
||||
break
|
||||
except Exception as e:
|
||||
error_str = str(e)
|
||||
if 'timeout' in error_str.lower() or 'timed out' in error_str.lower():
|
||||
if attempt < max_retries:
|
||||
logger.warning(f"Таймаут при отправке приветственного сообщения (попытка {attempt}/{max_retries}), повтор через {retry_interval} сек...")
|
||||
time.sleep(retry_interval)
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Таймаут при отправке приветственного сообщения после {max_retries} попыток: {e}")
|
||||
raise
|
||||
else:
|
||||
raise
|
||||
except Exception as e:
|
||||
error_msg = f"Ошибка в обработке /start: {e}"
|
||||
logger.error(error_msg)
|
||||
|
||||
Reference in New Issue
Block a user