Skip to content

Commit 3ed791a

Browse files
authored
Merge pull request chigwell#132 from artgas1/feat/media-flag-listings
feat: surface attached media in get_history / get_messages listings
2 parents 4d86231 + 33b4ca1 commit 3ed791a

1 file changed

Lines changed: 60 additions & 1 deletion

File tree

‎telegram_mcp/tools/messages.py‎

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,60 @@
33
from telegram_mcp.runtime import *
44

55

6+
def get_media_label(msg) -> str:
7+
"""Short label of attached media for a message, or "" if none.
8+
9+
The media object is already present on the fetched message (msg.media /
10+
msg.photo / msg.document etc.) — no extra API call needed. Surfacing it in
11+
listings prevents the classic miss where a photo/file WITH a caption shows
12+
up looking like a plain text message (Telethon puts the caption in
13+
msg.message but the media stays in msg.media).
14+
"""
15+
try:
16+
# стикер/голос/видео/аудио/гиф — это тоже document, поэтому проверяем их РАНЬШЕ document
17+
sticker = getattr(msg, "sticker", None)
18+
if sticker is not None:
19+
alt = ""
20+
for attr in getattr(sticker, "attributes", []) or []:
21+
a = getattr(attr, "alt", None)
22+
if a:
23+
alt = a
24+
break
25+
return f"sticker {alt}".strip()
26+
if getattr(msg, "photo", None) is not None:
27+
return "photo"
28+
if getattr(msg, "voice", None) is not None:
29+
return "voice"
30+
if getattr(msg, "video_note", None) is not None:
31+
return "video_note"
32+
if getattr(msg, "video", None) is not None:
33+
return "video"
34+
if getattr(msg, "audio", None) is not None:
35+
return "audio"
36+
if getattr(msg, "gif", None) is not None:
37+
return "gif"
38+
if getattr(msg, "document", None) is not None:
39+
name = None
40+
f = getattr(msg, "file", None)
41+
if f is not None:
42+
name = getattr(f, "name", None)
43+
return f"document: {name}" if name else "document"
44+
if getattr(msg, "contact", None) is not None:
45+
return "contact"
46+
if getattr(msg, "geo", None) is not None:
47+
return "geo"
48+
if getattr(msg, "poll", None) is not None:
49+
return "poll"
50+
# web-превью ссылки — это не вложение, не флагуем
51+
if getattr(msg, "web_preview", None) is not None:
52+
return ""
53+
if getattr(msg, "media", None) is not None:
54+
return "media"
55+
return ""
56+
except Exception:
57+
return ""
58+
59+
660
@mcp.tool(annotations=ToolAnnotations(title="Get Messages", openWorldHint=True, readOnlyHint=True))
761
@with_account(readonly=True)
862
@validate_id("chat_id")
@@ -34,9 +88,11 @@ async def get_messages(
3488

3589
engagement_info = get_engagement_info(msg)
3690
safe_text = sanitize_user_content(msg.message).replace("\n", "\\n")
91+
media_label = get_media_label(msg)
92+
media_info = f" | 📎 {media_label}" if media_label else ""
3793

3894
lines.append(
39-
f"ID: {msg.id} | {sender_name} | Date: {msg.date}{reply_info}{engagement_info} | Message: {safe_text}"
95+
f"ID: {msg.id} | {sender_name} | Date: {msg.date}{reply_info}{engagement_info}{media_info} | Message: {safe_text}"
4096
)
4197
return "\n".join(lines)
4298
except Exception as e:
@@ -1192,6 +1248,9 @@ async def get_history(chat_id: Union[int, str], limit: int = 100, account: str =
11921248
reply_to_id = getattr(msg.reply_to, "reply_to_msg_id", None) if msg.reply_to else None
11931249
if reply_to_id:
11941250
record["reply_to"] = reply_to_id
1251+
media_label = get_media_label(msg)
1252+
if media_label:
1253+
record["media"] = media_label
11951254
records.append(record)
11961255
return format_tool_result(records)
11971256
except Exception as e:

0 commit comments

Comments
 (0)