TypeError: Can't instantiate abstract class InputFile without an implementation for abstract method 'read'
import asyncio
from aiogram import Bot
from telethon import TelegramClient, events
from sqlalchemy.ext.asyncio import AsyncSession
from app.database.requests import get_channels, get_subscribed_users, get_subscribed_user_ids, get_user_by_internal_id
from aiogram.types import InputFile
import os, io
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO) # или DEBUG для более подробного вывода
api_id = 'апи айди' # Получите на my.telegram.org
api_hash = 'хэш' # Получите на my.telegram.org
phone_number = 'фон' # Ваш номер телефона для авторизации
# Создаем клиент Telethon
telethon_client = TelegramClient('session_name', api_id, api_hash)
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO) # или DEBUG для более подробного вывода
async def setup_channel_handlers(channels, bot: Bot):
for channel in channels:
try:
# Получаем объект канала по имени
channel_entity = await telethon_client.get_entity(channel)
logging.info(f"Отслеживаем канал: {channel_entity.title} (ID: {channel_entity.id})")
@telethon_client.on(events.NewMessage(chats=channel_entity))
async def handler(event):
logging.info(f"Новое сообщение получено в канале {event.chat_id}")
# Проверяем, есть ли текст в сообщении
message_text = event.message.text or ""
logging.debug(f"Текст сообщения: {message_text}")
# Проверяем, содержит ли сообщение изображение или другое медиа
if event.message.media:
# Если есть медиа, скачиваем его
media_file = await event.message.download_media()
logging.info(f"Медиафайл скачан: {media_file}")
# Открываем файл и создаем поток
with open(media_file, 'rb') as file:
photo = InputFile(media_file, filename=os.path.basename(media_file))
logging.info(f"Готовим отправку фото: {media_file}")
# Получаем название канала
channel_name = event.chat.username or f"Channel ID: {event.chat_id}"
logging.info(f"Название канала: {channel_name}")
# Формируем текст с источником
caption = f"\n\nИсточник: @{channel_name}" if event.chat.username else f"\n\nИсточник: {channel_name}"
full_message = f"*Рассылка новостей*\n\n{message_text}{caption}" if message_text else caption
logging.debug(f"Полное сообщение для отправки: {full_message}")
# Получаем список пользователей, подписанных на канал
subscribed_users = await get_subscribed_users(channel_tg_id=channel_entity.id)
logging.info(f"Подписанные пользователи: {subscribed_users}")
# Отправляем сообщение каждому пользователю
for user in subscribed_users:
try:
if event.message.media:
# Если есть медиафайл, отправляем его вместе с текстом
await bot.send_photo(user.tg_id,photo, caption=full_message, parse_mode='Markdown')
logging.info(f"Медиафайл отправлен пользователю {user.tg_id}")
else:
# Если медиафайла нет, просто отправляем текст
await bot.send_message(user.tg_id, full_message, parse_mode='Markdown')
logging.info(f"Сообщение отправлено пользователю {user.tg_id}")
except Exception as e:
logging.error(f"Ошибка при отправке сообщения пользователю {user.tg_id}: {e}")
except Exception as e:
logging.error(f"Ошибка при получении объекта канала {channel}: {e}")
# Функция для запуска Telethon в фоновом режиме
async def start_telethon(session: AsyncSession, bot: Bot):
# Запуск клиента Telethon
await telethon_client.start(phone=phone_number)
# Получаем список каналов из базы данных
channels = await get_channels(session)
# Настраиваем обработку сообщений для каждого канала
await setup_channel_handlers(channels, bot)
# Ожидание новых сообщений
await telethon_client.run_until_disconnected()
нужна помощь, вкратце этот хэндлер ловит сообщения из других тг каналов и пересылает сообщения обратно юзеру в бота, проблема заключается в том что я хочу что бы бот пересылал также фотографии и др медиа файлы помимо текста, но когда тг канал приходит сообщение с фотографией или другим медиа фалом, он скачивает фотку и не пересылает говорит вот какую ошибку. Код написан на Aiogram, Python 3.12.6
File "C:\Users\PC\Desktop\bot\real_digest_bot\app\telethon_handlers.py", line 51, in handler
photo = InputFile(media_file, filename=os.path.basename(media_file))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Can't instantiate abstract class InputFile without an implementation for abstract method 'read'
Ответы (1 шт):
Автор решения: CrazyElf
→ Ссылка
Ну там же написано в ошибке, что это абстрактный класс. Используйте одну из его конкретных реализаций, описанных в документации. Например, FSInputFile
:
from aiogram.types.input_file import FSInputFile
photo = FSInputFile(media_file, filename=os.path.basename(media_file))