[ВОЛК] добавлен отладочный скрипт для ловли причин таймаута в телеге
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
import os
|
||||
import logging
|
||||
import asyncio
|
||||
import time
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from telegram import Bot
|
||||
from telegram.error import TelegramError, RetryAfter, TimedOut
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Загрузка переменных окружения
|
||||
load_dotenv()
|
||||
|
||||
# Настройки из переменных окружения
|
||||
POSTER_BOT_TOKEN = os.getenv('POSTER_BOT_TOKEN')
|
||||
RESPONDER_BOT_NAME = os.getenv('RESPONDER_BOT_NAME')
|
||||
CHANNEL_ID = os.getenv('CHANNEL_ID')
|
||||
DESC_PREFIX = os.getenv('DESC_PREFIX', '')
|
||||
PZK_PREFIX = os.getenv('PZK_PREFIX', '')
|
||||
MAX_CAPTION_LENGTH = int(os.getenv('MAX_CAPTION_LENGTH', 1000))
|
||||
MAX_TEXT_LENGTH = int(os.getenv('MAX_TEXT_LENGTH', 4000))
|
||||
PUBLISH_SILENTLY = os.getenv('PUBLISH_SILENTLY', 'false').lower() in ('true', '1', 'yes', 'on')
|
||||
USE_SUBSCRIPTION_BOT = os.getenv('USE_SUBSCRIPTION_BOT', 'true').lower() in ('true', '1', 'yes', 'on')
|
||||
|
||||
# Настройка логирования
|
||||
LOG_FILE = 'volk_telegram_testing.log'
|
||||
logger = logging.getLogger('VOLK_TG_Test')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# Консольный обработчик
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
console_handler.setFormatter(formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# Файловый обработчик с повторными попытками
|
||||
class RetryFileHandler(logging.FileHandler):
|
||||
def emit(self, record):
|
||||
for _ in range(5):
|
||||
try:
|
||||
super().emit(record)
|
||||
return
|
||||
except (IOError, PermissionError):
|
||||
time.sleep(0.5)
|
||||
print(f"Failed to write to log file after 5 attempts: {record.msg}")
|
||||
|
||||
file_handler = RetryFileHandler(LOG_FILE, encoding='utf-8')
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
file_handler.setFormatter(formatter)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
async def test_telegram_publish():
|
||||
"""Тестовая публикация сообщения в Telegram"""
|
||||
logger.info("=" * 80)
|
||||
logger.info("НАЧАЛО ТЕСТОВОЙ ПУБЛИКАЦИИ В TELEGRAM")
|
||||
logger.info("=" * 80)
|
||||
|
||||
# Логируем загруженные параметры
|
||||
logger.info("Загруженные параметры из .env:")
|
||||
logger.info(f" POSTER_BOT_TOKEN: {'*' * 20 if POSTER_BOT_TOKEN else 'НЕ ЗАДАН'}")
|
||||
logger.info(f" RESPONDER_BOT_NAME: {RESPONDER_BOT_NAME}")
|
||||
logger.info(f" CHANNEL_ID: {CHANNEL_ID}")
|
||||
logger.info(f" DESC_PREFIX: {DESC_PREFIX}")
|
||||
logger.info(f" PZK_PREFIX: {PZK_PREFIX}")
|
||||
logger.info(f" MAX_CAPTION_LENGTH: {MAX_CAPTION_LENGTH}")
|
||||
logger.info(f" MAX_TEXT_LENGTH: {MAX_TEXT_LENGTH}")
|
||||
logger.info(f" PUBLISH_SILENTLY: {PUBLISH_SILENTLY}")
|
||||
logger.info(f" USE_SUBSCRIPTION_BOT: {USE_SUBSCRIPTION_BOT}")
|
||||
|
||||
# Проверка обязательных параметров
|
||||
if not POSTER_BOT_TOKEN:
|
||||
logger.error("ОШИБКА: POSTER_BOT_TOKEN не задан в .env")
|
||||
return False
|
||||
|
||||
if not CHANNEL_ID:
|
||||
logger.error("ОШИБКА: CHANNEL_ID не задан в .env")
|
||||
return False
|
||||
|
||||
# Формируем тестовое сообщение
|
||||
test_number = "TEST001"
|
||||
test_tags = "#тест #volk_testing"
|
||||
test_unit_name = "Тестовая площадка"
|
||||
test_name = "Тестовое событие для проверки публикации"
|
||||
test_about = "Это тестовое сообщение для проверки работы публикации в Telegram. " * 5
|
||||
|
||||
# Формируем базовый текст
|
||||
base_text = f"{test_tags}\n{test_unit_name}\n<b>{test_name}</b>"
|
||||
base_text_length = len(base_text)
|
||||
|
||||
# Формируем строку ссылок
|
||||
placeholder_message_id = '1234567890'
|
||||
if USE_SUBSCRIPTION_BOT:
|
||||
links_line = f'🔎 <a href="{DESC_PREFIX}{test_number}/">Инфо</a> | 📌 <a href="{PZK_PREFIX}{test_number}/">Иду</a> | 🔜 <a href="https://t.me/{RESPONDER_BOT_NAME}?start=event_{placeholder_message_id}">Подписка</a>'
|
||||
else:
|
||||
links_line = f'🔎 <a href="{DESC_PREFIX}{test_number}/">Инфо</a>'
|
||||
|
||||
links_line_length = len(links_line)
|
||||
|
||||
# Определяем максимальную длину
|
||||
max_length = MAX_CAPTION_LENGTH # Используем caption для теста
|
||||
|
||||
# Вычисляем доступную длину для текста
|
||||
available_length = max_length - base_text_length - links_line_length - 3
|
||||
if available_length < 0:
|
||||
available_length = 0
|
||||
|
||||
# Обрезаем about до доступной длины
|
||||
if len(test_about) > available_length:
|
||||
test_about = test_about[:available_length-3] + "..."
|
||||
|
||||
# Формируем финальный текст
|
||||
final_text = f"{base_text}\n\n{test_about}\n\n{links_line}"
|
||||
|
||||
# Логируем детали сообщения
|
||||
logger.info("=" * 80)
|
||||
logger.info("ДЕТАЛИ ТЕСТОВОГО СООБЩЕНИЯ:")
|
||||
logger.info("=" * 80)
|
||||
logger.info(f"Длина base_text: {base_text_length} символов")
|
||||
logger.info(f"Длина test_about: {len(test_about)} символов")
|
||||
logger.info(f"Длина links_line: {links_line_length} символов")
|
||||
logger.info(f"Максимальная длина (max_length): {max_length} символов")
|
||||
logger.info(f"Доступная длина для about: {available_length} символов")
|
||||
logger.info(f"Длина final_text: {len(final_text)} символов")
|
||||
logger.info(f"Используется изображение: НЕТ")
|
||||
logger.info("=" * 80)
|
||||
logger.info("ТЕКСТ СООБЩЕНИЯ:")
|
||||
logger.info("=" * 80)
|
||||
logger.info(final_text)
|
||||
logger.info("=" * 80)
|
||||
|
||||
# Создаем бота
|
||||
try:
|
||||
logger.info("Создание объекта Bot...")
|
||||
bot = Bot(token=POSTER_BOT_TOKEN)
|
||||
logger.info("Объект Bot успешно создан")
|
||||
|
||||
# Получаем информацию о боте
|
||||
try:
|
||||
bot_info = await bot.get_me()
|
||||
logger.info(f"Информация о боте:")
|
||||
logger.info(f" ID: {bot_info.id}")
|
||||
logger.info(f" Username: @{bot_info.username}")
|
||||
logger.info(f" First name: {bot_info.first_name}")
|
||||
logger.info(f" Is bot: {bot_info.is_bot}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Не удалось получить информацию о боте: {e}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"ОШИБКА при создании объекта Bot: {e}")
|
||||
logger.error(f" Тип ошибки: {type(e).__name__}")
|
||||
logger.error(f" Все атрибуты: {vars(e)}")
|
||||
return False
|
||||
|
||||
# Публикуем тестовое сообщение
|
||||
try:
|
||||
logger.info("=" * 80)
|
||||
logger.info("ПОПЫТКА ОТПРАВКИ ТЕСТОВОГО СООБЩЕНИЯ")
|
||||
logger.info("=" * 80)
|
||||
logger.info(f"Параметры запроса:")
|
||||
logger.info(f" chat_id: {CHANNEL_ID}")
|
||||
logger.info(f" text_length: {len(final_text)}")
|
||||
logger.info(f" parse_mode: HTML")
|
||||
logger.info(f" disable_notification: {PUBLISH_SILENTLY}")
|
||||
logger.info(f" disable_web_page_preview: True")
|
||||
|
||||
start_time = datetime.now()
|
||||
message = await bot.send_message(
|
||||
chat_id=CHANNEL_ID,
|
||||
text=final_text,
|
||||
parse_mode="HTML",
|
||||
disable_notification=PUBLISH_SILENTLY,
|
||||
disable_web_page_preview=True
|
||||
)
|
||||
end_time = datetime.now()
|
||||
duration = (end_time - start_time).total_seconds()
|
||||
|
||||
logger.info("=" * 80)
|
||||
logger.info("СООБЩЕНИЕ УСПЕШНО ОТПРАВЛЕНО!")
|
||||
logger.info("=" * 80)
|
||||
logger.info(f"Message ID: {message.message_id}")
|
||||
logger.info(f"Chat ID: {message.chat.id}")
|
||||
logger.info(f"Chat type: {message.chat.type}")
|
||||
logger.info(f"Chat title: {message.chat.title if hasattr(message.chat, 'title') else 'N/A'}")
|
||||
logger.info(f"Время отправки: {duration:.2f} секунд")
|
||||
logger.info(f"Дата сообщения: {message.date}")
|
||||
logger.info("=" * 80)
|
||||
|
||||
return True
|
||||
|
||||
except TimedOut as e:
|
||||
logger.error("=" * 80)
|
||||
logger.error("ТАЙМАУТ ПРИ ОТПРАВКЕ СООБЩЕНИЯ!")
|
||||
logger.error("=" * 80)
|
||||
logger.error(f"Тип ошибки: {type(e).__name__}")
|
||||
logger.error(f"Сообщение: {str(e)}")
|
||||
logger.error(f"Все атрибуты ошибки: {vars(e)}")
|
||||
logger.error(f"Полное представление: {repr(e)}")
|
||||
logger.error(f"Параметры запроса:")
|
||||
logger.error(f" chat_id: {CHANNEL_ID}")
|
||||
logger.error(f" text_length: {len(final_text)}")
|
||||
logger.error(f" parse_mode: HTML")
|
||||
return False
|
||||
|
||||
except RetryAfter as e:
|
||||
logger.error("=" * 80)
|
||||
logger.error("ОШИБКА FLOODWAIT (429) ПРИ ОТПРАВКЕ СООБЩЕНИЯ!")
|
||||
logger.error("=" * 80)
|
||||
logger.error(f"Тип ошибки: {type(e).__name__}")
|
||||
logger.error(f"Сообщение: {str(e)}")
|
||||
logger.error(f"Необходимо подождать: {e.retry_after} секунд")
|
||||
logger.error(f"Все атрибуты ошибки: {vars(e)}")
|
||||
logger.error(f"Полное представление: {repr(e)}")
|
||||
return False
|
||||
|
||||
except TelegramError as e:
|
||||
logger.error("=" * 80)
|
||||
logger.error("ОШИБКА TELEGRAM ПРИ ОТПРАВКЕ СООБЩЕНИЯ!")
|
||||
logger.error("=" * 80)
|
||||
logger.error(f"Тип ошибки: {type(e).__name__}")
|
||||
logger.error(f"Сообщение: {str(e)}")
|
||||
logger.error(f"Все атрибуты ошибки: {vars(e)}")
|
||||
logger.error(f"Полное представление: {repr(e)}")
|
||||
logger.error(f"Параметры запроса:")
|
||||
logger.error(f" chat_id: {CHANNEL_ID}")
|
||||
logger.error(f" text_length: {len(final_text)}")
|
||||
logger.error(f" parse_mode: HTML")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error("=" * 80)
|
||||
logger.error("НЕОЖИДАННАЯ ОШИБКА ПРИ ОТПРАВКЕ СООБЩЕНИЯ!")
|
||||
logger.error("=" * 80)
|
||||
logger.error(f"Тип ошибки: {type(e).__name__}")
|
||||
logger.error(f"Сообщение: {str(e)}")
|
||||
logger.error(f"Все атрибуты ошибки: {vars(e) if hasattr(e, '__dict__') else 'N/A'}")
|
||||
logger.error(f"Полное представление: {repr(e)}")
|
||||
import traceback
|
||||
logger.error(f"Трассировка стека:\n{traceback.format_exc()}")
|
||||
return False
|
||||
|
||||
async def main():
|
||||
"""Главная функция"""
|
||||
try:
|
||||
success = await test_telegram_publish()
|
||||
if success:
|
||||
logger.info("=" * 80)
|
||||
logger.info("ТЕСТ ЗАВЕРШЕН УСПЕШНО")
|
||||
logger.info("=" * 80)
|
||||
sys.exit(0)
|
||||
else:
|
||||
logger.error("=" * 80)
|
||||
logger.error("ТЕСТ ЗАВЕРШЕН С ОШИБКОЙ")
|
||||
logger.error("=" * 80)
|
||||
sys.exit(1)
|
||||
except KeyboardInterrupt:
|
||||
logger.warning("Прервано пользователем")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
logger.error(f"Критическая ошибка: {e}")
|
||||
import traceback
|
||||
logger.error(f"Трассировка стека:\n{traceback.format_exc()}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user