Telethon icon indicating copy to clipboard operation
Telethon copied to clipboard

Get/Set folders for dialogs

Open mkellerman opened this issue 5 years ago • 17 comments

Please add a feature to get/set the list of folders, ans add/remove dialogs from those folders.

mkellerman avatar Nov 12 '20 16:11 mkellerman

client.edit_folder already does the second thing you request.

Lonami avatar Nov 12 '20 20:11 Lonami

It seems to provide if the dialog is 'archived', but not custom folders. Can someone confirm?

mkellerman avatar Nov 12 '20 20:11 mkellerman

Folders other than archived should just be different numbers.

Lonami avatar Nov 12 '20 22:11 Lonami

I've just verified, and folder_id only provides null or 1, depending if it's 'archived' or not. no other folders id is provided.

mkellerman avatar Dec 10 '20 04:12 mkellerman

Other folder IDs should work just fine. I encourage you to create them with an official client and then check their value in Telethon to find out how other clients assign the IDs.

Lonami avatar Dec 10 '20 07:12 Lonami

I have. I created folders in the telegram app on iOS, and put some dialogs in there and they show as null in folder_id.

mkellerman avatar Dec 10 '20 15:12 mkellerman

That really shouldn't be the case, perhaps iter_dialogs is acting up. Have you tried using the raw API method getDialogs (https://tl.telethon.dev) directly?

Lonami avatar Dec 10 '20 17:12 Lonami

I wish I could help you investigate the issue more, but I barely know what I'm doing.

this is the implementation I'm using to get the dialogs.. and it returns null in the folder_id (except those that are archived, which returns 1):

client.start()
async def main():
    async for dialog in client.iter_dialogs():

mkellerman avatar Dec 10 '20 19:12 mkellerman

I've confirmed that using the GetDialogsRequest() is providing None as a folder_id except those that are Archived.

code used:

client = TelegramClient(StringSession(SessionId), api_id, api_hash)
async def main():

    request = await client(functions.messages.GetDialogsRequest(offset_date=None,
                    offset_id=0,
                    offset_peer=types.InputPeerEmpty(),
                    limit=10,
                    hash=0))
    for dialog in request.dialogs:
        print('GetDialogRequest:', dialog.folder_id)

    dialogs = await client.get_dialogs(10)
    for dialog in dialogs:
        print('get_dialogs:', dialog.folder_id)

    async for dialog in client.iter_dialogs(10):
        print('iter_dialogs:', dialog.folder_id)

with client:
    client.loop.run_until_complete(main())

results:

GetDialogRequest: None
GetDialogRequest: None
GetDialogRequest: None
GetDialogRequest: None
GetDialogRequest: None
GetDialogRequest: None
GetDialogRequest: None
GetDialogRequest: None
GetDialogRequest: None
GetDialogRequest: None
get_dialogs: None
get_dialogs: None
get_dialogs: None
get_dialogs: None
get_dialogs: None
get_dialogs: None
get_dialogs: None
get_dialogs: None
get_dialogs: None
get_dialogs: None
iter_dialogs: None
iter_dialogs: None
iter_dialogs: None
iter_dialogs: None
iter_dialogs: None
iter_dialogs: None
iter_dialogs: None
iter_dialogs: None
iter_dialogs: None
iter_dialogs: None

mkellerman avatar Feb 05 '21 22:02 mkellerman

So now we're using raw API and Telegram is directly telling us that those dialogs have no folder -- here Telethon can't change the results or go wrong, as you're talking with Telegram. Not sure then, maybe there's another way for different folders.

Lonami avatar Feb 05 '21 23:02 Lonami

I'm basically learning python from scratch to be able to debug and dig into this issue.. lol.. but I'm trying! ¯_(ツ)_/¯

mkellerman avatar Feb 05 '21 23:02 mkellerman

So I have managed to get the list of all folders and included\excluded chats in it:

async def main():

    request = await client(functions.messages.GetDialogFiltersRequest())
    for dialog_filter in request:
        print(dialog_filter.to_dict())

with client:
    client.loop.run_until_complete(main())

goodwind avatar Mar 15 '21 09:03 goodwind

Nice, but can i add dialogs to folders? client.edit_folder with id from GetDialogFiltersRequest doesn't work

Skovorp avatar Jan 10 '22 21:01 Skovorp

Sorry for messy code but seems like I got it. Seems like client.edit_folder works with peer folders which work only with archived chats. So with those you cant work with actual folders that you can see in your regular client.

In order to do that you need to use DialogFilters and update those with UpdateDialogFilterRequest

from telethon.sessions import StringSession
from telethon.sync import TelegramClient
from telethon.tl.functions.messages import GetDialogFiltersRequest
from telethon.tl.functions.messages import UpdateDialogFilterRequest
from telethon.tl.types import InputPeerUser


async def main():
    request = await client(GetDialogFiltersRequest())
    for dialog_filter in request:
        print(dialog_filter.to_dict())
    return request


async def update(folder_id, new):
    request = await client(UpdateDialogFilterRequest(folder_id, new))
    print(request)


with TelegramClient(StringSession(session_string), api_id, api_hash) as client:
    t = client.loop.run_until_complete(main())[0] # here i get DialogFilter
    print(type(t.include_peers), t.include_peers)
    entity = client.get_entity('Sposiboh')
    print(type(entity), entity)

    to_add = InputPeerUser(entity.id, entity.access_hash) # i get user entity and convert it to PeerUser
    
    t.include_peers.append(to_add) # i add to_add to the list of other users in DialogFilter
    client.loop.run_until_complete(update(162, t)) # 162 is folder id that i got from GetDialogFiltersRequest
    print('ok')

Skovorp avatar Jan 10 '22 22:01 Skovorp

Skovorp's code helped a lot in understanding how to work with folders.

But I'm also very interested in method for creating and editing folders (DialogFilters?)

As of now, I have to create them in official client and then search using GetDialogFiltersRequest method, comparing the name with the one I've chosen.

fox22432 avatar Feb 28 '22 19:02 fox22432

It turns out you CAN both create and delete Folders using the UpdateDialogFilterRequest method. The way you do it is described nicely in official api docs: https://core.telegram.org/api/folders Basically, to create a folder, you pass a new integer as "id" parameter, and types.DialogFilter object as "filter". New id does not have to be in sequential order. To delete a folder, simply pass None as "filter".

fox22432 avatar Mar 10 '22 12:03 fox22432

Sorry for messy code but seems like I got it. Seems like client.edit_folder works with peer folders which work only with archived chats. So with those you cant work with actual folders that you can see in your regular client.

In order to do that you need to use DialogFilters and update those with UpdateDialogFilterRequest

from telethon.sessions import StringSession
from telethon.sync import TelegramClient
from telethon.tl.functions.messages import GetDialogFiltersRequest
from telethon.tl.functions.messages import UpdateDialogFilterRequest
from telethon.tl.types import InputPeerUser


async def main():
    request = await client(GetDialogFiltersRequest())
    for dialog_filter in request:
        print(dialog_filter.to_dict())
    return request


async def update(folder_id, new):
    request = await client(UpdateDialogFilterRequest(folder_id, new))
    print(request)


with TelegramClient(StringSession(session_string), api_id, api_hash) as client:
    t = client.loop.run_until_complete(main())[0] # here i get DialogFilter
    print(type(t.include_peers), t.include_peers)
    entity = client.get_entity('Sposiboh')
    print(type(entity), entity)

    to_add = InputPeerUser(entity.id, entity.access_hash) # i get user entity and convert it to PeerUser
    
    t.include_peers.append(to_add) # i add to_add to the list of other users in DialogFilter
    client.loop.run_until_complete(update(162, t)) # 162 is folder id that i got from GetDialogFiltersRequest
    print('ok')

The addition gives a true and prints ok but the chat is not added to folder

bibinvargheset avatar Aug 21 '22 06:08 bibinvargheset

This is unlikely to happen in the near future so I will be closing the issue. We can reopen it if there's still interest once the time is right.

Lonami avatar Apr 06 '23 12:04 Lonami

I'm interested in using this feature, and do believe it should be an official part of the documentation

aryashivakumar avatar Jan 12 '24 23:01 aryashivakumar