Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 32 additions & 14 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,24 @@ def get_entity_type(entity: Any) -> str:
return type(entity).__name__


def get_marked_id(entity: Any) -> int:
"""Return Telethon-compatible marked ID for any entity.

Telethon's resolve_id expects:
- positive int -> PeerUser
- negative int (> -1000000000000) -> PeerChat
- negative int (< -1000000000000) -> PeerChannel (strip -100 prefix)

Using entity.id (unmarked) for channels/chats causes resolve_id
to misinterpret them as PeerUser, leading to ValueError.
"""
if isinstance(entity, Channel):
return -1000000000000 - entity.id
if isinstance(entity, Chat):
return -entity.id
return entity.id


def get_entity_filter_type(entity: Any) -> Optional[str]:
"""Return list_chats-compatible filter type: user/group/channel."""
entity_type = get_entity_type(entity)
Expand Down Expand Up @@ -320,7 +338,7 @@ def validate_single_id(value, p_name):

def format_entity(entity) -> Dict[str, Any]:
"""Helper function to format entity information consistently."""
result = {"id": entity.id}
result = {"id": get_marked_id(entity)}

if hasattr(entity, "title"):
result["name"] = entity.title
Expand Down Expand Up @@ -703,7 +721,7 @@ async def get_chats(page: int = 1, page_size: int = 20) -> str:
lines = []
for dialog in chats:
entity = dialog.entity
chat_id = entity.id
chat_id = get_marked_id(entity)
title = getattr(entity, "title", None) or getattr(entity, "first_name", "Unknown")
lines.append(f"Chat ID: {chat_id}, Title: {title}")
return "\n".join(lines)
Expand Down Expand Up @@ -1297,7 +1315,7 @@ async def list_chats(
continue

# Format chat info
chat_info = f"Chat ID: {entity.id}"
chat_info = f"Chat ID: {get_marked_id(entity)}"

if hasattr(entity, "title"):
chat_info += f", Title: {entity.title}"
Expand Down Expand Up @@ -1382,7 +1400,7 @@ async def get_chat(chat_id: Union[int, str]) -> str:
entity = await resolve_entity(chat_id)

result = []
result.append(f"ID: {entity.id}")
result.append(f"ID: {get_marked_id(entity)}")

is_user = isinstance(entity, User)

Expand Down Expand Up @@ -1483,7 +1501,7 @@ async def get_direct_chat_by_contact(contact_query: str) -> str:
)
for dialog in dialogs:
if isinstance(dialog.entity, User) and dialog.entity.id == contact.id:
chat_info = f"Chat ID: {dialog.entity.id}, Contact: {contact_name}"
chat_info = f"Chat ID: {get_marked_id(dialog.entity)}, Contact: {contact_name}"
if getattr(contact, "username", ""):
chat_info += f", Username: @{contact.username}"
if dialog.unread_count:
Expand Down Expand Up @@ -1530,7 +1548,7 @@ async def get_contact_chats(contact_id: Union[int, str]) -> str:
# Look for direct chat
for dialog in dialogs:
if isinstance(dialog.entity, User) and dialog.entity.id == contact_id:
chat_info = f"Direct Chat ID: {dialog.entity.id}, Type: Private"
chat_info = f"Direct Chat ID: {get_marked_id(dialog.entity)}, Type: Private"
if dialog.unread_count:
chat_info += f", Unread: {dialog.unread_count}"
results.append(chat_info)
Expand All @@ -1542,7 +1560,7 @@ async def get_contact_chats(contact_id: Union[int, str]) -> str:
common = await client.get_common_chats(contact)
for chat in common:
chat_type = get_entity_type(chat)
chat_info = f"Chat ID: {chat.id}, Title: {chat.title}, Type: {chat_type}"
chat_info = f"Chat ID: {get_marked_id(chat)}, Title: {chat.title}, Type: {chat_type}"
results.append(chat_info)
except:
results.append("Could not retrieve common groups.")
Expand Down Expand Up @@ -1904,9 +1922,9 @@ async def create_group(title: str, user_ids: List[Union[int, str]]) -> str:
# Check what type of response we got
if hasattr(result, "chats") and result.chats:
created_chat = result.chats[0]
return f"Group created with ID: {created_chat.id}"
return f"Group created with ID: {get_marked_id(created_chat)}"
elif hasattr(result, "chat") and result.chat:
return f"Group created with ID: {result.chat.id}"
return f"Group created with ID: {get_marked_id(result.chat)}"
elif hasattr(result, "chat_id"):
return f"Group created with ID: {result.chat_id}"
else:
Expand All @@ -1916,7 +1934,7 @@ async def create_group(title: str, user_ids: List[Union[int, str]]) -> str:
dialogs = await client.get_dialogs(limit=5) # Get recent dialogs
for dialog in dialogs:
if dialog.title == title:
return f"Group created with ID: {dialog.id}"
return f"Group created with ID: {get_marked_id(dialog.entity)}"

# If we still can't find it, at least return success
return f"Group created successfully. Please check your recent chats for '{title}'."
Expand Down Expand Up @@ -3629,7 +3647,7 @@ async def get_bot_info(bot_username: str) -> str:
# Fallback if to_dict is not available
info = {
"bot_info": {
"id": entity.id,
"id": get_marked_id(entity),
"username": entity.username,
"first_name": entity.first_name,
"last_name": getattr(entity, "last_name", ""),
Expand Down Expand Up @@ -4282,7 +4300,7 @@ async def get_folder(folder_id: int) -> str:
try:
entity = await resolve_entity(peer)
chat_info = {
"id": entity.id,
"id": get_marked_id(entity),
"name": getattr(entity, "title", None)
or getattr(entity, "first_name", "Unknown"),
"type": get_entity_type(entity),
Expand All @@ -4299,7 +4317,7 @@ async def get_folder(folder_id: int) -> str:
try:
entity = await resolve_entity(peer)
chat_info = {
"id": entity.id,
"id": get_marked_id(entity),
"name": getattr(entity, "title", None)
or getattr(entity, "first_name", "Unknown"),
"type": get_entity_type(entity),
Expand All @@ -4314,7 +4332,7 @@ async def get_folder(folder_id: int) -> str:
try:
entity = await resolve_entity(peer)
chat_info = {
"id": entity.id,
"id": get_marked_id(entity),
"name": getattr(entity, "title", None)
or getattr(entity, "first_name", "Unknown"),
"type": get_entity_type(entity),
Expand Down
Loading