Как можно изменить функциональность моего бота-автопостера и парсера, чтобы он сохранял последний пост из указанного канала на компьютер и публиковал его в списке каналов, указанном в файле channels.json? В настоящее время мой парсер сохраняет только одно медиа и текст, и если сообщение содержит больше одного медиа, он загружает только одно фото или видео, а текст не сохраняется.
Вот код парсера:
<pre><code class="python">import os
import json
from telethon.sync import TelegramClient
from telethon.errors import SessionPasswordNeededError
from telethon.tl.types import MessageMediaPhoto, MessageMediaDocument # Убираем все устаревшие импорты
from config import API_ID, API_HASH, PHONE_NUMBER, ADMIN_ID
from handlers.logging import log_error, log_action # Импортируем логирование
# Загружаем данные из last_post.json
def load_last_post():
"""Загружает данные о последнем посте из файла"""
try:
with open('data/last_post.json', 'r', encoding='utf-8') as file:
data = json.load(file)
print("Загружены данные о последнем посте:", data) # Для отладки
return data
except Exception as e:
print(f"Ошибка при загрузке данных о последнем посте: {e}")
return {"channels": {}}
# Сохраняем данные в last_post.json
def save_last_post(data):
"""Сохраняет данные в last_post.json"""
with open('data/last_post.json', 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
async def process_message(message, client, channel_folder):
"""Обработка сообщения, извлечение текста и медиа."""
message_data = {
'message_id': message.id,
'text': "Без текста", # Начальная установка, если текст не н
Чтобы изменить функциональность вашего бота парсера на Telethon так, чтобы он сохранял все медиафайлы и текст последнего поста, а затем публиковал его на указанных каналах из `channels.json`, вам нужно внести несколько изменений в ваш код.
Ниже приведен модифицированный код, который реализует эту функциональность:
```python
import os
import json
from telethon.sync import TelegramClient
from telethon.errors import SessionPasswordNeededError
from telethon.tl.types import MessageMediaPhoto, MessageMediaDocument, MessageMediaVideo
from config import API_ID, API_HASH, PHONE_NUMBER, ADMIN_ID
from handlers.logging import log_error, log_action
# Загружаем данные из last_post.json
def load_last_post():
"""Загружает данные о последнем посте из файла"""
try:
with open('data/last_post.json', 'r', encoding='utf-8') as file:
data = json.load(file)
print("Загружены данные о последнем посте:", data) # Для отладки
return data
except Exception as e:
print(f"Ошибка при загрузке данных о последнем посте: {e}")
return {"channels": {}}
# Сохраняем данные в last_post.json
def save_last_post(data):
"""Сохраняет данные в last_post.json"""
with open('data/last_post.json', 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
async def process_message(message, client, channel_folder):
"""Обработка сообщения, извлечение текста и медиа."""
message_data = {
'message_id': message.id,
'text': message.message if message.message else "Без текста",
'media_files': [] # Список для сохранения медиафайлов
}
# Обработка медиа
if message.media:
# Получаем тип медиа и обрабатываем соответствующим образом
if isinstance(message.media, (MessageMediaPhoto, MessageMediaVideo, MessageMediaDocument)):
media_file = await client.download_media(message.media, file=channel_folder)
if media_file:
message_data['media_files'].append(media_file)
# Сохраняем данные о сообщении
save_last_post(message_data)
return message_data
async def main():
# Ваш код инициализации клиента и получения канала
async with TelegramClient('session_name', API_ID, API_HASH) as client:
# Ваш код для получения канала и обработки сообщений
channel = 'username_of_the_channel'
channel_folder = 'data/' + channel.replace('@', '')
os.makedirs(channel_folder, exist_ok=True)
# Пример получения последнего сообщения из канала
last_message = await client.get_messages(channel, limit=1)
if last_message:
await process_message(last_message[0], client, channel_folder)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
```
### Что было изменено:
1. **Сохранение текста сообщения**: Теперь текст сообщений сохраняется, даже если его нет — в этом случае используется значение "Без текста".
2. **Сохранение медиафайлов**: Добавлен список `media_files`, в который сохраняются все загруженные медиафайлы.
3. **Загрузка всех типов медиа**: Проверяется, является ли `message.media` одним из типов медиа, и в случае успеха загружается медиа и добавляется в список `media_files`.
### Дополнительно
Вы можете также добавить логику для последующей публикации загруженных медиафайлов в каналы, указанные в `channels.json`. Для этого необходимо:
- Загрузить список каналов из файла `channels.json`.
- Реализовать функцию, которая будет отправлять сообщение (включая текст и медиафайлы) в эти каналы.
Если у вас есть вопросы по реализации этой функциональности, не стесняйтесь обращаться!
В ТГ сообщение с несколькими медиафайлами, медиа приходят по сути разными сообщениями и соответственно у тебя проблема с тем что получается парсить только текст с одним медиа потому что на один объект сообщения можно закрепить одно фото. Чтобы сгруппировать фото из одного альбома, ты можешь использовать параметр grouped_id и с помощью него корректно сформировать медиа-группу и спарсить сообщение с несколькими медиа.
Для того чтобы было более понятно, оставил пример кода как достать значение параметра.
from telethon import TelegramClient api_id = 11111111 api_hash = '' client = TelegramClient('123', api_id, api_hash) async def main(): msgs = await client.get_messages(-10000000000, limit=2) print(msgs[0]) print(msgs[0].grouped_id) print(msgs[1].grouped_id) with client: client.loop.run_until_complete(main())
Также если будешь реализовывать бота через прослушивание, то ниже закрепил код для того чтобы сразу одним объектом получать такие альбомы.
from telethon import events @client.on(events.Album) async def handler(event): # Counting how many photos or videos the album has print('Got an album with', len(event), 'items') # Forwarding the album as a whole to some chat event.forward_to(chat) # Printing the caption print(event.text) # Replying to the fifth item in the album await event.messages[4].reply('Cool!')