fix: get_message_link

fix: работа с изменёнными сообщениями
теперь новый текст тоже проверятся на совпадение
и соответсвенно пересылвается или удаляется
This commit is contained in:
Евгений Панков 2025-08-21 01:00:34 +03:00
parent 5a4fe0ae94
commit 0055684b34

117
main.py
View File

@ -2,7 +2,7 @@
# from __future__ import annotations
from telethon import TelegramClient, events
from telethon.tl.types import PeerUser, PeerChat, PeerChannel, Message
from telethon.tl.types import PeerUser, PeerChat, Chat, PeerChannel, Channel, Message
import re
import os
import json
@ -159,6 +159,39 @@ async def prepare_entities(target_groups: list) -> list:
print(f"Неизвестная ошибка при обработке {item}: {e}")
async def get_message_link(client, message):
"""
Генерирует ссылку на сообщение вида https://t.me/username/123 или https://t.me/c/123456789/123
Работает с любыми чатами: личка, группа, канал (публичный/приватный).
"""
msg_id = message.id
# Шаг 1: Пытаемся использовать message.chat, если он загружен и имеет username
if message.chat and getattr(message.chat, 'username', None):
return f"https://t.me/{message.chat.username}/{msg_id}"
# Шаг 2: Используем peer_id для получения сущности
try:
chat = await client.get_entity(message.peer_id)
except Exception as e:
print(f"Failed to get entity from peer_id: {e}")
return None
# Шаг 3: Строим ссылку
if getattr(chat, 'username', None):
return f"https://t.me/{chat.username}/{msg_id}"
# Для приватных чатов и каналов: используем формат t.me/c/{id}/{msg_id}
chat_id = str(chat.id)
if isinstance(chat, (Channel, Chat)) and chat_id.startswith('-100'):
base_id = chat_id[4:] # Убираем -100
return f"https://t.me/c/{base_id}/{msg_id}"
# На всякий случай (редкий случай)
return f"https://t.me/c/{chat_id}/{msg_id}"
async def forward_to_targets(
message: Message,
targets: Optional[list[str | int]] = None,
@ -172,7 +205,7 @@ async def forward_to_targets(
if source_reply_to_msg_id and (forwarded_info:=source_messages.get(str(source_reply_to_msg_id))):
for str_chat_id, target_msg_id in forwarded_info['forwarded_msg_id'].items():
if str_chat_id == str(entity.id):
link = await client.get_message_link(message)
link = await get_message_link(message)
text = f'Переслано из [{message.chat.title}]({link})\n{message.text}'
new_msg = await client.send_message(str_chat_id, text, reply_to=target_msg_id, parse_mode='markdown')
else:
@ -237,45 +270,55 @@ async def handler_NewMessages(event: events.NewMessage.Event):
@client.on(events.MessageEdited(chats=source_channel_username))
async def handler_edited(event: events.MessageEdited.Event):
stored_m_info = source_messages.get(str(event.message.id))
if not stored_m_info:
if check(event.message.text):
log.info(f"📝 Изменённое с новым триггером, пересылаю: {shorten(event.message.text)}")
await forward_to_targets(event.message)
if stored_m_info and stored_m_info['text'] != event.message.text:
log.info(f"📝 Сообщение изменено: {shorten(stored_m_info['text'])}{shorten(event.message.text)}")
# Редактируем пересланное сообщение
for str_chat_id, msg_id in stored_m_info['forwarded_msg_id'].items():
chat_id = int(str_chat_id)
# Получаем ID последнего сообщения в целевом чате
last_msg_id = last_known_msg_id.get(str_chat_id)
if not last_msg_id:
last_msg_id = await update_last_msg_id(chat_id)
log.debug(f'chat_id={chat_id}, stored_msg_id={msg_id}, last_msg_id_on_channel={last_msg_id}')
# Проверяем, является ли наше пересланное сообщение последним
if msg_id == last_msg_id:
# Это последнее сообщение — можно удалить и переслать заново
await forward_to_targets(event.message, targets=[chat_id])
if not check(event.message.text):
log.info(f"📝 Сообщение изменено, не попадает в фильтр - удаляю: {shorten(stored_m_info['text'])}{shorten(event.message.text)}")
for str_chat_id, msg_id in stored_m_info['forwarded_msg_id'].items():
chat_id = int(str_chat_id)
await client.delete_messages(chat_id, msg_id)
log.info(f"🔁 {chat_id} Сообщение было последним → Заменено")
else:
# Не последнее → отправляем изменённый текст как ответ
new_msg = await client.send_message(
chat_id,
f"🔄 Текст изменён:\n{event.message.text}",
reply_to=stored_m_info['forwarded_msg_id'][str_chat_id]
)
# Запоминаем пересланные данные сообщения
sm = source_messages.get(str(event.message.id))
if not sm:
source_messages[str(event.message.id)] = {
'text': event.message.text,
'timestamp': event.message.date.timestamp(),
'forwarded_msg_id': {str(new_msg.chat.id): new_msg.id}
}
else:
log.info(f"📝 Сообщение изменено: {shorten(stored_m_info['text'])}{shorten(event.message.text)}")
# Редактируем пересланное сообщение
for str_chat_id, msg_id in stored_m_info['forwarded_msg_id'].items():
chat_id = int(str_chat_id)
# Получаем ID последнего сообщения в целевом чате
last_msg_id = last_known_msg_id.get(str_chat_id)
if not last_msg_id:
last_msg_id = await update_last_msg_id(chat_id)
log.debug(f'chat_id={chat_id}, stored_msg_id={msg_id}, last_msg_id_on_channel={last_msg_id}')
# Проверяем, является ли наше пересланное сообщение последним
if msg_id == last_msg_id:
# Это последнее сообщение — можно удалить и переслать заново
await forward_to_targets(event.message, targets=[chat_id])
await client.delete_messages(chat_id, msg_id)
log.info(f"🔁 {chat_id} Сообщение было последним → Заменено")
else:
sm['text'] = event.message.text
sm['timestamp'] = event.message.date.timestamp()
sm['forwarded_msg_id'][str(new_msg.chat.id)] = new_msg.id
# Обновляем последние известные id для канала
last_known_msg_id[str(new_msg.chat.id)] = new_msg.id
# Не последнее → отправляем изменённый текст как ответ
new_msg = await client.send_message(
chat_id,
f"🔄 Текст изменён:\n{event.message.text}",
reply_to=stored_m_info['forwarded_msg_id'][str_chat_id]
)
# Запоминаем пересланные данные сообщения
sm = source_messages.get(str(event.message.id))
if not sm:
source_messages[str(event.message.id)] = {
'text': event.message.text,
'timestamp': event.message.date.timestamp(),
'forwarded_msg_id': {str(new_msg.chat.id): new_msg.id}
}
else:
sm['text'] = event.message.text
sm['timestamp'] = event.message.date.timestamp()
sm['forwarded_msg_id'][str(new_msg.chat.id)] = new_msg.id
# Обновляем последние известные id для канала
last_known_msg_id[str(new_msg.chat.id)] = new_msg.id
log.info(f"💬 {chat_id} Сообщение не последнее → Отправлен ответ")
log.info(f"💬 {chat_id} Сообщение не последнее → Отправлен ответ")
@client.on(events.MessageDeleted(chats=source_channel_username))