import streamSaver from 'streamsaver' import { Api } from 'telegram' import { req } from './Fetcher' import { telegramClient } from './Telegram' export async function download(id: string): Promise { const { data: response } = await req.get(`/files/${id}`, { params: { raw: 1, as_array: 1 } }) let cancel = false const client = await telegramClient.connect() const readableStream = new ReadableStream({ start(_controller: ReadableStreamDefaultController) { }, async pull(controller: ReadableStreamDefaultController) { let countFiles = 1 console.log('start downloading:', response.files) for (const file of response.files) { let chat: any if (file.forward_info && file.forward_info.match(/^channel\//gi)) { const [type, peerId, id, accessHash] = file.forward_info.split('/') let peer: Api.InputPeerChannel | Api.InputPeerUser | Api.InputPeerChat if (type === 'channel') { peer = new Api.InputPeerChannel({ channelId: BigInt(peerId) as any, accessHash: BigInt(accessHash as string) as any }) chat = await client.invoke(new Api.channels.GetMessages({ channel: peer, id: [new Api.InputMessageID({ id: Number(id) })] })) } } else { chat = await client.invoke(new Api.messages.GetMessages({ id: [new Api.InputMessageID({ id: Number(file.message_id) })] })) } const getData = async () => await client.downloadMedia(chat['messages'][0].media, { outputFile: { write: (chunk: Buffer) => { if (cancel) return false return controller.enqueue(chunk) }, close: () => { if (countFiles++ >= Number(response.files.length)) controller.close() } }, progressCallback: (received, total) => { console.log('progress: ', (Number(received) / Number(total) * 100).toFixed(2), '%') } }) try { await getData() } catch (error) { console.log(error) } } }, cancel() { cancel = true } }, { size(chunk: any) { return chunk.length } }) return readableStream } export const directDownload = async (id: string, name: string): Promise => { const fileStream = streamSaver.createWriteStream(name) const writer = fileStream.getWriter() const reader = (await download(id)).getReader() const pump = () => reader.read().then(({ value, done }) => { if (done) return writer.close() writer.write(value) return writer.ready.then(pump) }) await pump() }