first work version
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import logging
|
||||
from pyrogram import Client, errors
|
||||
from pyrogram.types import Message
|
||||
from config import get_settings
|
||||
import base64
|
||||
import os
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
settings = get_settings()
|
||||
|
||||
class TelegramClient:
|
||||
def __init__(self):
|
||||
if settings["session_string"]:
|
||||
self.client = Client(
|
||||
name="pyro_bridge",
|
||||
session_string=settings["session_string"],
|
||||
api_id=settings["tg_api_id"],
|
||||
api_hash=settings["tg_api_hash"],
|
||||
in_memory=True
|
||||
)
|
||||
else:
|
||||
self.client = Client(
|
||||
name="pyro_bridge",
|
||||
api_id=settings["tg_api_id"],
|
||||
api_hash=settings["tg_api_hash"],
|
||||
workdir=settings["session_path"],
|
||||
in_memory=True
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
if not self.client.is_connected:
|
||||
await self.client.start()
|
||||
logger.info("Telegram client connected")
|
||||
|
||||
async def stop(self):
|
||||
if self.client.is_connected:
|
||||
await self.client.stop()
|
||||
logger.info("Telegram client disconnected")
|
||||
|
||||
async def _parse_message(self, message: Message) -> dict:
|
||||
# Extract text from different sources
|
||||
text = message.text or ""
|
||||
|
||||
# Try to get caption for media messages
|
||||
if not text and hasattr(message, "caption"):
|
||||
text = message.caption or ""
|
||||
|
||||
# Try to get text from other attributes
|
||||
if not text and hasattr(message, "action"):
|
||||
text = str(message.action) # For service messages
|
||||
|
||||
# Parse media and add video markers
|
||||
media = []
|
||||
if message.media:
|
||||
media_obj = message.media
|
||||
if hasattr(message, "video"):
|
||||
media.append(await self._parse_media(message.video))
|
||||
else:
|
||||
if isinstance(media_obj, list):
|
||||
for m in media_obj:
|
||||
media.append(await self._parse_media(m))
|
||||
elif hasattr(media_obj, "photo"):
|
||||
media.append(await self._parse_media(media_obj.photo))
|
||||
else:
|
||||
media.append(await self._parse_media(media_obj))
|
||||
|
||||
video_count = sum(1 for m in media if m.get("type") == "video")
|
||||
if video_count > 0:
|
||||
text = f"[{'Video' if video_count == 1 else f'{video_count} Videos'}] {text}" if text else f"[{'Video' if video_count == 1 else f'{video_count} Videos'}]"
|
||||
|
||||
# Always add reactions if present
|
||||
reactions_text = ""
|
||||
if getattr(message, "reactions", None):
|
||||
reactions_text = "\nReactions: " + ", ".join(
|
||||
f"{r.emoji}({r.count})"
|
||||
for r in message.reactions.reactions
|
||||
)
|
||||
text += reactions_text
|
||||
|
||||
return {
|
||||
"id": message.id,
|
||||
"date": message.date.isoformat(),
|
||||
"text": text,
|
||||
"media": media,
|
||||
"views": message.views or 0,
|
||||
"reactions": [r.emoji for r in message.reactions.reactions] if getattr(message, "reactions", None) else []
|
||||
}
|
||||
|
||||
async def _parse_media(self, media_obj) -> dict:
|
||||
# Handle different media types
|
||||
media_type = media_obj.__class__.__name__.lower()
|
||||
file_id = getattr(media_obj, "file_id", "")
|
||||
thumbnail_base64 = None
|
||||
|
||||
# Special cases
|
||||
if media_type == "photofile":
|
||||
file_id = getattr(media_obj, "photo_file_id", file_id)
|
||||
elif media_type == "webpage":
|
||||
return {"type": "webpage", "url": getattr(media_obj, "url", "")}
|
||||
elif media_type == "video":
|
||||
# Download and encode thumbnail
|
||||
if media_obj.thumbs:
|
||||
try:
|
||||
thumb_path = await self.client.download_media(media_obj.thumbs[0].file_id)
|
||||
with open(thumb_path, "rb") as image_file:
|
||||
thumbnail_base64 = base64.b64encode(image_file.read()).decode("utf-8")
|
||||
os.remove(thumb_path)
|
||||
except Exception as e:
|
||||
logger.error(f"Thumbnail error: {e.__class__.__name__} - {str(e)}")
|
||||
|
||||
return {
|
||||
"type": "video",
|
||||
"url": file_id,
|
||||
"size": media_obj.file_size,
|
||||
"duration": media_obj.duration,
|
||||
"thumbnail": thumbnail_base64
|
||||
}
|
||||
|
||||
return {
|
||||
"type": media_type,
|
||||
"url": str(file_id),
|
||||
"size": getattr(media_obj, "file_size", None),
|
||||
"thumbnail": thumbnail_base64
|
||||
}
|
||||
|
||||
async def get_post(self, channel: str, post_id: int) -> dict:
|
||||
try:
|
||||
message = await self.client.get_messages(
|
||||
chat_id=channel,
|
||||
message_ids=post_id
|
||||
)
|
||||
if not message:
|
||||
raise ValueError("Message not found")
|
||||
|
||||
# Debug raw message structure
|
||||
print("Raw message object: %s", message)
|
||||
print("Message attributes: %s", dir(message))
|
||||
print("Message media type: %s", type(message.media) if message.media else None)
|
||||
|
||||
return await self._parse_message(message)
|
||||
except errors.RPCError as e:
|
||||
logger.error(f"Telegram API error: {e.__class__.__name__} - {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Unexpected error in get_post: {str(e)}")
|
||||
raise
|
||||
Reference in New Issue
Block a user