fix: add support for shared folders (DialogFilterChatlist) in folder operations

Shared folders in Telegram use DialogFilterChatlist type instead of
DialogFilter. Previously, all folder operations (list, get, create,
add/remove chat) silently ignored shared folders. This fix ensures
they are recognized and handled correctly alongside regular folders.
This commit is contained in:
mxl 2026-03-16 06:50:02 +03:00
parent 26b1287a5b
commit b0b568bf82

64
main.py
View file

@ -37,6 +37,7 @@ from telethon.tl.types import (
InputPeerChat, InputPeerChat,
InputPeerChannel, InputPeerChannel,
DialogFilter, DialogFilter,
DialogFilterChatlist,
DialogFilterDefault, DialogFilterDefault,
TextWithEntities, TextWithEntities,
) )
@ -4123,6 +4124,21 @@ async def list_folders() -> str:
} }
folders.append(folder_data) folders.append(folder_data)
elif isinstance(f, DialogFilterChatlist):
# Shared folders use DialogFilterChatlist type
title = f.title
if isinstance(title, TextWithEntities):
title = title.text
folder_data = {
"id": f.id,
"title": title,
"emoticon": getattr(f, "emoticon", None),
"type": "shared",
"included_peers_count": len(getattr(f, "include_peers", [])),
"pinned_peers_count": len(getattr(f, "pinned_peers", [])),
}
folders.append(folder_data)
if not folders: if not folders:
return "No folders found. Create one with create_folder tool." return "No folders found. Create one with create_folder tool."
@ -4147,7 +4163,7 @@ async def get_folder(folder_id: int) -> str:
target_folder = None target_folder = None
for f in result.filters: for f in result.filters:
if isinstance(f, DialogFilter) and f.id == folder_id: if isinstance(f, (DialogFilter, DialogFilterChatlist)) and f.id == folder_id:
target_folder = f target_folder = f
break break
@ -4212,7 +4228,15 @@ async def get_folder(folder_id: int) -> str:
"id": target_folder.id, "id": target_folder.id,
"title": title, "title": title,
"emoticon": getattr(target_folder, "emoticon", None), "emoticon": getattr(target_folder, "emoticon", None),
"filters": { "included_chats": included_chats,
"excluded_chats": excluded_chats,
"pinned_chats": pinned_chats,
}
if isinstance(target_folder, DialogFilterChatlist):
folder_data["type"] = "shared"
else:
folder_data["filters"] = {
"contacts": getattr(target_folder, "contacts", False), "contacts": getattr(target_folder, "contacts", False),
"non_contacts": getattr(target_folder, "non_contacts", False), "non_contacts": getattr(target_folder, "non_contacts", False),
"groups": getattr(target_folder, "groups", False), "groups": getattr(target_folder, "groups", False),
@ -4221,10 +4245,6 @@ async def get_folder(folder_id: int) -> str:
"exclude_muted": getattr(target_folder, "exclude_muted", False), "exclude_muted": getattr(target_folder, "exclude_muted", False),
"exclude_read": getattr(target_folder, "exclude_read", False), "exclude_read": getattr(target_folder, "exclude_read", False),
"exclude_archived": getattr(target_folder, "exclude_archived", False), "exclude_archived": getattr(target_folder, "exclude_archived", False),
},
"included_chats": included_chats,
"excluded_chats": excluded_chats,
"pinned_chats": pinned_chats,
} }
return json.dumps(folder_data, indent=2, default=json_serializer) return json.dumps(folder_data, indent=2, default=json_serializer)
@ -4274,7 +4294,7 @@ async def create_folder(
existing_ids = set() existing_ids = set()
folder_count = 0 folder_count = 0
for f in result.filters: for f in result.filters:
if isinstance(f, DialogFilter): if isinstance(f, (DialogFilter, DialogFilterChatlist)):
existing_ids.add(f.id) existing_ids.add(f.id)
folder_count += 1 folder_count += 1
@ -4356,7 +4376,7 @@ async def add_chat_to_folder(
target_folder = None target_folder = None
for f in result.filters: for f in result.filters:
if isinstance(f, DialogFilter) and f.id == folder_id: if isinstance(f, (DialogFilter, DialogFilterChatlist)) and f.id == folder_id:
target_folder = f target_folder = f
break break
@ -4390,6 +4410,17 @@ async def add_chat_to_folder(
pinned_peers.append(peer) pinned_peers.append(peer)
# Update the folder (keep all original attributes) # Update the folder (keep all original attributes)
if isinstance(target_folder, DialogFilterChatlist):
updated_filter = DialogFilterChatlist(
id=target_folder.id,
title=target_folder.title,
emoticon=getattr(target_folder, "emoticon", None),
pinned_peers=pinned_peers,
include_peers=include_peers,
title_noanimate=getattr(target_folder, "title_noanimate", None),
color=getattr(target_folder, "color", None),
)
else:
updated_filter = DialogFilter( updated_filter = DialogFilter(
id=target_folder.id, id=target_folder.id,
title=target_folder.title, title=target_folder.title,
@ -4446,7 +4477,7 @@ async def remove_chat_from_folder(folder_id: int, chat_id: Union[int, str]) -> s
target_folder = None target_folder = None
for f in result.filters: for f in result.filters:
if isinstance(f, DialogFilter) and f.id == folder_id: if isinstance(f, (DialogFilter, DialogFilterChatlist)) and f.id == folder_id:
target_folder = f target_folder = f
break break
@ -4485,6 +4516,17 @@ async def remove_chat_from_folder(folder_id: int, chat_id: Union[int, str]) -> s
return f"Chat {chat_id} was not in folder {folder_id}." return f"Chat {chat_id} was not in folder {folder_id}."
# Update the folder (keep all original attributes) # Update the folder (keep all original attributes)
if isinstance(target_folder, DialogFilterChatlist):
updated_filter = DialogFilterChatlist(
id=target_folder.id,
title=target_folder.title,
emoticon=getattr(target_folder, "emoticon", None),
pinned_peers=pinned_peers,
include_peers=include_peers,
title_noanimate=getattr(target_folder, "title_noanimate", None),
color=getattr(target_folder, "color", None),
)
else:
updated_filter = DialogFilter( updated_filter = DialogFilter(
id=target_folder.id, id=target_folder.id,
title=target_folder.title, title=target_folder.title,
@ -4545,7 +4587,7 @@ async def delete_folder(folder_id: int) -> str:
folder_exists = False folder_exists = False
folder_title = None folder_title = None
for f in result.filters: for f in result.filters:
if isinstance(f, DialogFilter) and f.id == folder_id: if isinstance(f, (DialogFilter, DialogFilterChatlist)) and f.id == folder_id:
folder_exists = True folder_exists = True
# Handle title which can be str or TextWithEntities # Handle title which can be str or TextWithEntities
title = f.title title = f.title
@ -4584,7 +4626,7 @@ async def reorder_folders(folder_ids: List[int]) -> str:
existing_ids = set() existing_ids = set()
for f in result.filters: for f in result.filters:
if isinstance(f, DialogFilter): if isinstance(f, (DialogFilter, DialogFilterChatlist)):
existing_ids.add(f.id) existing_ids.add(f.id)
# Validate all provided IDs exist # Validate all provided IDs exist