From 23bc4b5e30d135908aaf8b5cdb122a8bab379d31 Mon Sep 17 00:00:00 2001 From: teidesu <86301490+teidesu@users.noreply.github.com> Date: Fri, 2 Jul 2021 17:04:45 +0300 Subject: [PATCH] feat(client): uploadMedia method --- packages/client/src/client.ts | 22 +++++ packages/client/src/methods/_imports.ts | 4 +- .../client/src/methods/files/upload-media.ts | 93 +++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 packages/client/src/methods/files/upload-media.ts diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index d2a5b5d4..5a6c8f87 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -79,6 +79,7 @@ import { _normalizeFileToDocument } from './methods/files/normalize-file-to-docu import { _normalizeInputFile } from './methods/files/normalize-input-file' import { _normalizeInputMedia } from './methods/files/normalize-input-media' import { uploadFile } from './methods/files/upload-file' +import { uploadMedia } from './methods/files/upload-media' import { createInviteLink } from './methods/invite-links/create-invite-link' import { editInviteLink } from './methods/invite-links/edit-invite-link' import { exportInviteLink } from './methods/invite-links/export-invite-link' @@ -177,10 +178,12 @@ import { InputStickerSetItem, MaybeDynamic, Message, + MessageMedia, PartialExcept, PartialOnly, Photo, Poll, + RawDocument, ReplyMarkup, SentCode, StickerSet, @@ -1629,6 +1632,24 @@ export interface TelegramClient extends BaseTelegramClient { */ progressCallback?: (uploaded: number, total: number) => void }): Promise + /** + * Upload a media to Telegram servers, without actually + * sending a message anywhere. Useful when File ID is needed. + * + * The difference with {@link uploadFile} is that + * the returned object will act like a message media + * and contain fields like File ID. + * + * @param media Media to upload + * @param params (default: `{}`) Upload parameters + */ + uploadMedia( + media: InputMediaLike, + params?: { + peer?: InputPeerLike + progressCallback?: (uploaded: number, total: number) => void + } + ): Promise> /** * Create an additional invite link for the chat. * @@ -3270,6 +3291,7 @@ export class TelegramClient extends BaseTelegramClient { _normalizeInputFile = _normalizeInputFile _normalizeInputMedia = _normalizeInputMedia uploadFile = uploadFile + uploadMedia = uploadMedia createInviteLink = createInviteLink editInviteLink = editInviteLink exportInviteLink = exportInviteLink diff --git a/packages/client/src/methods/_imports.ts b/packages/client/src/methods/_imports.ts index 413bd20a..ca0691c9 100644 --- a/packages/client/src/methods/_imports.ts +++ b/packages/client/src/methods/_imports.ts @@ -39,7 +39,9 @@ import { ChatsIndex, GameHighScore, ArrayWithTotal, - BotCommands + BotCommands, + MessageMedia, + RawDocument } from '../types' // @copy diff --git a/packages/client/src/methods/files/upload-media.ts b/packages/client/src/methods/files/upload-media.ts new file mode 100644 index 00000000..ca86ebe3 --- /dev/null +++ b/packages/client/src/methods/files/upload-media.ts @@ -0,0 +1,93 @@ +import { + InputMediaLike, + InputPeerLike, + MessageMedia, + MtCuteArgumentError, + MtCuteTypeAssertionError, + Photo, RawDocument, +} from '../../types' +import { TelegramClient } from '../../client' +import { assertTypeIs } from '../../utils/type-assertion' +import { parseDocument } from '../../types/media/document-utils' + +/** + * Upload a media to Telegram servers, without actually + * sending a message anywhere. Useful when File ID is needed. + * + * The difference with {@link uploadFile} is that + * the returned object will act like a message media + * and contain fields like File ID. + * + * @param media Media to upload + * @param params Upload parameters + * @internal + */ +export async function uploadMedia( + this: TelegramClient, + media: InputMediaLike, + params: { + /** + * Peer to associate this media with. + * Defaults to `self` + */ + peer?: InputPeerLike + + /** + * Upload progress callback + * + * @param uploaded Number of bytes uploaded + * @param total Total file size + */ + progressCallback?: (uploaded: number, total: number) => void + } = {} +): Promise> { + const normMedia = await this._normalizeInputMedia(media, params, false) + + switch (normMedia._) { + case 'inputMediaEmpty': + case 'inputMediaGeoPoint': + case 'inputMediaGeoLive': + case 'inputMediaContact': + case 'inputMediaVenue': + case 'inputMediaGame': + case 'inputMediaInvoice': + case 'inputMediaPoll': + case 'inputMediaDice': + throw new MtCuteArgumentError("This media can't be uploaded") + } + + const res = await this.call({ + _: 'messages.uploadMedia', + peer: params.peer + ? await this.resolvePeer(params.peer) + : { + _: 'inputPeerSelf', + }, + media: normMedia, + }) + + if (res._ === 'messageMediaEmpty') { + throw new MtCuteTypeAssertionError( + 'uploadMedia', + 'not messageMediaEmpty', + 'messageMediaEmpty' + ) + } + + switch (normMedia._) { + case 'inputMediaUploadedPhoto': + case 'inputMediaPhoto': + case 'inputMediaPhotoExternal': + assertTypeIs('uploadMedia', res, 'messageMediaPhoto') + assertTypeIs('uploadMedia', res.photo!, 'photo') + + return new Photo(this, res.photo) + case 'inputMediaUploadedDocument': + case 'inputMediaDocument': + case 'inputMediaDocumentExternal': + assertTypeIs('uploadMedia', res, 'messageMediaDocument') + assertTypeIs('uploadMedia', res.document!, 'document') + + return parseDocument(this, res.document) as any + } +}