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.
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;
messages.dialogFilters#2ad93719 flags:# tags_enabled:flags.0?true filters:Vector<DialogFilter> = messages.DialogFilters;
---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.
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;
updateDialogFilters#3504914f = Update;
messages.dialogFilters#2ad93719 flags:# tags_enabled:flags.0?true filters:Vector<DialogFilter> = messages.DialogFilters;
---functions---
messages.toggleDialogFilterTags#fd2dda49 enabled:Bool = Bool;
messages.getDialogFilters#efd48c89 = messages.DialogFilters;
Folder tags may be enabled or disabled for all folders using the messages.toggleDialogFilterTags method (Business users only).
If the new value of the toggle is different, the method will emit an updateDialogFilters to all other currently-logged in sessions, which should trigger a call to messages.toggleDialogFilterTags to load the new value of the toggle, in messages.dialogFilters.tags_enabled
.
If folder tags are enabled, clients should add folder tags (one for each folder the dialog entry is a part of, except for the "All chats" folder represented by dialogFilterDefault and tags with color=-1
) to all dialog entries, under the preview of the latest message.
These folder tags should contain the name of the folder, and should be colored with the color
specified in the dialog folder entry.
The color is an integer ranging from -1 to 6; if -1, the tag must not be shown in the dialog list; use red, orange, violet, green, cyan, blue, pink for indexes 0 to 6 (i.e. the same colors used for randomized fallback message accent colors).
The tag color
may only be changed if the user has a Premium subscription and tags are enabled.
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.
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.