From 8050f8c5863ed59495b6551345c6ed888cbd2827 Mon Sep 17 00:00:00 2001 From: Alina Sireneva Date: Fri, 8 Dec 2023 04:36:00 +0300 Subject: [PATCH] fix(client): use inputMessageCallbackQuery levin said this has better rate-limits, who am i to judge --- packages/client/src/client.ts | 19 +++++ .../messages/get-callback-query-message.ts | 72 +++++++++++++++++++ .../client/src/types/bots/callback-query.ts | 16 ++++- .../dispatcher/src/context/callback-query.ts | 6 +- 4 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 packages/client/src/methods/messages/get-callback-query-message.ts diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 59216644..7135a45b 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -132,6 +132,7 @@ import { deleteScheduledMessages } from './methods/messages/delete-scheduled-mes import { editInlineMessage } from './methods/messages/edit-inline-message.js' import { editMessage } from './methods/messages/edit-message.js' import { ForwardMessageOptions, forwardMessages, forwardMessagesById } from './methods/messages/forward-messages.js' +import { getCallbackQueryMessage } from './methods/messages/get-callback-query-message.js' import { getDiscussionMessage } from './methods/messages/get-discussion-message.js' import { getHistory, GetHistoryOffset } from './methods/messages/get-history.js' import { getMessageByLink } from './methods/messages/get-message-by-link.js' @@ -3070,6 +3071,23 @@ export interface TelegramClient extends BaseTelegramClient { messages: Message[] }, ): Promise + + /** + * Get the message containing the button being clicked + * in the given callback query. + * **Available**: 🤖 bots only + * + */ + getCallbackQueryMessage( + id: + | CallbackQuery + | tl.RawUpdateBotCallbackQuery + | { + messageId: number + queryId: tl.Long + peer: InputPeerLike + }, + ): Promise // public version of the same method because why not /** * Get discussion message for some channel post. @@ -5281,6 +5299,7 @@ export class TelegramClient extends BaseTelegramClient { editMessage = editMessage.bind(null, this) forwardMessagesById = forwardMessagesById.bind(null, this) forwardMessages = forwardMessages.bind(null, this) + getCallbackQueryMessage = getCallbackQueryMessage.bind(null, this) getDiscussionMessage = getDiscussionMessage.bind(null, this) getHistory = getHistory.bind(null, this) getMessageByLink = getMessageByLink.bind(null, this) diff --git a/packages/client/src/methods/messages/get-callback-query-message.ts b/packages/client/src/methods/messages/get-callback-query-message.ts new file mode 100644 index 00000000..890a8c79 --- /dev/null +++ b/packages/client/src/methods/messages/get-callback-query-message.ts @@ -0,0 +1,72 @@ +import { BaseTelegramClient, tl } from '@mtcute/core' +import { assertTypeIsNot } from '@mtcute/core/utils.js' + +import type { CallbackQuery } from '../../types/bots/callback-query.js' +import { Message } from '../../types/messages/message.js' +import { InputPeerLike, PeersIndex } from '../../types/peers/index.js' +import { isInputPeerChannel, toInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' + +// @available=bot +/** + * Get the message containing the button being clicked + * in the given callback query. + */ +export async function getCallbackQueryMessage( + client: BaseTelegramClient, + id: + | CallbackQuery + | tl.RawUpdateBotCallbackQuery + | { + messageId: number + queryId: tl.Long + peer: InputPeerLike + }, +): Promise { + let msgId: number + let queryId: tl.Long + let peer: tl.TypeInputPeer + + if ('_' in id) { + msgId = id.msgId + queryId = id.queryId + peer = await resolvePeer(client, id.peer) + } else if ('raw' in id) { + msgId = id.messageId + queryId = id.id + peer = id.chat.inputPeer + } else { + msgId = id.messageId + queryId = id.queryId + peer = await resolvePeer(client, id.peer) + } + + const inputMessage: tl.TypeInputMessage = { + _: 'inputMessageCallbackQuery', + id: msgId, + queryId, + } + + const isChannel = isInputPeerChannel(peer) + + const res = await client.call( + isChannel ? + { + _: 'channels.getMessages', + id: [inputMessage], + channel: toInputChannel(peer), + } : + { + _: 'messages.getMessages', + id: [inputMessage], + }, + ) + + assertTypeIsNot('getCallbackQueryMessage', res, 'messages.messagesNotModified') + + if (res.messages[0]._ === 'messageEmpty') { + return null + } + + return new Message(res.messages[0], PeersIndex.from(res)) +} diff --git a/packages/client/src/types/bots/callback-query.ts b/packages/client/src/types/bots/callback-query.ts index c55d0500..2c09250a 100644 --- a/packages/client/src/types/bots/callback-query.ts +++ b/packages/client/src/types/bots/callback-query.ts @@ -3,6 +3,7 @@ import { BasicPeerType, getBasicPeerType, getMarkedPeerId, MtArgumentError, tl } import { makeInspectable, utf8Decode } from '../../utils/index.js' import { encodeInlineMessageId } from '../../utils/inline-utils.js' import { memoizeGetters } from '../../utils/memoize.js' +import { Chat } from '../peers/chat.js' import { PeersIndex } from '../peers/peers-index.js' import { User } from '../peers/user.js' @@ -93,6 +94,19 @@ export class CallbackQuery { return getMarkedPeerId(this.raw.peer) } + /** + * Chat where this message was sent + * + * Only available in case `isInline = false` + */ + get chat(): Chat { + if (this.raw._ !== 'updateBotCallbackQuery') { + throw new MtArgumentError('Cannot get message id for inline callback') + } + + return new Chat(this._peers.get(this.raw.peer)) + } + /** * Basic peer type of the chat where this message was sent, * derived based on {@link chatId} @@ -148,5 +162,5 @@ export class CallbackQuery { } } -memoizeGetters(CallbackQuery, ['user', 'dataStr']) +memoizeGetters(CallbackQuery, ['user', 'chat', 'dataStr', 'inlineMessageIdStr']) makeInspectable(CallbackQuery) diff --git a/packages/dispatcher/src/context/callback-query.ts b/packages/dispatcher/src/context/callback-query.ts index 210681a7..c6f9bcfe 100644 --- a/packages/dispatcher/src/context/callback-query.ts +++ b/packages/dispatcher/src/context/callback-query.ts @@ -31,19 +31,17 @@ export class CallbackQueryContext extends CallbackQuery implements UpdateContext } /** - * * Message that contained the callback button that was clicked. + * Get the message containing the callback button being clicked. * * Note that the message may have been deleted, in which case * `MessageNotFoundError` is thrown. - * - * Can only be used if `isInline = false` */ async getMessage() { if (this.raw._ !== 'updateBotCallbackQuery') { throw new MtArgumentError('Cannot get message for inline callback query') } - const [msg] = await this.client.getMessages(this.raw.peer, this.raw.msgId) + const msg = await this.client.getCallbackQueryMessage(this) if (!msg) { throw new MtMessageNotFoundError(getMarkedPeerId(this.raw.peer), this.raw.msgId, 'Message not found')