From 47960abc38b68ac16ee6f96a97157c032273d92f Mon Sep 17 00:00:00 2001 From: gitadmin Date: Sun, 21 Dec 2025 15:55:39 +0300 Subject: [PATCH] =?UTF-8?q?[=D0=92=D0=9E=D0=9B=D0=9A]=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BE=D1=82=D0=BB=D0=B0=D0=B4?= =?UTF-8?q?=D0=BE=D1=87=D0=BD=D1=8B=D0=B9=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF?= =?UTF-8?q?=D1=82=20=D0=B4=D0=BB=D1=8F=20=D0=BB=D0=BE=D0=B2=D0=BB=D0=B8=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D1=87=D0=B8=D0=BD=20=D1=82=D0=B0=D0=B9=D0=BC?= =?UTF-8?q?=D0=B0=D1=83=D1=82=D0=B0=20=D0=B2=20=D1=82=D0=B5=D0=BB=D0=B5?= =?UTF-8?q?=D0=B3=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- volk_telegram_testing.py | 267 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 volk_telegram_testing.py diff --git a/volk_telegram_testing.py b/volk_telegram_testing.py new file mode 100644 index 0000000..5a9c3cb --- /dev/null +++ b/volk_telegram_testing.py @@ -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{test_name}" + base_text_length = len(base_text) + + # Формируем строку ссылок + placeholder_message_id = '1234567890' + if USE_SUBSCRIPTION_BOT: + links_line = f'🔎 Инфо | 📌 Иду | 🔜 Подписка' + else: + links_line = f'🔎 Инфо' + + 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())