import { TelegramBaseClient , TelegramClientParams } from "./telegramBaseClient" ; import * as authMethods from "./auth" ; import * as botMethods from "./bots" ; import * as buttonsMethods from "./buttons" ; import * as downloadMethods from "./downloads" ; import * as parseMethods from "./messageParse" ; import * as messageMethods from "./messages" ; import * as updateMethods from "./updates" ; import * as uploadMethods from "./uploads" ; import * as userMethods from "./users" ; import * as chatMethods from "./chats" ; import * as dialogMethods from "./dialogs" ; import * as twoFA from "./2fa" ; import type { ButtonLike , Entity , EntityLike , MessageIDLike } from "../define" ; import { Api } from "../tl" ; import { sanitizeParseMode } from "../Utils" ; import type { EventBuilder } from "../events/common" ; import { MTProtoSender } from "../network" ; import { LAYER } from "../tl/AllTLObjects" ; import { betterConsoleLog , IS_NODE } from "../Helpers" ; import { DownloadMediaInterface } from "./downloads" ; import { NewMessage , NewMessageEvent } from "../events" ; import { _handleUpdate , _updateLoop } from "./updates" ; import { Session } from "../sessions" ; import { inspect } from "util" ; import { Album , AlbumEvent } from "../events/Album" ; import { CallbackQuery , CallbackQueryEvent } from "../events/CallbackQuery" ; import { EditedMessage , EditedMessageEvent } from "../events/EditedMessage" ; import { DeletedMessage , DeletedMessageEvent } from "../events/DeletedMessage" ; /**
 * The TelegramClient uses several methods in different files to provide all the common functionality in a nice interface.</br>
 * **In short, to create a client you must do:**
 *
 * ```ts
 * import {TelegramClient} from "telegram";
 *
 * const client = new TelegramClient(new StringSession(''),apiId,apiHash,{});
 * ```
 *
 * You don't need to import any methods that are inside the TelegramClient class as they binding in it.
 */ export class TelegramClient extends TelegramBaseClient { param session param apiId param apiHash param clientParams - see  TelegramClientParams constructor ( session , apiId , apiHash , clientParams ) { super ( session , apiId , apiHash , clientParams ) ; } /**
     * Used to handle all aspects of connecting to telegram.<br/>
     * This method will connect to the telegram servers and check if the user is already logged in.<br/>
     * in the case of a new connection this will sign in if the phone already exists or sign up otherwise<br/>
     * By using this method you are **agreeing to Telegram's Terms of Service** https://core.telegram.org/api/terms.<br/>
     * this method also calls  getMe to tell telegram that we want to receive updates.<br/>
     *  param authParams return example start ( authParams ) { return authMethods . start ( this , authParams ) ; } example return checkAuthorization ( ) { return authMethods . checkAuthorization ( this ) ; } example param apiCredentials param authParams signInUser ( apiCredentials , authParams ) { return authMethods . signInUser ( this , apiCredentials , authParams ) ; } example param apiCredentials param authParams signInUserWithQrCode ( apiCredentials , authParams ) { return authMethods . signInUserWithQrCode ( this , apiCredentials , authParams ) ; } example param apiCredentials param phoneNumber param forceSMS return sendCode ( apiCredentials , phoneNumber , forceSMS = false ) { return authMethods . sendCode ( this , apiCredentials , phoneNumber , forceSMS ) ; } param apiCredentials param authParams returns signInWithPassword ( apiCredentials , authParams ) { return authMethods . signInWithPassword ( this , apiCredentials , authParams ) ; } example param apiCredentials param authParams return signInBot ( apiCredentials , authParams ) { return authMethods . signInBot ( this , apiCredentials , authParams ) ; } param client param isCheckPassword param currentPassword param newPassword param hint param email param emailCodeCallback param onEmailCodeError returns throws async updateTwoFaSettings ( { isCheckPassword , currentPassword , newPassword , hint = "" , email , emailCodeCallback , onEmailCodeError , } ) { return twoFA . updateTwoFaSettings ( this , { isCheckPassword , currentPassword , newPassword , hint , email , emailCodeCallback , onEmailCodeError , } ) ; } param bot param query param entity param offset param geoPoint return example pic inlineQuery ( bot , query , entity ? , offset ? , geoPoint ? ) { return botMethods . inlineQuery ( this , bot , query , entity , offset , geoPoint ) ; } param buttons param inlineOnly example buildReplyMarkup ( buttons , inlineOnly = false ) { return buttonsMethods . buildReplyMarkup ( buttons , inlineOnly ) ; } param inputLocation param fileParams -  DownloadFileParams return example downloadFile ( inputLocation , fileParams ) { return downloadMethods . downloadFile ( this , inputLocation , fileParams ) ; } param entity param downloadProfilePhotoParams -  DownloadProfilePhotoParams return example downloadProfilePhoto ( entity , downloadProfilePhotoParams = { isBig : false , } ) { return downloadMethods . downloadProfilePhoto ( this , entity , downloadProfilePhotoParams ) ; } remarks param messageOrMedia param downloadParams -  DownloadMediaInterface return example downloadMedia ( messageOrMedia , downloadParams ) { return downloadMethods . downloadMedia ( this , messageOrMedia , downloadParams ) ; } /**
     * This property is the default parse mode used when sending messages. Defaults to  MarkdownParser .<br/>
     * It will always be either undefined or an object with parse and unparse methods.<br/>
     * When setting a different value it should be one of:<br/>
     *<br/>
     *  - Object with parse and unparse methods.<br/>
     *  - A str indicating the parse_mode. For Markdown 'md' or 'markdown' may be used. For HTML, 'html' may be used.<br/>
     * The parse method should be a function accepting a single parameter, the text to parse, and returning a tuple consisting of (parsed message str, [MessageEntity instances]).<br/>
     * <br/>
     * The unparse method should be the inverse of parse such that text == unparse(parse(text)).<br/>
     * <br/>
     * See  Api . TypeMessageEntity for allowed message entities.
     *  example get parseMode ( ) { return this . _parseMode ; } /** Setter for parseMode.
     *  parseMode param mode example setParseMode ( mode ) { if ( mode ) { this . _parseMode = sanitizeParseMode ( mode ) ; } else { this . _parseMode = undefined ; } } /**
     * Iterates over the messages for a given chat.
     * <br/>
     * The default order is from newest to oldest but can be changed with the reverse param.<br/>
     * If either `search`, `filter` or `fromUser` are provided this will use  Api . messages . Search instead of  Api . messages . GetHistory .
     *  remarks param entity param iterParams -  IterMessagesParams yield Instances of custom  Message example iterMessages ( entity , iterParams ) { return messageMethods . iterMessages ( this , entity , iterParams ) ; } param entity - The entity from whom to retrieve the message history. see  iterMessages .<br/>
     *  param getMessagesParams - see  IterMessagesParams .
     *  return { link example getMessages ( entity , getMessagesParams ) { return messageMethods . getMessages ( this , entity , getMessagesParams ) ; } param entity param sendMessageParams - see  SendMessageParams return example sendMessage ( entity , sendMessageParams ) { return messageMethods . sendMessage ( this , entity , sendMessageParams ) ; } /**
     * Forwards the given messages to the specified entity.<br/>
     *<br/>
     * If you want to "forward" a message without the forward header
     * (the "forwarded from" text), you should use `sendMessage` with
     * the original message instead. This will send a copy of it.
     *<br/>
     * See also  Message . forwardTo `.
     *  param entity param forwardMessagesParams - see  ForwardMessagesParams return example forwardMessages ( entity , forwardMessagesParams ) { return messageMethods . forwardMessages ( this , entity , forwardMessagesParams ) ; } param entity param editMessageParams - see  EditMessageParams .
     *   return throws example editMessage ( entity , editMessageParams ) { return messageMethods . editMessage ( this , entity , editMessageParams ) ; } /**
     * Deletes the given messages, optionally "for everyone".
     *
     * See also  Message . delete `.
     *
     *  remarks param entity param messageIds param revoke return A list of  AffectedMessages , each item being the result for the delete calls of the messages in chunks of 100 each.
     *  example deleteMessages ( entity , messageIds , { revoke = true } ) { return messageMethods . deleteMessages ( this , entity , messageIds , { revoke : revoke , } ) ; } /**
     * Pins a message in a chat.
     *
     * See also  Message . pin `.
     *
     *  remarks param entity param message param pinMessageParams - see  UpdatePinMessageParams .
     *  return The pinned message. if message is undefined the return will be  AffectedHistory example pinMessage ( entity , message ? , pinMessageParams ? ) ; pinMessage ( entity , message , pinMessageParams ? ) ; pinMessage ( entity , message ? , pinMessageParams ? ) { return messageMethods . pinMessage ( this , entity , message , pinMessageParams ) ; } /**
     * Unpins a message in a chat.
     *
     * See also  Message . unpin `.
     *
     *  remarks param entity param message param pinMessageParams - see  UpdatePinMessageParams .
     *  return The pinned message. if message is undefined the return will be  AffectedHistory example unpinMessage ( entity , message ? , pinMessageParams ? ) ; unpinMessage ( entity , message , pinMessageParams ? ) ; unpinMessage ( entity , message ? , unpinMessageParams ? ) { return messageMethods . unpinMessage ( this , entity , message , unpinMessageParams ) as Promise < Api . messages . AffectedHistory | undefined > ; } /**
     * Marks messages as read and optionally clears mentions. <br/>
     * This effectively marks a message as read (or more than one) in the given conversation. <br />
     * If a message or maximum ID is provided, all the messages up to and
     * including such ID will be marked as read (for all messages whose ID ≤ max_id).
     *
     * See also  Message . markRead `.
     *
     *  remarks param entity param message param markAsReadParams - see  MarkAsReadParams .
     *  return example markAsRead ( entity , message ? , markAsReadParams ? ) { return messageMethods . markAsRead ( this , entity , message , markAsReadParams ) ; } param iterDialogsParams - see  IterDialogsParams yield instances of custom  Dialog .
     *  example iterDialogs ( iterDialogsParams ) { return dialogMethods . iterDialogs ( this , iterDialogsParams ) ; } param params -  IterDialogsParams example getDialogs ( params ) { return dialogMethods . getDialogs ( this , params ) ; } param entity param params -  IterParticipantsParams remarks yield example iterParticipants ( entity , params ) { return chatMethods . iterParticipants ( this , entity , params ) ; } param entity param params -  IterParticipantsParams .
     *  return getParticipants ( entity , params ) { return chatMethods . getParticipants ( this , entity , params ) ; } /** TODO */ on ( event ) { return updateMethods . on ( this , event ) ; } param callback param event -The event builder class or instance to be used,
     * for example ``new events.NewMessage({});``.
     * If left unspecified,  Raw (the  Api . TypeUpdate objects with no further processing) will be passed instead.<br>
     *
     *  example addEventHandler ( callback , event ) ; addEventHandler ( callback , event ) ; addEventHandler ( callback , event ) ; addEventHandler ( callback , event ) ; addEventHandler ( callback , event ) ; addEventHandler ( callback , event ? ) ; addEventHandler ( callback , event ? ) { return updateMethods . addEventHandler ( this , callback , event ) ; } param callback param event removeEventHandler ( callback , event ) { return updateMethods . removeEventHandler ( this , callback , event ) ; } return listEventHandlers ( ) { return updateMethods . listEventHandlers ( this ) ; } remarks generally it's better to use  sendFile instead.
     * This method returns a handle (an instance of InputFile or InputFileBig, as required) which can be later used before it expires (they are usable during less than a day).<br/>
     * Uploading a file will simply return a "handle" to the file stored remotely in the Telegram servers,
     * which can be later used on. This will not upload the file to your own chat or any chat at all.
     * This also can be used to update profile pictures
     *  param fileParams see  UploadFileParams return { link Api.InputFileBig} if the file size is larger than 10mb otherwise  Api . InputFile example uploadFile ( fileParams ) { return uploadMethods . uploadFile ( this , fileParams ) ; } /**
     * Sends message with the given file to the specified entity.
     * This uses  uploadFile internally so if you want more control over uploads you can use that.
     *  param entity param sendFileParams - see  SendFileInterface example sendFile ( entity , sendFileParams ) { return uploadMethods . sendFile ( this , entity , sendFileParams ) ; } param request return example invoke < R extends Api . AnyRequest > ( request ) { return userMethods . invoke ( this , request ) ; } /**
     * Gets the current logged in  Api . User .
     * If the user has not logged in this will throw an error.
     *  param inputPeer - Whether to return the input peer version  Api . InputPeerUser or the whole user  Api . User .
     *  return Your own  Api . User example getMe ( inputPeer = false ) { return userMethods . getMe ( this , inputPeer ) ; } example isBot ( ) { return userMethods . isBot ( this ) ; } example isUserAuthorized ( ) { return userMethods . isUserAuthorized ( this ) ; } /**
     * Turns the given entity into a valid Telegram  Api . User ,  Api . Chat or  Api . Channel .<br/>
     * You can also pass a list or iterable of entities, and they will be efficiently fetched from the network.
     *  remarks param entity return { link Api.Chat}, Api . Chat or  Api . Channel corresponding to the input entity. A list will be returned if more than one was given.
     *  example getEntity ( entity ) ; getEntity ( entity ) ; getEntity ( entity ) { return userMethods . getEntity ( this , entity ) ; } param entity return { link Api.InputPeerUser} ,  Api . InputPeerChat ,  Api . InputPeerChannel or  Api . InputPeerSelf if the parameter  is "me" or "self"
     *  example getInputEntity ( entity ) { return userMethods . getInputEntity ( this , entity ) ; } param peer param addMark return example getPeerId ( peer , addMark = true ) { return userMethods . getPeerId ( this , peer , addMark ) ; } hidden _getInputDialog ( peer ) { return userMethods . _getInputDialog ( this , peer ) ; } hidden _getInputNotify ( notify ) { return userMethods . _getInputNotify ( this , notify ) ; } async connect ( ) { await this . _initSession ( ) ; if ( this . _sender === undefined ) { this . _sender = new MTProtoSender ( this . session . getAuthKey ( ) , { logger : this . _log , dcId : this . session . dcId || 4 , retries : this . _connectionRetries , delay : this . _retryDelay , autoReconnect : this . _autoReconnect , connectTimeout : this . _timeout , authKeyCallback : this . _authKeyCallback . bind ( this ) , updateCallback : _handleUpdate . bind ( this ) , isMainSender : true , client : this , } ) ; } this . _sender . userDisconnected = false ; this . _sender . _userConnected = false ; this . _sender . _reconnecting = false ; this . _sender . _disconnected = true ; const connection = new this . _connection ( this . session . serverAddress , this . useWSS ? 443 : 80 , this . session . dcId , this . _log , this . _proxy ) ; const newConnection = await this . _sender . connect ( connection ) ; if ( ! newConnection ) { if ( ! this . _loopStarted ) { _updateLoop ( this ) ; this . _loopStarted = true ; } return ; } this . session . setAuthKey ( this . _sender . authKey ) ; this . _initRequest . query = new Api . help . GetConfig ( ) ; await this . _sender . send ( new Api . InvokeWithLayer ( { layer : LAYER , query : this . _initRequest , } ) ) ; if ( ! this . _loopStarted ) { _updateLoop ( this ) ; this . _loopStarted = true ; } this . _reconnecting = false ; } hidden async _switchDC ( newDc ) { this . _log . info ( `Reconnecting to new data center ${ newDc }` ) ; const DC = await this . getDC ( newDc ) ; this . session . setDC ( newDc , DC . ipAddress , DC . port ) ; await this . _sender ! . authKey . setKey ( undefined ) ; this . session . setAuthKey ( undefined ) ; this . _reconnecting = true ; await this . disconnect ( ) ; return this . connect ( ) ; } param dcId param downloadDC async getDC ( dcId , downloadDC = false ) { this . _log . debug ( `Getting DC ${ dcId }` ) ; if ( ! IS_NODE ) { switch ( dcId ) { case 1 : return { id : 1 , ipAddress : `pluto${ downloadDC ? "-1" : "" }.web.telegram.org` , port : 443 , } ; case 2 : return { id : 2 , ipAddress : `venus${ downloadDC ? "-1" : "" }.web.telegram.org` , port : 443 , } ; case 3 : return { id : 3 , ipAddress : `aurora${ downloadDC ? "-1" : "" }.web.telegram.org` , port : 443 , } ; case 4 : return { id : 4 , ipAddress : `vesta${ downloadDC ? "-1" : "" }.web.telegram.org` , port : 443 , } ; case 5 : return { id : 5 , ipAddress : `flora${ downloadDC ? "-1" : "" }.web.telegram.org` , port : 443 , } ; default : throw new Error ( `Cannot find the DC with the ID of ${ dcId }` ) ; } } if ( ! this . _config ) { this . _config = await this . invoke ( new Api . help . GetConfig ( ) ) ; } for ( const DC of this . _config . dcOptions ) { if ( DC . id === dcId && ! ! DC . ipv6 === this . _useIPV6 ) { return { id : DC . id , ipAddress : DC . ipAddress , port : 443 , } ; } } throw new Error ( `Cannot find the DC with the ID of ${ dcId }` ) ; } hidden _removeSender ( dcId ) { delete this . _borrowedSenderPromises [ dcId ] ; } hidden _getResponseMessage ( req , result , inputChat ) { return parseMethods . _getResponseMessage ( this , req , result , inputChat ) ; } hidden [ inspect . custom ] ( ) { return betterConsoleLog ( this ) ; } /**
     * Small hack for using it in browsers
     */ static get events ( ) { return require ( "../events" ) ; } }