diff --git a/packages/client/src/types/media/audio.ts b/packages/client/src/types/media/audio.ts index 7b13cdaf..bb65fc35 100644 --- a/packages/client/src/types/media/audio.ts +++ b/packages/client/src/types/media/audio.ts @@ -48,4 +48,4 @@ export class Audio extends RawDocument { } } -makeInspectable(Audio, ['fileSize', 'dcId']) +makeInspectable(Audio, ['fileSize', 'dcId'], ['inputMedia']) diff --git a/packages/client/src/types/media/contact.ts b/packages/client/src/types/media/contact.ts index 9f9bb5bd..0cf2a19e 100644 --- a/packages/client/src/types/media/contact.ts +++ b/packages/client/src/types/media/contact.ts @@ -38,6 +38,18 @@ export class Contact { get userId(): number { return this.obj.userId } + + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} + */ + get inputMedia(): tl.TypeInputMedia { + return { + ...this.obj, + _: 'inputMediaContact', + } + } } -makeInspectable(Contact) +makeInspectable(Contact, undefined, ['inputMedia']) diff --git a/packages/client/src/types/media/dice.ts b/packages/client/src/types/media/dice.ts index bbe94b65..05ac6707 100644 --- a/packages/client/src/types/media/dice.ts +++ b/packages/client/src/types/media/dice.ts @@ -159,6 +159,21 @@ export class Dice { get value(): number { return this.obj.value } + + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} + * + * Note that when you use this media, a new `value` + * will be generated! + */ + get inputMedia(): tl.TypeInputMedia { + return { + _: 'inputMediaDice', + emoticon: this.obj.emoticon + } + } } -makeInspectable(Dice) +makeInspectable(Dice, undefined, ['inputMedia']) diff --git a/packages/client/src/types/media/document.ts b/packages/client/src/types/media/document.ts index 6f4cbd19..4b085269 100644 --- a/packages/client/src/types/media/document.ts +++ b/packages/client/src/types/media/document.ts @@ -111,29 +111,16 @@ export class RawDocument extends FileLocation { /** * Input media TL object generated from this object, - * to be used inside {@link InputMediaLike} + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} */ - get inputMediaTl(): tl.TypeInputMedia { + get inputMedia(): tl.TypeInputMedia { return { _: 'inputMediaDocument', id: this.inputDocument } } - /** - * Input media object generated from this object, - * to be used with {@link TelegramClient.sendMedia} - */ - get inputMedia(): InputMediaLike { - return { - // type is only really used for creating tl.InputMedia, - // but since we are providing it directly, we can use `auto` - type: 'auto', - file: this.inputMediaTl - // other fields are not needed since it's a forwarded media - } - } - protected _fileIdType(): td.FileType { return td.FileType.Document } @@ -185,4 +172,4 @@ export class RawDocument extends FileLocation { */ export class Document extends RawDocument {} -makeInspectable(Document, ['fileSize', 'dcId']) +makeInspectable(Document, ['fileSize', 'dcId'], ['inputMedia']) diff --git a/packages/client/src/types/media/game.ts b/packages/client/src/types/media/game.ts index 6ae49f52..d9ecd6cb 100644 --- a/packages/client/src/types/media/game.ts +++ b/packages/client/src/types/media/game.ts @@ -79,6 +79,22 @@ export class Game { return this._animation } + + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} + */ + get inputMedia(): tl.TypeInputMedia { + return { + _: 'inputMediaGame', + id: { + _: 'inputGameID', + id: this.game.id, + accessHash: this.game.accessHash + } + } + } } -makeInspectable(Game) +makeInspectable(Game, undefined, ['inputMedia']) diff --git a/packages/client/src/types/media/invoice.ts b/packages/client/src/types/media/invoice.ts index 41c93998..3051dc34 100644 --- a/packages/client/src/types/media/invoice.ts +++ b/packages/client/src/types/media/invoice.ts @@ -2,6 +2,7 @@ import { tl } from '@mtcute/tl' import { TelegramClient } from '../../client' import { makeInspectable } from '../utils' import { WebDocument } from '../files/web-document' +import { MtCuteArgumentError } from '../errors' /** * An invoice @@ -90,6 +91,20 @@ export class Invoice { get startParam(): string { return this.raw.startParam } + + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia}. + * + * Invoice can't provide an input media, since some + * of the data is not available to the user, + * which is required to send it. This getter + * is only provided to allow using `msg.media.inputMedia` + */ + get inputMedia(): tl.TypeInputMedia { + throw new MtCuteArgumentError('Invoice cannot provide an InputMedia') + } } -makeInspectable(Invoice) +makeInspectable(Invoice, undefined, ['inputMedia']) diff --git a/packages/client/src/types/media/location.ts b/packages/client/src/types/media/location.ts index a6307133..c71fb77f 100644 --- a/packages/client/src/types/media/location.ts +++ b/packages/client/src/types/media/location.ts @@ -84,6 +84,23 @@ export class Location { scale: params.scale ?? 1, }) } + + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} + */ + get inputMedia(): tl.TypeInputMedia { + return { + _: 'inputMediaGeoPoint', + geoPoint: { + _: 'inputGeoPoint', + lat: this.geo.lat, + long: this.geo.long, + accuracyRadius: this.geo.accuracyRadius + } + } + } } export class LiveLocation extends Location { @@ -108,8 +125,32 @@ export class LiveLocation extends Location { return this.live.period } + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} + * + * Note that using this will result in an + * independent live geolocation, which + * will not be auto-updated with the current + */ + get inputMedia(): tl.TypeInputMedia { + return { + _: 'inputMediaGeoLive', + geoPoint: { + _: 'inputGeoPoint', + lat: this.geo.lat, + long: this.geo.long, + accuracyRadius: this.geo.accuracyRadius + }, + heading: this.live.heading, + period: this.live.period, + proximityNotificationRadius: this.live.proximityNotificationRadius + } + } + // todo: api to subscribe for real-time updates } -makeInspectable(Location) -makeInspectable(LiveLocation) +makeInspectable(Location, undefined, ['inputMedia']) +makeInspectable(LiveLocation, undefined, ['inputMedia']) diff --git a/packages/client/src/types/media/photo.ts b/packages/client/src/types/media/photo.ts index 4b6535b0..8239466b 100644 --- a/packages/client/src/types/media/photo.ts +++ b/packages/client/src/types/media/photo.ts @@ -109,10 +109,10 @@ export class Photo extends FileLocation { /** * Input media generated from this object, - * to be used in {@link TelegramClient.sendPhoto} - * and {@link InputMediaLike} + * to be used in {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} */ - get inputMediaTl(): tl.TypeInputMedia { + get inputMedia(): tl.TypeInputMedia { return { _: 'inputMediaPhoto', id: { @@ -123,20 +123,6 @@ export class Photo extends FileLocation { }, } } - - /** - * Input media object generated from this object, - * to be used with {@link TelegramClient.sendMedia} - */ - get inputMedia(): InputMediaLike { - return { - // type is only really used for creating tl.InputMedia, - // but since we are providing it directly, we can use `auto` - type: 'auto', - file: this.inputMediaTl, - // other fields are not needed since it's a forwarded media - } - } } -makeInspectable(Photo, ['fileSize', 'dcId', 'width', 'height']) +makeInspectable(Photo, ['fileSize', 'dcId', 'width', 'height'], ['inputMedia']) diff --git a/packages/client/src/types/media/poll.ts b/packages/client/src/types/media/poll.ts index aecc12eb..2ead6446 100644 --- a/packages/client/src/types/media/poll.ts +++ b/packages/client/src/types/media/poll.ts @@ -2,6 +2,7 @@ import { makeInspectable } from '../utils' import { tl } from '@mtcute/tl' import { TelegramClient } from '../../client' import { MessageEntity } from '../messages' +import bigInt from 'big-integer' export namespace Poll { export interface PollAnswer { @@ -180,6 +181,38 @@ export class Poll { .getParseMode(parseMode) .unparse(this.solution, this.solutionEntities!) } + + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} + * + * A few notes: + * - Using this will result in an + * independent poll, which will not + * be auto-updated with the current. + * - If this is a quiz, a normal poll + * will be returned since the client does not + * know the correct answer. + * - This always returns a non-closed poll, + * even if the current poll was closed + */ + get inputMedia(): tl.TypeInputMedia { + return { + _: 'inputMediaPoll', + poll: { + _: 'poll', + closed: false, + id: bigInt.zero, + publicVoters: this.raw.publicVoters, + multipleChoice: this.raw.multipleChoice, + question: this.raw.question, + answers: this.raw.answers, + closePeriod: this.raw.closePeriod, + closeDate: this.raw.closeDate + }, + } + } } -makeInspectable(Poll) +makeInspectable(Poll, undefined, ['inputMedia']) diff --git a/packages/client/src/types/media/sticker.ts b/packages/client/src/types/media/sticker.ts index 7996f819..532aae15 100644 --- a/packages/client/src/types/media/sticker.ts +++ b/packages/client/src/types/media/sticker.ts @@ -158,4 +158,4 @@ export class Sticker extends RawDocument { } } -makeInspectable(Sticker, ['fileSize', 'dcId']) +makeInspectable(Sticker, ['fileSize', 'dcId'], ['inputMedia']) diff --git a/packages/client/src/types/media/venue.ts b/packages/client/src/types/media/venue.ts index 07d84c66..b9e1dda1 100644 --- a/packages/client/src/types/media/venue.ts +++ b/packages/client/src/types/media/venue.ts @@ -3,6 +3,7 @@ import { Location } from './location' import { assertTypeIs } from '../../utils/type-assertion' import { makeInspectable } from '../utils' import { TelegramClient } from '../../client' +import bigInt from 'big-integer' export namespace Venue { export interface VenueSource { @@ -76,6 +77,38 @@ export class Venue { type: this.raw.venueType, } } + + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia} + * + * A few notes: + * - Using this will result in an + * independent poll, which will not + * be auto-updated with the current. + * - If this is a quiz, a normal poll + * will be returned since the client does not + * know the correct answer. + * - This always returns a non-closed poll, + * even if the current poll was closed + */ + get inputMedia(): tl.TypeInputMedia { + return { + _: 'inputMediaVenue', + geoPoint: { + _: 'inputGeoPoint', + lat: (this.raw.geo as tl.RawGeoPoint).lat, + long: (this.raw.geo as tl.RawGeoPoint).long, + accuracyRadius: (this.raw.geo as tl.RawGeoPoint).accuracyRadius, + }, + title: this.raw.title, + address: this.raw.address, + provider: this.raw.provider, + venueId: this.raw.venueId, + venueType: this.raw.venueType + } + } } -makeInspectable(Venue) +makeInspectable(Venue, undefined, ['inputMedia']) diff --git a/packages/client/src/types/media/video.ts b/packages/client/src/types/media/video.ts index e1c4bcad..81eca455 100644 --- a/packages/client/src/types/media/video.ts +++ b/packages/client/src/types/media/video.ts @@ -88,4 +88,4 @@ export class Video extends RawDocument { } } -makeInspectable(Video, ['fileSize', 'dcId']) +makeInspectable(Video, ['fileSize', 'dcId'], ['inputMedia']) diff --git a/packages/client/src/types/media/voice.ts b/packages/client/src/types/media/voice.ts index 553e6b04..7ad1b844 100644 --- a/packages/client/src/types/media/voice.ts +++ b/packages/client/src/types/media/voice.ts @@ -39,4 +39,4 @@ export class Voice extends RawDocument { } } -makeInspectable(Voice, ['fileSize', 'dcId']) +makeInspectable(Voice, ['fileSize', 'dcId'], ['inputMedia']) diff --git a/packages/client/src/types/media/web-page.ts b/packages/client/src/types/media/web-page.ts index 176d1b06..dd017a3e 100644 --- a/packages/client/src/types/media/web-page.ts +++ b/packages/client/src/types/media/web-page.ts @@ -4,6 +4,7 @@ import { TelegramClient } from '../../client' import { RawDocument } from './document' import { parseDocument } from './document-utils' import { makeInspectable } from '../utils' +import { MtCuteArgumentError } from '../errors' /** * Web page preview. @@ -206,6 +207,19 @@ export class WebPage { return this._document } + + /** + * Input media TL object generated from this object, + * to be used inside {@link InputMediaLike} and + * {@link TelegramClient.sendMedia}. + * + * WebPage can't provide an input media, since some + * can only be auto-generated from a link. This getter + * is only provided to allow using `msg.media.inputMedia` + */ + get inputMedia(): tl.TypeInputMedia { + throw new MtCuteArgumentError('WebPage cannot provide an InputMedia') + } } -makeInspectable(WebPage) +makeInspectable(WebPage, undefined, ['inputMedia']) diff --git a/packages/client/src/types/peers/index.ts b/packages/client/src/types/peers/index.ts index bd86fd75..48384cd9 100644 --- a/packages/client/src/types/peers/index.ts +++ b/packages/client/src/types/peers/index.ts @@ -6,6 +6,7 @@ export * from './chat-preview' export { InputChatPermissions } from './chat-permissions' export * from './chat-member' export * from './chat-invite-link' +export * from './typing-status' /** * Peer types that have one-to-one relation to tl.Peer* types. diff --git a/packages/dispatcher/src/updates/user-typing-update.ts b/packages/dispatcher/src/updates/user-typing-update.ts index f0fd9f2a..24b20e2d 100644 --- a/packages/dispatcher/src/updates/user-typing-update.ts +++ b/packages/dispatcher/src/updates/user-typing-update.ts @@ -1,7 +1,13 @@ -import { BasicPeerType, Chat, MtCuteUnsupportedError, TelegramClient, User } from '@mtcute/client' +import { + BasicPeerType, + Chat, + MtCuteUnsupportedError, + TelegramClient, + User, + TypingStatus, +} from '@mtcute/client' import { tl } from '@mtcute/tl' import { getBarePeerId, MAX_CHANNEL_ID } from '@mtcute/core' -import { TypingStatus } from '@mtcute/client/src/types/peers/typing-status' import { makeInspectable } from '@mtcute/client/src/types/utils' /**