Folders

Telegram allows placing chats into folders, based on their type, mute status, or other custom criteria, thanks to folder blacklists and whitelists: these folders may also be shared with other users.

Folders

Schema:

dialogFilter#5fb5523b flags:# contacts:flags.0?true non_contacts:flags.1?true groups:flags.2?true broadcasts:flags.3?true bots:flags.4?true exclude_muted:flags.11?true exclude_read:flags.12?true exclude_archived:flags.13?true id:int title:string emoticon:flags.25?string color:flags.27?int pinned_peers:Vector<InputPeer> include_peers:Vector<InputPeer> exclude_peers:Vector<InputPeer> = DialogFilter;
dialogFilterChatlist#9fe28ea4 flags:# has_my_invites:flags.26?true id:int title:string emoticon:flags.25?string color:flags.27?int pinned_peers:Vector<InputPeer> include_peers:Vector<InputPeer> = DialogFilter;
dialogFilterDefault#363293ae = DialogFilter;

dialogFilterSuggested#77744d4a filter:DialogFilter description:string = DialogFilterSuggested;

updateDialogFilter#26ffde7d flags:# id:int filter:flags.0?DialogFilter = Update;
updateDialogFilterOrder#a5d72105 order:Vector<int> = Update;
updateDialogFilters#3504914f = Update;

---functions---

messages.getDialogFilters#efd48c89 = messages.DialogFilters;
messages.getSuggestedDialogFilters#a29cd42c = Vector<DialogFilterSuggested>;
messages.updateDialogFilter#1ad4a04a flags:# id:int filter:flags.0?DialogFilter = Bool;
messages.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool;

help.getAppConfig#61e3f854 hash:int = help.AppConfig;

In the API, folders are called "dialog filters".
In the UI, folders are typically represented as tabs.

On startup, clients call:

The boolean under the dialog_filters_tooltip JSON key in the result of help.getAppConfig can be used to determine whether a folder tooltip should be presented to the user right away.
The UI should then show a list of suggested folder combinations.

Once configuration is finished, apps call messages.updateDialogFilter to create or update existing folders.
As per the dialogFilter/dialogFilterChatlist constructors, folders have multiple flags that can be combined to determine which chats should be included in (or excluded from) the folder, which emoji to use as icon for the folder and its name.
Folders can also have up to dialogs_folder_pinned_limit_* pinned chats, as determined by the client configuration.

dialogFilterChatlist constructors are used to represent imported shareable folders.

To reorder existing folders, messages.updateDialogFiltersOrder should be used with the IDs of the various dialog filters.

Premium users also have access to a dialogFilterDefault constructor, used only when reordering folders to indicate the default (all chats) folder.

To delete folders, use messages.updateDialogFilter without populating the filter flag field.

Clients can receive updateDialogFilter, updateDialogFilterOrder updates with new filter information, generated by other clients when modifying folder info.
Clients can also receive updateDialogFilters, in which case folder info should be refetched manually using messages.getDialogFilters.

Shared folders

inputChatlistDialogFilter#f3e0da33 filter_id:int = InputChatlist;

exportedChatlistInvite#0c5181ac flags:# title:string url:string peers:Vector<Peer> = ExportedChatlistInvite;

chatlists.exportedChatlistInvite#10e6e3a6 filter:DialogFilter invite:ExportedChatlistInvite = chatlists.ExportedChatlistInvite;

chatlists.exportedInvites#10ab6dc7 invites:Vector<ExportedChatlistInvite> chats:Vector<Chat> users:Vector<User> = chatlists.ExportedInvites;

chatlists.chatlistInviteAlready#fa87f659 filter_id:int missing_peers:Vector<Peer> already_peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = chatlists.ChatlistInvite;
chatlists.chatlistInvite#1dcd839d flags:# title:string emoticon:flags.0?string peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = chatlists.ChatlistInvite;

chatlists.chatlistUpdates#93bd878d missing_peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = chatlists.ChatlistUpdates;

---functions---

chatlists.exportChatlistInvite#8472478e chatlist:InputChatlist title:string peers:Vector<InputPeer> = chatlists.ExportedChatlistInvite;

chatlists.getExportedInvites#ce03da83 chatlist:InputChatlist = chatlists.ExportedInvites;
chatlists.editExportedInvite#653db63d flags:# chatlist:InputChatlist slug:string title:flags.1?string peers:flags.2?Vector<InputPeer> = ExportedChatlistInvite;
chatlists.deleteExportedInvite#719c5c5e chatlist:InputChatlist slug:string = Bool;

chatlists.checkChatlistInvite#41c10fff slug:string = chatlists.ChatlistInvite;
chatlists.joinChatlistInvite#a6b1e39a slug:string peers:Vector<InputPeer> = Updates;

chatlists.getChatlistUpdates#89419521 chatlist:InputChatlist = chatlists.ChatlistUpdates;
chatlists.joinChatlistUpdates#e089f8f5 chatlist:InputChatlist peers:Vector<InputPeer> = Updates;
chatlists.hideChatlistUpdates#66e486fb chatlist:InputChatlist = Bool;

chatlists.getLeaveChatlistSuggestions#fdbcd714 chatlist:InputChatlist = Vector<Peer>;
chatlists.leaveChatlist#74fae13a chatlist:InputChatlist peers:Vector<InputPeer> = Updates;

Folders may be shared using chat folder deep links.
These links are generated by invoking chatlists.exportChatlistInvite, passing the ID of the folder that should be exported, along with a list of peers that should be included in the shared folder.
Only channels and groups/supergroups may be specified in the peers array; these channels and groups must be public, or the user must have permission to manage invite links. Basic groups will automatically be converted to supergroups when invoking the method.
An optional name for the shared link may also be specified using title.

Use chatlists.getExportedInvites to list all links generated for a folder, use chatlists.editExportedInvite to edit the title or list of peers of a specific link and chatlists.deleteExportedInvite to revoke an exported link, preventing new users from importing it.

The maximum number of per-folder invites that can be created by Premium/non-Premium users is specified by the chatlist_invites_limit_default/chatlist_invites_limit_premium client configuration parameters ».

Use chatlists.checkChatlistInvite to obtain information about a chat folder deep link before importing it with chatlists.joinChatlistInvite, specifying in peers which channels and groups to join (excluding inaccessible channels/supergroups, i.e. the user may not join a supergroup/channel where they were banned, corresponding to a channelForbidden constructor).
If the user can't join any of the peers of a folder, the folder can't be imported.

The maximum number of shareable folders that a Premium/non-Premium user may join is specified by the chatlists_joined_limit_default/chatlists_joined_limit_premium client configuration parameters ».

Users that import a folder should retrieve additions made to the peer list by invoking chatlists.getChatlistUpdates at most every chatlist_update_period seconds (a client configuration parameter »).
If the returned missing_peers list is non-empty, the client should present it to the user, who may choose to join all or a subset of them (excluding inaccessible channels/supergroups), passing them to the peers parameter of chatlists.joinChatlistUpdates.
If after excluding inaccessible peers and peers deselected by the user the peers list is empty, invoke chatlists.hideChatlistUpdates instead of chatlists.joinChatlistUpdates.

When removing an imported folder, the list of included peers should be presented to the user prior to deletion, with the peers listed in chatlists.getLeaveChatlistSuggestions already pre-marked for deletion: the user may then choose to delete or keep some or all of the groups and channels of the folder when invoking chatlists.leaveChatlist to delete the folder, specifying in peers the list of channels and groups from the folder that should also be removed.

Peer folders

The API also has another method for identifying groups of peers, used by archived chats.

Schema:

inputFolderPeer#fbd2c296 peer:InputPeer folder_id:int = InputFolderPeer;

folderPeer#e9baa668 peer:Peer folder_id:int = FolderPeer;

updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;

updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;


inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer;
inputDialogPeerFolder#64600527 folder_id:int = InputDialogPeer;

dialogPeer#e56dbf05 peer:Peer = DialogPeer;
dialogPeerFolder#514519e2 folder_id:int = DialogPeer;

---functions---

folders.editPeerFolders#6847d0ab folder_peers:Vector<InputFolderPeer> = Updates;

API peer folders are typically used only by archived chats, and are really handy for distinguishing groups of peers, since most peer-related constructors (updates, chat info) will contain the folder_id assigned the specified chat.

In Telegram apps, API peer folders are used only to implement the chat archive, identified by folder_id 1; all other peers are in folder_id 0 by default; no other folder_id is allowed at the moment.

Both methods return an updates constructor, containing a single updateFolderPeers with the new folder_id of moved peers.
Clients can also receive updateFolderPeers as a normal update, generated by other clients when modifying peer folders.

Clients can then use InputDialogPeer to refer either to a specific chat, or to all chats in a peer folder: the server will return a DialogPeer in certain constructors for the same purpose.