sochix / TLSharp

Telegram client library implemented in C#
1k stars 380 forks source link

How to download a sticker or a set of stickers? #379

Open Starli0n opened 7 years ago

Starli0n commented 7 years ago

Hi,

I successfully retrieved messages from user dialogs, channels or groups with different kind of media (photos, videos, audio, links).

I am developing an application to archive all the content of a dialog using your library:

https://github.com/Starli0n/TLArchiver

However, I had difficulty in downloading stickers.

Here is the pseudo code I use:

foreach (var message in TLSharp.GetHistoryAsync())
{
    if (message.media is TLMessageMediaPhoto)
        ExportPhoto(media);

    else if (message.media is TLMessageMediaWebPage)
        ExportLink(media);

    else if (message.media is TLMessageMediaDocument)
        ExportDocument(media);
}

ExportDocument(media)
{
    if (media.document is TLDocument)
    {
        if (media.document.mime_type.StartsWith("audio"))
            ExportAudio(media);

        else if (media.document.attributes.lists has a TLDocumentAttributeSticker)
            ExportStickers(media);

        ExportFile(media);
    }
}

ExportStickers(media)
{
    TLDocument document = media.document as TLDocument;

    TLAbsInputFileLocation inputDocument = new TLInputDocumentFileLocation()
    {
        id = document.id,
        access_hash = document.access_hash,
        version = document.version
    };

    TLFile file = TLSharp.GetFile(inputDocument, document.size, 0);

    // file.type is TLFileUnknown and file.bytes.Length == 0
    // Failed!!

    // The algo above is used for other medias and it works but it does not work for stickers
}

Then, I tried to download all the set of stickers by doing:

ExportStickers(media)
{
    TLDocumentAttributeSticker attr = get from media.document.attributes.lists

    TLInputStickerSetID inputStickerSet = attr.stickerset as TLInputStickerSetID;

    TLStickerSet stickerSet = TLSharp.TLGetStickersSet(inputStickerSet);

    // stickerSet.set.short_name contains the name of the set. It works!

    foreach (TLStickerPack pack in stickerSet.packs.lists)
    {
        foreach (long hash in pack.documents.lists)
        {
            TLStickers stickers = TLSharp.GetStickers(pack.emoticon, hash.ToString()); // I added this method into TLSharp

            foreach (TLAbsDocument absDoc in stickers.stickers.lists)
            {
                TLDocument document = absDoc as TLDocument;

                // And then, from a TLDocument, use the same algo as above

                (...)
            }
        }
    }
}

This method above does download stickers but actually they are the default stickers of Telegram :-(

I tried also to download the TLDocument from stickerSet.documents.lists but it does not work either...

I dug into the official documentation and I found those two methods in:

https://core.telegram.org/schema and https://core.telegram.org/schema/json

    messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
    {
        "id":"-1373446075",
        "method":"messages.getStickers",
        "params":
        [
            {"name":"emoticon","type":"string"},
            {"name":"hash","type":"string"}
        ],
        "type":"messages.Stickers"
    }

    messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
    {
        "id":"-1438922648",
        "method":"messages.getAllStickers",
        "params":
        [
            {"name":"hash","type":"string"}
        ],
        "type":"messages.AllStickers"
    }

And I was not able to find those two id -1373446075 and -1438922648 in the TLSharp library.

Therefore I wondered whether the library is up-to-date.

The TLRequestGetAllStickers method does exist but with an id equals to 479598769.

Do you have any idea about that issue ?

Thanks

raznahan commented 4 years ago

@Starli0n I almost have the same problem here. I'm trying to download a list of sticker packs through their shortnames. When calling "client.GetFile" I get the exception saying "LIMIT_INVALID". Here is my code:

   var req = new TLRequestGetStickerSet()
            {

                Stickerset = new TLInputStickerSetShortName() { ShortName = "freddiethefox" },
            };

   var res = await client.SendRequestAsync<TeleSharp.TL.Messages.TLStickerSet>(req);

   var sticker = (TLDocument)res.Documents[0];

   var dl = await client.GetFile(new TLInputDocumentFileLocation() { AccessHash = 
  sticker.AccessHash, Id = sticker.Id, Version = sticker.Version }, sticker.Size);