gramjs icon indicating copy to clipboard operation
gramjs copied to clipboard

Is it possible to pass only id, accessHash, fileReference and dcId to download_media?

Open charlieelcarlino opened this issue 1 year ago • 1 comments

downloadMedia works perfectly fine when I pass the whole media, but if send only these four values it doesn't return nothing, is there anyway to solve this? Am I missing something?

I am trying to do it this way because first I fetch all the messages, each with these four attributes, then I download the images of only some of them (and I don't want to store the whole media object for each message).

Thank you

charlieelcarlino avatar Aug 26 '24 14:08 charlieelcarlino

Yes, i can confirm that in order for downloadMedia to work properly, you must provide the full Api.Document object. Not just id, accessHash, fileReference, and dcId.

Telegram requires the full context of the document (including attributes, mime type, size) to authorize the media download. Especially when you are not using a message object but a raw document.

In my case i had to manually reconstruct the Api.Document like this:

function deserializeDocument(raw: any): Api.Document {
  const attrs = raw.attributes.map((a: any) => {
    switch (a.className) {
      case 'DocumentAttributeImageSize':
        return new Api.DocumentAttributeImageSize({ w: a.w, h: a.h });
      case 'DocumentAttributeCustomEmoji':
        return new Api.DocumentAttributeCustomEmoji({
          free: a.free,
          textColor: a.textColor,
          alt: a.alt,
          stickerset: new Api.InputStickerSetID({
            id: bigInt(a.stickerset.id),
            accessHash: bigInt(a.stickerset.accessHash),
          }),
        });
      case 'DocumentAttributeFilename':
        return new Api.DocumentAttributeFilename({ fileName: a.fileName });
      default:
        return undefined;
    }
  }).filter(Boolean);

  return new Api.Document({
    id: bigInt(raw.id),
    accessHash: bigInt(raw.accessHash),
    fileReference: Buffer.from(raw.fileReference.data),
    date: raw.date,
    mimeType: raw.mimeType,
    size: bigInt(raw.size),
    dcId: raw.dcId,
    attributes: attrs,
  });
}
const sticker = deserializeDocument(rawSticker);
const media = new Api.MessageMediaDocument({
      document: sticker,
});
const fileBuffer = await tgClient.downloadMedia(media);

JuanBrotenelle avatar Jun 25 '25 11:06 JuanBrotenelle