- Улучшенная проверка на дубли для telegram
This commit is contained in:
@@ -31,17 +31,7 @@ class TelegramNewsClient:
|
||||
if message.text:
|
||||
# Если указан топик, фильтруем только сообщения из этого топика
|
||||
if self.config['topic_id']:
|
||||
is_in_topic = False
|
||||
|
||||
# В Telegram топиках все сообщения имеют reply_to_msg_id равный ID первого сообщения топика
|
||||
if hasattr(message, 'reply_to_msg_id') and message.reply_to_msg_id:
|
||||
# Сообщение принадлежит топику если его reply_to_msg_id равен topic_id
|
||||
if message.reply_to_msg_id == self.config['topic_id']:
|
||||
is_in_topic = True
|
||||
|
||||
# Также проверяем, если само сообщение является первым сообщением топика
|
||||
elif message.id == self.config['topic_id']:
|
||||
is_in_topic = True
|
||||
is_in_topic = self._is_message_in_topic(message, self.config['topic_id'])
|
||||
|
||||
self.logger.debug(f"Сообщение ID {message.id}, reply_to_msg_id={getattr(message, 'reply_to_msg_id', None)}, нужен топик {self.config['topic_id']}, в топике: {is_in_topic}")
|
||||
|
||||
@@ -57,9 +47,82 @@ class TelegramNewsClient:
|
||||
if title:
|
||||
titles.append(title)
|
||||
|
||||
self.logger.debug(f"Извлечено {len(titles)} заголовков из Telegram сообщений")
|
||||
self.logger.info(f"Извлечено {len(titles)} заголовков из Telegram сообщений: {titles[:5]}{'...' if len(titles) > 5 else ''}")
|
||||
return messages, titles
|
||||
|
||||
def _is_message_in_topic(self, message, topic_id):
|
||||
"""Проверка принадлежности сообщения к топику с улучшенной логикой"""
|
||||
# Само сообщение является первым сообщением топика
|
||||
if message.id == topic_id:
|
||||
return True
|
||||
|
||||
# Проверяем прямой ответ на сообщение топика
|
||||
if hasattr(message, 'reply_to_msg_id') and message.reply_to_msg_id:
|
||||
if message.reply_to_msg_id == topic_id:
|
||||
return True
|
||||
|
||||
# Дополнительная проверка: может быть это ответ на ответ в топике
|
||||
# В некоторых случаях Telegram API может показывать вложенную структуру
|
||||
try:
|
||||
# Получаем информацию о сообщении, на которое отвечали
|
||||
reply_to = message.reply_to
|
||||
if reply_to and hasattr(reply_to, 'reply_to_msg_id'):
|
||||
# Рекурсивно проверяем цепочку ответов
|
||||
current_reply_id = reply_to.reply_to_msg_id
|
||||
depth = 0
|
||||
while current_reply_id and depth < 10: # Ограничиваем глубину для безопасности
|
||||
if current_reply_id == topic_id:
|
||||
return True
|
||||
# В реальном случае здесь нужно было бы получать сообщение по ID
|
||||
# Но это может быть слишком дорого по API запросам
|
||||
break
|
||||
except Exception as e:
|
||||
self.logger.debug(f"Ошибка при проверке вложенной структуры ответов: {e}")
|
||||
|
||||
return False
|
||||
|
||||
def _check_duplicate_news(self, topic_title, tg_titles, tg_messages):
|
||||
"""Улучшенная проверка дубликатов новостей с детальным логированием"""
|
||||
# Проверяем точное совпадение с заголовками
|
||||
title_exists = topic_title in tg_titles
|
||||
if title_exists:
|
||||
self.logger.debug(f"Найдено точное совпадение заголовка: '{topic_title}'")
|
||||
return True
|
||||
|
||||
# Проверяем частичные совпадения в заголовках (нормализованные)
|
||||
normalized_topic = topic_title.lower().strip()
|
||||
for existing_title in tg_titles:
|
||||
normalized_existing = existing_title.lower().strip()
|
||||
if normalized_topic == normalized_existing:
|
||||
self.logger.debug(f"Найдено нормализованное совпадение заголовка: '{topic_title}' == '{existing_title}'")
|
||||
return True
|
||||
|
||||
# Проверяем наличие заголовка как части структурированного сообщения
|
||||
# Ищем точное совпадение в формате "### Заголовок\t"
|
||||
formatted_title = f"### {topic_title}\t"
|
||||
for message in tg_messages:
|
||||
if message and formatted_title in message:
|
||||
self.logger.debug(f"Найдено совпадение форматированного заголовка в сообщении: '{formatted_title}'")
|
||||
return True
|
||||
|
||||
# Дополнительная проверка: ищем заголовок в начале сообщений
|
||||
for message in tg_messages:
|
||||
if message:
|
||||
message_lines = message.strip().split('\n')
|
||||
if message_lines:
|
||||
first_line = message_lines[0].strip()
|
||||
# Убираем префиксы и сравниваем
|
||||
import re
|
||||
cleaned_first_line = re.sub(r'^[#*\s\t]+', '', first_line)
|
||||
cleaned_first_line = re.sub(r'\t.*$', '', cleaned_first_line).strip()
|
||||
|
||||
if cleaned_first_line.lower() == normalized_topic:
|
||||
self.logger.debug(f"Найдено совпадение в первой строке сообщения: '{cleaned_first_line}' == '{topic_title}'")
|
||||
return True
|
||||
|
||||
self.logger.debug(f"Новость '{topic_title}' не найдена среди {len(tg_titles)} существующих заголовков")
|
||||
return False
|
||||
|
||||
def _extract_title_from_message(self, message_text):
|
||||
"""Извлечение заголовка из текста сообщения"""
|
||||
import re
|
||||
@@ -180,14 +243,14 @@ class TelegramNewsClient:
|
||||
# Фильтруем новости для публикации
|
||||
list_for_public = []
|
||||
for topic_id, topic_title in news_list:
|
||||
# Проверяем по заголовкам и по полному тексту сообщений
|
||||
title_exists = any(topic_title == title for title in tg_titles)
|
||||
text_contains = any(topic_title in (msg or '') for msg in tg_messages)
|
||||
# Улучшенная проверка дубликатов
|
||||
is_duplicate = self._check_duplicate_news(topic_title, tg_titles, tg_messages)
|
||||
|
||||
if not title_exists and not text_contains:
|
||||
if not is_duplicate:
|
||||
list_for_public.append((topic_id, topic_title))
|
||||
self.logger.debug(f"Новость '{topic_title}' добавлена в список для публикации")
|
||||
else:
|
||||
self.logger.debug(f"Новость '{topic_title}' уже есть в Telegram (title_exists={title_exists}, text_contains={text_contains})")
|
||||
self.logger.debug(f"Новость '{topic_title}' уже существует в Telegram, пропускаем")
|
||||
|
||||
if not list_for_public:
|
||||
self.logger.warning("Новостей для публикации в Telegram нет")
|
||||
|
Reference in New Issue
Block a user