diff --git a/.eslintrc.js b/.eslintrc.js index 55f86b8d..b17f58b7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -147,10 +147,7 @@ module.exports = { }, ], 'space-in-parens': 2, - 'key-spacing': [ - 2, - { beforeColon: false, afterColon: true, mode: 'strict' }, - ], + 'key-spacing': [2, { beforeColon: false, afterColon: true, mode: 'strict' }], 'space-infix-ops': 2, 'padding-line-between-statements': [ 'error', @@ -176,10 +173,7 @@ module.exports = { { files: ['**/*.ts', '**/*.tsx'], env: { browser: true, es6: true, node: true }, - extends: [ - 'plugin:@typescript-eslint/strict', - 'plugin:import/typescript', - ], + extends: ['plugin:@typescript-eslint/strict', 'plugin:import/typescript'], globals: { Atomics: 'readonly', SharedArrayBuffer: 'readonly' }, parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint'], @@ -234,6 +228,13 @@ module.exports = { 'no-console': 'off', }, }, + { + files: ['packages/client/src/methods/**/*.ts'], + rules: { + // this + max 3 more + 'max-params': ['error', 4], + }, + }, ], settings: { 'import/resolver': { diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 074671ef..651f5434 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -15,7 +15,7 @@ import { import { AsyncLock, ConditionVariable, Deque, Logger, SortedLinkedList } from '@mtcute/core/utils' import { tdFileId } from '@mtcute/file-id' -import { acceptTos } from './methods/auth/accept-tos' +import { _onAuthorization } from './methods/auth/_initialize' import { checkPassword } from './methods/auth/check-password' import { getPasswordHint } from './methods/auth/get-password-hint' import { logOut } from './methods/auth/log-out' @@ -26,7 +26,6 @@ import { sendCode } from './methods/auth/send-code' import { sendRecoveryCode } from './methods/auth/send-recovery-code' import { signIn } from './methods/auth/sign-in' import { signInBot } from './methods/auth/sign-in-bot' -import { signUp } from './methods/auth/sign-up' import { start } from './methods/auth/start' import { startTest } from './methods/auth/start-test' import { answerCallbackQuery } from './methods/bots/answer-callback-query' @@ -97,7 +96,7 @@ import { findFolder } from './methods/dialogs/find-folder' import { _normalizeInputFolder, getFolders } from './methods/dialogs/get-folders' import { getPeerDialogs } from './methods/dialogs/get-peer-dialogs' import { iterDialogs } from './methods/dialogs/iter-dialogs' -import { setFoldersOrder } from './methods/dialogs/set-folders' +import { setFoldersOrder } from './methods/dialogs/set-folders-order' import { downloadAsBuffer } from './methods/files/download-buffer' import { downloadToFile } from './methods/files/download-file' import { downloadAsIterable } from './methods/files/download-iterable' @@ -319,7 +318,6 @@ import { StoryViewer, StoryViewersList, TakeoutSession, - TermsOfService, TypingStatus, UploadedFile, UploadFileLike, @@ -436,6 +434,13 @@ export interface TelegramClient extends BaseTelegramClient { * @param handler Edit message handler */ on(name: 'edit_message', handler: (upd: Message) => void): this + /** + * Register a message group handler + * + * @param name Event name + * @param handler Message group handler + */ + on(name: 'message_group', handler: (upd: Message[]) => void): this /** * Register a delete message handler * @@ -548,14 +553,8 @@ export interface TelegramClient extends BaseTelegramClient { * @param handler Delete story handler */ on(name: 'delete_story', handler: (upd: DeleteStoryUpdate) => void): this - /** - * Accept the given TOS - * - * **Available**: 👤 users only - * - * @param tosId TOS id - */ - acceptTos(tosId: string): Promise + + _onAuthorization(auth: tl.auth.TypeAuthorization, bot?: boolean): Promise /** * Check your Two-Step verification password and log in * @@ -590,11 +589,13 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param recoveryCode The recovery code sent via email * @returns The authorized user * @throws BadRequestError In case the code is invalid */ - recoverPassword(recoveryCode: string): Promise + recoverPassword(params: { + /** The recovery code sent via email */ + recoveryCode: string + }): Promise /** * Re-send the confirmation code using a different type. * @@ -603,10 +604,14 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param phone Phone number in international format - * @param phoneCodeHash Confirmation code identifier from {@link SentCode} */ - resendCode(phone: string, phoneCodeHash: string): Promise + resendCode(params: { + /** Phone number in international format */ + phone: string + + /** Confirmation code identifier from {@link SentCode} */ + phoneCodeHash: string + }): Promise /** * Simple wrapper that calls {@link start} and then * provided callback function (if any) without the @@ -626,10 +631,12 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param phone Phone number in international format. * @returns An object containing information about the sent confirmation code */ - sendCode(phone: string): Promise + sendCode(params: { + /** Phone number in international format */ + phone: string + }): Promise /** * Send a code to email needed to recover your password * @@ -653,29 +660,18 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param phone Phone number in international format - * @param phoneCodeHash Code identifier from {@link TelegramClient.sendCode} - * @param phoneCode The confirmation code that was received - * @returns - * - If the code was valid and authorization succeeded, the {@link User} is returned. - * - If the given phone number needs to be registered AND the ToS must be accepted, - * an object containing them is returned. - * - If the given phone number needs to be registered, `false` is returned. - * @throws BadRequestError In case the arguments are invalid - * @throws SessionPasswordNeededError In case a password is needed to sign in + * @returns If the code was valid and authorization succeeded, the {@link User} is returned. + * @throws BadRequestError In case the arguments are invalid + * @throws SessionPasswordNeededError In case a password is needed to sign in */ - signIn(phone: string, phoneCodeHash: string, phoneCode: string): Promise - /** - * Register a new user in Telegram. - * - * **Available**: 👤 users only - * - * @param phone Phone number in international format - * @param phoneCodeHash Code identifier from {@link TelegramClient.sendCode} - * @param firstName New user's first name - * @param [lastName=''] New user's last name - */ - signUp(phone: string, phoneCodeHash: string, firstName: string, lastName?: string): Promise + signIn(params: { + /** Phone number in international format */ + phone: string + /** Code identifier from {@link sendCode} */ + phoneCodeHash: string + /** The confirmation code that was received */ + phoneCode: string + }): Promise /** * Utility function to quickly authorize on test DC * using a [Test phone number](https://core.telegram.org/api/auth#test-phone-numbers), @@ -707,25 +703,6 @@ export interface TelegramClient extends BaseTelegramClient { * Override user's DC. Must be a valid test DC. */ dcId?: number - - /** - * First name of the user (used only for sign-up, defaults to 'User') - */ - firstName?: MaybeDynamic - - /** - * Last name of the user (used only for sign-up, defaults to empty) - */ - lastName?: MaybeDynamic - - /** - * By using this method to sign up an account, you are agreeing to Telegram - * ToS. This is required and your account will be banned otherwise. - * See https://telegram.org/tos and https://core.telegram.org/api/terms. - * - * If true, TOS will not be displayed and `tosCallback` will not be called. - */ - acceptTos?: boolean }): Promise /** @@ -796,31 +773,6 @@ export interface TelegramClient extends BaseTelegramClient { */ forceSms?: boolean - /** - * First name of the user (used only for sign-up, defaults to 'User') - */ - firstName?: MaybeDynamic - - /** - * Last name of the user (used only for sign-up, defaults to empty) - */ - lastName?: MaybeDynamic - - /** - * By using this method to sign up an account, you are agreeing to Telegram - * ToS. This is required and your account will be banned otherwise. - * See https://telegram.org/tos and https://core.telegram.org/api/terms. - * - * If true, TOS will not be displayed and `tosCallback` will not be called. - */ - acceptTos?: boolean - - /** - * Custom method to display ToS. Can be used to show a GUI alert of some kind. - * Defaults to `console.log` - */ - tosCallback?: (tos: TermsOfService) => MaybeAsync - /** * Custom method that is called when a code is sent. Can be used * to show a GUI alert of some kind. @@ -849,7 +801,6 @@ export interface TelegramClient extends BaseTelegramClient { */ catchUp?: boolean }): Promise - /** * Send an answer to a callback query. * @@ -865,7 +816,7 @@ export interface TelegramClient extends BaseTelegramClient { * Maximum amount of time in seconds for which * this result can be cached by the client (not server!). * - * Defaults to `0` + * @default 0 */ cacheTime?: number @@ -880,7 +831,7 @@ export interface TelegramClient extends BaseTelegramClient { * Whether to show an alert in the middle of the screen * instead of a notification at the top of the screen. * - * Defaults to `false`. + * @default false */ alert?: boolean @@ -913,7 +864,7 @@ export interface TelegramClient extends BaseTelegramClient { * Maximum number of time in seconds that the results of the * query may be cached on the server for. * - * Defaults to `300` + * @default 300 */ cacheTime?: number @@ -932,7 +883,7 @@ export interface TelegramClient extends BaseTelegramClient { * Whether the results should only be cached on the server * for the user who sent the query. * - * Defaults to `false` + * @default false */ private?: boolean @@ -940,7 +891,7 @@ export interface TelegramClient extends BaseTelegramClient { * Next pagination offset (up to 64 bytes). * * When user has reached the end of the current results, - * it will re-send the inline query with the same text, but + * the client will re-send the inline query with the same text, but * with `offset` set to this value. * * If omitted or empty string is provided, it is assumed that @@ -994,9 +945,14 @@ export interface TelegramClient extends BaseTelegramClient { * **Available**: ✅ both users and bots * * @param queryId Pre-checkout query ID - * @param error If pre-checkout is rejected, error message to show to the user */ - answerPreCheckoutQuery(queryId: tl.Long, error?: string): Promise + answerPreCheckoutQuery( + queryId: tl.Long, + params?: { + /** If pre-checkout is rejected, error message to show to the user */ + error?: string + }, + ): Promise /** * Delete commands for the current bot and the given scope. * @@ -1052,48 +1008,54 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param chatId Chat ID where the message was found - * @param message ID of the message containing the button - * @param data Data contained in the button * @param params */ - getCallbackAnswer( - chatId: InputPeerLike, - message: number, - data: string | Buffer, - params?: { - /** - * Timeout for the query in ms. - * - * Defaults to `10000` (10 sec) - */ - timeout?: number + getCallbackAnswer(params: { + /** Chat ID where the message was found */ + chatId: InputPeerLike - /** - * Whether this is a "play game" button - */ - game?: boolean + /** ID of the message containing the button */ + message: number - /** - * If the button requires password entry, - * your 2FA password. - * - * Your password is never exposed to the - * bot, it is checked by Telegram. - */ - password?: string - }, - ): Promise + /** Data contained in the button */ + data: string | Buffer + + /** + * Timeout for the query in ms. + * + * Defaults to `10000` (10 sec) + */ + timeout?: number + + /** + * Whether this is a "play game" button + */ + game?: boolean + + /** + * If the button requires password entry, your 2FA password. + * + * Your password is never exposed to the bot, + * it is checked by Telegram. + */ + password?: string + }): Promise /** * Get high scores of a game * * **Available**: 🤖 bots only * - * @param chatId ID of the chat where the game was found - * @param message ID of the message containing the game - * @param userId ID of the user to find high scores for */ - getGameHighScores(chatId: InputPeerLike, message: number, userId?: InputPeerLike): Promise + getGameHighScores(params: { + /** ID of the chat where the game was found */ + chatId: InputPeerLike + + /** ID of the message containing the game */ + message: number + + /** ID of the user to find high scores for */ + userId?: InputPeerLike + }): Promise /** * Get high scores of a game from an inline message * @@ -1178,12 +1140,16 @@ export interface TelegramClient extends BaseTelegramClient { setGameScore(params: { /** Chat where the game was found */ chatId: InputPeerLike + /** ID of the message where the game was found */ message: number + /** ID of the user who has scored */ userId: InputPeerLike + /** The new score (must be >0) */ score: number + /** * When `true`, the game message will not be modified * to include the new score @@ -1256,22 +1222,34 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 🤖 bots only * - * @param target Whether to target groups or channels. - * @param rights The default chat permissions. */ - setMyDefaultRights(target: 'channel' | 'group', rights: Omit): Promise + setMyDefaultRights(params: { + /** Whether to target groups or channels. */ + target: 'channel' | 'group' + /** The default chat permissions. */ + rights: Omit + }): Promise /** - * Add new members to a group, supergroup or channel. + * Add one or more new members to a group, supergroup or channel. * * **Available**: 👤 users only * * @param chatId ID of the chat or its username - * @param users ID(s) of the users, their username(s) or phone(s). - * @param [forwardCount=100] - * Number of old messages to be forwarded (0-100). - * Only applicable to legacy groups, ignored for supergroups and channels + * @param users ID(s) of the user(s) to add */ - addChatMembers(chatId: InputPeerLike, users: MaybeArray, forwardCount?: number): Promise + addChatMembers( + chatId: InputPeerLike, + users: MaybeArray, + params: { + /** + * Number of old messages to be forwarded (0-100). + * Only applicable to legacy groups, ignored for supergroups and channels + * + * @default 100 + */ + forwardCount?: number + }, + ): Promise /** * Archive one or more chats * @@ -1290,11 +1268,14 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID - * @param peerId User/Channel ID * @returns Service message about removed user, if one was generated. */ - banChatMember(chatId: InputPeerLike, peerId: InputPeerLike): Promise + banChatMember(params: { + /** Chat ID */ + chatId: InputPeerLike + /** ID of the user/channel to ban */ + participantId: InputPeerLike + }): Promise /** * Create a new broadcast channel * @@ -1413,42 +1394,58 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param chat Chat or user ID, username, phone number, `"me"` or `"self"` - * @param [mode='delete'] - * Deletion mode. Can be: - * - `delete`: delete messages (only for yourself) - * - `clear`: delete messages (only for yourself) - * - `revoke`: delete messages for all users - * - I'm not sure what's the difference between `delete` and `clear`, - * but they are in fact different flags in TL object. - * @param [maxId=0] Maximum ID of message to delete. Defaults to 0 (remove all messages) */ - deleteHistory(chat: InputPeerLike, mode?: 'delete' | 'clear' | 'revoke', maxId?: number): Promise + deleteHistory( + chat: InputPeerLike, + params?: { + /** + * Deletion mode. Can be: + * - `delete`: delete messages (only for yourself) + * - `clear`: delete messages (only for yourself) + * - `revoke`: delete messages for all users + * - I'm not sure what's the difference between `delete` and `clear`, + * but they are in fact different flags in TL object. + * + * @default 'delete' + */ + mode: 'delete' | 'clear' | 'revoke' + + /** + * Maximum ID of message to delete. + * + * @default 0, i.e. remove all messages + */ + maxId?: number + }, + ): Promise /** * Delete all messages of a user (or channel) in a supergroup * * **Available**: 👤 users only * - * @param chatId Chat ID - * @param participantId User/channel ID */ - deleteUserHistory(chatId: InputPeerLike, participantId: InputPeerLike): Promise + deleteUserHistory(params: { + /** Chat ID */ + chatId: InputPeerLike + /** User/channel ID whose messages to delete */ + participantId: InputPeerLike + }): Promise /** * Edit supergroup/channel admin rights of a user. * * **Available**: ✅ both users and bots * - * @param chatId Chat ID - * @param userId User ID - * @param rights New admin rights - * @param [rank=''] Custom admin rank */ - editAdminRights( - chatId: InputPeerLike, - userId: InputPeerLike, - rights: Omit, - rank?: string, - ): Promise + editAdminRights(params: { + /** Chat ID */ + chatId: InputPeerLike + /** User ID */ + userId: InputPeerLike + /** New admin rights */ + rights: Omit + /** Custom admin rank */ + rank?: string + }): Promise /** * Get chat event log ("Recent actions" in official clients). * @@ -1462,7 +1459,6 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param chatId Chat ID * @param params */ getChatEventLog( @@ -1526,7 +1522,12 @@ export interface TelegramClient extends BaseTelegramClient { * @param userId User ID, username, phone number, `"me"` or `"self"` * @throws UserNotParticipantError In case given user is not a participant of a given chat */ - getChatMember(chatId: InputPeerLike, userId: InputPeerLike): Promise + getChatMember(params: { + /** Chat ID or username */ + chatId: InputPeerLike + /** User ID, username, phone number, `"me"` or `"self"` */ + userId: InputPeerLike + }): Promise /** * Get a chunk of members of some chat. * @@ -1588,7 +1589,7 @@ export interface TelegramClient extends BaseTelegramClient { * * @param inviteLink Invite link * @throws MtArgumentError In case invite link has invalid format - * @throws MtNotFoundError + * @throws MtPeerNotFoundError * In case you are trying to get info about private chat that you have already joined. * Use {@link getChat} or {@link getFullChat} instead. */ @@ -1698,19 +1699,29 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID - * @param userId User ID */ - kickChatMember(chatId: InputPeerLike, userId: InputPeerLike): Promise + kickChatMember(params: { + /** Chat ID */ + chatId: InputPeerLike + /** User ID */ + userId: InputPeerLike + }): Promise /** * Leave a group chat, supergroup or channel * * **Available**: 👤 users only * * @param chatId Chat ID or username - * @param [clear=false] Whether to clear history after leaving (only for legacy group chats) */ - leaveChat(chatId: InputPeerLike, clear?: boolean): Promise + leaveChat( + chatId: InputPeerLike, + params?: { + /** + * Whether to clear history after leaving (only for legacy group chats) + */ + clear?: boolean + }, + ): Promise /** * Mark a chat as unread * @@ -1732,25 +1743,32 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID - * @param userId User ID - * @param restrictions - * Restrictions for the user. Note that unlike Bot API, this object contains - * the restrictions, and not the permissions, i.e. to - * passing `sendMessages=true` will disallow the user to send messages, - * and passing `{}` (empty object) will lift any restrictions - * @param until - * Date when the user will be unrestricted. - * When `number` is passed, UNIX time in ms is expected. - * If this value is less than 30 seconds or more than 366 days in - * the future, user will be restricted forever. Defaults to `0` (forever) */ - restrictChatMember( - chatId: InputPeerLike, - userId: InputPeerLike, - restrictions: Omit, - until?: number | Date, - ): Promise + restrictChatMember(params: { + /** Chat ID */ + chatId: InputPeerLike + + /** User ID */ + userId: InputPeerLike + + /** + * Restrictions for the user. Note that unlike Bot API, this object contains + * the restrictions, and not the permissions, i.e. + * passing `sendMessages=true` will disallow the user to send messages, + * and passing `{}` (empty object) will lift any restrictions + */ + restrictions: Omit + + /** + * Date when the user will be unrestricted. + * When `number` is passed, UNIX time in ms is expected. + * If this value is less than 30 seconds or more than 366 days in + * the future, user will be restricted forever. + * + * @default `0`, i.e. forever + */ + until?: number | Date + }): Promise /** * Save or delete a draft message associated with some chat * @@ -1770,7 +1788,7 @@ export interface TelegramClient extends BaseTelegramClient { * @param chatId Chat ID or username * @param restrictions * Restrictions for the chat. Note that unlike Bot API, this object contains - * the restrictions, and not the permissions, i.e. to + * the restrictions, and not the permissions, i.e. * passing `sendMessages=true` will disallow the users to send messages, * and passing `{}` (empty object) will lift any restrictions */ @@ -1796,19 +1814,23 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID or username - * @param type Media type (photo or video) - * @param media Input media file - * @param previewSec - * When `type = video`, timestamp in seconds which will be shown - * as a static preview. */ - setChatPhoto( - chatId: InputPeerLike, - type: 'photo' | 'video', - media: InputFileLike, - previewSec?: number, - ): Promise + setChatPhoto(params: { + /** Chat ID or username */ + chatId: InputPeerLike + + /** Media type (photo or video) */ + + type: 'photo' | 'video' + + /** Input media file */ + media: InputFileLike + /** + * When `type = video`, timestamp in seconds which will be shown + * as a static preview. + */ + previewSec?: number + }): Promise /** * Change chat title * @@ -1869,22 +1891,21 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param peerId Bot, channel or "me"/"self" */ - toggleFragmentUsername( - peerId: InputPeerLike, - params: { - /** - * Username to toggle - */ - username: string + toggleFragmentUsername(params: { + /** Peer ID whose username to toggle */ + peerId: InputPeerLike - /** - * Whether to enable or disable the username - */ - active: boolean - }, - ): Promise + /** + * Username to toggle + */ + username: string + + /** + * Whether to enable or disable the username + */ + active: boolean + }): Promise /** * Set whether a channel/supergroup has join requests enabled. * @@ -1928,10 +1949,14 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID - * @param peerId User/channel ID */ - unbanChatMember(chatId: InputPeerLike, peerId: InputPeerLike): Promise + unbanChatMember(params: { + /** Chat ID */ + chatId: InputPeerLike + + /** User/channel ID who should be unbanned */ + participantId: InputPeerLike + }): Promise /** * Unban a user/channel from a supergroup or a channel, @@ -1943,43 +1968,45 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID - * @param peerId User/channel ID */ - unrestrictChatMember(chatId: InputPeerLike, peerId: InputPeerLike): Promise + unrestrictChatMember(params: { + /** Chat ID */ + chatId: InputPeerLike + + /** User/channel ID who should be unbanned */ + participantId: InputPeerLike + }): Promise /** * Add an existing Telegram user as a contact * * **Available**: 👤 users only * - * @param userId User ID, username or phone number - * @param params Contact details */ - addContact( - userId: InputPeerLike, - params: { - /** - * First name of the contact - */ - firstName: string + addContact(params: { + /** User ID, username or phone number */ + userId: InputPeerLike - /** - * Last name of the contact - */ - lastName?: string + /** + * First name of the contact + */ + firstName: string - /** - * Phone number of the contact, if available - */ - phone?: string + /** + * Last name of the contact + */ + lastName?: string - /** - * Whether to share your own phone number - * with the newly created contact (defaults to `false`) - */ - sharePhone?: boolean - }, - ): Promise + /** + * Phone number of the contact, if available + */ + phone?: string + + /** + * Whether to share your own phone number + * with the newly created contact (defaults to `false`) + */ + sharePhone?: boolean + }): Promise /** * Delete a single contact from your Telegram contacts list * @@ -2041,18 +2068,20 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param folder - * Folder, folder ID or name. - * Note that passing an ID or name will require re-fetching all folders, - * and passing name might affect not the right folder if you have multiple - * with the same name. - * @param modification Modification that will be applied to this folder * @returns Modified folder */ - editFolder( - folder: tl.RawDialogFilter | number | string, - modification: Partial>, - ): Promise + editFolder(params: { + /** + * Folder, folder ID or name. + * Note that passing an ID or name will require re-fetching all folders, + * and passing name might affect not the right folder if you have multiple + * with the same name. + */ + folder: tl.RawDialogFilter | number | string + + /** Modification to be applied to this folder */ + modification: Partial> + }): Promise /** * Find a folder by its parameter. * @@ -2064,7 +2093,14 @@ export interface TelegramClient extends BaseTelegramClient { * * @param params Search parameters. At least one must be set. */ - findFolder(params: { title?: string; emoji?: string; id?: number }): Promise + findFolder(params: { + /** Folder title */ + title?: string + /** Folder emoji */ + emoji?: string + /** Folder ID */ + id?: number + }): Promise /** * Get list of folders. * **Available**: 👤 users only @@ -2198,10 +2234,9 @@ export interface TelegramClient extends BaseTelegramClient { /** * Reorder folders * - * Order is folder's ID (0 = default folder) - * * **Available**: 👤 users only * + * @param order New order of folders (folder IDs, where default = 0) */ setFoldersOrder(order: number[]): Promise /** @@ -2380,33 +2415,32 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID or username * @returns Service message for the created topic */ - createForumTopic( - chatId: InputPeerLike, - params: { - /** - * Topic title - */ - title: string + createForumTopic(params: { + /** Chat ID or username */ + chatId: InputPeerLike - /** - * Icon of the topic. - * - * Can be a number (color in RGB, see {@link ForumTopic} static members for allowed values) - * or a custom emoji ID. - * - * Icon color can't be changed after the topic is created. - */ - icon?: number | tl.Long + /** + * Topic title + */ + title: string - /** - * Send as a specific channel - */ - sendAs?: InputPeerLike - }, - ): Promise + /** + * Icon of the topic. + * + * Can be a number (color in RGB, see {@link ForumTopic} static members for allowed values) + * or a custom emoji ID. + * + * Icon color can't be changed after the topic is created. + */ + icon?: number | tl.Long + + /** + * Send as a specific channel + */ + sendAs?: InputPeerLike + }): Promise /** * Delete a forum topic and all its history * @@ -2427,24 +2461,25 @@ export interface TelegramClient extends BaseTelegramClient { * @param topicId ID of the topic (i.e. its top message ID) * @returns Service message about the modification */ - editForumTopic( - chatId: InputPeerLike, - topicId: number, - params: { - /** - * New topic title - */ - title?: string + editForumTopic(params: { + /** Chat ID or username */ + chatId: InputPeerLike + /** ID of the topic (i.e. its top message ID) */ - /** - * New icon of the topic. - * - * Can be a custom emoji ID, or `null` to remove the icon - * and use static color instead - */ - icon?: tl.Long | null - }, - ): Promise + topicId: number + /** + * New topic title + */ + title?: string + + /** + * New icon of the topic. + * + * Can be a custom emoji ID, or `null` to remove the icon + * and use static color instead + */ + icon?: tl.Long | null + }): Promise /** * Get a single forum topic by its ID * @@ -2515,23 +2550,21 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID or username - * @param topicId ID of the topic (i.e. its top message ID) */ - reorderPinnedForumTopics( - chatId: InputPeerLike, - params: { - /** - * Order of the pinned topics - */ - order: number[] + reorderPinnedForumTopics(params: { + /** Chat ID or username */ + chatId: InputPeerLike - /** - * Whether to un-pin topics not present in the order - */ - force?: boolean - }, - ): Promise + /** + * Order of the pinned topics + */ + order: number[] + + /** + * Whether to un-pin topics not present in the order + */ + force?: boolean + }): Promise /** * Toggle open/close status of a topic in a forum * @@ -2539,12 +2572,18 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID or username - * @param topicId ID of the topic (i.e. its top message ID) - * @param closed Whether the topic should be closed * @returns Service message about the modification */ - toggleForumTopicClosed(chatId: InputPeerLike, topicId: number, closed: boolean): Promise + toggleForumTopicClosed(parmas: { + /** Chat ID or username */ + chatId: InputPeerLike + + /** ID of the topic (i.e. its top message ID) */ + topicId: number + + /** Whether the topic should be closed */ + closed: boolean + }): Promise /** * Toggle whether a topic in a forum is pinned * @@ -2552,11 +2591,15 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID or username - * @param topicId ID of the topic (i.e. its top message ID) - * @param pinned Whether the topic should be pinned */ - toggleForumTopicPinned(chatId: InputPeerLike, topicId: number, pinned: boolean): Promise + toggleForumTopicPinned(params: { + /** Chat ID or username */ + chatId: InputPeerLike + /** ID of the topic (i.e. its top message ID) */ + topicId: number + /** Whether the topic should be pinned */ + pinned: boolean + }): Promise /** * Set whether a supergroup is a forum. * @@ -2627,31 +2670,31 @@ export interface TelegramClient extends BaseTelegramClient { * @param params * @returns Modified invite link */ - editInviteLink( - chatId: InputPeerLike, - link: string, - params: { - /** - * Date when this link will expire. - * If `number` is passed, UNIX time in ms is expected. - */ - expires?: number | Date + editInviteLink(params: { + /** Chat ID */ + chatId: InputPeerLike + /** Invite link to edit */ + link: string + /** + * Date when this link will expire. + * If `number` is passed, UNIX time in ms is expected. + */ + expires?: number | Date - /** - * Maximum number of users that can be members of this chat - * at the same time after joining using this link. - * - * Integer in range `[1, 99999]` or `Infinity`, - */ - usageLimit?: number + /** + * Maximum number of users that can be members of this chat + * at the same time after joining using this link. + * + * Integer in range `[1, 99999]` or `Infinity`, + */ + usageLimit?: number - /** - * Whether users to be joined via this link need to be - * approved by an admin - */ - withApproval?: boolean - }, - ): Promise + /** + * Whether users to be joined via this link need to be + * approved by an admin + */ + withApproval?: boolean + }): Promise /** * Generate a new primary invite link for a chat, * old primary link is revoked. @@ -2675,7 +2718,7 @@ export interface TelegramClient extends BaseTelegramClient { */ getInviteLinkMembers( chatId: InputPeerLike, - params: { + params?: { /** * Invite link for which to get members */ @@ -2776,21 +2819,31 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param peer Chat/channel ID - * @param action Whether to approve or deny the join requests - * @param link Invite link to target */ - hideAllJoinRequests(peer: InputPeerLike, action: 'approve' | 'deny', link?: string): Promise + hideAllJoinRequests(params: { + /** Chat/channel ID */ + chatId: InputPeerLike + + /** Whether to approve or deny the join requests */ + action: 'approve' | 'deny' + + /** Invite link to target */ + link?: string + }): Promise /** * Approve or deny join request to a chat. * * **Available**: ✅ both users and bots * - * @param peer Chat/channel ID - * @param user User ID - * @param action Whether to approve or deny the join request */ - hideJoinRequest(peer: InputPeerLike, user: InputPeerLike, action: 'approve' | 'deny'): Promise + hideJoinRequest(params: { + /** Chat/channel ID */ + chatId: InputPeerLike + /** User ID */ + user: InputPeerLike + /** Whether to approve or deny the join request */ + action: 'approve' | 'deny' + }): Promise /** * Iterate over users who have joined * the chat with the given invite link. @@ -2802,7 +2855,7 @@ export interface TelegramClient extends BaseTelegramClient { */ iterInviteLinkMembers( chatId: InputPeerLike, - params: Parameters[1] & { + params?: Parameters[1] & { /** * Maximum number of users to return * @@ -2870,10 +2923,13 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param chatId Chat ID where this poll was found - * @param message Message ID where this poll was found */ - closePoll(chatId: InputPeerLike, message: number): Promise + closePoll(params: { + /** Chat ID where this poll was found */ + chatId: InputPeerLike + /** Message ID where this poll was found */ + message: number + }): Promise /** * Delete messages, including service messages. * @@ -2881,10 +2937,20 @@ export interface TelegramClient extends BaseTelegramClient { * * @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`. * @param ids Message(s) ID(s) to delete. - * @param [revoke=true] Whether to "revoke" (i.e. delete for both sides). - * Only used for chats and private chats. */ - deleteMessages(chatId: InputPeerLike, ids: MaybeArray, revoke?: boolean): Promise + deleteMessages( + chatId: InputPeerLike, + ids: MaybeArray, + params?: { + /** + * Whether to "revoke" (i.e. delete for both sides). + * Only used for chats and private chats. + * + * @default true + */ + revoke?: boolean + }, + ): Promise /** * Delete scheduled messages. * @@ -2904,59 +2970,62 @@ export interface TelegramClient extends BaseTelegramClient { * TDLib and Bot API compatible string * @param params */ - editInlineMessage( - messageId: tl.TypeInputBotInlineMessageID | string, - params: { - /** - * New message text - * - * When `media` is passed, `media.caption` is used instead - */ - text?: string | FormattedString + editInlineMessage(params: { + /** + * Inline message ID, either as a TL object, or as a + * TDLib and Bot API compatible string + */ + messageId: tl.TypeInputBotInlineMessageID | string - /** - * Parse mode to use to parse entities before sending - * the message. Defaults to current default parse mode (if any). - * - * Passing `null` will explicitly disable formatting. - */ - parseMode?: string | null + /** + * New message text + * + * When `media` is passed, `media.caption` is used instead + */ + text?: string | FormattedString - /** - * List of formatting entities to use instead of parsing via a - * parse mode. - * - * **Note:** Passing this makes the method ignore {@link parseMode} - * - * When `media` is passed, `media.entities` is used instead - */ - entities?: tl.TypeMessageEntity[] + /** + * Parse mode to use to parse entities before sending + * the message. Defaults to current default parse mode (if any). + * + * Passing `null` will explicitly disable formatting. + */ + parseMode?: string | null - /** - * New message media - */ - media?: InputMediaLike + /** + * List of formatting entities to use instead of parsing via a + * parse mode. + * + * **Note:** Passing this makes the method ignore {@link parseMode} + * + * When `media` is passed, `media.entities` is used instead + */ + entities?: tl.TypeMessageEntity[] - /** - * Whether to disable links preview in this message - */ - disableWebPreview?: boolean + /** + * New message media + */ + media?: InputMediaLike - /** - * For bots: new reply markup. - * If omitted, existing markup will be removed. - */ - replyMarkup?: ReplyMarkup + /** + * Whether to disable links preview in this message + */ + disableWebPreview?: boolean - /** - * For media, upload progress callback. - * - * @param uploaded Number of bytes uploaded - * @param total Total file size in bytes - */ - progressCallback?: (uploaded: number, total: number) => void - }, - ): Promise + /** + * For bots: new reply markup. + * If omitted, existing markup will be removed. + */ + replyMarkup?: ReplyMarkup + + /** + * For media, upload progress callback. + * + * @param uploaded Number of bytes uploaded + * @param total Total file size in bytes + */ + progressCallback?: (uploaded: number, total: number) => void + }): Promise /** * Edit message text, media, reply markup and schedule date. * @@ -2966,66 +3035,67 @@ export interface TelegramClient extends BaseTelegramClient { * @param message Message or its ID * @param params */ - editMessage( - chatId: InputPeerLike, - message: number | Message, - params: { - /** - * New message text - * - * When `media` is passed, `media.caption` is used instead - */ - text?: string | FormattedString + editMessage(params: { + /** Chat ID */ + chatId: InputPeerLike + /** Message to edit */ + message: number | Message - /** - * Parse mode to use to parse entities before sending - * the message. Defaults to current default parse mode (if any). - * - * Passing `null` will explicitly disable formatting. - */ - parseMode?: string | null + /** + * New message text + * + * When `media` is passed, `media.caption` is used instead + */ + text?: string | FormattedString - /** - * List of formatting entities to use instead of parsing via a - * parse mode. - * - * **Note:** Passing this makes the method ignore {@link parseMode} - * - * When `media` is passed, `media.entities` is used instead - */ - entities?: tl.TypeMessageEntity[] + /** + * Parse mode to use to parse entities before sending + * the message. Defaults to current default parse mode (if any). + * + * Passing `null` will explicitly disable formatting. + */ + parseMode?: string | null - /** - * New message media - */ - media?: InputMediaLike + /** + * List of formatting entities to use instead of parsing via a + * parse mode. + * + * **Note:** Passing this makes the method ignore {@link parseMode} + * + * When `media` is passed, `media.entities` is used instead + */ + entities?: tl.TypeMessageEntity[] - /** - * Whether to disable links preview in this message - */ - disableWebPreview?: boolean + /** + * New message media + */ + media?: InputMediaLike - /** - * For bots: new reply markup. - * If omitted, existing markup will be removed. - */ - replyMarkup?: ReplyMarkup + /** + * Whether to disable links preview in this message + */ + disableWebPreview?: boolean - /** - * To re-schedule a message: new schedule date. - * When passing a number, a UNIX time in ms is expected. - */ - scheduleDate?: Date | number + /** + * For bots: new reply markup. + * If omitted, existing markup will be removed. + */ + replyMarkup?: ReplyMarkup - /** - * For media, upload progress callback. - * - * @param uploaded Number of bytes uploaded - * @param total Total file size in bytes - */ - progressCallback?: (uploaded: number, total: number) => void - }, - ): Promise + /** + * To re-schedule a message: new schedule date. + * When passing a number, a UNIX time in ms is expected. + */ + scheduleDate?: Date | number + + /** + * For media, upload progress callback. + * + * @param uploaded Number of bytes uploaded + * @param total Total file size in bytes + */ + progressCallback?: (uploaded: number, total: number) => void + }): Promise _findMessageInUpdate(res: tl.TypeUpdates, isEdit?: boolean): Message /** @@ -3033,92 +3103,92 @@ export interface TelegramClient extends BaseTelegramClient { * * To forward with a caption, use another overload that takes an array of IDs. * - * @param toChatId Destination chat ID, username, phone, `"me"` or `"self"` - * @param fromChatId Source chat ID, username, phone, `"me"` or `"self"` * @param message Message ID * @param params Additional sending parameters * @returns Newly sent, forwarded messages in the destination chat */ - forwardMessages( - toChatId: InputPeerLike, - fromChatId: InputPeerLike, - message: number, - params?: { - /** - * Optionally, a caption for your forwarded message(s). - * It will be sent as a separate message before the forwarded messages. - * - * You can either pass `caption` or `captionMedia`, passing both will - * result in an error - */ - caption?: string | FormattedString + forwardMessages(params: { + /** Source chat ID, username, phone, `"me"` or `"self"` */ + fromChatId: InputPeerLike + /** Destination chat ID, username, phone, `"me"` or `"self"` */ + toChatId: InputPeerLike + /** Message ID */ + messages: number - /** - * Optionally, a media caption for your forwarded message(s). - * It will be sent as a separate message before the forwarded messages. - * - * You can either pass `caption` or `captionMedia`, passing both will - * result in an error - */ - captionMedia?: InputMediaLike + /** + * Optionally, a caption for your forwarded message(s). + * It will be sent as a separate message before the forwarded messages. + * + * You can either pass `caption` or `captionMedia`, passing both will + * result in an error + */ + caption?: string | FormattedString - /** - * Parse mode to use to parse entities in caption. - * Defaults to current default parse mode (if any). - * - * Passing `null` will explicitly disable formatting. - */ - parseMode?: string | null + /** + * Optionally, a media caption for your forwarded message(s). + * It will be sent as a separate message before the forwarded messages. + * + * You can either pass `caption` or `captionMedia`, passing both will + * result in an error + */ + captionMedia?: InputMediaLike - /** - * List of formatting entities in caption to use instead - * of parsing via a parse mode. - * - * **Note:** Passing this makes the method ignore {@link parseMode} - */ - entities?: tl.TypeMessageEntity[] + /** + * Parse mode to use to parse entities in caption. + * Defaults to current default parse mode (if any). + * + * Passing `null` will explicitly disable formatting. + */ + parseMode?: string | null - /** - * Whether to forward silently (also applies to caption message). - */ - silent?: boolean + /** + * List of formatting entities in caption to use instead + * of parsing via a parse mode. + * + * **Note:** Passing this makes the method ignore {@link parseMode} + */ + entities?: tl.TypeMessageEntity[] - /** - * If set, the forwarding will be scheduled to this date - * (also applies to caption message). - * When passing a number, a UNIX time in ms is expected. - * - * You can also pass `0x7FFFFFFE`, this will send the message - * once the peer is online - */ - schedule?: Date | number + /** + * Whether to forward silently (also applies to caption message). + */ + silent?: boolean - /** - * Whether to clear draft after sending this message (only used for caption) - * - * Defaults to `false` - */ - clearDraft?: boolean + /** + * If set, the forwarding will be scheduled to this date + * (also applies to caption message). + * When passing a number, a UNIX time in ms is expected. + * + * You can also pass `0x7FFFFFFE`, this will send the message + * once the peer is online + */ + schedule?: Date | number - /** - * Whether to forward without author - */ - noAuthor?: boolean + /** + * Whether to clear draft after sending this message (only used for caption) + * + * Defaults to `false` + */ + clearDraft?: boolean - /** - * Whether to forward without caption (implies {@link noAuthor}) - */ - noCaption?: boolean + /** + * Whether to forward without author + */ + noAuthor?: boolean - /** - * Whether to disallow further forwards of this message. - * - * Only for bots, works even if the target chat does not - * have content protection. - */ - forbidForwards?: boolean - }, - ): Promise + /** + * Whether to forward without caption (implies {@link noAuthor}) + */ + noCaption?: boolean + + /** + * Whether to disallow further forwards of this message. + * + * Only for bots, works even if the target chat does not + * have content protection. + */ + forbidForwards?: boolean + }): Promise /** * Forward one or more messages, optionally including a caption message. * You can forward no more than 100 messages at once. @@ -3133,86 +3203,88 @@ export interface TelegramClient extends BaseTelegramClient { * Newly sent, forwarded messages in the destination chat. * If a caption message was provided, it will be the first message in the array. */ - forwardMessages( - toChatId: InputPeerLike, - fromChatId: InputPeerLike, - messages: number[], - params?: { - /** - * Optionally, a caption for your forwarded message(s). - * It will be sent as a separate message before the forwarded messages. - * - * You can either pass `caption` or `captionMedia`, passing both will - * result in an error - */ - caption?: string | FormattedString + forwardMessages(params: { + /** Source chat ID, username, phone, `"me"` or `"self"` */ + fromChatId: InputPeerLike + /** Destination chat ID, username, phone, `"me"` or `"self"` */ + toChatId: InputPeerLike + /** Message IDs */ + messages: number[] - /** - * Optionally, a media caption for your forwarded message(s). - * It will be sent as a separate message before the forwarded messages. - * - * You can either pass `caption` or `captionMedia`, passing both will - * result in an error - */ - captionMedia?: InputMediaLike + /** + * Optionally, a caption for your forwarded message(s). + * It will be sent as a separate message before the forwarded messages. + * + * You can either pass `caption` or `captionMedia`, passing both will + * result in an error + */ + caption?: string | FormattedString - /** - * Parse mode to use to parse entities in caption. - * Defaults to current default parse mode (if any). - * - * Passing `null` will explicitly disable formatting. - */ - parseMode?: string | null + /** + * Optionally, a media caption for your forwarded message(s). + * It will be sent as a separate message before the forwarded messages. + * + * You can either pass `caption` or `captionMedia`, passing both will + * result in an error + */ + captionMedia?: InputMediaLike - /** - * List of formatting entities in caption to use instead - * of parsing via a parse mode. - * - * **Note:** Passing this makes the method ignore {@link parseMode} - */ - entities?: tl.TypeMessageEntity[] + /** + * Parse mode to use to parse entities in caption. + * Defaults to current default parse mode (if any). + * + * Passing `null` will explicitly disable formatting. + */ + parseMode?: string | null - /** - * Whether to forward silently (also applies to caption message). - */ - silent?: boolean + /** + * List of formatting entities in caption to use instead + * of parsing via a parse mode. + * + * **Note:** Passing this makes the method ignore {@link parseMode} + */ + entities?: tl.TypeMessageEntity[] - /** - * If set, the forwarding will be scheduled to this date - * (also applies to caption message). - * When passing a number, a UNIX time in ms is expected. - * - * You can also pass `0x7FFFFFFE`, this will send the message - * once the peer is online - */ - schedule?: Date | number + /** + * Whether to forward silently (also applies to caption message). + */ + silent?: boolean - /** - * Whether to clear draft after sending this message (only used for caption) - * - * Defaults to `false` - */ - clearDraft?: boolean + /** + * If set, the forwarding will be scheduled to this date + * (also applies to caption message). + * When passing a number, a UNIX time in ms is expected. + * + * You can also pass `0x7FFFFFFE`, this will send the message + * once the peer is online + */ + schedule?: Date | number - /** - * Whether to forward without author - */ - noAuthor?: boolean + /** + * Whether to clear draft after sending this message (only used for caption) + * + * Defaults to `false` + */ + clearDraft?: boolean - /** - * Whether to forward without caption (implies {@link noAuthor}) - */ - noCaption?: boolean + /** + * Whether to forward without author + */ + noAuthor?: boolean - /** - * Whether to disallow further forwards of this message. - * - * Only for bots, works even if the target chat does not - * have content protection. - */ - forbidForwards?: boolean - }, - ): Promise> + /** + * Whether to forward without caption (implies {@link noAuthor}) + */ + noCaption?: boolean + + /** + * Whether to disallow further forwards of this message. + * + * Only for bots, works even if the target chat does not + * have content protection. + */ + forbidForwards?: boolean + }): Promise> _getDiscussionMessage(peer: InputPeerLike, message: number): Promise<[tl.TypeInputPeer, number]> // public version of the same method because why not @@ -3561,20 +3633,40 @@ export interface TelegramClient extends BaseTelegramClient { * * @param chatId Chat ID, username, phone number, `"self"` or `"me"` * @param messageId Message ID - * @param [notify=false] Whether to send a notification (only for legacy groups and supergroups) - * @param [bothSides=false] Whether to pin for both sides (only for private chats) */ - pinMessage(chatId: InputPeerLike, messageId: number, notify?: boolean, bothSides?: boolean): Promise + pinMessage( + chatId: InputPeerLike, + messageId: number, + params?: { + /** Whether to send a notification (only for legacy groups and supergroups) */ + notify?: boolean + /** Whether to pin for both sides (only for private chats) */ + bothSides?: boolean + }, + ): Promise /** * Mark chat history as read. * * **Available**: 👤 users only * * @param chatId Chat ID - * @param [message=0] Message up until which to read history (by default everything is read) - * @param [clearMentions=false] Whether to also clear all mentions in the chat */ - readHistory(chatId: InputPeerLike, message?: number, clearMentions?: boolean): Promise + readHistory( + chatId: InputPeerLike, + params?: { + /** + * Message up until which to read history + * + * @default 0, i.e. read everything + */ + maxId?: number + + /** + * Whether to also clear all mentions in the chat + */ + clearMentions?: boolean + }, + ): Promise /** * Mark all reactions in chat as read. * @@ -3748,85 +3840,83 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param toChatId Source chat ID - * @param fromChatId Target chat ID - * @param message Message ID to forward * @param params */ - sendCopy( - toChatId: InputPeerLike, - fromChatId: InputPeerLike, - message: number, - params?: { - /** - * Whether to send this message silently. - */ - silent?: boolean + sendCopy(params: { + /** Source chat ID */ + fromChatId: InputPeerLike + /** Target chat ID */ + toChatId: InputPeerLike + /** Message ID to forward */ + message: number + /** + * Whether to send this message silently. + */ + silent?: boolean - /** - * If set, the message will be scheduled to this date. - * When passing a number, a UNIX time in ms is expected. - * - * You can also pass `0x7FFFFFFE`, this will send the message - * once the peer is online - */ - schedule?: Date | number + /** + * If set, the message will be scheduled to this date. + * When passing a number, a UNIX time in ms is expected. + * + * You can also pass `0x7FFFFFFE`, this will send the message + * once the peer is online + */ + schedule?: Date | number - /** - * New message caption (only used for media) - */ - caption?: string | FormattedString + /** + * New message caption (only used for media) + */ + caption?: string | FormattedString - /** - * Parse mode to use to parse `text` entities before sending - * the message. Defaults to current default parse mode (if any). - * - * Passing `null` will explicitly disable formatting. - */ - parseMode?: string | null + /** + * Parse mode to use to parse `text` entities before sending + * the message. Defaults to current default parse mode (if any). + * + * Passing `null` will explicitly disable formatting. + */ + parseMode?: string | null - /** - * Message to reply to. Either a message object or message ID. - * - * For forums - can also be an ID of the topic (i.e. its top message ID) - */ - replyTo?: number | Message + /** + * Message to reply to. Either a message object or message ID. + * + * For forums - can also be an ID of the topic (i.e. its top message ID) + */ + replyTo?: number | Message - /** - * Whether to throw an error if {@link replyTo} - * message does not exist. - * - * If that message was not found, `NotFoundError` is thrown, - * with `text` set to `MESSAGE_NOT_FOUND`. - * - * Incurs an additional request, so only use when really needed. - * - * Defaults to `false` - */ - mustReply?: boolean + /** + * Whether to throw an error if {@link replyTo} + * message does not exist. + * + * If that message was not found, `NotFoundError` is thrown, + * with `text` set to `MESSAGE_NOT_FOUND`. + * + * Incurs an additional request, so only use when really needed. + * + * Defaults to `false` + */ + mustReply?: boolean - /** - * List of formatting entities to use instead of parsing via a - * parse mode. - * - * **Note:** Passing this makes the method ignore {@link parseMode} - */ - entities?: tl.TypeMessageEntity[] + /** + * List of formatting entities to use instead of parsing via a + * parse mode. + * + * **Note:** Passing this makes the method ignore {@link parseMode} + */ + entities?: tl.TypeMessageEntity[] - /** - * For bots: inline or reply markup or an instruction - * to hide a reply keyboard or to force a reply. - */ - replyMarkup?: ReplyMarkup + /** + * For bots: inline or reply markup or an instruction + * to hide a reply keyboard or to force a reply. + */ + replyMarkup?: ReplyMarkup - /** - * Whether to clear draft after sending this message. - * - * Defaults to `false` - */ - clearDraft?: boolean - }, - ): Promise + /** + * Whether to clear draft after sending this message. + * + * Defaults to `false` + */ + clearDraft?: boolean + }): Promise /** * Send a group of media. * @@ -4049,13 +4139,18 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param chatId Chat ID with the message to react to - * @param message Message ID to react to - * @param emoji Reaction emoji (or `null` to remove reaction) - * @param [big=false] Whether to use a big reaction * @returns Message to which the reaction was sent */ - sendReaction(chatId: InputPeerLike, message: number, emoji?: InputReaction | null, big?: boolean): Promise + sendReaction(params: { + /** Chat ID with the message to react to */ + chatId: InputPeerLike + /** Message ID to react to */ + message: number + /** Reaction emoji (or `null` to remove reaction) */ + emoji?: InputReaction | null + /** Whether to use a big reaction */ + big?: boolean + }): Promise /** * Send s previously scheduled message. * @@ -4214,33 +4309,36 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param chatId Chat ID where this poll was found - * @param message Message ID where this poll was found - * @param options - * Selected options, or `null` to retract. - * You can pass indexes of the answers or the `Buffer`s - * representing them. In case of indexes, the poll will first - * be requested from the server. */ - sendVote(chatId: InputPeerLike, message: number, options: null | MaybeArray): Promise + sendVote(params: { + /** Chat ID where this poll was found */ + chatId: InputPeerLike + /** Message ID where this poll was found */ + message: number + /** + * Selected options, or `null` to retract. + * You can pass indexes of the answers or the `Buffer`s + * representing them. In case of indexes, the poll will first + * be requested from the server. + */ + options: null | MaybeArray + }): Promise /** * Translate message text to a given language. * * Returns `null` if it could not translate the message. * - * > **Note**: For now doesn't seem to work, returns null for all messages. - * * **Available**: 👤 users only * - * @param chatId Chat or user ID - * @param messageId Identifier of the message to translate - * @param toLanguage Target language (two-letter ISO 639-1 language code) */ - translateMessage( - chatId: InputPeerLike, - messageId: number, - toLanguage: string, - ): Promise<[string, MessageEntity[]] | null> + translateMessage(params: { + /** Chat or user ID */ + chatId: InputPeerLike + /** Identifier of the message to translate */ + messageId: number + /** Target language (two-letter ISO 639-1 language code) */ + toLanguage: string + }): Promise<[string, MessageEntity[]] | null> /** * Translate text to a given language. * @@ -4344,11 +4442,15 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param currentPassword Current password as plaintext - * @param newPassword New password as plaintext - * @param hint Hint for the new password */ - changeCloudPassword(currentPassword: string, newPassword: string, hint?: string): Promise + changeCloudPassword(params: { + /** Current password as plaintext */ + currentPassword: string + /** New password as plaintext */ + newPassword: string + /** Hint for the new password */ + hint?: string + }): Promise /** * Enable 2FA password on your account * @@ -4359,11 +4461,15 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: 👤 users only * - * @param password 2FA password as plaintext - * @param hint Hint for the new password - * @param email Recovery email */ - enableCloudPassword(password: string, hint?: string, email?: string): Promise + enableCloudPassword(params: { + /** 2FA password as plaintext */ + password: string + /** Hint for the new password */ + hint?: string + /** Recovery email */ + email?: string + }): Promise /** * Verify an email to use as 2FA recovery method * @@ -4402,13 +4508,13 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param id Sticker set short name or TL object with input sticker set + * @param setId Sticker set short name or TL object with input sticker set * @param sticker Sticker to be added * @param params * @returns Modfiied sticker set */ addStickerToSet( - id: InputStickerSet, + setId: InputStickerSet, sticker: InputStickerSetItem, params?: { /** @@ -4536,9 +4642,9 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param id Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID + * @param setId Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID */ - getStickerSet(id: InputStickerSet): Promise + getStickerSet(setId: InputStickerSet): Promise /** * Move a sticker in a sticker set * to another position @@ -4563,12 +4669,12 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param id Sticker set short name or a TL object with input sticker set + * @param setId Sticker set short name or a TL object with input sticker set * @param thumb Sticker set thumbnail * @param params * @returns Modified sticker set */ - setChatStickerSet(chatId: InputPeerLike, id: InputStickerSet): Promise + setChatStickerSet(chatId: InputPeerLike, setId: InputStickerSet): Promise /** * Set sticker set thumbnail * @@ -5438,7 +5544,7 @@ export interface TelegramClient extends BaseTelegramClient { /** * Get the `InputPeer` of a known peer id. - * Useful when an `InputPeer` is needed. + * Useful when an `InputPeer` is needed in Raw API. * * **Available**: ✅ both users and bots * @@ -5486,17 +5592,15 @@ export interface TelegramClient extends BaseTelegramClient { * * **Available**: ✅ both users and bots * - * @param type Media type (photo or video) - * @param media Input media file - * @param previewSec - * When `type = video`, timestamp in seconds which will be shown - * as a static preview. */ - setProfilePhoto( - type: 'photo' | 'video', - media: InputFileLike | tl.TypeInputPhoto, - previewSec?: number, - ): Promise + setProfilePhoto(params: { + /** Media type (photo or video) */ + type: 'photo' | 'video' + /** Input media file */ + media: InputFileLike | tl.TypeInputPhoto + /** When `type = video`, timestamp in seconds which will be shown as a static preview. */ + previewSec?: number + }): Promise /** * Change username of the current user. * @@ -5628,7 +5732,7 @@ export class TelegramClient extends BaseTelegramClient { this._updsLog = this.log.create('updates') this._resolvePeerManyPoolLimit = opts.resolvePeerManyPoolLimit ?? 8 } - acceptTos = acceptTos + _onAuthorization = _onAuthorization checkPassword = checkPassword getPasswordHint = getPasswordHint logOut = logOut @@ -5639,7 +5743,6 @@ export class TelegramClient extends BaseTelegramClient { sendRecoveryCode = sendRecoveryCode signInBot = signInBot signIn = signIn - signUp = signUp startTest = startTest start = start answerCallbackQuery = answerCallbackQuery diff --git a/packages/client/src/methods/_imports.ts b/packages/client/src/methods/_imports.ts index b739a591..0c398b83 100644 --- a/packages/client/src/methods/_imports.ts +++ b/packages/client/src/methods/_imports.ts @@ -78,7 +78,6 @@ import { StoryViewer, StoryViewersList, TakeoutSession, - TermsOfService, TypingStatus, UploadedFile, UploadFileLike, diff --git a/packages/client/src/methods/auth/_initialize.ts b/packages/client/src/methods/auth/_initialize.ts index 4f8bb19d..9f2e0a83 100644 --- a/packages/client/src/methods/auth/_initialize.ts +++ b/packages/client/src/methods/auth/_initialize.ts @@ -1,5 +1,9 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ +import { MtUnsupportedError, tl } from '@mtcute/core' +import { assertTypeIs } from '@mtcute/core/utils' + import { TelegramClient } from '../../client' +import { User } from '../../types' // @extension interface AuthState { @@ -20,3 +24,35 @@ function _initializeAuthState(this: TelegramClient) { this._selfUsername = null this.log.prefix = '[USER N/A] ' } + +/** @internal */ +export async function _onAuthorization( + this: TelegramClient, + auth: tl.auth.TypeAuthorization, + bot = false, +): Promise { + if (auth._ === 'auth.authorizationSignUpRequired') { + throw new MtUnsupportedError( + 'Signup is no longer supported by Telegram for non-official clients. Please use your mobile device to sign up.', + ) + } + + assertTypeIs('_onAuthorization (@ auth.authorization -> user)', auth.user, 'user') + + this._userId = auth.user.id + this.log.prefix = `[USER ${this._userId}] ` + this._isBot = bot + this._selfUsername = auth.user.username! + this._selfChanged = true + + await this.network.notifyLoggedIn(auth) + + await this._fetchUpdatesState() + await this._saveStorage() + + // telegram ignores invokeWithoutUpdates for auth methods + if (this.network.params.disableUpdates) this.network.resetSessions() + else this.startUpdatesLoop() + + return new User(this, auth.user) +} diff --git a/packages/client/src/methods/auth/accept-tos.ts b/packages/client/src/methods/auth/accept-tos.ts deleted file mode 100644 index 1c6af305..00000000 --- a/packages/client/src/methods/auth/accept-tos.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { MtTypeAssertionError } from '@mtcute/core' - -import { TelegramClient } from '../../client' - -/** - * Accept the given TOS - * - * @param tosId TOS id - * @internal - */ -export async function acceptTos(this: TelegramClient, tosId: string): Promise { - const res = await this.call({ - _: 'help.acceptTermsOfService', - id: { - _: 'dataJSON', - data: tosId, - }, - }) - - if (!res) { - throw new MtTypeAssertionError('help.acceptTermsOfService', 'true', 'false') - } - - return true -} diff --git a/packages/client/src/methods/auth/check-password.ts b/packages/client/src/methods/auth/check-password.ts index 5bb6d311..4cbd1bf9 100644 --- a/packages/client/src/methods/auth/check-password.ts +++ b/packages/client/src/methods/auth/check-password.ts @@ -1,4 +1,4 @@ -import { assertTypeIs, computeSrpParams } from '@mtcute/core/utils' +import { computeSrpParams } from '@mtcute/core/utils' import { TelegramClient } from '../../client' import { User } from '../../types' @@ -23,22 +23,5 @@ export async function checkPassword(this: TelegramClient, password: string): Pro ), }) - assertTypeIs('checkPassword (@ auth.checkPassword)', res, 'auth.authorization') - assertTypeIs('checkPassword (@ auth.checkPassword -> user)', res.user, 'user') - - this._userId = res.user.id - this.log.prefix = `[USER ${this._userId}] ` - this._isBot = false - this._selfChanged = true - this._selfUsername = res.user.username ?? null - await this.network.notifyLoggedIn(res) - - await this._fetchUpdatesState() - await this._saveStorage() - - // telegram ignores invokeWithoutUpdates for auth methods - if (this.network.params.disableUpdates) this.network.resetSessions() - else this.startUpdatesLoop() - - return new User(this, res.user) + return this._onAuthorization(res) } diff --git a/packages/client/src/methods/auth/recover-password.ts b/packages/client/src/methods/auth/recover-password.ts index 91ddd36d..67966207 100644 --- a/packages/client/src/methods/auth/recover-password.ts +++ b/packages/client/src/methods/auth/recover-password.ts @@ -1,29 +1,26 @@ -import { assertTypeIs } from '@mtcute/core/utils' - import { TelegramClient } from '../../client' import { User } from '../../types' /** * Recover your password with a recovery code and log in. * - * @param recoveryCode The recovery code sent via email * @returns The authorized user * @throws BadRequestError In case the code is invalid * @internal */ -export async function recoverPassword(this: TelegramClient, recoveryCode: string): Promise { +export async function recoverPassword( + this: TelegramClient, + params: { + /** The recovery code sent via email */ + recoveryCode: string + }, +): Promise { + const { recoveryCode } = params + const res = await this.call({ _: 'auth.recoverPassword', code: recoveryCode, }) - assertTypeIs('recoverPassword (@ auth.recoverPassword)', res, 'auth.authorization') - assertTypeIs('recoverPassword (@ auth.recoverPassword -> user)', res.user, 'user') - - this._userId = res.user.id - this._isBot = false - this._selfChanged = true - await this._saveStorage() - - return new User(this, res.user) + return this._onAuthorization(res) } diff --git a/packages/client/src/methods/auth/resend-code.ts b/packages/client/src/methods/auth/resend-code.ts index bb7a0411..6329a5b0 100644 --- a/packages/client/src/methods/auth/resend-code.ts +++ b/packages/client/src/methods/auth/resend-code.ts @@ -10,16 +10,23 @@ import { normalizePhoneNumber } from '../../utils/misc-utils' * The type of the code to be re-sent is specified in the `nextType` attribute of * {@link SentCode} object returned by {@link sendCode} * - * @param phone Phone number in international format - * @param phoneCodeHash Confirmation code identifier from {@link SentCode} * @internal */ -export async function resendCode(this: TelegramClient, phone: string, phoneCodeHash: string): Promise { - phone = normalizePhoneNumber(phone) +export async function resendCode( + this: TelegramClient, + params: { + /** Phone number in international format */ + phone: string + + /** Confirmation code identifier from {@link SentCode} */ + phoneCodeHash: string + }, +): Promise { + const { phone, phoneCodeHash } = params const res = await this.call({ _: 'auth.resendCode', - phoneNumber: phone, + phoneNumber: normalizePhoneNumber(phone), phoneCodeHash, }) diff --git a/packages/client/src/methods/auth/send-code.ts b/packages/client/src/methods/auth/send-code.ts index 9d46b57c..9f69ed4a 100644 --- a/packages/client/src/methods/auth/send-code.ts +++ b/packages/client/src/methods/auth/send-code.ts @@ -7,12 +7,17 @@ import { normalizePhoneNumber } from '../../utils/misc-utils' /** * Send the confirmation code to the given phone number * - * @param phone Phone number in international format. * @returns An object containing information about the sent confirmation code * @internal */ -export async function sendCode(this: TelegramClient, phone: string): Promise { - phone = normalizePhoneNumber(phone) +export async function sendCode( + this: TelegramClient, + params: { + /** Phone number in international format */ + phone: string + }, +): Promise { + const phone = normalizePhoneNumber(params.phone) const res = await this.call({ _: 'auth.sendCode', diff --git a/packages/client/src/methods/auth/sign-in-bot.ts b/packages/client/src/methods/auth/sign-in-bot.ts index 0190d5a0..faa0b9a7 100644 --- a/packages/client/src/methods/auth/sign-in-bot.ts +++ b/packages/client/src/methods/auth/sign-in-bot.ts @@ -1,5 +1,3 @@ -import { assertTypeIs } from '@mtcute/core/utils' - import { TelegramClient } from '../../client' import { User } from '../../types' @@ -20,23 +18,5 @@ export async function signInBot(this: TelegramClient, token: string): Promise user)', res.user, 'user') - - this._userId = res.user.id - this.log.prefix = `[USER ${this._userId}] ` - this._isBot = true - this._selfUsername = res.user.username! - this._selfChanged = true - - await this.network.notifyLoggedIn(res) - - await this._fetchUpdatesState() - await this._saveStorage() - - // telegram ignores invokeWithoutUpdates for auth methods - if (this.network.params.disableUpdates) this.network.resetSessions() - else this.startUpdatesLoop() - - return new User(this, res.user) + return this._onAuthorization(res, true) } diff --git a/packages/client/src/methods/auth/sign-in.ts b/packages/client/src/methods/auth/sign-in.ts index 34a68dd5..9369c74e 100644 --- a/packages/client/src/methods/auth/sign-in.ts +++ b/packages/client/src/methods/auth/sign-in.ts @@ -1,60 +1,34 @@ -import { assertTypeIs } from '@mtcute/core/utils' - import { TelegramClient } from '../../client' -import { TermsOfService, User } from '../../types' +import { User } from '../../types' import { normalizePhoneNumber } from '../../utils/misc-utils' /** * Authorize a user in Telegram with a valid confirmation code. * - * @param phone Phone number in international format - * @param phoneCodeHash Code identifier from {@link TelegramClient.sendCode} - * @param phoneCode The confirmation code that was received - * @returns - * - If the code was valid and authorization succeeded, the {@link User} is returned. - * - If the given phone number needs to be registered AND the ToS must be accepted, - * an object containing them is returned. - * - If the given phone number needs to be registered, `false` is returned. - * @throws BadRequestError In case the arguments are invalid - * @throws SessionPasswordNeededError In case a password is needed to sign in + * @returns If the code was valid and authorization succeeded, the {@link User} is returned. + * @throws BadRequestError In case the arguments are invalid + * @throws SessionPasswordNeededError In case a password is needed to sign in * @internal */ export async function signIn( this: TelegramClient, - phone: string, - phoneCodeHash: string, - phoneCode: string, -): Promise { - phone = normalizePhoneNumber(phone) + params: { + /** Phone number in international format */ + phone: string + /** Code identifier from {@link sendCode} */ + phoneCodeHash: string + /** The confirmation code that was received */ + phoneCode: string + }, +): Promise { + const { phone, phoneCodeHash, phoneCode } = params const res = await this.call({ _: 'auth.signIn', - phoneNumber: phone, + phoneNumber: normalizePhoneNumber(phone), phoneCodeHash, phoneCode, }) - if (res._ === 'auth.authorizationSignUpRequired') { - if (res.termsOfService) return new TermsOfService(res.termsOfService) - - return false - } - - assertTypeIs('signIn (@ auth.signIn -> user)', res.user, 'user') - - this._userId = res.user.id - this.log.prefix = `[USER ${this._userId}] ` - this._isBot = false - this._selfChanged = true - this._selfUsername = res.user.username ?? null - await this.network.notifyLoggedIn(res) - - await this._fetchUpdatesState() - await this._saveStorage() - - // telegram ignores invokeWithoutUpdates for auth methods - if (this.network.params.disableUpdates) this.network.resetSessions() - else this.startUpdatesLoop() - - return new User(this, res.user) + return this._onAuthorization(res) } diff --git a/packages/client/src/methods/auth/sign-up.ts b/packages/client/src/methods/auth/sign-up.ts deleted file mode 100644 index f6c63cb5..00000000 --- a/packages/client/src/methods/auth/sign-up.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { assertTypeIs } from '@mtcute/core/utils' - -import { TelegramClient } from '../../client' -import { User } from '../../types' -import { normalizePhoneNumber } from '../../utils/misc-utils' - -/** - * Register a new user in Telegram. - * - * @param phone Phone number in international format - * @param phoneCodeHash Code identifier from {@link TelegramClient.sendCode} - * @param firstName New user's first name - * @param lastName New user's last name - * @internal - */ -export async function signUp( - this: TelegramClient, - phone: string, - phoneCodeHash: string, - firstName: string, - lastName = '', -): Promise { - phone = normalizePhoneNumber(phone) - - const res = await this.call({ - _: 'auth.signUp', - phoneNumber: phone, - phoneCodeHash, - firstName, - lastName, - }) - - assertTypeIs('signUp (@ auth.signUp)', res, 'auth.authorization') - assertTypeIs('signUp (@ auth.signUp -> user)', res.user, 'user') - - this._userId = res.user.id - this.log.prefix = `[USER ${this._userId}] ` - this._isBot = false - this._selfChanged = true - - await this.network.notifyLoggedIn(res) - - await this._fetchUpdatesState() - await this._saveStorage() - - // telegram ignores invokeWithoutUpdates for auth methods - if (this.network.params.disableUpdates) this.network.resetSessions() - else this.startUpdatesLoop() - - return new User(this, res.user) -} diff --git a/packages/client/src/methods/auth/start-test.ts b/packages/client/src/methods/auth/start-test.ts index 4d12ea40..4f3af8f3 100644 --- a/packages/client/src/methods/auth/start-test.ts +++ b/packages/client/src/methods/auth/start-test.ts @@ -1,7 +1,7 @@ import { MtArgumentError } from '@mtcute/core' import { TelegramClient } from '../../client' -import { MaybeDynamic, User } from '../../types' +import { User } from '../../types' /** * Utility function to quickly authorize on test DC @@ -35,25 +35,6 @@ export async function startTest( * Override user's DC. Must be a valid test DC. */ dcId?: number - - /** - * First name of the user (used only for sign-up, defaults to 'User') - */ - firstName?: MaybeDynamic - - /** - * Last name of the user (used only for sign-up, defaults to empty) - */ - lastName?: MaybeDynamic - - /** - * By using this method to sign up an account, you are agreeing to Telegram - * ToS. This is required and your account will be banned otherwise. - * See https://telegram.org/tos and https://core.telegram.org/api/terms. - * - * If true, TOS will not be displayed and `tosCallback` will not be called. - */ - acceptTos?: boolean }, ): Promise { if (!params) params = {} @@ -100,9 +81,6 @@ export async function startTest( return this.start({ phone, code: () => code, - firstName: params.firstName, - lastName: params.lastName, - acceptTos: params.acceptTos, codeSentCallback: (sent) => { for (let i = 0; i < sent.length; i++) { code += phone![5] diff --git a/packages/client/src/methods/auth/start.ts b/packages/client/src/methods/auth/start.ts index 33ab0532..14eb32f4 100644 --- a/packages/client/src/methods/auth/start.ts +++ b/packages/client/src/methods/auth/start.ts @@ -2,7 +2,7 @@ import { MaybeAsync, MtArgumentError, tl } from '@mtcute/core' import { TelegramClient } from '../../client' -import { MaybeDynamic, SentCode, TermsOfService, User } from '../../types' +import { MaybeDynamic, SentCode, User } from '../../types' import { normalizePhoneNumber, resolveMaybeDynamic } from '../../utils/misc-utils' // @available=both @@ -75,31 +75,6 @@ export async function start( */ forceSms?: boolean - /** - * First name of the user (used only for sign-up, defaults to 'User') - */ - firstName?: MaybeDynamic - - /** - * Last name of the user (used only for sign-up, defaults to empty) - */ - lastName?: MaybeDynamic - - /** - * By using this method to sign up an account, you are agreeing to Telegram - * ToS. This is required and your account will be banned otherwise. - * See https://telegram.org/tos and https://core.telegram.org/api/terms. - * - * If true, TOS will not be displayed and `tosCallback` will not be called. - */ - acceptTos?: boolean - - /** - * Custom method to display ToS. Can be used to show a GUI alert of some kind. - * Defaults to `console.log` - */ - tosCallback?: (tos: TermsOfService) => MaybeAsync - /** * Custom method that is called when a code is sent. Can be used * to show a GUI alert of some kind. @@ -185,10 +160,10 @@ export async function start( return await this.signInBot(botToken) } - let sentCode = await this.sendCode(phone) + let sentCode = await this.sendCode({ phone }) if (params.forceSms && sentCode.type === 'app') { - sentCode = await this.resendCode(phone, sentCode.phoneCodeHash) + sentCode = await this.resendCode({ phone, phoneCodeHash: sentCode.phoneCodeHash }) } if (params.codeSentCallback) { @@ -199,14 +174,12 @@ export async function start( let has2fa = false - let result: User | TermsOfService | false - for (;;) { const code = await resolveMaybeDynamic(params.code) if (!code) throw new tl.RpcError(400, 'PHONE_CODE_EMPTY') try { - result = await this.signIn(phone, sentCode.phoneCodeHash, code) + return await this.signIn({ phone, phoneCodeHash: sentCode.phoneCodeHash, phoneCode: code }) } catch (e) { if (!tl.RpcError.is(e)) throw e @@ -246,7 +219,7 @@ export async function start( const password = await resolveMaybeDynamic(params.password) try { - result = await this.checkPassword(password) + return await this.checkPassword(password) } catch (e) { if (typeof params.password !== 'function') { throw new MtArgumentError('Provided password was invalid') @@ -261,41 +234,8 @@ export async function start( continue } else throw e } - - break } } - // to make ts happy - result = result! - - if (result instanceof User) { - return result - } - - let tosId: string | null = null - - if (result instanceof TermsOfService && !params.acceptTos) { - if (params.tosCallback) { - await params.tosCallback(result) - } else { - console.log(result.text) - } - - tosId = result.id - } - - // signup - result = await this.signUp( - phone, - sentCode.phoneCodeHash, - await resolveMaybeDynamic(params.firstName ?? 'User'), - await resolveMaybeDynamic(params.lastName), - ) - - if (tosId) { - await this.acceptTos(tosId) - } - - return result + throw new MtArgumentError('Failed to log in with provided credentials') } diff --git a/packages/client/src/methods/bots/answer-callback-query.ts b/packages/client/src/methods/bots/answer-callback-query.ts index 7dcbafdc..f21d0757 100644 --- a/packages/client/src/methods/bots/answer-callback-query.ts +++ b/packages/client/src/methods/bots/answer-callback-query.ts @@ -2,7 +2,6 @@ import { Long } from '@mtcute/core' import { TelegramClient } from '../../client' -// @available=bot /** * Send an answer to a callback query. * @@ -18,7 +17,7 @@ export async function answerCallbackQuery( * Maximum amount of time in seconds for which * this result can be cached by the client (not server!). * - * Defaults to `0` + * @default 0 */ cacheTime?: number @@ -33,7 +32,7 @@ export async function answerCallbackQuery( * Whether to show an alert in the middle of the screen * instead of a notification at the top of the screen. * - * Defaults to `false`. + * @default false */ alert?: boolean @@ -49,14 +48,14 @@ export async function answerCallbackQuery( url?: string }, ): Promise { - if (!params) params = {} + const { cacheTime = 0, text, alert, url } = params ?? {} await this.call({ _: 'messages.setBotCallbackAnswer', queryId, - cacheTime: params.cacheTime ?? 0, - alert: params.alert, - message: params.text, - url: params.url, + cacheTime, + alert, + message: text, + url, }) } diff --git a/packages/client/src/methods/bots/answer-inline-query.ts b/packages/client/src/methods/bots/answer-inline-query.ts index cbf65c2f..cf974449 100644 --- a/packages/client/src/methods/bots/answer-inline-query.ts +++ b/packages/client/src/methods/bots/answer-inline-query.ts @@ -20,7 +20,7 @@ export async function answerInlineQuery( * Maximum number of time in seconds that the results of the * query may be cached on the server for. * - * Defaults to `300` + * @default 300 */ cacheTime?: number @@ -39,7 +39,7 @@ export async function answerInlineQuery( * Whether the results should only be cached on the server * for the user who sent the query. * - * Defaults to `false` + * @default false */ private?: boolean @@ -47,7 +47,7 @@ export async function answerInlineQuery( * Next pagination offset (up to 64 bytes). * * When user has reached the end of the current results, - * it will re-send the inline query with the same text, but + * the client will re-send the inline query with the same text, but * with `offset` set to this value. * * If omitted or empty string is provided, it is assumed that @@ -95,23 +95,23 @@ export async function answerInlineQuery( parseMode?: string | null }, ): Promise { - if (!params) params = {} + const { cacheTime = 300, gallery, private: priv, nextOffset, switchPm, parseMode } = params ?? {} - const [gallery, tlResults] = await BotInline._convertToTl(this, results, params.parseMode) + const [defaultGallery, tlResults] = await BotInline._convertToTl(this, results, parseMode) await this.call({ _: 'messages.setInlineBotResults', queryId, results: tlResults, - cacheTime: params.cacheTime ?? 300, - gallery: params.gallery ?? gallery, - private: params.private, - nextOffset: params.nextOffset, - switchPm: params.switchPm ? + cacheTime, + gallery: gallery ?? defaultGallery, + private: priv, + nextOffset, + switchPm: switchPm ? { _: 'inlineBotSwitchPM', - text: params.switchPm.text, - startParam: params.switchPm.parameter, + text: switchPm.text, + startParam: switchPm.parameter, } : undefined, }) diff --git a/packages/client/src/methods/bots/answer-pre-checkout-query.ts b/packages/client/src/methods/bots/answer-pre-checkout-query.ts index a0e8ccc2..9e78d9ee 100644 --- a/packages/client/src/methods/bots/answer-pre-checkout-query.ts +++ b/packages/client/src/methods/bots/answer-pre-checkout-query.ts @@ -6,10 +6,18 @@ import { TelegramClient } from '../../client' * Answer a pre-checkout query. * * @param queryId Pre-checkout query ID - * @param error If pre-checkout is rejected, error message to show to the user * @internal */ -export async function answerPreCheckoutQuery(this: TelegramClient, queryId: tl.Long, error?: string): Promise { +export async function answerPreCheckoutQuery( + this: TelegramClient, + queryId: tl.Long, + params?: { + /** If pre-checkout is rejected, error message to show to the user */ + error?: string + }, +): Promise { + const { error } = params ?? {} + await this.call({ _: 'messages.setBotPrecheckoutResults', queryId, diff --git a/packages/client/src/methods/bots/get-callback-answer.ts b/packages/client/src/methods/bots/get-callback-answer.ts index 635716dd..49a37ec2 100644 --- a/packages/client/src/methods/bots/get-callback-answer.ts +++ b/packages/client/src/methods/bots/get-callback-answer.ts @@ -8,18 +8,21 @@ import { InputPeerLike } from '../../types' * Request a callback answer from a bot, * i.e. click an inline button that contains data. * - * @param chatId Chat ID where the message was found - * @param message ID of the message containing the button - * @param data Data contained in the button * @param params * @internal */ export async function getCallbackAnswer( this: TelegramClient, - chatId: InputPeerLike, - message: number, - data: string | Buffer, - params?: { + params: { + /** Chat ID where the message was found */ + chatId: InputPeerLike + + /** ID of the message containing the button */ + message: number + + /** Data contained in the button */ + data: string | Buffer + /** * Timeout for the query in ms. * @@ -33,15 +36,16 @@ export async function getCallbackAnswer( game?: boolean /** - * If the button requires password entry, - * your 2FA password. + * If the button requires password entry, your 2FA password. * - * Your password is never exposed to the - * bot, it is checked by Telegram. + * Your password is never exposed to the bot, + * it is checked by Telegram. */ password?: string }, ): Promise { + const { chatId, message, data, game, timeout = 10000 } = params + let password: tl.TypeInputCheckPasswordSRP | undefined = undefined if (params?.password) { @@ -56,8 +60,8 @@ export async function getCallbackAnswer( msgId: message, data: typeof data === 'string' ? Buffer.from(data) : data, password, - game: params?.game, + game: game, }, - { timeout: params?.timeout ?? 10000 }, + { timeout }, ) } diff --git a/packages/client/src/methods/bots/get-game-high-scores.ts b/packages/client/src/methods/bots/get-game-high-scores.ts index 1e051138..0afafb7f 100644 --- a/packages/client/src/methods/bots/get-game-high-scores.ts +++ b/packages/client/src/methods/bots/get-game-high-scores.ts @@ -8,17 +8,23 @@ import { normalizeToInputUser } from '../../utils/peer-utils' /** * Get high scores of a game * - * @param chatId ID of the chat where the game was found - * @param message ID of the message containing the game - * @param userId ID of the user to find high scores for * @internal */ export async function getGameHighScores( this: TelegramClient, - chatId: InputPeerLike, - message: number, - userId?: InputPeerLike, + params: { + /** ID of the chat where the game was found */ + chatId: InputPeerLike + + /** ID of the message containing the game */ + message: number + + /** ID of the user to find high scores for */ + userId?: InputPeerLike + }, ): Promise { + const { chatId, message, userId } = params + const chat = await this.resolvePeer(chatId) let user: tl.TypeInputUser diff --git a/packages/client/src/methods/bots/set-game-score.ts b/packages/client/src/methods/bots/set-game-score.ts index 3ce98d39..6bbbbef9 100644 --- a/packages/client/src/methods/bots/set-game-score.ts +++ b/packages/client/src/methods/bots/set-game-score.ts @@ -17,12 +17,16 @@ export async function setGameScore( params: { /** Chat where the game was found */ chatId: InputPeerLike + /** ID of the message where the game was found */ message: number + /** ID of the user who has scored */ userId: InputPeerLike + /** The new score (must be >0) */ score: number + /** * When `true`, the game message will not be modified * to include the new score diff --git a/packages/client/src/methods/bots/set-my-default-rights.ts b/packages/client/src/methods/bots/set-my-default-rights.ts index 983b27b8..0b96533f 100644 --- a/packages/client/src/methods/bots/set-my-default-rights.ts +++ b/packages/client/src/methods/bots/set-my-default-rights.ts @@ -5,15 +5,19 @@ import { TelegramClient } from '../../client' /** * Sets the default chat permissions for the bot in the supergroup or channel. * - * @param target Whether to target groups or channels. - * @param rights The default chat permissions. * @internal */ export async function setMyDefaultRights( this: TelegramClient, - target: 'channel' | 'group', - rights: Omit, + params: { + /** Whether to target groups or channels. */ + target: 'channel' | 'group' + /** The default chat permissions. */ + rights: Omit + }, ): Promise { + const { target, rights } = params + await this.call({ _: target === 'group' ? 'bots.setBotGroupDefaultAdminRights' : 'bots.setBotBroadcastDefaultAdminRights', adminRights: { diff --git a/packages/client/src/methods/chats/add-chat-members.ts b/packages/client/src/methods/chats/add-chat-members.ts index 6933ceff..1e97dd6b 100644 --- a/packages/client/src/methods/chats/add-chat-members.ts +++ b/packages/client/src/methods/chats/add-chat-members.ts @@ -10,21 +10,28 @@ import { } from '../../utils/peer-utils' /** - * Add new members to a group, supergroup or channel. + * Add one or more new members to a group, supergroup or channel. * * @param chatId ID of the chat or its username - * @param users ID(s) of the users, their username(s) or phone(s). - * @param forwardCount - * Number of old messages to be forwarded (0-100). - * Only applicable to legacy groups, ignored for supergroups and channels + * @param users ID(s) of the user(s) to add * @internal */ export async function addChatMembers( this: TelegramClient, chatId: InputPeerLike, users: MaybeArray, - forwardCount = 100, + params: { + /** + * Number of old messages to be forwarded (0-100). + * Only applicable to legacy groups, ignored for supergroups and channels + * + * @default 100 + */ + forwardCount?: number + }, ): Promise { + const { forwardCount = 100 } = params + const chat = await this.resolvePeer(chatId) if (!Array.isArray(users)) users = [users] diff --git a/packages/client/src/methods/chats/archive-chats.ts b/packages/client/src/methods/chats/archive-chats.ts index 141b9aaa..0ad4ea63 100644 --- a/packages/client/src/methods/chats/archive-chats.ts +++ b/packages/client/src/methods/chats/archive-chats.ts @@ -1,4 +1,4 @@ -import { MaybeArray, tl } from '@mtcute/core' +import { MaybeArray } from '@mtcute/core' import { TelegramClient } from '../../client' import { InputPeerLike } from '../../types' @@ -12,19 +12,15 @@ import { InputPeerLike } from '../../types' export async function archiveChats(this: TelegramClient, chats: MaybeArray): Promise { if (!Array.isArray(chats)) chats = [chats] - const folderPeers: tl.TypeInputFolderPeer[] = [] - - for (const chat of chats) { - folderPeers.push({ - _: 'inputFolderPeer', - peer: await this.resolvePeer(chat), - folderId: 1, - }) - } + const resolvedPeers = await this.resolvePeerMany(chats) const updates = await this.call({ _: 'folders.editPeerFolders', - folderPeers, + folderPeers: resolvedPeers.map((peer) => ({ + _: 'inputFolderPeer', + peer, + folderId: 1, + })), }) this._handleUpdate(updates) } diff --git a/packages/client/src/methods/chats/ban-chat-member.ts b/packages/client/src/methods/chats/ban-chat-member.ts index 2bef7f45..3bd003bd 100644 --- a/packages/client/src/methods/chats/ban-chat-member.ts +++ b/packages/client/src/methods/chats/ban-chat-member.ts @@ -17,18 +17,20 @@ import { * When banning a channel, the user won't be able to use * any of their channels to post until the ban is lifted. * - * @param chatId Chat ID - * @param peerId User/Channel ID * @returns Service message about removed user, if one was generated. * @internal */ export async function banChatMember( this: TelegramClient, - chatId: InputPeerLike, - peerId: InputPeerLike, + params: { + /** Chat ID */ + chatId: InputPeerLike + /** ID of the user/channel to ban */ + participantId: InputPeerLike + }, ): Promise { - const chat = await this.resolvePeer(chatId) - const peer = await this.resolvePeer(peerId) + const chat = await this.resolvePeer(params.chatId) + const peer = await this.resolvePeer(params.participantId) let res if (isInputPeerChannel(chat)) { @@ -49,7 +51,7 @@ export async function banChatMember( chatId: chat.chatId, userId: normalizeToInputUser(peer), }) - } else throw new MtInvalidPeerTypeError(chatId, 'chat or channel') + } else throw new MtInvalidPeerTypeError(params.chatId, 'chat or channel') try { return this._findMessageInUpdate(res) diff --git a/packages/client/src/methods/chats/delete-history.ts b/packages/client/src/methods/chats/delete-history.ts index 4591afe9..15e0ec4c 100644 --- a/packages/client/src/methods/chats/delete-history.ts +++ b/packages/client/src/methods/chats/delete-history.ts @@ -7,23 +7,34 @@ import { createDummyUpdate } from '../../utils/updates-utils' * Delete communication history (for private chats * and legacy groups) * - * @param chat Chat or user ID, username, phone number, `"me"` or `"self"` - * @param mode - * Deletion mode. Can be: - * - `delete`: delete messages (only for yourself) - * - `clear`: delete messages (only for yourself) - * - `revoke`: delete messages for all users - * - I'm not sure what's the difference between `delete` and `clear`, - * but they are in fact different flags in TL object. - * @param maxId Maximum ID of message to delete. Defaults to 0 (remove all messages) * @internal */ export async function deleteHistory( this: TelegramClient, chat: InputPeerLike, - mode: 'delete' | 'clear' | 'revoke' = 'delete', - maxId = 0, + params?: { + /** + * Deletion mode. Can be: + * - `delete`: delete messages (only for yourself) + * - `clear`: delete messages (only for yourself) + * - `revoke`: delete messages for all users + * - I'm not sure what's the difference between `delete` and `clear`, + * but they are in fact different flags in TL object. + * + * @default 'delete' + */ + mode: 'delete' | 'clear' | 'revoke' + + /** + * Maximum ID of message to delete. + * + * @default 0, i.e. remove all messages + */ + maxId?: number + }, ): Promise { + const { mode = 'delete', maxId = 0 } = params ?? {} + const peer = await this.resolvePeer(chat) const res = await this.call({ diff --git a/packages/client/src/methods/chats/delete-user-history.ts b/packages/client/src/methods/chats/delete-user-history.ts index 94d3f62a..c7cb9ad9 100644 --- a/packages/client/src/methods/chats/delete-user-history.ts +++ b/packages/client/src/methods/chats/delete-user-history.ts @@ -8,15 +8,19 @@ import { createDummyUpdate } from '../../utils/updates-utils' /** * Delete all messages of a user (or channel) in a supergroup * - * @param chatId Chat ID - * @param participantId User/channel ID * @internal */ export async function deleteUserHistory( this: TelegramClient, - chatId: InputPeerLike, - participantId: InputPeerLike, + params: { + /** Chat ID */ + chatId: InputPeerLike + /** User/channel ID whose messages to delete */ + participantId: InputPeerLike + }, ): Promise { + const { chatId, participantId } = params + const channel = normalizeToInputChannel(await this.resolvePeer(chatId), chatId) const peer = await this.resolvePeer(participantId) diff --git a/packages/client/src/methods/chats/edit-admin-rights.ts b/packages/client/src/methods/chats/edit-admin-rights.ts index 65151907..626cd897 100644 --- a/packages/client/src/methods/chats/edit-admin-rights.ts +++ b/packages/client/src/methods/chats/edit-admin-rights.ts @@ -7,19 +7,23 @@ import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer- /** * Edit supergroup/channel admin rights of a user. * - * @param chatId Chat ID - * @param userId User ID - * @param rights New admin rights - * @param rank Custom admin rank * @internal */ export async function editAdminRights( this: TelegramClient, - chatId: InputPeerLike, - userId: InputPeerLike, - rights: Omit, - rank = '', + params: { + /** Chat ID */ + chatId: InputPeerLike + /** User ID */ + userId: InputPeerLike + /** New admin rights */ + rights: Omit + /** Custom admin rank */ + rank?: string + }, ): Promise { + const { chatId, userId, rights, rank = '' } = params + const chat = normalizeToInputChannel(await this.resolvePeer(chatId), chatId) const user = normalizeToInputUser(await this.resolvePeer(userId), userId) diff --git a/packages/client/src/methods/chats/get-chat-event-log.ts b/packages/client/src/methods/chats/get-chat-event-log.ts index 89d49cde..4c714430 100644 --- a/packages/client/src/methods/chats/get-chat-event-log.ts +++ b/packages/client/src/methods/chats/get-chat-event-log.ts @@ -16,7 +16,6 @@ import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer- * in direct chronological order (i.e. newer * events have bigger event ID) * - * @param chatId Chat ID * @param params * @internal */ @@ -73,12 +72,10 @@ export async function getChatEventLog( limit?: number }, ): Promise { - if (!params) params = {} + const { maxId = Long.ZERO, minId = Long.ZERO, query = '', limit = 100, users, filters } = params ?? {} const channel = normalizeToInputChannel(await this.resolvePeer(chatId), chatId) - const { maxId = Long.ZERO, minId = Long.ZERO, query = '', limit = 100, users, filters } = params - const admins: tl.TypeInputUser[] | undefined = users ? await this.resolvePeerMany(users, normalizeToInputUser) : undefined diff --git a/packages/client/src/methods/chats/get-chat-member.ts b/packages/client/src/methods/chats/get-chat-member.ts index 5f11829d..84066b03 100644 --- a/packages/client/src/methods/chats/get-chat-member.ts +++ b/packages/client/src/methods/chats/get-chat-member.ts @@ -15,9 +15,15 @@ import { isInputPeerChannel, isInputPeerChat, isInputPeerUser, normalizeToInputC */ export async function getChatMember( this: TelegramClient, - chatId: InputPeerLike, - userId: InputPeerLike, + params: { + /** Chat ID or username */ + chatId: InputPeerLike + /** User ID, username, phone number, `"me"` or `"self"` */ + userId: InputPeerLike + }, ): Promise { + const { chatId, userId } = params + const user = await this.resolvePeer(userId) const chat = await this.resolvePeer(chatId) diff --git a/packages/client/src/methods/chats/get-chat-members.ts b/packages/client/src/methods/chats/get-chat-members.ts index afdee5a1..1fcce9a5 100644 --- a/packages/client/src/methods/chats/get-chat-members.ts +++ b/packages/client/src/methods/chats/get-chat-members.ts @@ -60,7 +60,7 @@ export async function getChatMembers( type?: 'all' | 'banned' | 'restricted' | 'bots' | 'recent' | 'admins' | 'contacts' | 'mention' }, ): Promise> { - if (!params) params = {} + const { query = '', offset = 0, limit = 200, type = 'recent' } = params ?? {} const chat = await this.resolvePeer(chatId) @@ -75,21 +75,18 @@ export async function getChatMembers( let members = res.fullChat.participants._ === 'chatParticipantsForbidden' ? [] : res.fullChat.participants.participants - if (params.offset) members = members.slice(params.offset) - if (params.limit) members = members.slice(0, params.limit) + if (offset) members = members.slice(offset) + if (limit) members = members.slice(0, limit) const peers = PeersIndex.from(res) - const ret = members.map((m) => new ChatMember(this, m, peers)) as ArrayWithTotal + const ret = members.map((m) => new ChatMember(this, m, peers)) - ret.total = ret.length - - return ret + return makeArrayWithTotal(ret, ret.length) } if (isInputPeerChannel(chat)) { - const q = params.query?.toLowerCase() ?? '' - const type = params.type ?? 'recent' + const q = query let filter: tl.TypeChannelParticipantsFilter @@ -126,8 +123,8 @@ export async function getChatMembers( _: 'channels.getParticipants', channel: normalizeToInputChannel(chat), filter, - offset: params.offset ?? 0, - limit: params.limit ?? 200, + offset, + limit, hash: Long.ZERO, }) diff --git a/packages/client/src/methods/chats/get-chat-preview.ts b/packages/client/src/methods/chats/get-chat-preview.ts index fe3a6597..2f6fde40 100644 --- a/packages/client/src/methods/chats/get-chat-preview.ts +++ b/packages/client/src/methods/chats/get-chat-preview.ts @@ -9,7 +9,7 @@ import { INVITE_LINK_REGEX } from '../../utils/peer-utils' * * @param inviteLink Invite link * @throws MtArgumentError In case invite link has invalid format - * @throws MtNotFoundError + * @throws MtPeerNotFoundError * In case you are trying to get info about private chat that you have already joined. * Use {@link getChat} or {@link getFullChat} instead. * @internal diff --git a/packages/client/src/methods/chats/kick-chat-member.ts b/packages/client/src/methods/chats/kick-chat-member.ts index 9d2b8574..7cdabc15 100644 --- a/packages/client/src/methods/chats/kick-chat-member.ts +++ b/packages/client/src/methods/chats/kick-chat-member.ts @@ -9,24 +9,28 @@ import { isInputPeerChannel } from '../../utils/peer-utils' * * This effectively bans a user and immediately unbans them. * - * @param chatId Chat ID - * @param userId User ID * @internal */ export async function kickChatMember( this: TelegramClient, - chatId: InputPeerLike, - userId: InputPeerLike, + params: { + /** Chat ID */ + chatId: InputPeerLike + /** User ID */ + userId: InputPeerLike + }, ): Promise { + const { chatId, userId } = params + const chat = await this.resolvePeer(chatId) const user = await this.resolvePeer(userId) - await this.banChatMember(chat, user) + await this.banChatMember({ chatId: chat, participantId: user }) // not needed in case this is a legacy group if (isInputPeerChannel(chat)) { // i fucking love telegram serverside race conditions await sleep(1000) - await this.unbanChatMember(chat, user) + await this.unbanChatMember({ chatId: chat, participantId: user }) } } diff --git a/packages/client/src/methods/chats/leave-chat.ts b/packages/client/src/methods/chats/leave-chat.ts index 8c60373b..be417a26 100644 --- a/packages/client/src/methods/chats/leave-chat.ts +++ b/packages/client/src/methods/chats/leave-chat.ts @@ -6,10 +6,18 @@ import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '.. * Leave a group chat, supergroup or channel * * @param chatId Chat ID or username - * @param clear Whether to clear history after leaving (only for legacy group chats) * @internal */ -export async function leaveChat(this: TelegramClient, chatId: InputPeerLike, clear = false): Promise { +export async function leaveChat( + this: TelegramClient, + chatId: InputPeerLike, + params?: { + /** + * Whether to clear history after leaving (only for legacy group chats) + */ + clear?: boolean + }, +): Promise { const chat = await this.resolvePeer(chatId) if (isInputPeerChannel(chat)) { @@ -26,7 +34,7 @@ export async function leaveChat(this: TelegramClient, chatId: InputPeerLike, cle }) this._handleUpdate(res) - if (clear) { + if (params?.clear) { await this.deleteHistory(chat) } } else throw new MtInvalidPeerTypeError(chatId, 'chat or channel') diff --git a/packages/client/src/methods/chats/restrict-chat-member.ts b/packages/client/src/methods/chats/restrict-chat-member.ts index f7251f45..e80d428d 100644 --- a/packages/client/src/methods/chats/restrict-chat-member.ts +++ b/packages/client/src/methods/chats/restrict-chat-member.ts @@ -8,27 +8,38 @@ import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-ut /** * Restrict a user in a supergroup. * - * @param chatId Chat ID - * @param userId User ID - * @param restrictions - * Restrictions for the user. Note that unlike Bot API, this object contains - * the restrictions, and not the permissions, i.e. to - * passing `sendMessages=true` will disallow the user to send messages, - * and passing `{}` (empty object) will lift any restrictions - * @param until - * Date when the user will be unrestricted. - * When `number` is passed, UNIX time in ms is expected. - * If this value is less than 30 seconds or more than 366 days in - * the future, user will be restricted forever. Defaults to `0` (forever) * @internal */ export async function restrictChatMember( this: TelegramClient, - chatId: InputPeerLike, - userId: InputPeerLike, - restrictions: Omit, - until?: number | Date, + params: { + /** Chat ID */ + chatId: InputPeerLike + + /** User ID */ + userId: InputPeerLike + + /** + * Restrictions for the user. Note that unlike Bot API, this object contains + * the restrictions, and not the permissions, i.e. + * passing `sendMessages=true` will disallow the user to send messages, + * and passing `{}` (empty object) will lift any restrictions + */ + restrictions: Omit + + /** + * Date when the user will be unrestricted. + * When `number` is passed, UNIX time in ms is expected. + * If this value is less than 30 seconds or more than 366 days in + * the future, user will be restricted forever. + * + * @default `0`, i.e. forever + */ + until?: number | Date + }, ): Promise { + const { chatId, userId, restrictions, until = 0 } = params + const chat = await this.resolvePeer(chatId) if (!isInputPeerChannel(chat)) { diff --git a/packages/client/src/methods/chats/set-chat-default-permissions.ts b/packages/client/src/methods/chats/set-chat-default-permissions.ts index 888ee92f..aa6e65e7 100644 --- a/packages/client/src/methods/chats/set-chat-default-permissions.ts +++ b/packages/client/src/methods/chats/set-chat-default-permissions.ts @@ -12,7 +12,7 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils' * @param chatId Chat ID or username * @param restrictions * Restrictions for the chat. Note that unlike Bot API, this object contains - * the restrictions, and not the permissions, i.e. to + * the restrictions, and not the permissions, i.e. * passing `sendMessages=true` will disallow the users to send messages, * and passing `{}` (empty object) will lift any restrictions * @internal diff --git a/packages/client/src/methods/chats/set-chat-photo.ts b/packages/client/src/methods/chats/set-chat-photo.ts index 54dc099e..a90c2a1e 100644 --- a/packages/client/src/methods/chats/set-chat-photo.ts +++ b/packages/client/src/methods/chats/set-chat-photo.ts @@ -10,21 +10,29 @@ import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '.. * * You must be an administrator and have the appropriate permissions. * - * @param chatId Chat ID or username - * @param type Media type (photo or video) - * @param media Input media file - * @param previewSec - * When `type = video`, timestamp in seconds which will be shown - * as a static preview. * @internal */ export async function setChatPhoto( this: TelegramClient, - chatId: InputPeerLike, - type: 'photo' | 'video', - media: InputFileLike, - previewSec?: number, + params: { + /** Chat ID or username */ + chatId: InputPeerLike + + /** Media type (photo or video) */ + + type: 'photo' | 'video' + + /** Input media file */ + media: InputFileLike + /** + * When `type = video`, timestamp in seconds which will be shown + * as a static preview. + */ + previewSec?: number + }, ): Promise { + const { chatId, type, media, previewSec } = params + const chat = await this.resolvePeer(chatId) if (!(isInputPeerChannel(chat) || isInputPeerChat(chat))) { diff --git a/packages/client/src/methods/chats/toggle-fragment-username.ts b/packages/client/src/methods/chats/toggle-fragment-username.ts index a0296ec5..533652da 100644 --- a/packages/client/src/methods/chats/toggle-fragment-username.ts +++ b/packages/client/src/methods/chats/toggle-fragment-username.ts @@ -8,13 +8,14 @@ import { isInputPeerChannel, isInputPeerUser, normalizeToInputChannel, normalize * > **Note**: non-collectible usernames must still be changed * > using {@link setUsername}/{@link setChatUsername} * - * @param peerId Bot, channel or "me"/"self" * @internal */ export async function toggleFragmentUsername( this: TelegramClient, - peerId: InputPeerLike, params: { + /** Peer ID whose username to toggle */ + peerId: InputPeerLike + /** * Username to toggle */ @@ -26,7 +27,7 @@ export async function toggleFragmentUsername( active: boolean }, ): Promise { - const { username, active } = params + const { peerId, username, active } = params const peer = await this.resolvePeer(peerId) diff --git a/packages/client/src/methods/chats/unban-chat-member.ts b/packages/client/src/methods/chats/unban-chat-member.ts index 09fd5453..40d2d857 100644 --- a/packages/client/src/methods/chats/unban-chat-member.ts +++ b/packages/client/src/methods/chats/unban-chat-member.ts @@ -11,17 +11,21 @@ import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '.. * * This method acts as a no-op in case a legacy group is passed. * - * @param chatId Chat ID - * @param peerId User/channel ID * @internal */ export async function unbanChatMember( this: TelegramClient, - chatId: InputPeerLike, - peerId: InputPeerLike, + params: { + /** Chat ID */ + chatId: InputPeerLike + + /** User/channel ID who should be unbanned */ + participantId: InputPeerLike + }, ): Promise { + const { chatId, participantId } = params const chat = await this.resolvePeer(chatId) - const peer = await this.resolvePeer(peerId) + const peer = await this.resolvePeer(participantId) if (isInputPeerChannel(chat)) { const res = await this.call({ diff --git a/packages/client/src/methods/contacts/add-contact.ts b/packages/client/src/methods/contacts/add-contact.ts index 576ad867..9f9a2c07 100644 --- a/packages/client/src/methods/contacts/add-contact.ts +++ b/packages/client/src/methods/contacts/add-contact.ts @@ -6,14 +6,14 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils' /** * Add an existing Telegram user as a contact * - * @param userId User ID, username or phone number - * @param params Contact details * @internal */ export async function addContact( this: TelegramClient, - userId: InputPeerLike, params: { + /** User ID, username or phone number */ + userId: InputPeerLike + /** * First name of the contact */ @@ -36,15 +36,16 @@ export async function addContact( sharePhone?: boolean }, ): Promise { + const { userId, firstName, lastName = '', phone = '', sharePhone = false } = params const peer = normalizeToInputUser(await this.resolvePeer(userId), userId) const res = await this.call({ _: 'contacts.addContact', id: peer, - firstName: params.firstName, - lastName: params.lastName ?? '', - phone: params.phone ?? '', - addPhonePrivacyException: Boolean(params.sharePhone), + firstName, + lastName, + phone, + addPhonePrivacyException: sharePhone, }) assertIsUpdatesGroup('contacts.addContact', res) diff --git a/packages/client/src/methods/dialogs/edit-folder.ts b/packages/client/src/methods/dialogs/edit-folder.ts index 6741412d..66f0de16 100644 --- a/packages/client/src/methods/dialogs/edit-folder.ts +++ b/packages/client/src/methods/dialogs/edit-folder.ts @@ -5,20 +5,27 @@ import { TelegramClient } from '../../client' /** * Edit a folder with given modification * - * @param folder - * Folder, folder ID or name. - * Note that passing an ID or name will require re-fetching all folders, - * and passing name might affect not the right folder if you have multiple - * with the same name. - * @param modification Modification that will be applied to this folder * @returns Modified folder * @internal */ export async function editFolder( this: TelegramClient, - folder: tl.RawDialogFilter | number | string, - modification: Partial>, + params: { + /** + * Folder, folder ID or name. + * Note that passing an ID or name will require re-fetching all folders, + * and passing name might affect not the right folder if you have multiple + * with the same name. + */ + folder: tl.RawDialogFilter | number | string + + /** Modification to be applied to this folder */ + modification: Partial> + }, ): Promise { + const { modification } = params + let { folder } = params + if (folder === 0) { throw new MtArgumentError('Cannot modify default folder') } diff --git a/packages/client/src/methods/dialogs/find-folder.ts b/packages/client/src/methods/dialogs/find-folder.ts index 5ae71b28..484fee25 100644 --- a/packages/client/src/methods/dialogs/find-folder.ts +++ b/packages/client/src/methods/dialogs/find-folder.ts @@ -15,8 +15,11 @@ import { TelegramClient } from '../../client' export async function findFolder( this: TelegramClient, params: { + /** Folder title */ title?: string + /** Folder emoji */ emoji?: string + /** Folder ID */ id?: number }, ): Promise { diff --git a/packages/client/src/methods/dialogs/set-folders.ts b/packages/client/src/methods/dialogs/set-folders-order.ts similarity index 79% rename from packages/client/src/methods/dialogs/set-folders.ts rename to packages/client/src/methods/dialogs/set-folders-order.ts index b9386c2c..8452639a 100644 --- a/packages/client/src/methods/dialogs/set-folders.ts +++ b/packages/client/src/methods/dialogs/set-folders-order.ts @@ -3,8 +3,7 @@ import { TelegramClient } from '../../client' /** * Reorder folders * - * Order is folder's ID (0 = default folder) - * + * @param order New order of folders (folder IDs, where default = 0) * @internal */ export async function setFoldersOrder(this: TelegramClient, order: number[]): Promise { diff --git a/packages/client/src/methods/forums/create-forum-topic.ts b/packages/client/src/methods/forums/create-forum-topic.ts index 8240dde2..9facc38a 100644 --- a/packages/client/src/methods/forums/create-forum-topic.ts +++ b/packages/client/src/methods/forums/create-forum-topic.ts @@ -10,14 +10,15 @@ import { normalizeToInputChannel } from '../../utils/peer-utils' * * Only admins with `manageTopics` permission can do this. * - * @param chatId Chat ID or username * @returns Service message for the created topic * @internal */ export async function createForumTopic( this: TelegramClient, - chatId: InputPeerLike, params: { + /** Chat ID or username */ + chatId: InputPeerLike + /** * Topic title */ @@ -39,7 +40,7 @@ export async function createForumTopic( sendAs?: InputPeerLike }, ): Promise { - const { title, icon, sendAs } = params + const { chatId, title, icon, sendAs } = params const res = await this.call({ _: 'channels.createForumTopic', diff --git a/packages/client/src/methods/forums/edit-forum-topic.ts b/packages/client/src/methods/forums/edit-forum-topic.ts index fae24f57..75d21075 100644 --- a/packages/client/src/methods/forums/edit-forum-topic.ts +++ b/packages/client/src/methods/forums/edit-forum-topic.ts @@ -16,9 +16,12 @@ import { normalizeToInputChannel } from '../../utils/peer-utils' */ export async function editForumTopic( this: TelegramClient, - chatId: InputPeerLike, - topicId: number, params: { + /** Chat ID or username */ + chatId: InputPeerLike + /** ID of the topic (i.e. its top message ID) */ + + topicId: number /** * New topic title */ @@ -33,7 +36,7 @@ export async function editForumTopic( icon?: tl.Long | null }, ): Promise { - const { title, icon } = params + const { chatId, topicId, title, icon } = params const res = await this.call({ _: 'channels.editForumTopic', diff --git a/packages/client/src/methods/forums/reorder-pinned-forum-topics.ts b/packages/client/src/methods/forums/reorder-pinned-forum-topics.ts index fea07ccf..023169a9 100644 --- a/packages/client/src/methods/forums/reorder-pinned-forum-topics.ts +++ b/packages/client/src/methods/forums/reorder-pinned-forum-topics.ts @@ -7,14 +7,14 @@ import { normalizeToInputChannel } from '../../utils/peer-utils' * * Only admins with `manageTopics` permission can do this. * - * @param chatId Chat ID or username - * @param topicId ID of the topic (i.e. its top message ID) * @internal */ export async function reorderPinnedForumTopics( this: TelegramClient, - chatId: InputPeerLike, params: { + /** Chat ID or username */ + chatId: InputPeerLike + /** * Order of the pinned topics */ @@ -26,7 +26,7 @@ export async function reorderPinnedForumTopics( force?: boolean }, ): Promise { - const { order, force } = params + const { chatId, order, force } = params await this.call({ _: 'channels.reorderPinnedForumTopics', channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId), diff --git a/packages/client/src/methods/forums/toggle-forum-topic-closed.ts b/packages/client/src/methods/forums/toggle-forum-topic-closed.ts index 75475549..25afdc35 100644 --- a/packages/client/src/methods/forums/toggle-forum-topic-closed.ts +++ b/packages/client/src/methods/forums/toggle-forum-topic-closed.ts @@ -7,18 +7,24 @@ import { normalizeToInputChannel } from '../../utils/peer-utils' * * Only admins with `manageTopics` permission can do this. * - * @param chatId Chat ID or username - * @param topicId ID of the topic (i.e. its top message ID) - * @param closed Whether the topic should be closed * @returns Service message about the modification * @internal */ export async function toggleForumTopicClosed( this: TelegramClient, - chatId: InputPeerLike, - topicId: number, - closed: boolean, + parmas: { + /** Chat ID or username */ + chatId: InputPeerLike + + /** ID of the topic (i.e. its top message ID) */ + topicId: number + + /** Whether the topic should be closed */ + closed: boolean + }, ): Promise { + const { chatId, topicId, closed } = parmas + const res = await this.call({ _: 'channels.editForumTopic', channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId), diff --git a/packages/client/src/methods/forums/toggle-forum-topic-pinned.ts b/packages/client/src/methods/forums/toggle-forum-topic-pinned.ts index e0bef375..87a05b79 100644 --- a/packages/client/src/methods/forums/toggle-forum-topic-pinned.ts +++ b/packages/client/src/methods/forums/toggle-forum-topic-pinned.ts @@ -7,17 +7,21 @@ import { normalizeToInputChannel } from '../../utils/peer-utils' * * Only admins with `manageTopics` permission can do this. * - * @param chatId Chat ID or username - * @param topicId ID of the topic (i.e. its top message ID) - * @param pinned Whether the topic should be pinned * @internal */ export async function toggleForumTopicPinned( this: TelegramClient, - chatId: InputPeerLike, - topicId: number, - pinned: boolean, + params: { + /** Chat ID or username */ + chatId: InputPeerLike + /** ID of the topic (i.e. its top message ID) */ + topicId: number + /** Whether the topic should be pinned */ + pinned: boolean + }, ): Promise { + const { chatId, topicId, pinned } = params + await this.call({ _: 'channels.updatePinnedForumTopic', channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId), diff --git a/packages/client/src/methods/invite-links/edit-invite-link.ts b/packages/client/src/methods/invite-links/edit-invite-link.ts index d4dc6f54..0c93e122 100644 --- a/packages/client/src/methods/invite-links/edit-invite-link.ts +++ b/packages/client/src/methods/invite-links/edit-invite-link.ts @@ -16,9 +16,11 @@ import { normalizeDate } from '../../utils/misc-utils' */ export async function editInviteLink( this: TelegramClient, - chatId: InputPeerLike, - link: string, params: { + /** Chat ID */ + chatId: InputPeerLike + /** Invite link to edit */ + link: string /** * Date when this link will expire. * If `number` is passed, UNIX time in ms is expected. @@ -40,13 +42,15 @@ export async function editInviteLink( withApproval?: boolean }, ): Promise { + const { chatId, link, expires, usageLimit, withApproval } = params + const res = await this.call({ _: 'messages.editExportedChatInvite', peer: await this.resolvePeer(chatId), link, - expireDate: normalizeDate(params.expires), - usageLimit: params.usageLimit, - requestNeeded: params.withApproval, + expireDate: normalizeDate(expires), + usageLimit, + requestNeeded: withApproval, }) const peers = PeersIndex.from(res) diff --git a/packages/client/src/methods/invite-links/get-invite-link-members.ts b/packages/client/src/methods/invite-links/get-invite-link-members.ts index 26f32af6..ba965d6c 100644 --- a/packages/client/src/methods/invite-links/get-invite-link-members.ts +++ b/packages/client/src/methods/invite-links/get-invite-link-members.ts @@ -15,7 +15,7 @@ import { makeArrayPaginated, normalizeDate, normalizeToInputUser } from '../../u export async function getInviteLinkMembers( this: TelegramClient, chatId: InputPeerLike, - params: { + params?: { /** * Invite link for which to get members */ @@ -54,6 +54,7 @@ export async function getInviteLinkMembers( }, ): Promise> { const peer = await this.resolvePeer(chatId) + if (!params) params = {} const { limit = 100, link, requestedSearch, requested = Boolean(requestedSearch) } = params diff --git a/packages/client/src/methods/invite-links/hide-all-join-requests.ts b/packages/client/src/methods/invite-links/hide-all-join-requests.ts index 9f8f5167..fb2fe17a 100644 --- a/packages/client/src/methods/invite-links/hide-all-join-requests.ts +++ b/packages/client/src/methods/invite-links/hide-all-join-requests.ts @@ -4,21 +4,27 @@ import { InputPeerLike } from '../../types' /** * Approve or deny multiple join requests to a chat. * - * @param peer Chat/channel ID - * @param action Whether to approve or deny the join requests - * @param link Invite link to target * @internal */ export async function hideAllJoinRequests( this: TelegramClient, - peer: InputPeerLike, - action: 'approve' | 'deny', - link?: string, + params: { + /** Chat/channel ID */ + chatId: InputPeerLike + + /** Whether to approve or deny the join requests */ + action: 'approve' | 'deny' + + /** Invite link to target */ + link?: string + }, ): Promise { + const { chatId, action, link } = params + await this.call({ _: 'messages.hideAllChatJoinRequests', approved: action === 'approve', - peer: await this.resolvePeer(peer), + peer: await this.resolvePeer(chatId), link, }) } diff --git a/packages/client/src/methods/invite-links/hide-join-request.ts b/packages/client/src/methods/invite-links/hide-join-request.ts index 885796c2..c94c12b8 100644 --- a/packages/client/src/methods/invite-links/hide-join-request.ts +++ b/packages/client/src/methods/invite-links/hide-join-request.ts @@ -5,23 +5,27 @@ import { normalizeToInputUser } from '../../utils/peer-utils' /** * Approve or deny join request to a chat. * - * @param peer Chat/channel ID - * @param user User ID - * @param action Whether to approve or deny the join request * @internal */ export async function hideJoinRequest( this: TelegramClient, - peer: InputPeerLike, - user: InputPeerLike, - action: 'approve' | 'deny', + params: { + /** Chat/channel ID */ + chatId: InputPeerLike + /** User ID */ + user: InputPeerLike + /** Whether to approve or deny the join request */ + action: 'approve' | 'deny' + }, ): Promise { + const { chatId, user, action } = params + const userId = normalizeToInputUser(await this.resolvePeer(user), user) await this.call({ _: 'messages.hideChatJoinRequest', approved: action === 'approve', - peer: await this.resolvePeer(peer), + peer: await this.resolvePeer(chatId), userId, }) } diff --git a/packages/client/src/methods/invite-links/iter-invite-link-members.ts b/packages/client/src/methods/invite-links/iter-invite-link-members.ts index 3f5a199f..fda9de7b 100644 --- a/packages/client/src/methods/invite-links/iter-invite-link-members.ts +++ b/packages/client/src/methods/invite-links/iter-invite-link-members.ts @@ -12,7 +12,7 @@ import { ChatInviteLinkMember, InputPeerLike } from '../../types' export async function* iterInviteLinkMembers( this: TelegramClient, chatId: InputPeerLike, - params: Parameters[1] & { + params?: Parameters[1] & { /** * Maximum number of users to return * @@ -30,6 +30,7 @@ export async function* iterInviteLinkMembers( }, ): AsyncIterableIterator { const peer = await this.resolvePeer(chatId) + if (!params) params = {} const { limit = Infinity, chunkSize = 100, link, requestedSearch, requested = Boolean(requestedSearch) } = params diff --git a/packages/client/src/methods/messages/close-poll.ts b/packages/client/src/methods/messages/close-poll.ts index 0d76ed0f..f7d71bff 100644 --- a/packages/client/src/methods/messages/close-poll.ts +++ b/packages/client/src/methods/messages/close-poll.ts @@ -11,11 +11,19 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils' * Once closed, poll can't be re-opened, and nobody * will be able to vote in it * - * @param chatId Chat ID where this poll was found - * @param message Message ID where this poll was found * @internal */ -export async function closePoll(this: TelegramClient, chatId: InputPeerLike, message: number): Promise { +export async function closePoll( + this: TelegramClient, + params: { + /** Chat ID where this poll was found */ + chatId: InputPeerLike + /** Message ID where this poll was found */ + message: number + }, +): Promise { + const { chatId, message } = params + const res = await this.call({ _: 'messages.editMessage', peer: await this.resolvePeer(chatId), diff --git a/packages/client/src/methods/messages/delete-messages.ts b/packages/client/src/methods/messages/delete-messages.ts index 99ff9224..0517d8c4 100644 --- a/packages/client/src/methods/messages/delete-messages.ts +++ b/packages/client/src/methods/messages/delete-messages.ts @@ -10,16 +10,24 @@ import { createDummyUpdate } from '../../utils/updates-utils' * * @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`. * @param ids Message(s) ID(s) to delete. - * @param revoke Whether to "revoke" (i.e. delete for both sides). - * Only used for chats and private chats. * @internal */ export async function deleteMessages( this: TelegramClient, chatId: InputPeerLike, ids: MaybeArray, - revoke = true, + params?: { + /** + * Whether to "revoke" (i.e. delete for both sides). + * Only used for chats and private chats. + * + * @default true + */ + revoke?: boolean + }, ): Promise { + const { revoke = true } = params ?? {} + if (!Array.isArray(ids)) ids = [ids] const peer = await this.resolvePeer(chatId) diff --git a/packages/client/src/methods/messages/edit-inline-message.ts b/packages/client/src/methods/messages/edit-inline-message.ts index eea9ec8c..34c22240 100644 --- a/packages/client/src/methods/messages/edit-inline-message.ts +++ b/packages/client/src/methods/messages/edit-inline-message.ts @@ -15,8 +15,13 @@ import { normalizeInlineId } from '../../utils/inline-utils' */ export async function editInlineMessage( this: TelegramClient, - messageId: tl.TypeInputBotInlineMessageID | string, params: { + /** + * Inline message ID, either as a TL object, or as a + * TDLib and Bot API compatible string + */ + messageId: tl.TypeInputBotInlineMessageID | string + /** * New message text * @@ -71,7 +76,7 @@ export async function editInlineMessage( let entities: tl.TypeMessageEntity[] | undefined let media: tl.TypeInputMedia | undefined = undefined - const id = normalizeInlineId(messageId) + const id = normalizeInlineId(params.messageId) if (params.media) { media = await this._normalizeInputMedia(params.media, params, true) diff --git a/packages/client/src/methods/messages/edit-message.ts b/packages/client/src/methods/messages/edit-message.ts index 08aae062..84810279 100644 --- a/packages/client/src/methods/messages/edit-message.ts +++ b/packages/client/src/methods/messages/edit-message.ts @@ -13,9 +13,12 @@ import { BotKeyboard, FormattedString, InputMediaLike, InputPeerLike, Message, R */ export async function editMessage( this: TelegramClient, - chatId: InputPeerLike, - message: number | Message, params: { + /** Chat ID */ + chatId: InputPeerLike + /** Message to edit */ + message: number | Message + /** * New message text * @@ -72,6 +75,7 @@ export async function editMessage( progressCallback?: (uploaded: number, total: number) => void }, ): Promise { + const { chatId, message } = params let content: string | undefined = undefined let entities: tl.TypeMessageEntity[] | undefined let media: tl.TypeInputMedia | undefined = undefined diff --git a/packages/client/src/methods/messages/forward-messages.ts b/packages/client/src/methods/messages/forward-messages.ts index 4bf11c55..d3598f73 100644 --- a/packages/client/src/methods/messages/forward-messages.ts +++ b/packages/client/src/methods/messages/forward-messages.ts @@ -11,8 +11,6 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils' * * To forward with a caption, use another overload that takes an array of IDs. * - * @param toChatId Destination chat ID, username, phone, `"me"` or `"self"` - * @param fromChatId Source chat ID, username, phone, `"me"` or `"self"` * @param message Message ID * @param params Additional sending parameters * @returns Newly sent, forwarded messages in the destination chat @@ -20,10 +18,14 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils' */ export async function forwardMessages( this: TelegramClient, - toChatId: InputPeerLike, - fromChatId: InputPeerLike, - message: number, - params?: { + params: { + /** Source chat ID, username, phone, `"me"` or `"self"` */ + fromChatId: InputPeerLike + /** Destination chat ID, username, phone, `"me"` or `"self"` */ + toChatId: InputPeerLike + /** Message ID */ + messages: number + /** * Optionally, a caption for your forwarded message(s). * It will be sent as a separate message before the forwarded messages. @@ -117,10 +119,14 @@ export async function forwardMessages( */ export async function forwardMessages( this: TelegramClient, - toChatId: InputPeerLike, - fromChatId: InputPeerLike, - messages: number[], - params?: { + params: { + /** Source chat ID, username, phone, `"me"` or `"self"` */ + fromChatId: InputPeerLike + /** Destination chat ID, username, phone, `"me"` or `"self"` */ + toChatId: InputPeerLike + /** Message IDs */ + messages: number[] + /** * Optionally, a caption for your forwarded message(s). * It will be sent as a separate message before the forwarded messages. @@ -200,10 +206,11 @@ export async function forwardMessages( /** @internal */ export async function forwardMessages( this: TelegramClient, - toChatId: InputPeerLike, - fromChatId: InputPeerLike, - messages: MaybeArray, - params?: { + params: { + toChatId: InputPeerLike + fromChatId: InputPeerLike + messages: MaybeArray + /** * Optionally, a caption for your forwarded message(s). * It will be sent as a separate message before the forwarded messages. @@ -283,7 +290,20 @@ export async function forwardMessages( sendAs?: InputPeerLike }, ): Promise> { - if (!params) params = {} + const { + toChatId, + fromChatId, + parseMode, + entities, + silent, + schedule, + clearDraft, + forbidForwards, + sendAs, + noAuthor, + noCaption, + } = params + let { messages } = params let isSingle = false @@ -309,22 +329,22 @@ export async function forwardMessages( } captionMessage = await this.sendText(toPeer, params.caption, { - parseMode: params.parseMode, - entities: params.entities, - silent: params.silent, - schedule: params.schedule, - clearDraft: params.clearDraft, - forbidForwards: params.forbidForwards, - sendAs: params.sendAs, + parseMode, + entities, + silent, + schedule, + clearDraft, + forbidForwards, + sendAs, }) } else if (params.captionMedia) { captionMessage = await this.sendMedia(toPeer, params.captionMedia, { - parseMode: params.parseMode, - silent: params.silent, - schedule: params.schedule, - clearDraft: params.clearDraft, - forbidForwards: params.forbidForwards, - sendAs: params.sendAs, + parseMode, + silent, + schedule, + clearDraft, + forbidForwards, + sendAs, }) } @@ -333,13 +353,13 @@ export async function forwardMessages( toPeer, fromPeer: await this.resolvePeer(fromChatId), id: messages, - silent: params.silent, - scheduleDate: normalizeDate(params.schedule), + silent, + scheduleDate: normalizeDate(schedule), randomId: Array.from({ length: messages.length }, () => randomLong()), - dropAuthor: params.noAuthor, - dropMediaCaptions: params.noCaption, - noforwards: params.forbidForwards, - sendAs: params.sendAs ? await this.resolvePeer(params.sendAs) : undefined, + dropAuthor: noAuthor, + dropMediaCaptions: noCaption, + noforwards: forbidForwards, + sendAs: sendAs ? await this.resolvePeer(sendAs) : undefined, }) assertIsUpdatesGroup('messages.forwardMessages', res) diff --git a/packages/client/src/methods/messages/pin-message.ts b/packages/client/src/methods/messages/pin-message.ts index a9b344c1..3a5f1c95 100644 --- a/packages/client/src/methods/messages/pin-message.ts +++ b/packages/client/src/methods/messages/pin-message.ts @@ -9,17 +9,21 @@ import { InputPeerLike } from '../../types' * * @param chatId Chat ID, username, phone number, `"self"` or `"me"` * @param messageId Message ID - * @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) * @internal */ export async function pinMessage( this: TelegramClient, chatId: InputPeerLike, messageId: number, - notify = false, - bothSides = false, + params?: { + /** Whether to send a notification (only for legacy groups and supergroups) */ + notify?: boolean + /** Whether to pin for both sides (only for private chats) */ + bothSides?: boolean + }, ): Promise { + const { notify, bothSides } = params ?? {} + const res = await this.call({ _: 'messages.updatePinnedMessage', peer: await this.resolvePeer(chatId), diff --git a/packages/client/src/methods/messages/read-history.ts b/packages/client/src/methods/messages/read-history.ts index e187e1df..358eb6c8 100644 --- a/packages/client/src/methods/messages/read-history.ts +++ b/packages/client/src/methods/messages/read-history.ts @@ -7,16 +7,27 @@ import { createDummyUpdate } from '../../utils/updates-utils' * Mark chat history as read. * * @param chatId Chat ID - * @param message Message up until which to read history (by default everything is read) - * @param clearMentions Whether to also clear all mentions in the chat * @internal */ export async function readHistory( this: TelegramClient, chatId: InputPeerLike, - message = 0, - clearMentions = false, + params?: { + /** + * Message up until which to read history + * + * @default 0, i.e. read everything + */ + maxId?: number + + /** + * Whether to also clear all mentions in the chat + */ + clearMentions?: boolean + }, ): Promise { + const { maxId = 0, clearMentions } = params ?? {} + const peer = await this.resolvePeer(chatId) if (clearMentions) { @@ -36,13 +47,13 @@ export async function readHistory( await this.call({ _: 'channels.readHistory', channel: normalizeToInputChannel(peer), - maxId: message, + maxId, }) } else { const res = await this.call({ _: 'messages.readHistory', peer, - maxId: message, + maxId, }) this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount)) } diff --git a/packages/client/src/methods/messages/send-copy.ts b/packages/client/src/methods/messages/send-copy.ts index 3a1c8d1b..3241bbc1 100644 --- a/packages/client/src/methods/messages/send-copy.ts +++ b/packages/client/src/methods/messages/send-copy.ts @@ -16,18 +16,18 @@ import { FormattedString, InputPeerLike, Message, MtMessageNotFoundError, ReplyM * > use {@link Message.sendCopy} instead, since that is * > much more efficient, and that is what this method wraps. * - * @param toChatId Source chat ID - * @param fromChatId Target chat ID - * @param message Message ID to forward * @param params * @internal */ export async function sendCopy( this: TelegramClient, - toChatId: InputPeerLike, - fromChatId: InputPeerLike, - message: number, - params?: { + params: { + /** Source chat ID */ + fromChatId: InputPeerLike + /** Target chat ID */ + toChatId: InputPeerLike + /** Message ID to forward */ + message: number /** * Whether to send this message silently. */ @@ -97,6 +97,8 @@ export async function sendCopy( clearDraft?: boolean }, ): Promise { + const { fromChatId, toChatId, message, ...rest } = params + const fromPeer = await this.resolvePeer(fromChatId) const msg = await this.getMessages(fromPeer, message) @@ -105,5 +107,5 @@ export async function sendCopy( throw new MtMessageNotFoundError(getMarkedPeerId(fromPeer), message, 'to copy') } - return msg.sendCopy(toChatId, params) + return msg.sendCopy(toChatId, rest) } diff --git a/packages/client/src/methods/messages/send-reaction.ts b/packages/client/src/methods/messages/send-reaction.ts index bd3aec5b..5f484b05 100644 --- a/packages/client/src/methods/messages/send-reaction.ts +++ b/packages/client/src/methods/messages/send-reaction.ts @@ -5,20 +5,24 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils' /** * Send or remove a reaction. * - * @param chatId Chat ID with the message to react to - * @param message Message ID to react to - * @param emoji Reaction emoji (or `null` to remove reaction) - * @param big Whether to use a big reaction * @returns Message to which the reaction was sent * @internal */ export async function sendReaction( this: TelegramClient, - chatId: InputPeerLike, - message: number, - emoji?: InputReaction | null, - big = false, + params: { + /** Chat ID with the message to react to */ + chatId: InputPeerLike + /** Message ID to react to */ + message: number + /** Reaction emoji (or `null` to remove reaction) */ + emoji?: InputReaction | null + /** Whether to use a big reaction */ + big?: boolean + }, ): Promise { + const { chatId, message, emoji, big } = params + const reaction = normalizeInputReaction(emoji) const res = await this.call({ diff --git a/packages/client/src/methods/messages/send-vote.ts b/packages/client/src/methods/messages/send-vote.ts index dffbc0a1..98d8d132 100644 --- a/packages/client/src/methods/messages/send-vote.ts +++ b/packages/client/src/methods/messages/send-vote.ts @@ -8,21 +8,27 @@ import { assertIsUpdatesGroup } from '../../utils/updates-utils' /** * Send or retract a vote in a poll. * - * @param chatId Chat ID where this poll was found - * @param message Message ID where this poll was found - * @param options - * Selected options, or `null` to retract. - * You can pass indexes of the answers or the `Buffer`s - * representing them. In case of indexes, the poll will first - * be requested from the server. * @internal */ export async function sendVote( this: TelegramClient, - chatId: InputPeerLike, - message: number, - options: null | MaybeArray, + params: { + /** Chat ID where this poll was found */ + chatId: InputPeerLike + /** Message ID where this poll was found */ + message: number + /** + * Selected options, or `null` to retract. + * You can pass indexes of the answers or the `Buffer`s + * representing them. In case of indexes, the poll will first + * be requested from the server. + */ + options: null | MaybeArray + }, ): Promise { + const { chatId, message } = params + let { options } = params + if (options === null) options = [] if (!Array.isArray(options)) options = [options] diff --git a/packages/client/src/methods/messages/translate-message.ts b/packages/client/src/methods/messages/translate-message.ts index e992c714..6cc18bbe 100644 --- a/packages/client/src/methods/messages/translate-message.ts +++ b/packages/client/src/methods/messages/translate-message.ts @@ -6,19 +6,21 @@ import { InputPeerLike, MessageEntity } from '../../types' * * Returns `null` if it could not translate the message. * - * > **Note**: For now doesn't seem to work, returns null for all messages. - * - * @param chatId Chat or user ID - * @param messageId Identifier of the message to translate - * @param toLanguage Target language (two-letter ISO 639-1 language code) * @internal */ export async function translateMessage( this: TelegramClient, - chatId: InputPeerLike, - messageId: number, - toLanguage: string, + params: { + /** Chat or user ID */ + chatId: InputPeerLike + /** Identifier of the message to translate */ + messageId: number + /** Target language (two-letter ISO 639-1 language code) */ + toLanguage: string + }, ): Promise<[string, MessageEntity[]] | null> { + const { chatId, messageId, toLanguage } = params + const res = await this.call({ _: 'messages.translateText', peer: await this.resolvePeer(chatId), diff --git a/packages/client/src/methods/pasword/change-cloud-password.ts b/packages/client/src/methods/pasword/change-cloud-password.ts index ed1da652..96f1ee81 100644 --- a/packages/client/src/methods/pasword/change-cloud-password.ts +++ b/packages/client/src/methods/pasword/change-cloud-password.ts @@ -6,17 +6,21 @@ import { TelegramClient } from '../../client' /** * Change your 2FA password * - * @param currentPassword Current password as plaintext - * @param newPassword New password as plaintext - * @param hint Hint for the new password * @internal */ export async function changeCloudPassword( this: TelegramClient, - currentPassword: string, - newPassword: string, - hint?: string, + params: { + /** Current password as plaintext */ + currentPassword: string + /** New password as plaintext */ + newPassword: string + /** Hint for the new password */ + hint?: string + }, ): Promise { + const { currentPassword, newPassword, hint } = params + const pwd = await this.call({ _: 'account.getPassword' }) if (!pwd.hasPassword) { diff --git a/packages/client/src/methods/pasword/enable-cloud-password.ts b/packages/client/src/methods/pasword/enable-cloud-password.ts index 8960ccc1..413f3545 100644 --- a/packages/client/src/methods/pasword/enable-cloud-password.ts +++ b/packages/client/src/methods/pasword/enable-cloud-password.ts @@ -11,17 +11,21 @@ import { TelegramClient } from '../../client' * {@link resendPasswordEmail} or {@link cancelPasswordEmail}, * and the call this method again * - * @param password 2FA password as plaintext - * @param hint Hint for the new password - * @param email Recovery email * @internal */ export async function enableCloudPassword( this: TelegramClient, - password: string, - hint?: string, - email?: string, + params: { + /** 2FA password as plaintext */ + password: string + /** Hint for the new password */ + hint?: string + /** Recovery email */ + email?: string + }, ): Promise { + const { password, hint, email } = params + const pwd = await this.call({ _: 'account.getPassword' }) if (pwd.hasPassword) { diff --git a/packages/client/src/methods/stickers/add-sticker-to-set.ts b/packages/client/src/methods/stickers/add-sticker-to-set.ts index 1fb6945f..00d4d30a 100644 --- a/packages/client/src/methods/stickers/add-sticker-to-set.ts +++ b/packages/client/src/methods/stickers/add-sticker-to-set.ts @@ -13,7 +13,7 @@ import { * Only for bots, and the sticker set must * have been created by this bot. * - * @param id Sticker set short name or TL object with input sticker set + * @param setId Sticker set short name or TL object with input sticker set * @param sticker Sticker to be added * @param params * @returns Modfiied sticker set @@ -21,7 +21,7 @@ import { */ export async function addStickerToSet( this: TelegramClient, - id: InputStickerSet, + setId: InputStickerSet, sticker: InputStickerSetItem, params?: { /** @@ -35,7 +35,7 @@ export async function addStickerToSet( ): Promise { const res = await this.call({ _: 'stickers.addStickerToSet', - stickerset: normalizeInputStickerSet(id), + stickerset: normalizeInputStickerSet(setId), sticker: { _: 'inputStickerSetItem', document: await this._normalizeFileToDocument(sticker.file, params ?? {}), diff --git a/packages/client/src/methods/stickers/get-sticker-set.ts b/packages/client/src/methods/stickers/get-sticker-set.ts index 62027c9c..771e82e9 100644 --- a/packages/client/src/methods/stickers/get-sticker-set.ts +++ b/packages/client/src/methods/stickers/get-sticker-set.ts @@ -4,13 +4,13 @@ import { InputStickerSet, normalizeInputStickerSet, StickerSet } from '../../typ /** * Get a sticker pack and stickers inside of it. * - * @param id Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID + * @param setId Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID * @internal */ -export async function getStickerSet(this: TelegramClient, id: InputStickerSet): Promise { +export async function getStickerSet(this: TelegramClient, setId: InputStickerSet): Promise { const res = await this.call({ _: 'messages.getStickerSet', - stickerset: normalizeInputStickerSet(id), + stickerset: normalizeInputStickerSet(setId), hash: 0, }) diff --git a/packages/client/src/methods/stickers/set-chat-sticker-set.ts b/packages/client/src/methods/stickers/set-chat-sticker-set.ts index 384e1915..2e351f45 100644 --- a/packages/client/src/methods/stickers/set-chat-sticker-set.ts +++ b/packages/client/src/methods/stickers/set-chat-sticker-set.ts @@ -5,7 +5,7 @@ import { normalizeToInputChannel } from '../../utils' /** * Set group sticker set for a supergroup * - * @param id Sticker set short name or a TL object with input sticker set + * @param setId Sticker set short name or a TL object with input sticker set * @param thumb Sticker set thumbnail * @param params * @returns Modified sticker set @@ -14,11 +14,11 @@ import { normalizeToInputChannel } from '../../utils' export async function setChatStickerSet( this: TelegramClient, chatId: InputPeerLike, - id: InputStickerSet, + setId: InputStickerSet, ): Promise { await this.call({ _: 'channels.setStickers', channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId), - stickerset: normalizeInputStickerSet(id), + stickerset: normalizeInputStickerSet(setId), }) } diff --git a/packages/client/src/methods/updates.ts b/packages/client/src/methods/updates.ts index 3ddef0e0..6e1122b3 100644 --- a/packages/client/src/methods/updates.ts +++ b/packages/client/src/methods/updates.ts @@ -1,4 +1,4 @@ -/* eslint-disable max-depth */ +/* eslint-disable max-depth,max-params */ import { assertNever, MtArgumentError, tl } from '@mtcute/core' import { AsyncLock, diff --git a/packages/client/src/methods/users/resolve-peer.ts b/packages/client/src/methods/users/resolve-peer.ts index 15282711..90ff15a5 100644 --- a/packages/client/src/methods/users/resolve-peer.ts +++ b/packages/client/src/methods/users/resolve-peer.ts @@ -8,7 +8,7 @@ import { normalizeToInputPeer } from '../../utils/peer-utils' // @available=both /** * Get the `InputPeer` of a known peer id. - * Useful when an `InputPeer` is needed. + * Useful when an `InputPeer` is needed in Raw API. * * @param peerId The peer identifier that you want to extract the `InputPeer` from. * @param force Whether to force re-fetch the peer from the server diff --git a/packages/client/src/methods/users/set-profile-photo.ts b/packages/client/src/methods/users/set-profile-photo.ts index 6a853c59..2023869e 100644 --- a/packages/client/src/methods/users/set-profile-photo.ts +++ b/packages/client/src/methods/users/set-profile-photo.ts @@ -9,19 +9,22 @@ import { InputFileLike, Photo } from '../../types' * * You can also pass a file ID or an InputPhoto to re-use existing photo. * - * @param type Media type (photo or video) - * @param media Input media file - * @param previewSec - * When `type = video`, timestamp in seconds which will be shown - * as a static preview. * @internal */ export async function setProfilePhoto( this: TelegramClient, - type: 'photo' | 'video', - media: InputFileLike | tl.TypeInputPhoto, - previewSec?: number, + params: { + /** Media type (photo or video) */ + type: 'photo' | 'video' + /** Input media file */ + media: InputFileLike | tl.TypeInputPhoto + /** When `type = video`, timestamp in seconds which will be shown as a static preview. */ + previewSec?: number + }, ): Promise { + const { type, previewSec } = params + let { media } = params + // try parsing media as file id or input photo if (tdFileId.isFileIdLike(media) || (typeof media === 'object' && tl.isAnyInputPhoto(media))) { if (typeof media === 'string' && media.match(/^https?:\/\//)) { diff --git a/packages/client/src/types/auth/index.ts b/packages/client/src/types/auth/index.ts index 3c71f24a..11fab783 100644 --- a/packages/client/src/types/auth/index.ts +++ b/packages/client/src/types/auth/index.ts @@ -1,2 +1 @@ export * from './sent-code' -export * from './terms-of-service' diff --git a/packages/client/src/types/auth/terms-of-service.ts b/packages/client/src/types/auth/terms-of-service.ts deleted file mode 100644 index 392a126a..00000000 --- a/packages/client/src/types/auth/terms-of-service.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { tl } from '@mtcute/core' - -import { makeInspectable } from '../../utils' -import { MessageEntity } from '../messages' - -/** - * Telegram's Terms of Service returned by {@link TelegramClient.signIn} - */ -export class TermsOfService { - /** - * Underlying raw TL object - */ - readonly tos: tl.help.TypeTermsOfService - - constructor(obj: tl.help.TypeTermsOfService) { - this.tos = obj - } - - /** - * Terms of Service identifier - */ - get id(): string { - return this.tos.id.data - } - - /** - * Terms of Service text - */ - get text(): string { - return this.tos.text - } - - private _entities?: MessageEntity[] - - /** - * Terms of Service entities text - */ - get entities(): ReadonlyArray { - return (this._entities ??= this.tos.entities.map((it) => new MessageEntity(it, this.tos.text))) - } -} - -makeInspectable(TermsOfService) diff --git a/packages/client/src/types/bots/callback-query.ts b/packages/client/src/types/bots/callback-query.ts index 541ed9f3..b246370f 100644 --- a/packages/client/src/types/bots/callback-query.ts +++ b/packages/client/src/types/bots/callback-query.ts @@ -182,17 +182,17 @@ export class CallbackQuery { return this.client.answerCallbackQuery(this.raw.queryId, params) } - /** - * Edit the message that originated this callback query - */ - async editMessage(params: Parameters[1]): Promise { - // we can use editInlineMessage as a parameter since they share most of the parameters, - // except the ones that won't apply to already sent message anyways. - if (this.raw._ === 'updateInlineBotCallbackQuery') { - return this.client.editInlineMessage(this.raw.msgId, params) - } - await this.client.editMessage(getMarkedPeerId(this.raw.peer), this.raw.msgId, params) - } + // /** + // * Edit the message that originated this callback query + // */ + // async editMessage(params: Parameters[1]): Promise { + // // we can use editInlineMessage as a parameter since they share most of the parameters, + // // except the ones that won't apply to already sent message anyways. + // if (this.raw._ === 'updateInlineBotCallbackQuery') { + // return this.client.editInlineMessage(this.raw.msgId, params) + // } + // await this.client.editMessage(getMarkedPeerId(this.raw.peer), this.raw.msgId, params) + // } } makeInspectable(CallbackQuery) diff --git a/packages/client/src/types/conversation.ts b/packages/client/src/types/conversation.ts index da83f7f8..14ac9996 100644 --- a/packages/client/src/types/conversation.ts +++ b/packages/client/src/types/conversation.ts @@ -218,7 +218,7 @@ export class Conversation { message = this._lastMessage ?? 0 } - return this.client.readHistory(this._inputPeer, message, clearMentions) + return this.client.readHistory(this._inputPeer, { maxId: message, clearMentions }) } /** diff --git a/packages/client/src/types/messages/message.ts b/packages/client/src/types/messages/message.ts index 9aa5def3..5ed31659 100644 --- a/packages/client/src/types/messages/message.ts +++ b/packages/client/src/types/messages/message.ts @@ -786,17 +786,14 @@ export class Message { * @param revoke Whether to "revoke" (i.e. delete for both sides). Only used for chats and private chats. */ delete(revoke = false): Promise { - return this.client.deleteMessages(this.chat.inputPeer, this.id, revoke) + return this.client.deleteMessages(this.chat.inputPeer, this.id, { revoke }) } /** * Pin this message. - * - * @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) */ - pin(notify = false, bothSides = false): Promise { - return this.client.pinMessage(this.chat.inputPeer, this.id, notify, bothSides) + pin(params?: Parameters[2]): Promise { + return this.client.pinMessage(this.chat.inputPeer, this.id, params) } /** @@ -806,34 +803,34 @@ export class Message { return this.client.pinMessage(this.chat.inputPeer, this.id) } - /** - * Edit this message's text and/or reply markup - * - * @link TelegramClient.editMessage - */ - edit(params: Parameters[2]): Promise { - return this.client.editMessage(this.chat.inputPeer, this.id, params) - } + // /** + // * Edit this message's text and/or reply markup + // * + // * @link TelegramClient.editMessage + // */ + // edit(params: Parameters[2]): Promise { + // return this.client.editMessage(this.chat.inputPeer, this.id, params) + // } - /** - * Edit message text and optionally reply markup. - * - * Convenience method that just wraps {@link edit}, - * passing positional `text` as object field. - * - * @param text New message text - * @param params? Additional parameters - * @link TelegramClient.editMessage - */ - editText( - text: string | FormattedString, - params?: Omit[2], 'text'>, - ): Promise { - return this.edit({ - text, - ...(params || {}), - }) - } + // /** + // * Edit message text and optionally reply markup. + // * + // * Convenience method that just wraps {@link edit}, + // * passing positional `text` as object field. + // * + // * @param text New message text + // * @param params? Additional parameters + // * @link TelegramClient.editMessage + // */ + // editText( + // text: string | FormattedString, + // params?: Omit[2], 'text'>, + // ): Promise { + // return this.edit({ + // text, + // ...(params || {}), + // }) + // } /** * Forward this message to some chat @@ -842,13 +839,20 @@ export class Message { * @param params * @returns Forwarded message */ - forwardTo(peer: InputPeerLike, params?: Parameters[3]): Promise { - return this.client.forwardMessages(peer, this.chat.inputPeer, this.id, params) + forwardTo( + peer: InputPeerLike, + params?: Omit[0], 'messages' | 'toChatId' | 'fromChatId'>, + ): Promise { + return this.client.forwardMessages({ + toChatId: peer, + fromChatId: this.chat.inputPeer, + messages: this.id, + ...params, + }) } /** - * Send this message as a copy (i.e. send the same message, - * but do not forward it). + * Send this message as a copy (i.e. send the same message, but do not forward it). * * Note that if the message contains a webpage, * it will be copied simply as a text message, @@ -858,7 +862,10 @@ export class Message { * @param toChatId Target chat ID * @param params Copy parameters */ - sendCopy(toChatId: InputPeerLike, params?: Parameters[3]): Promise { + sendCopy( + toChatId: InputPeerLike, + params?: Omit[0], 'fromChatId' | 'message' | 'toChatId'>, + ): Promise { if (!params) params = {} if (this.raw._ === 'messageService') { @@ -912,7 +919,7 @@ export class Message { * @param clearMentions Whether to also clear mentions */ async read(clearMentions = false): Promise { - return this.client.readHistory(this.chat.inputPeer, this.raw.id, clearMentions) + return this.client.readHistory(this.chat.inputPeer, { maxId: this.raw.id, clearMentions }) } /** @@ -922,7 +929,12 @@ export class Message { * @param big Whether to use a big reaction */ async react(emoji: string | null, big?: boolean): Promise { - return this.client.sendReaction(this.chat.inputPeer, this.raw.id, emoji, big) + return this.client.sendReaction({ + chatId: this.chat.inputPeer, + message: this.raw.id, + emoji, + big, + }) } async getCustomEmojis(): Promise { diff --git a/packages/client/src/types/peers/chat.ts b/packages/client/src/types/peers/chat.ts index 204ed578..a8c7132d 100644 --- a/packages/client/src/types/peers/chat.ts +++ b/packages/client/src/types/peers/chat.ts @@ -614,7 +614,7 @@ export class Chat { * Only applicable to legacy groups, ignored for supergroups and channels */ async addMembers(users: MaybeArray, forwardCount?: number): Promise { - return this.client.addChatMembers(this.inputPeer, users, forwardCount) + return this.client.addChatMembers(this.inputPeer, users, { forwardCount }) } /** @@ -638,7 +638,7 @@ export class Chat { * @param clearMentions Whether to also clear all mentions in the chat */ async readHistory(message = 0, clearMentions = false): Promise { - return this.client.readHistory(this.inputPeer, message, clearMentions) + return this.client.readHistory(this.inputPeer, { maxId: message, clearMentions }) } /** diff --git a/packages/client/src/types/updates/bot-chat-join-request.ts b/packages/client/src/types/updates/bot-chat-join-request.ts index b3b3222c..ff68538b 100644 --- a/packages/client/src/types/updates/bot-chat-join-request.ts +++ b/packages/client/src/types/updates/bot-chat-join-request.ts @@ -74,9 +74,9 @@ export class BotChatJoinRequestUpdate { /** * Approve or deny the request. */ - hide(action: Parameters[2]): Promise { - return this.client.hideJoinRequest(this.chat.inputPeer, this.user.inputPeer, action) - } + // hide(action: Parameters[1]['action']): Promise { + // return this.client.hideJoinRequest(this.chat.inputPeer, { action, user: this.user.inputPeer }) + // } } makeInspectable(BotChatJoinRequestUpdate) diff --git a/packages/client/src/types/updates/chat-join-request.ts b/packages/client/src/types/updates/chat-join-request.ts index 6e2aa9c8..2817c1fe 100644 --- a/packages/client/src/types/updates/chat-join-request.ts +++ b/packages/client/src/types/updates/chat-join-request.ts @@ -55,19 +55,19 @@ export class ChatJoinRequestUpdate { /** * Approve or deny the last requested user */ - hideLast(action: Parameters[2]): Promise { - return this.client.hideJoinRequest(this.chatId, this.raw.recentRequesters[0], action) - } + // hideLast(action: Parameters[1]['action']): Promise { + // return this.client.hideJoinRequest(this.chatId, { user: this.raw.recentRequesters[0], action }) + // } /** * Approve or deny all recent requests * (the ones available in {@link recentRequesters}) */ - async hideAllRecent(action: Parameters[2]): Promise { - for (const id of this.raw.recentRequesters) { - await this.client.hideJoinRequest(this.chatId, id, action) - } - } + // async hideAllRecent(action: Parameters[1]['action']): Promise { + // for (const id of this.raw.recentRequesters) { + // await this.client.hideJoinRequest(this.chatId, { user: id, action }) + // } + // } } makeInspectable(ChatJoinRequestUpdate) diff --git a/packages/client/src/types/updates/chosen-inline-result.ts b/packages/client/src/types/updates/chosen-inline-result.ts index db215201..8d9001af 100644 --- a/packages/client/src/types/updates/chosen-inline-result.ts +++ b/packages/client/src/types/updates/chosen-inline-result.ts @@ -1,4 +1,4 @@ -import { MtArgumentError, tl } from '@mtcute/core' +import { tl } from '@mtcute/core' import { TelegramClient } from '../../client' import { makeInspectable } from '../../utils' @@ -78,13 +78,13 @@ export class ChosenInlineResult { return encodeInlineMessageId(this.raw.msgId) } - async editMessage(params: Parameters[1]): Promise { - if (!this.raw.msgId) { - throw new MtArgumentError('No message ID, make sure you have included reply markup!') - } + // async editMessage(params: Parameters[1]): Promise { + // if (!this.raw.msgId) { + // throw new MtArgumentError('No message ID, make sure you have included reply markup!') + // } - return this.client.editInlineMessage(this.raw.msgId, params) - } + // return this.client.editInlineMessage(this.raw.msgId, params) + // } } makeInspectable(ChosenInlineResult) diff --git a/packages/client/src/types/updates/pre-checkout-query.ts b/packages/client/src/types/updates/pre-checkout-query.ts index 981b0cb6..acb586a5 100644 --- a/packages/client/src/types/updates/pre-checkout-query.ts +++ b/packages/client/src/types/updates/pre-checkout-query.ts @@ -75,7 +75,7 @@ export class PreCheckoutQuery { * Reject the query */ reject(error = ''): Promise { - return this.client.answerPreCheckoutQuery(this.queryId, error) + return this.client.answerPreCheckoutQuery(this.queryId, { error }) } }