From 95069d01202abdc17fdb1e77bda392e81e5fb30d Mon Sep 17 00:00:00 2001 From: teidesu Date: Sat, 17 Apr 2021 10:05:31 +0300 Subject: [PATCH] feat(client): startTest method test numbers dont seem to work currently though. --- packages/client/src/client.ts | 67 ++++++++++-- .../client/src/methods/auth/start-test.ts | 103 ++++++++++++++++++ 2 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 packages/client/src/methods/auth/start-test.ts diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 30b93dfa..27230e2c 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -12,6 +12,7 @@ import { sendRecoveryCode } from './methods/auth/send-recovery-code' import { signInBot } from './methods/auth/sign-in-bot' import { signIn } from './methods/auth/sign-in' import { signUp } from './methods/auth/sign-up' +import { startTest } from './methods/auth/start-test' import { start } from './methods/auth/start' import { addChatMembers } from './methods/chats/add-chat-members' import { archiveChats } from './methods/chats/archive-chats' @@ -261,6 +262,48 @@ export class TelegramClient extends BaseTelegramClient { ): Promise { return signUp.apply(this, arguments) } + /** + * Utility function to quickly authorize on test DC + * using a [Test phone number](https://core.telegram.org/api/auth#test-phone-numbers), + * which is randomly generated by default. + * + * > **Note**: Using this method assumes that you + * > are using a test DC in `primaryDc` parameter. + * + * @param params Additional parameters + */ + startTest(params?: { + /** + * Whether to log out if current session is logged in. + * + * Defaults to false. + */ + logout?: boolean + + /** + * Override phone number. Must be a valid Test phone number. + * + * By default is randomly generated. + */ + phone?: string + + /** + * 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 + }): Promise { + return startTest.apply(this, arguments) + } /** * Start the client in an interactive and declarative manner, * by providing callbacks for authorization details. @@ -777,7 +820,12 @@ export class TelegramClient extends BaseTelegramClient { return editFolder.apply(this, arguments) } /** - * Iterate over dialogs + * Iterate over dialogs. + * + * Note that due to Telegram limitations, + * ordering here can only be anti-chronological + * (i.e. newest - first), and draft update date + * is not considered when sorting. * * @param params Fetch parameters */ @@ -824,14 +872,9 @@ export class TelegramClient extends BaseTelegramClient { * * Defaults to `include`. * - * > **Note**: fetching pinned dialogs from - * > folders is slow because of Telegram API limitations. - * > When possible, try to either `exclude` them, - * > or use `keep` and find them using {@link Dialog.findPinned}, - * > passing your folder there. - * > - * > Additionally, when using `include` mode with folders, - * > folders will only be fetched if all offset parameters are unset. + * > **Note**: When using `include` mode with folders, + * > pinned dialogs will only be fetched if all offset + * > parameters are unset. */ pinned?: 'include' | 'exclude' | 'only' | 'keep' @@ -860,6 +903,12 @@ export class TelegramClient extends BaseTelegramClient { * and passing a title may fetch from * a wrong folder if you have multiple with the same title. * + * Also note that fetching dialogs in a folder is + * *orders of magnitudes* slower than normal because + * of Telegram API limitations - we have to fetch all dialogs + * and filter the ones we need manually. If possible, + * use {@link Dialog.filterFolder} instead. + * * When a folder with given ID or title is not found, * {@link MtCuteArgumentError} is thrown * diff --git a/packages/client/src/methods/auth/start-test.ts b/packages/client/src/methods/auth/start-test.ts new file mode 100644 index 00000000..ca7ab348 --- /dev/null +++ b/packages/client/src/methods/auth/start-test.ts @@ -0,0 +1,103 @@ +import { MaybeDynamic, MtCuteArgumentError, User } from '../../types' +import { TelegramClient } from '../../client' + +/** + * Utility function to quickly authorize on test DC + * using a [Test phone number](https://core.telegram.org/api/auth#test-phone-numbers), + * which is randomly generated by default. + * + * > **Note**: Using this method assumes that you + * > are using a test DC in `primaryDc` parameter. + * + * @param params Additional parameters + * @internal + */ +export async function startTest ( + this: TelegramClient, + params?: { + /** + * Whether to log out if current session is logged in. + * + * Defaults to false. + */ + logout?: boolean + + /** + * Override phone number. Must be a valid Test phone number. + * + * By default is randomly generated. + */ + phone?: string + + /** + * 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 = {} + + if (params.logout) + try { + await this.logOut() + } catch (e) { + } + + const availableDcs = await this.call({ + _: 'help.getConfig', + }).then((res) => res.dcOptions) + + let phone = params.phone + if (phone) { + if (!phone.match(/^99966\d{5}/)) + throw new MtCuteArgumentError( + `${phone} is an invalid test phone number`, + ) + const id = parseInt(phone[5]) + if (!availableDcs.find(dc => dc.id === id)) + throw new MtCuteArgumentError(`${phone} has invalid DC ID (${id})`) + } else { + let dcId = this._primaryDc.id + if (params.dcId) { + if (!availableDcs.find(dc => dc.id === params!.dcId)) + throw new MtCuteArgumentError(`DC ID is invalid (${dcId})`) + dcId = params.dcId + } + + let numbers = Math.floor(Math.random() * 9999).toString() + while (numbers.length !== 4) numbers += '0' + + phone = `99966${dcId}${numbers}` + } + + // such a smart solution, much wow + const code = phone[5] + phone[5] + phone[5] + phone[5] + phone[5] + + return this.start({ + phone, + code, + firstName: params.firstName, + lastName: params.lastName, + acceptTos: params.acceptTos, + codeSentCallback: () => {} + }) +}