Коррекция логики добавления ссылок при [ZILANT] постинге в ТГ
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
+98
-73
@@ -16,7 +16,14 @@ from formatter import get_event_text
|
||||
from telegram import Bot
|
||||
from telegram.error import TelegramError, TimedOut
|
||||
from telegram.request import HTTPXRequest
|
||||
from telegram_relay import get_ptb_base_urls, get_relay_url
|
||||
from telegram_relay import (
|
||||
get_ptb_base_urls,
|
||||
get_relay_url,
|
||||
EDIT_LINKS_INITIAL_DELAY_SEC,
|
||||
EDIT_LINKS_MAX_ATTEMPTS,
|
||||
EDIT_LINKS_RETRY_INTERVAL_SEC,
|
||||
published_text_has_links,
|
||||
)
|
||||
from season_links import subscription_start_link
|
||||
|
||||
# Настройка anyio для правильной работы в отдельном потоке
|
||||
@@ -146,6 +153,88 @@ async def download_image(image_url, httpx_client):
|
||||
logger.error(f"Ошибка при скачивании изображения {image_url}: {e}")
|
||||
raise
|
||||
|
||||
|
||||
async def _edit_post_add_links(bot, message_id, message_has_image, final_text, vk_post_id):
|
||||
"""
|
||||
Второй шаг публикации: editMessageCaption/Text со ссылками.
|
||||
Повторяет попытку, пока в ответе API нет href= (защита от гонки после sendPhoto).
|
||||
"""
|
||||
await asyncio.sleep(EDIT_LINKS_INITIAL_DELAY_SEC)
|
||||
|
||||
for attempt in range(1, EDIT_LINKS_MAX_ATTEMPTS + 1):
|
||||
try:
|
||||
if message_has_image:
|
||||
edited = await bot.edit_message_caption(
|
||||
chat_id=CHANNEL_ID,
|
||||
message_id=message_id,
|
||||
caption=final_text,
|
||||
parse_mode='HTML',
|
||||
)
|
||||
published_text = edited.caption or ""
|
||||
else:
|
||||
edited = await bot.edit_message_text(
|
||||
chat_id=CHANNEL_ID,
|
||||
message_id=message_id,
|
||||
text=final_text,
|
||||
parse_mode='HTML',
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
published_text = edited.text or ""
|
||||
|
||||
if published_text_has_links(published_text):
|
||||
logger.info(
|
||||
f"Ссылки добавлены для записи VK ID {vk_post_id} "
|
||||
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS})"
|
||||
)
|
||||
return True
|
||||
|
||||
logger.warning(
|
||||
f"editMessage* ok, но href= не найден в ответе "
|
||||
f"(попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) для VK ID {vk_post_id}"
|
||||
)
|
||||
except TimedOut as e:
|
||||
if attempt >= EDIT_LINKS_MAX_ATTEMPTS:
|
||||
logger.error(
|
||||
f"Таймаут редактирования ссылок для VK ID {vk_post_id} "
|
||||
f"после {EDIT_LINKS_MAX_ATTEMPTS} попыток: {e}"
|
||||
)
|
||||
return False
|
||||
logger.warning(
|
||||
f"Таймаут edit (попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) "
|
||||
f"для VK ID {vk_post_id}, повтор"
|
||||
)
|
||||
except TelegramError as e:
|
||||
if hasattr(e, 'retry_after') or '429' in str(e):
|
||||
raise RetryAfterException(getattr(e, 'retry_after', 60))
|
||||
err = str(e).lower()
|
||||
if "not modified" in err:
|
||||
logger.warning(
|
||||
f"message is not modified (попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) "
|
||||
f"для VK ID {vk_post_id} — повтор"
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
f"Ошибка edit ссылок (попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) "
|
||||
f"для VK ID {vk_post_id}: {e}"
|
||||
)
|
||||
except RetryAfterException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
f"Неожиданная ошибка edit ссылок (попытка {attempt}/{EDIT_LINKS_MAX_ATTEMPTS}) "
|
||||
f"для VK ID {vk_post_id}: {e}"
|
||||
)
|
||||
|
||||
if attempt < EDIT_LINKS_MAX_ATTEMPTS:
|
||||
await asyncio.sleep(EDIT_LINKS_RETRY_INTERVAL_SEC)
|
||||
|
||||
logger.error(
|
||||
f"Не удалось добавить строку ссылок для VK ID {vk_post_id} "
|
||||
f"после {EDIT_LINKS_MAX_ATTEMPTS} попыток"
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
async def publish_to_tg(vk_post_id):
|
||||
"""Публикация одной записи по VK post ID"""
|
||||
logger.info(f"Запуск публикации для записи VK ID {vk_post_id}")
|
||||
@@ -429,78 +518,14 @@ async def publish_to_tg(vk_post_id):
|
||||
links_line = " | ".join(updated_links)
|
||||
final_text = f"{text}\n\n{links_line}"
|
||||
|
||||
await asyncio.sleep(2) # задержка между обращениями к телеграм
|
||||
|
||||
# Редактируем сообщение, добавляя ссылки
|
||||
# Используем message_has_image для определения типа сообщения
|
||||
# Если было отправлено изображение, редактируем caption, иначе - текст
|
||||
if message_has_image:
|
||||
# Сообщение с изображением - редактируем caption с повторными попытками
|
||||
edit_success = False
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
await bot.edit_message_caption(
|
||||
chat_id=CHANNEL_ID,
|
||||
message_id=message_id,
|
||||
caption=final_text,
|
||||
parse_mode='HTML'
|
||||
)
|
||||
edit_success = True
|
||||
logger.info(f"Caption успешно отредактирован для записи VK ID {vk_post_id}")
|
||||
break # Успешное редактирование, выходим из цикла
|
||||
except TimedOut as e:
|
||||
if attempt < max_retries:
|
||||
logger.warning(f"Таймаут при редактировании caption (попытка {attempt}/{max_retries}) для записи VK ID {vk_post_id}. Повтор через {retry_interval} секунд...")
|
||||
await asyncio.sleep(retry_interval)
|
||||
else:
|
||||
logger.warning(f"Таймаут при редактировании caption после {max_retries} попыток для записи VK ID {vk_post_id}. Сообщение опубликовано, но без ссылок.")
|
||||
# Не критичная ошибка - сообщение уже опубликовано
|
||||
break
|
||||
except TelegramError as e:
|
||||
if hasattr(e, 'retry_after') or '429' in str(e):
|
||||
retry_after = getattr(e, 'retry_after', 60)
|
||||
raise RetryAfterException(retry_after)
|
||||
# Не критичная ошибка - сообщение уже опубликовано
|
||||
logger.warning(f"Не удалось отредактировать caption для записи VK ID {vk_post_id}: {type(e).__name__}: {e}. Сообщение опубликовано, но без ссылок.")
|
||||
break
|
||||
except Exception as e:
|
||||
# Не критичная ошибка - сообщение уже опубликовано
|
||||
logger.warning(f"Неожиданная ошибка при редактировании caption для записи VK ID {vk_post_id}: {type(e).__name__}: {e}. Сообщение опубликовано, но без ссылок.")
|
||||
break
|
||||
else:
|
||||
# Текстовое сообщение - редактируем текст с повторными попытками
|
||||
edit_success = False
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
await bot.edit_message_text(
|
||||
chat_id=CHANNEL_ID,
|
||||
message_id=message_id,
|
||||
text=final_text,
|
||||
parse_mode='HTML',
|
||||
disable_web_page_preview=True
|
||||
)
|
||||
edit_success = True
|
||||
logger.info(f"Текст успешно отредактирован для записи VK ID {vk_post_id}")
|
||||
break # Успешное редактирование, выходим из цикла
|
||||
except TimedOut as e:
|
||||
if attempt < max_retries:
|
||||
logger.warning(f"Таймаут при редактировании текста (попытка {attempt}/{max_retries}) для записи VK ID {vk_post_id}. Повтор через {retry_interval} секунд...")
|
||||
await asyncio.sleep(retry_interval)
|
||||
else:
|
||||
logger.warning(f"Таймаут при редактировании текста после {max_retries} попыток для записи VK ID {vk_post_id}. Сообщение опубликовано, но без ссылок.")
|
||||
# Не критичная ошибка - сообщение уже опубликовано
|
||||
break
|
||||
except TelegramError as e:
|
||||
if hasattr(e, 'retry_after') or '429' in str(e):
|
||||
retry_after = getattr(e, 'retry_after', 60)
|
||||
raise RetryAfterException(retry_after)
|
||||
# Не критичная ошибка - сообщение уже опубликовано
|
||||
logger.warning(f"Не удалось отредактировать текст для записи VK ID {vk_post_id}: {type(e).__name__}: {e}. Сообщение опубликовано, но без ссылок.")
|
||||
break
|
||||
except Exception as e:
|
||||
# Не критичная ошибка - сообщение уже опубликовано
|
||||
logger.warning(f"Неожиданная ошибка при редактировании текста для записи VK ID {vk_post_id}: {type(e).__name__}: {e}. Сообщение опубликовано, но без ссылок.")
|
||||
break
|
||||
if not await _edit_post_add_links(
|
||||
bot, message_id, message_has_image, final_text, vk_post_id
|
||||
):
|
||||
logger.error(
|
||||
f"Запись VK ID {vk_post_id}: сообщение отправлено (id={message_id}), "
|
||||
f"но ссылки не добавлены — published_in_tg не обновляем"
|
||||
)
|
||||
return False
|
||||
|
||||
await asyncio.sleep(2) # задержка между обращениями к телеграм
|
||||
|
||||
|
||||
Reference in New Issue
Block a user