feat(client): support more service messages

This commit is contained in:
teidesu 2021-05-10 16:29:33 +03:00
parent 977527b78a
commit e28ec79110
2 changed files with 434 additions and 144 deletions

View file

@ -0,0 +1,42 @@
/**
* Phone call discard reason. Can be:
* - `missed`: The call was missed
* - `disconnect`: The connection has interrupted
* - `hangup`: The call was ended normally
* - `busy`: The call was discarded because the user is in another call
*/
import { tl } from '@mtcute/tl'
export type CallDiscardReason = 'missed' | 'disconnect' | 'hangup' | 'busy'
/** @internal */
export function _callDiscardReasonFromTl(
raw: tl.TypePhoneCallDiscardReason
): CallDiscardReason {
switch (raw._) {
case 'phoneCallDiscardReasonMissed':
return 'missed'
case 'phoneCallDiscardReasonDisconnect':
return 'disconnect'
case 'phoneCallDiscardReasonHangup':
return 'hangup'
case 'phoneCallDiscardReasonBusy':
return 'busy'
}
}
/** @internal */
export function _callDiscardReasonToTl(
r: CallDiscardReason
): tl.TypePhoneCallDiscardReason {
switch (r) {
case 'missed':
return { _: 'phoneCallDiscardReasonMissed' }
case 'disconnect':
return { _: 'phoneCallDiscardReasonDisconnect' }
case 'hangup':
return { _: 'phoneCallDiscardReasonHangup' }
case 'busy':
return { _: 'phoneCallDiscardReasonBusy' }
}
}

View file

@ -29,6 +29,10 @@ import {
WebPage, WebPage,
} from '../media' } from '../media'
import { parseDocument } from '../media/document-utils' import { parseDocument } from '../media/document-utils'
import {
_callDiscardReasonFromTl,
CallDiscardReason,
} from '../calls/discard-reason'
/** /**
* A message or a service message * A message or a service message
@ -152,6 +156,134 @@ export namespace Message {
readonly inviter: number readonly inviter: number
} }
/** A payment was received from a user (bot) */
export interface ActionPaymentReceived {
readonly type: 'payment_received'
/** Three-letter ISO 4217 currency code */
readonly currency: string
/**
* Price of the product in the smallest units of the currency
* (integer, not float/double). For example, for a price of
* `US$ 1.45`, `amount = 145`
*/
readonly amount: tl.Long
/** Bot specified invoice payload */
readonly payload: Buffer
/** Order information provided by the user */
readonly info?: tl.TypePaymentRequestedInfo
/** ID of the shipping option chosen by the user */
readonly shippingOptionId?: string
/** Payment provider ID */
readonly charge?: tl.TypePaymentCharge
}
/** A payment was sent to a user */
export interface ActionPaymentSent {
readonly type: 'payment_sent'
/** Three-letter ISO 4217 currency code */
readonly currency: string
/**
* Price of the product in the smallest units of the currency
* (integer, not float/double). For example, for a price of
* `US$ 1.45`, `amount = 145`
*/
readonly amount: tl.Long
}
/** A phone call */
export interface ActionCall {
readonly type: 'call'
/** Call ID */
readonly id: tl.Long
/** Whether this is a video call */
readonly isVideo: boolean
/** Duration if the call in seconds (0 if not available) */
readonly duration: number
/** Call discard reason, if available */
readonly reason?: CallDiscardReason
}
/** A screenshot was taken */
export interface ActionScreenshotTaken {
readonly type: 'screenshot_taken'
}
/** User has authorized via the bot */
export interface ActionBotAllowed {
readonly type: 'bot_allowed'
/** Domain where the user has logged in */
readonly domain: string
}
/**
* A user is in proximity of another user
* (see [Proximity alerts]{https://core.telegram.org/api/live-location#proximity-alert})
*/
export interface ActionGeoProximity {
readonly type: 'geo_proximity'
/** ID of the user who sent the geolocation with proximity alerts */
readonly targetId: number
/** ID of the user who has approached `targetId` */
readonly userId: number
/** Distance between them in meters */
readonly distance: number
}
/** Group call has started */
export interface ActionGroupCallStarted {
readonly type: 'group_call_started'
/** TL object representing the call */
readonly call: tl.TypeInputGroupCall
}
/** Group call has ended */
export interface ActionGroupCallEnded {
readonly type: 'group_call_ended'
/** TL object representing the call */
readonly call: tl.TypeInputGroupCall
/** Duration of the call */
readonly duration: number
}
/** Group call has ended */
export interface ActionGroupInvite {
readonly type: 'group_call_invite'
/** TL object representing the call */
readonly call: tl.TypeInputGroupCall
/** IDs of the users invited to the call */
readonly userIds: number[]
}
/** Messages TTL changed */
export interface ActionSetTtl {
readonly type: 'set_ttl'
/** New TTL period */
readonly period: number
}
/** Information about a forward */
export interface MessageForwardInfo { export interface MessageForwardInfo {
/** /**
* Date the original message was sent * Date the original message was sent
@ -193,6 +325,16 @@ export namespace Message {
| ActionUserLeft | ActionUserLeft
| ActionUserRemoved | ActionUserRemoved
| ActionUserJoinedLink | ActionUserJoinedLink
| ActionPaymentReceived
| ActionPaymentSent
| ActionCall
| ActionScreenshotTaken
| ActionBotAllowed
| ActionGeoProximity
| ActionGroupCallStarted
| ActionGroupCallEnded
| ActionGroupInvite
| ActionSetTtl
| null | null
// todo: venue, poll, invoice, successful_payment, // todo: venue, poll, invoice, successful_payment,
@ -245,12 +387,12 @@ export class Message {
private _emptyError?: MtCuteEmptyError private _emptyError?: MtCuteEmptyError
constructor ( constructor(
client: TelegramClient, client: TelegramClient,
raw: tl.TypeMessage, raw: tl.TypeMessage,
users: Record<number, tl.TypeUser>, users: Record<number, tl.TypeUser>,
chats: Record<number, tl.TypeChat>, chats: Record<number, tl.TypeChat>,
isScheduled = false, isScheduled = false
) { ) {
this.client = client this.client = client
this._users = users this._users = users
@ -286,7 +428,7 @@ export class Message {
readonly isScheduled: boolean readonly isScheduled: boolean
/** Unique message identifier inside this chat */ /** Unique message identifier inside this chat */
get id (): number { get id(): number {
return this.raw.id return this.raw.id
} }
@ -295,7 +437,7 @@ export class Message {
* *
* `null` for service messages and non-post messages. * `null` for service messages and non-post messages.
*/ */
get views (): number | null { get views(): number | null {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
return this.raw._ === 'message' ? this.raw.views ?? null : null return this.raw._ === 'message' ? this.raw.views ?? null : null
@ -307,7 +449,7 @@ export class Message {
* - Messages sent by you to other chats are outgoing (`outgoing = true`) * - Messages sent by you to other chats are outgoing (`outgoing = true`)
* - Messages to yourself (i.e. *Saved Messages*) are incoming (`outgoing = false`) * - Messages to yourself (i.e. *Saved Messages*) are incoming (`outgoing = false`)
*/ */
get outgoing (): boolean { get outgoing(): boolean {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
return this.raw.out! return this.raw.out!
@ -319,7 +461,7 @@ export class Message {
* *
* `null` for service messages and non-grouped messages * `null` for service messages and non-grouped messages
*/ */
get groupedId (): tl.Long | null { get groupedId(): tl.Long | null {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
return this.raw._ === 'message' ? this.raw.groupedId ?? null : null return this.raw._ === 'message' ? this.raw.groupedId ?? null : null
@ -340,7 +482,7 @@ export class Message {
* If the message is a forwarded channel post, * If the message is a forwarded channel post,
* sender is the channel itself. * sender is the channel itself.
*/ */
get sender (): User | Chat { get sender(): User | Chat {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
if (this._sender === undefined) { if (this._sender === undefined) {
@ -352,18 +494,15 @@ export class Message {
// forwarded channel post // forwarded channel post
this._sender = new Chat( this._sender = new Chat(
this.client, this.client,
this._chats[from.channelId], this._chats[from.channelId]
) )
} else if (from._ === 'peerUser') { } else if (from._ === 'peerUser') {
this._sender = new User( this._sender = new User(this.client, this._users[from.userId])
this.client,
this._users[from.userId],
)
} else } else
throw new MtCuteTypeAssertionError( throw new MtCuteTypeAssertionError(
'Message#sender (@ raw.fromId)', 'Message#sender (@ raw.fromId)',
'peerUser | peerChannel', 'peerUser | peerChannel',
from._, from._
) )
} }
@ -375,7 +514,7 @@ export class Message {
/** /**
* Conversation the message belongs to * Conversation the message belongs to
*/ */
get chat (): Chat { get chat(): Chat {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
if (this._chat === undefined) { if (this._chat === undefined) {
@ -383,7 +522,7 @@ export class Message {
this.client, this.client,
this.raw, this.raw,
this._users, this._users,
this._chats, this._chats
) )
} }
@ -393,7 +532,7 @@ export class Message {
/** /**
* Date the message was sent * Date the message was sent
*/ */
get date (): Date { get date(): Date {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
return new Date(this.raw.date * 1000) return new Date(this.raw.date * 1000)
@ -404,7 +543,7 @@ export class Message {
/** /**
* If this message is a forward, contains info about it. * If this message is a forward, contains info about it.
*/ */
get forward (): Message.MessageForwardInfo | null { get forward(): Message.MessageForwardInfo | null {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
if (!this._forward) { if (!this._forward) {
@ -420,18 +559,18 @@ export class Message {
if (fwd.fromId._ === 'peerChannel') { if (fwd.fromId._ === 'peerChannel') {
sender = new Chat( sender = new Chat(
this.client, this.client,
this._chats[fwd.fromId.channelId], this._chats[fwd.fromId.channelId]
) )
} else if (fwd.fromId._ === 'peerUser') { } else if (fwd.fromId._ === 'peerUser') {
sender = new User( sender = new User(
this.client, this.client,
this._users[fwd.fromId.userId], this._users[fwd.fromId.userId]
) )
} else } else
throw new MtCuteTypeAssertionError( throw new MtCuteTypeAssertionError(
'Message#forward (@ raw.fwdFrom.fromId)', 'Message#forward (@ raw.fwdFrom.fromId)',
'peerUser | peerChannel', 'peerUser | peerChannel',
fwd.fromId._, fwd.fromId._
) )
} else { } else {
this._forward = null this._forward = null
@ -454,7 +593,7 @@ export class Message {
* For replies, the ID of the message that current message * For replies, the ID of the message that current message
* replies to. * replies to.
*/ */
get replyToMessageId (): number | null { get replyToMessageId(): number | null {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
return this.raw.replyTo?.replyToMsgId ?? null return this.raw.replyTo?.replyToMsgId ?? null
@ -463,7 +602,7 @@ export class Message {
/** /**
* Whether this message contains mention of the current user * Whether this message contains mention of the current user
*/ */
get mentioned (): boolean { get mentioned(): boolean {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
return !!this.raw.mentioned return !!this.raw.mentioned
@ -474,7 +613,7 @@ export class Message {
* If this message is generated from an inline query, * If this message is generated from an inline query,
* information about the bot which generated it * information about the bot which generated it
*/ */
get viaBot (): User | null { get viaBot(): User | null {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
if (this._viaBot === undefined) { if (this._viaBot === undefined) {
@ -483,7 +622,7 @@ export class Message {
} else { } else {
this._viaBot = new User( this._viaBot = new User(
this.client, this.client,
this._users[this.raw.viaBotId], this._users[this.raw.viaBotId]
) )
} }
} }
@ -497,7 +636,7 @@ export class Message {
* Empty string for service messages * Empty string for service messages
* (you should handle i18n yourself) * (you should handle i18n yourself)
*/ */
get text (): string { get text(): string {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
return this.raw._ === 'messageService' ? '' : this.raw.message return this.raw._ === 'messageService' ? '' : this.raw.message
@ -507,7 +646,7 @@ export class Message {
/** /**
* Message text/caption entities (may be empty) * Message text/caption entities (may be empty)
*/ */
get entities (): MessageEntity[] { get entities(): MessageEntity[] {
if (this._emptyError) throw this._emptyError if (this._emptyError) throw this._emptyError
if (!this._entities) { if (!this._entities) {
@ -530,7 +669,7 @@ export class Message {
* *
* For unsupported events, use `.raw.action` directly. * For unsupported events, use `.raw.action` directly.
*/ */
get action (): Message.MessageAction { get action(): Message.MessageAction {
if (!this._action) { if (!this._action) {
if (this.raw._ === 'message') { if (this.raw._ === 'message') {
this._action = null this._action = null
@ -538,86 +677,184 @@ export class Message {
const act = this.raw.action const act = this.raw.action
let action: Message.MessageAction let action: Message.MessageAction
if (act._ === 'messageActionChatCreate') { switch (act._) {
action = { case 'messageActionChatCreate':
type: 'chat_created',
title: act.title,
users: act.users,
}
} else if (act._ === 'messageActionChannelCreate') {
action = {
type: 'channel_created',
title: act.title,
}
} else if (act._ === 'messageActionChatMigrateTo') {
action = {
type: 'chat_migrate_to',
id: act.channelId,
}
} else if (act._ === 'messageActionChannelMigrateFrom') {
action = {
type: 'channel_migrate_from',
id: act.chatId,
title: act.title,
}
} else if (act._ === 'messageActionPinMessage') {
action = {
type: 'message_pinned',
}
} else if (act._ === 'messageActionHistoryClear') {
action = {
type: 'history_cleared',
}
} else if (act._ === 'messageActionGameScore') {
action = {
type: 'game_score',
gameId: act.gameId,
score: act.score,
}
} else if (act._ === 'messageActionContactSignUp') {
action = {
type: 'contact_joined',
}
} else if (act._ === 'messageActionChatEditTitle') {
action = {
type: 'title_changed',
title: act.title,
}
} else if (act._ === 'messageActionChatEditPhoto') {
action = {
type: 'photo_changed',
photo: new Photo(this.client, act.photo as tl.RawPhoto),
}
} else if (act._ === 'messageActionChatDeletePhoto') {
action = {
type: 'photo_deleted',
}
} else if (act._ === 'messageActionChatAddUser') {
action = {
type: 'users_added',
users: act.users,
}
} else if (act._ === 'messageActionChatDeleteUser') {
if (
this.raw.fromId?._ === 'peerUser' &&
act.userId === this.raw.fromId.userId
) {
action = { action = {
type: 'user_left', type: 'chat_created',
title: act.title,
users: act.users,
} }
} else { break
case 'messageActionChannelCreate':
action = { action = {
type: 'user_removed', type: 'channel_created',
user: act.userId, title: act.title,
} }
} break
} else if (act._ === 'messageActionChatJoinedByLink') { case 'messageActionChatMigrateTo':
action = { action = {
type: 'user_joined_link', type: 'chat_migrate_to',
inviter: act.inviterId, id: act.channelId,
} }
} else { break
action = null case 'messageActionChannelMigrateFrom':
action = {
type: 'channel_migrate_from',
id: act.chatId,
title: act.title,
}
break
case 'messageActionPinMessage':
action = {
type: 'message_pinned',
}
break
case 'messageActionHistoryClear':
action = {
type: 'history_cleared',
}
break
case 'messageActionGameScore':
action = {
type: 'game_score',
gameId: act.gameId,
score: act.score,
}
break
case 'messageActionContactSignUp':
action = {
type: 'contact_joined',
}
break
case 'messageActionChatEditTitle':
action = {
type: 'title_changed',
title: act.title,
}
break
case 'messageActionChatEditPhoto':
action = {
type: 'photo_changed',
photo: new Photo(
this.client,
act.photo as tl.RawPhoto
),
}
break
case 'messageActionChatDeletePhoto':
action = {
type: 'photo_deleted',
}
break
case 'messageActionChatAddUser':
action = {
type: 'users_added',
users: act.users,
}
break
case 'messageActionChatDeleteUser':
if (
this.raw.fromId?._ === 'peerUser' &&
act.userId === this.raw.fromId.userId
) {
action = {
type: 'user_left',
}
} else {
action = {
type: 'user_removed',
user: act.userId,
}
}
break
case 'messageActionChatJoinedByLink':
action = {
type: 'user_joined_link',
inviter: act.inviterId,
}
break
case 'messageActionPaymentSentMe':
action = {
type: 'payment_received',
currency: act.currency,
amount: act.totalAmount,
payload: act.payload,
info: act.info,
shippingOptionId: act.shippingOptionId,
charge: act.charge,
}
break
case 'messageActionPaymentSent':
action = {
type: 'payment_sent',
currency: act.currency,
amount: act.totalAmount,
}
break
case 'messageActionPhoneCall':
action = {
type: 'call',
id: act.callId,
isVideo: !!act.video,
reason: act.reason
? _callDiscardReasonFromTl(act.reason)
: undefined,
duration: act.duration ?? 0,
}
break
case 'messageActionScreenshotTaken':
action = {
type: 'screenshot_taken'
}
break
case 'messageActionBotAllowed':
action = {
type: 'bot_allowed',
domain: act.domain
}
break
case 'messageActionGeoProximityReached':
if (act.fromId._ !== 'peerUser' || act.toId._ !== 'peerUser') {
action = null
} else {
action = {
type: 'geo_proximity',
targetId: act.toId.userId,
userId: act.fromId.userId,
distance: act.distance
}
}
break
case 'messageActionGroupCall':
if (act.duration) {
action = {
type: 'group_call_ended',
call: act.call,
duration: act.duration
}
} else {
action = {
type: 'group_call_started',
call: act.call
}
}
break
case 'messageActionInviteToGroupCall':
action = {
type: 'group_call_invite',
call: act.call,
userIds: act.users
}
break
case 'messageActionSetMessagesTTL':
action = {
type: 'set_ttl',
period: act.period
}
break
default:
action = null
break
} }
this._action = action this._action = action
@ -634,7 +871,7 @@ export class Message {
* *
* For unsupported media types, use `.raw.media` directly. * For unsupported media types, use `.raw.media` directly.
*/ */
get media (): Message.MessageMedia { get media(): Message.MessageMedia {
if (this._media === undefined) { if (this._media === undefined) {
if ( if (
this.raw._ === 'messageService' || this.raw._ === 'messageService' ||
@ -676,7 +913,12 @@ export class Message {
} else if (m._ === 'messageMediaVenue') { } else if (m._ === 'messageMediaVenue') {
media = new Venue(this.client, m) media = new Venue(this.client, m)
} else if (m._ === 'messageMediaPoll') { } else if (m._ === 'messageMediaPoll') {
media = new Poll(this.client, m.poll, this._users, m.results) media = new Poll(
this.client,
m.poll,
this._users,
m.results
)
} else if (m._ === 'messageMediaInvoice') { } else if (m._ === 'messageMediaInvoice') {
media = new Invoice(this.client, m) media = new Invoice(this.client, m)
} else { } else {
@ -694,7 +936,7 @@ export class Message {
/** /**
* Reply markup provided with this message, if any. * Reply markup provided with this message, if any.
*/ */
get markup (): ReplyMarkup | null { get markup(): ReplyMarkup | null {
if (this._markup === undefined) { if (this._markup === undefined) {
if (this.raw._ === 'messageService' || !this.raw.replyMarkup) { if (this.raw._ === 'messageService' || !this.raw.replyMarkup) {
this._markup = null this._markup = null
@ -739,7 +981,7 @@ export class Message {
* *
* @throws MtCuteArgumentError In case the chat does not support message links * @throws MtCuteArgumentError In case the chat does not support message links
*/ */
get link (): string { get link(): string {
if (this.chat.type === 'supergroup' || this.chat.type === 'channel') { if (this.chat.type === 'supergroup' || this.chat.type === 'channel') {
if (this.chat.username) { if (this.chat.username) {
return `https://t.me/${this.chat.username}/${this.id}` return `https://t.me/${this.chat.username}/${this.id}`
@ -751,7 +993,7 @@ export class Message {
} }
throw new MtCuteArgumentError( throw new MtCuteArgumentError(
`Cannot generate message link for ${this.chat.type}`, `Cannot generate message link for ${this.chat.type}`
) )
} }
@ -762,7 +1004,7 @@ export class Message {
* *
* @param parseMode Parse mode to use (`null` for default) * @param parseMode Parse mode to use (`null` for default)
*/ */
unparse (parseMode?: string | null): string { unparse(parseMode?: string | null): string {
return this.client return this.client
.getParseMode(parseMode) .getParseMode(parseMode)
.unparse(this.text, this.entities) .unparse(this.text, this.entities)
@ -773,7 +1015,7 @@ export class Message {
* *
* @throws MtCuteArgumentError In case the message is not a reply * @throws MtCuteArgumentError In case the message is not a reply
*/ */
getReplyTo (): Promise<Message> { getReplyTo(): Promise<Message> {
if (!this.replyToMessageId) if (!this.replyToMessageId)
throw new MtCuteArgumentError('This message is not a reply!') throw new MtCuteArgumentError('This message is not a reply!')
@ -790,16 +1032,14 @@ export class Message {
* @param visible Whether the reply should be visible * @param visible Whether the reply should be visible
* @param params * @param params
*/ */
replyText ( replyText(
text: string, text: string,
visible = false, visible = false,
params?: Parameters<TelegramClient['sendText']>[2], params?: Parameters<TelegramClient['sendText']>[2]
): ReturnType<TelegramClient['sendText']> { ): ReturnType<TelegramClient['sendText']> {
if (visible) { if (visible) {
return this.client.sendText(this.chat.inputPeer, text, { return this.client.sendText(this.chat.inputPeer, text, {
...( ...(params || {}),
params || {}
),
replyTo: this.id, replyTo: this.id,
}) })
} }
@ -816,16 +1056,14 @@ export class Message {
* @param visible Whether the reply should be visible * @param visible Whether the reply should be visible
* @param params * @param params
*/ */
replyMedia ( replyMedia(
media: InputMediaLike, media: InputMediaLike,
visible = false, visible = false,
params?: Parameters<TelegramClient['sendMedia']>[2], params?: Parameters<TelegramClient['sendMedia']>[2]
): ReturnType<TelegramClient['sendMedia']> { ): ReturnType<TelegramClient['sendMedia']> {
if (visible) { if (visible) {
return this.client.sendMedia(this.chat.inputPeer, media, { return this.client.sendMedia(this.chat.inputPeer, media, {
...( ...(params || {}),
params || {}
),
replyTo: this.id, replyTo: this.id,
}) })
} }
@ -837,7 +1075,7 @@ export class Message {
* *
* @param revoke Whether to "revoke" (i.e. delete for both sides). Only used for chats and private chats. * @param revoke Whether to "revoke" (i.e. delete for both sides). Only used for chats and private chats.
*/ */
delete (revoke = false): Promise<boolean> { delete(revoke = false): Promise<boolean> {
return this.client.deleteMessages(this.chat.inputPeer, this.id, revoke) return this.client.deleteMessages(this.chat.inputPeer, this.id, revoke)
} }
@ -847,14 +1085,19 @@ export class Message {
* @param notify Whether to send a notification (only for legacy groups and supergroups) * @param notify Whether to send a notification (only for legacy groups and supergroups)
* @param bothSides Whether to pin for both sides (only for private chats) * @param bothSides Whether to pin for both sides (only for private chats)
*/ */
pin (notify = false, bothSides = false): Promise<void> { pin(notify = false, bothSides = false): Promise<void> {
return this.client.pinMessage(this.chat.inputPeer, this.id, notify, bothSides) return this.client.pinMessage(
this.chat.inputPeer,
this.id,
notify,
bothSides
)
} }
/** /**
* Unpin this message. * Unpin this message.
*/ */
unpin (): Promise<void> { unpin(): Promise<void> {
return this.client.pinMessage(this.chat.inputPeer, this.id) return this.client.pinMessage(this.chat.inputPeer, this.id)
} }
@ -863,8 +1106,8 @@ export class Message {
* *
* @link TelegramClient.editMessage * @link TelegramClient.editMessage
*/ */
edit ( edit(
params: Parameters<TelegramClient['editMessage']>[2], params: Parameters<TelegramClient['editMessage']>[2]
): Promise<Message> { ): Promise<Message> {
return this.client.editMessage(this.chat.inputPeer, this.id, params) return this.client.editMessage(this.chat.inputPeer, this.id, params)
} }
@ -879,15 +1122,13 @@ export class Message {
* @param params Additional parameters * @param params Additional parameters
* @link TelegramClient.editMessage * @link TelegramClient.editMessage
*/ */
editText ( editText(
text: string, text: string,
params?: Omit<Parameters<TelegramClient['editMessage']>[2], 'text'>, params?: Omit<Parameters<TelegramClient['editMessage']>[2], 'text'>
): Promise<Message> { ): Promise<Message> {
return this.edit({ return this.edit({
text, text,
...( ...(params || {}),
params || {}
),
}) })
} }
@ -903,23 +1144,31 @@ export class Message {
* @param toChatId Target chat ID * @param toChatId Target chat ID
* @param params Copy parameters * @param params Copy parameters
*/ */
sendCopy (toChatId: InputPeerLike, params: Parameters<TelegramClient['sendCopy']>[3]): Promise<Message> { sendCopy(
toChatId: InputPeerLike,
params: Parameters<TelegramClient['sendCopy']>[3]
): Promise<Message> {
if (!params) params = {} if (!params) params = {}
if (this.raw._ === 'messageService') { if (this.raw._ === 'messageService') {
throw new MtCuteArgumentError('Service messages can\'t be copied') throw new MtCuteArgumentError("Service messages can't be copied")
} }
if (this.media && !( if (this.media && !(this.media instanceof WebPage)) {
this.media instanceof WebPage return this.client.sendMedia(
)) { toChatId,
return this.client.sendMedia(toChatId, { {
type: 'auto', type: 'auto',
file: this.media.inputMedia, file: this.media.inputMedia,
caption: params.caption ?? this.raw.message, caption: params.caption ?? this.raw.message,
// we shouldn't use original entities if the user wants custom text // we shouldn't use original entities if the user wants custom text
entities: params.entities ?? params.caption ? undefined : this.raw.entities, entities:
}, params) params.entities ?? params.caption
? undefined
: this.raw.entities,
},
params
)
} }
return this.client.sendText(toChatId, this.raw.message, params) return this.client.sendText(toChatId, this.raw.message, params)
@ -940,5 +1189,4 @@ export class Message {
} }
} }
makeInspectable(Message, ['empty', 'isScheduled'], ['link']) makeInspectable(Message, ['empty', 'isScheduled'], ['link'])