feat(client): support file ids in sendMedia, sendPhoto and sendChatPhoto methods
This commit is contained in:
parent
c0b72018fb
commit
3bb9a61ac7
5 changed files with 112 additions and 38 deletions
|
@ -1603,12 +1603,15 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
* Send a single media.
|
* Send a single media.
|
||||||
*
|
*
|
||||||
* @param chatId ID of the chat, its username, phone or `"me"` or `"self"`
|
* @param chatId ID of the chat, its username, phone or `"me"` or `"self"`
|
||||||
* @param media Media contained in the message
|
* @param media
|
||||||
|
* Media contained in the message. You can also pass TDLib
|
||||||
|
* and Bot API compatible File ID, which will be wrapped
|
||||||
|
* in {@link InputMedia.auto}
|
||||||
* @param params Additional sending parameters
|
* @param params Additional sending parameters
|
||||||
*/
|
*/
|
||||||
sendMedia(
|
sendMedia(
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
media: InputMediaLike,
|
media: InputMediaLike | string,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
* Message to reply to. Either a message object or message ID.
|
* Message to reply to. Either a message object or message ID.
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
} from '../../types'
|
} from '../../types'
|
||||||
import { normalizeToInputChannel, normalizeToInputPeer } from '../../utils/peer-utils'
|
import { normalizeToInputChannel, normalizeToInputPeer } from '../../utils/peer-utils'
|
||||||
import { tl } from '@mtcute/tl'
|
import { tl } from '@mtcute/tl'
|
||||||
|
import { fileIdToInputPhoto, tdFileId } from '@mtcute/file-id'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new chat photo or video.
|
* Set a new chat photo or video.
|
||||||
|
@ -33,27 +34,37 @@ export async function setChatPhoto(
|
||||||
if (!(chat._ === 'inputPeerChat' || chat._ === 'inputPeerChannel'))
|
if (!(chat._ === 'inputPeerChat' || chat._ === 'inputPeerChannel'))
|
||||||
throw new MtCuteInvalidPeerTypeError(chatId, 'chat or channel')
|
throw new MtCuteInvalidPeerTypeError(chatId, 'chat or channel')
|
||||||
|
|
||||||
let input: tl.TypeInputFile
|
let photo: tl.TypeInputChatPhoto
|
||||||
|
|
||||||
if (typeof media === 'string' && media.match(/^https?:\/\//)) {
|
if (tdFileId.isFileIdLike(media)) {
|
||||||
throw new MtCuteArgumentError("Chat photo can't be external")
|
if (typeof media === 'string' && media.match(/^https?:\/\//))
|
||||||
} else if (typeof media === 'object' && tl.isAnyInputMedia(media)) {
|
throw new MtCuteArgumentError("Chat photo can't be external")
|
||||||
throw new MtCuteArgumentError("Chat photo can't be InputMedia")
|
|
||||||
} else if (isUploadedFile(media)) {
|
const input = fileIdToInputPhoto(media)
|
||||||
input = media.inputFile
|
photo = {
|
||||||
} else if (typeof media === 'object' && tl.isAnyInputFile(media)) {
|
_: 'inputChatPhoto',
|
||||||
input = media
|
id: input
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const uploaded = await this.uploadFile({
|
let inputFile: tl.TypeInputFile
|
||||||
file: media,
|
if (typeof media === 'object' && tl.isAnyInputMedia(media)) {
|
||||||
})
|
throw new MtCuteArgumentError("Chat photo can't be InputMedia")
|
||||||
input = uploaded.inputFile
|
} else if (isUploadedFile(media)) {
|
||||||
}
|
inputFile = media.inputFile
|
||||||
|
} else if (typeof media === 'object' && tl.isAnyInputFile(media)) {
|
||||||
|
inputFile = media
|
||||||
|
} else {
|
||||||
|
const uploaded = await this.uploadFile({
|
||||||
|
file: media,
|
||||||
|
})
|
||||||
|
inputFile = uploaded.inputFile
|
||||||
|
}
|
||||||
|
|
||||||
const photo: tl.RawInputChatUploadedPhoto = {
|
photo = {
|
||||||
_: 'inputChatUploadedPhoto',
|
_: 'inputChatUploadedPhoto',
|
||||||
[type === 'photo' ? 'file' : 'video']: input,
|
[type === 'photo' ? 'file' : 'video']: inputFile,
|
||||||
videoStartTs: previewSec
|
videoStartTs: previewSec
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let res
|
let res
|
||||||
|
|
|
@ -12,19 +12,28 @@ import { tl } from '@mtcute/tl'
|
||||||
import { extractFileName } from '../../utils/file-utils'
|
import { extractFileName } from '../../utils/file-utils'
|
||||||
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||||
import { normalizeDate, randomUlong } from '../../utils/misc-utils'
|
import { normalizeDate, randomUlong } from '../../utils/misc-utils'
|
||||||
|
import {
|
||||||
|
fileIdToInputDocument,
|
||||||
|
fileIdToInputPhoto,
|
||||||
|
parseFileId,
|
||||||
|
tdFileId,
|
||||||
|
} from '@mtcute/file-id'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a single media.
|
* Send a single media.
|
||||||
*
|
*
|
||||||
* @param chatId ID of the chat, its username, phone or `"me"` or `"self"`
|
* @param chatId ID of the chat, its username, phone or `"me"` or `"self"`
|
||||||
* @param media Media contained in the message
|
* @param media
|
||||||
|
* Media contained in the message. You can also pass TDLib
|
||||||
|
* and Bot API compatible File ID, which will be wrapped
|
||||||
|
* in {@link InputMedia.auto}
|
||||||
* @param params Additional sending parameters
|
* @param params Additional sending parameters
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export async function sendMedia(
|
export async function sendMedia(
|
||||||
this: TelegramClient,
|
this: TelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
media: InputMediaLike,
|
media: InputMediaLike | string,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
* Message to reply to. Either a message object or message ID.
|
* Message to reply to. Either a message object or message ID.
|
||||||
|
@ -76,6 +85,13 @@ export async function sendMedia(
|
||||||
): Promise<Message> {
|
): Promise<Message> {
|
||||||
if (!params) params = {}
|
if (!params) params = {}
|
||||||
|
|
||||||
|
if (typeof media === 'string') {
|
||||||
|
media = {
|
||||||
|
type: 'auto',
|
||||||
|
file: media
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (media.type === 'photo') {
|
if (media.type === 'photo') {
|
||||||
return this.sendPhoto(chatId, media.file, {
|
return this.sendPhoto(chatId, media.file, {
|
||||||
caption: media.caption,
|
caption: media.caption,
|
||||||
|
@ -91,13 +107,38 @@ export async function sendMedia(
|
||||||
let mime = 'application/octet-stream'
|
let mime = 'application/octet-stream'
|
||||||
|
|
||||||
const input = media.file
|
const input = media.file
|
||||||
if (typeof input === 'object' && tl.isAnyInputMedia(input)) {
|
if (tdFileId.isFileIdLike(input)) {
|
||||||
inputMedia = input
|
if (typeof input === 'string' && input.match(/^https?:\/\//)) {
|
||||||
} else if (typeof input === 'string' && input.match(/^https?:\/\//)) {
|
inputMedia = {
|
||||||
inputMedia = {
|
_: 'inputMediaDocumentExternal',
|
||||||
_: 'inputMediaDocumentExternal',
|
url: input,
|
||||||
url: input,
|
}
|
||||||
|
} else {
|
||||||
|
const parsed =
|
||||||
|
typeof input === 'string' ? parseFileId(input) : input
|
||||||
|
|
||||||
|
if (parsed.location._ === 'photo') {
|
||||||
|
inputMedia = {
|
||||||
|
_: 'inputMediaPhoto',
|
||||||
|
id: fileIdToInputPhoto(parsed),
|
||||||
|
}
|
||||||
|
} else if (parsed.location._ === 'web') {
|
||||||
|
inputMedia = {
|
||||||
|
_:
|
||||||
|
parsed.type === tdFileId.FileType.Photo
|
||||||
|
? 'inputMediaPhotoExternal'
|
||||||
|
: 'inputMediaDocumentExternal',
|
||||||
|
url: parsed.location.url,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
inputMedia = {
|
||||||
|
_: 'inputMediaDocument',
|
||||||
|
id: fileIdToInputDocument(parsed),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (typeof input === 'object' && tl.isAnyInputMedia(input)) {
|
||||||
|
inputMedia = input
|
||||||
} else if (isUploadedFile(input)) {
|
} else if (isUploadedFile(input)) {
|
||||||
inputFile = input.inputFile
|
inputFile = input.inputFile
|
||||||
mime = input.mime
|
mime = input.mime
|
||||||
|
@ -120,8 +161,8 @@ export async function sendMedia(
|
||||||
const t = media.thumb
|
const t = media.thumb
|
||||||
if (typeof t === 'object' && tl.isAnyInputMedia(t)) {
|
if (typeof t === 'object' && tl.isAnyInputMedia(t)) {
|
||||||
throw new MtCuteArgumentError("Thumbnail can't be InputMedia")
|
throw new MtCuteArgumentError("Thumbnail can't be InputMedia")
|
||||||
} else if (typeof t === 'string' && t.match(/^https?:\/\//)) {
|
} else if (tdFileId.isFileIdLike(t)) {
|
||||||
throw new MtCuteArgumentError("Thumbnail can't be external")
|
throw new MtCuteArgumentError("Thumbnail can't be a URL or a File ID")
|
||||||
} else if (isUploadedFile(t)) {
|
} else if (isUploadedFile(t)) {
|
||||||
thumb = t.inputFile
|
thumb = t.inputFile
|
||||||
} else if (typeof t === 'object' && tl.isAnyInputFile(t)) {
|
} else if (typeof t === 'object' && tl.isAnyInputFile(t)) {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { tl } from '@mtcute/tl'
|
||||||
import { TelegramClient } from '../../client'
|
import { TelegramClient } from '../../client'
|
||||||
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||||
import { normalizeDate, randomUlong } from '../../utils/misc-utils'
|
import { normalizeDate, randomUlong } from '../../utils/misc-utils'
|
||||||
|
import { fileIdToInputPhoto, tdFileId } from '@mtcute/file-id'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a single photo
|
* Send a single photo
|
||||||
|
@ -94,14 +95,23 @@ export async function sendPhoto(
|
||||||
if (!params) params = {}
|
if (!params) params = {}
|
||||||
|
|
||||||
let media: tl.TypeInputMedia
|
let media: tl.TypeInputMedia
|
||||||
if (typeof photo === 'object' && tl.isAnyInputMedia(photo)) {
|
|
||||||
media = photo
|
if (tdFileId.isFileIdLike(photo)) {
|
||||||
} else if (typeof photo === 'string' && photo.match(/^https?:\/\//)) {
|
if (typeof photo === 'string' && photo.match(/^https?:\/\//)) {
|
||||||
media = {
|
media = {
|
||||||
_: 'inputMediaPhotoExternal',
|
_: 'inputMediaPhotoExternal',
|
||||||
url: photo,
|
url: photo,
|
||||||
ttlSeconds: params.ttlSeconds,
|
ttlSeconds: params.ttlSeconds,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const input = fileIdToInputPhoto(photo)
|
||||||
|
media = {
|
||||||
|
_: 'inputMediaPhoto',
|
||||||
|
id: input
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (typeof photo === 'object' && tl.isAnyInputMedia(photo)) {
|
||||||
|
media = photo
|
||||||
} else if (isUploadedFile(photo)) {
|
} else if (isUploadedFile(photo)) {
|
||||||
media = {
|
media = {
|
||||||
_: 'inputMediaUploadedPhoto',
|
_: 'inputMediaUploadedPhoto',
|
||||||
|
|
|
@ -35,7 +35,7 @@ export namespace tdFileId {
|
||||||
* Provided File ID cannot be converted to that TL object.
|
* Provided File ID cannot be converted to that TL object.
|
||||||
*/
|
*/
|
||||||
export class ConversionError extends FileIdError {
|
export class ConversionError extends FileIdError {
|
||||||
constructor (to: string) {
|
constructor(to: string) {
|
||||||
super(`Cannot convert given File ID to ${to}`)
|
super(`Cannot convert given File ID to ${to}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,4 +190,13 @@ export namespace tdFileId {
|
||||||
*/
|
*/
|
||||||
readonly location: TypeRemoteFileLocation
|
readonly location: TypeRemoteFileLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isFileIdLike(
|
||||||
|
obj: any
|
||||||
|
): obj is string | RawFullRemoteFileLocation {
|
||||||
|
return (
|
||||||
|
typeof obj === 'string' ||
|
||||||
|
(typeof obj === 'object' && obj._ === 'remoteFileLocation')
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue