some changes
i've been wanting to name a commit like this for my entire life, lol. seriously though, a lot has changed: - extracted TL-related stuff to `@mtcute/tl-utils` and `@mtcute/tl-runtime`, rewrote codegen in TS - updated to layer 134, moved to int64 identifiers - rewritten networking (mtproto), rewritten updates handling - *lots* of refactoring still a very early version though, there are a lot of improvements to be made, but at least it runs, lol also tl-reference will not be updated anytime soon because i want to rewrite it
This commit is contained in:
parent
a834fbfa8d
commit
ec736f8590
244 changed files with 12560 additions and 6951 deletions
|
@ -36,6 +36,7 @@ module.exports = {
|
|||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-this-alias': 'off',
|
||||
'prefer-rest-params': 'off',
|
||||
'no-prototype-builtins': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/adjacent-overload-signatures': 'off',
|
||||
'@typescript-eslint/no-namespace': 'off',
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/long": "^4.0.1",
|
||||
"@types/node": "^15.12.1",
|
||||
"@mtcute/tl": "~1.131.0",
|
||||
"@mtcute/tl": "~134.0",
|
||||
"@mtcute/core": "^1.0.0",
|
||||
"@mtcute/file-id": "^1.0.0",
|
||||
"eager-async-pool": "^1.0.0",
|
||||
"file-type": "^16.2.0",
|
||||
"big-integer": "1.6.48"
|
||||
"long": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ const ts = require('typescript')
|
|||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const prettier = require('prettier')
|
||||
// not the best way but who cares lol
|
||||
const { createWriter } = require('../../tl/scripts/common')
|
||||
const updates = require('./generate-updates')
|
||||
|
||||
const targetDir = path.join(__dirname, '../src')
|
||||
|
@ -130,7 +128,7 @@ async function addSingleMethod(state, fileName) {
|
|||
|
||||
if (!isExported && !isPrivate) {
|
||||
throwError(
|
||||
isExported,
|
||||
stmt,
|
||||
fileName,
|
||||
'Public methods MUST be exported.'
|
||||
)
|
||||
|
@ -228,6 +226,14 @@ async function addSingleMethod(state, fileName) {
|
|||
}
|
||||
}
|
||||
} else if (stmt.kind === ts.SyntaxKind.InterfaceDeclaration) {
|
||||
if (isCopy) {
|
||||
state.copy.push({
|
||||
from: relPath,
|
||||
code: stmt.getText()
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
if (!checkForFlag(stmt, '@extension')) continue
|
||||
const isExported = (stmt.modifiers || []).find(
|
||||
(mod) => mod.kind === 92 /* ExportKeyword */
|
||||
|
@ -260,7 +266,7 @@ async function addSingleMethod(state, fileName) {
|
|||
}
|
||||
|
||||
async function main() {
|
||||
const output = createWriter('../src/client.ts', __dirname)
|
||||
const output = fs.createWriteStream(path.join(__dirname, '../src/client.ts'))
|
||||
const state = {
|
||||
imports: {},
|
||||
fields: [],
|
||||
|
@ -282,23 +288,22 @@ async function main() {
|
|||
output.write(
|
||||
'/* THIS FILE WAS AUTO-GENERATED */\n' +
|
||||
"import { BaseTelegramClient } from '@mtcute/core'\n" +
|
||||
"import { tl } from '@mtcute/tl'"
|
||||
"import { tl } from '@mtcute/tl'\n"
|
||||
)
|
||||
Object.entries(state.imports).forEach(([module, items]) => {
|
||||
items = [...items]
|
||||
output.write(`import { ${items.sort().join(', ')} } from '${module}'`)
|
||||
output.write(`import { ${items.sort().join(', ')} } from '${module}'\n`)
|
||||
})
|
||||
|
||||
output.write()
|
||||
output.write('\n')
|
||||
|
||||
state.copy.forEach(({ from, code }) => {
|
||||
output.write(`// from ${from}\n${code}\n`)
|
||||
})
|
||||
|
||||
output.write(
|
||||
'\nexport interface TelegramClient extends BaseTelegramClient {'
|
||||
'\nexport interface TelegramClient extends BaseTelegramClient {\n'
|
||||
)
|
||||
output.tab()
|
||||
|
||||
output.write(`/**
|
||||
* Register a raw update handler
|
||||
|
@ -306,14 +311,14 @@ async function main() {
|
|||
* @param name Event name
|
||||
* @param handler Raw update handler
|
||||
*/
|
||||
on(name: 'raw_update', handler: ((upd: tl.TypeUpdate | tl.TypeMessage, users: UsersIndex, chats: ChatsIndex) => void)): this
|
||||
on(name: 'raw_update', handler: ((upd: tl.TypeUpdate | tl.TypeMessage, peers: PeersIndex) => void)): this
|
||||
/**
|
||||
* Register a parsed update handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Raw update handler
|
||||
*/
|
||||
on(name: 'update', handler: ((upd: ParsedUpdate) => void)): this`)
|
||||
on(name: 'update', handler: ((upd: ParsedUpdate) => void)): this\n`)
|
||||
|
||||
updates.types.forEach((type) => {
|
||||
output.write(`/**
|
||||
|
@ -322,7 +327,7 @@ async function main() {
|
|||
* @param name Event name
|
||||
* @param handler ${updates.toSentence(type, 'full')}
|
||||
*/
|
||||
on(name: '${type.typeName}', handler: ((upd: ${type.updateType}) => void)): this`)
|
||||
on(name: '${type.typeName}', handler: ((upd: ${type.updateType}) => void)): this\n`)
|
||||
})
|
||||
|
||||
|
||||
|
@ -441,10 +446,10 @@ on(name: '${type.typeName}', handler: ((upd: ${type.updateType}) => void)): this
|
|||
if (!isPrivate && !hasOverloads) {
|
||||
if (!comment.match(/\/\*\*?\s*\*\//))
|
||||
// empty comment, no need to write it
|
||||
output.write(comment)
|
||||
output.write(comment + '\n')
|
||||
|
||||
output.write(
|
||||
`${name}${generics}(${parameters})${returnType}`
|
||||
`${name}${generics}(${parameters})${returnType}\n`
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -456,27 +461,22 @@ on(name: '${type.typeName}', handler: ((upd: ${type.updateType}) => void)): this
|
|||
}
|
||||
}
|
||||
)
|
||||
output.untab()
|
||||
output.write('}')
|
||||
|
||||
output.write(
|
||||
'/** @internal */\nexport class TelegramClient extends BaseTelegramClient {'
|
||||
)
|
||||
output.tab()
|
||||
|
||||
state.fields.forEach(({ code }) => output.write('protected ' + code))
|
||||
|
||||
output.write('constructor(opts: BaseTelegramClient.Options) {')
|
||||
output.tab()
|
||||
output.write('super(opts)')
|
||||
state.init.forEach((code) => {
|
||||
output.write(code)
|
||||
})
|
||||
output.untab()
|
||||
output.write('}\n')
|
||||
|
||||
classContents.forEach((line) => output.write(line))
|
||||
output.untab()
|
||||
output.write(
|
||||
'/** @internal */\nexport class TelegramClient extends BaseTelegramClient {\n'
|
||||
)
|
||||
|
||||
state.fields.forEach(({ code }) => output.write(`protected ${code}\n`))
|
||||
|
||||
output.write('constructor(opts: BaseTelegramClient.Options) {\n')
|
||||
output.write('super(opts)\n')
|
||||
state.init.forEach((code) => {
|
||||
output.write(code + '\n')
|
||||
})
|
||||
output.write('}\n')
|
||||
|
||||
classContents.forEach((line) => output.write(line + '\n'))
|
||||
output.write('}')
|
||||
|
||||
// format the resulting file with prettier
|
||||
|
|
|
@ -1,11 +1,24 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const prettier = require('prettier')
|
||||
const {
|
||||
snakeToCamel,
|
||||
camelToPascal,
|
||||
camelToSnake,
|
||||
} = require('../../tl/scripts/common')
|
||||
|
||||
const snakeToCamel = (s) => {
|
||||
return s.replace(/(?<!^|_)(_[a-z0-9])/gi, ($1) => {
|
||||
return $1.substr(1).toUpperCase()
|
||||
})
|
||||
}
|
||||
|
||||
const camelToPascal = (s) =>
|
||||
s[0].toUpperCase() + s.substr(1)
|
||||
|
||||
const camelToSnake = (s) => {
|
||||
return s.replace(
|
||||
/(?<=[a-zA-Z0-9])([A-Z0-9]+(?=[A-Z]|$)|[A-Z0-9])/g,
|
||||
($1) => {
|
||||
return '_' + $1.toLowerCase()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function parseUpdateTypes() {
|
||||
const lines = fs
|
||||
|
|
|
@ -145,14 +145,31 @@ import { getInstalledStickers } from './methods/stickers/get-installed-stickers'
|
|||
import { getStickerSet } from './methods/stickers/get-sticker-set'
|
||||
import { moveStickerInSet } from './methods/stickers/move-sticker-in-set'
|
||||
import { setStickerSetThumb } from './methods/stickers/set-sticker-set-thumb'
|
||||
import { ConditionVariable } from '@mtcute/core/src/utils/condition-variable'
|
||||
import {
|
||||
AsyncLock,
|
||||
Deque,
|
||||
MaybeArray,
|
||||
MaybeAsync,
|
||||
SessionConnection,
|
||||
SortedLinkedList,
|
||||
} from '@mtcute/core'
|
||||
import { RpsMeter } from './utils/rps-meter'
|
||||
import {
|
||||
_dispatchUpdate,
|
||||
_fetchUpdatesState,
|
||||
_handleUpdate,
|
||||
_keepAliveAction,
|
||||
_loadStorage,
|
||||
_onStop,
|
||||
_saveStorage,
|
||||
_updatesLoop,
|
||||
catchUp,
|
||||
enableRps,
|
||||
getCurrentRpsIncoming,
|
||||
getCurrentRpsProcessing,
|
||||
startUpdatesLoop,
|
||||
stopUpdatesLoop,
|
||||
} from './methods/updates'
|
||||
import { blockUser } from './methods/users/block-user'
|
||||
import { deleteProfilePhotos } from './methods/users/delete-profile-photos'
|
||||
|
@ -181,7 +198,6 @@ import {
|
|||
ChatMember,
|
||||
ChatMemberUpdate,
|
||||
ChatPreview,
|
||||
ChatsIndex,
|
||||
ChosenInlineResult,
|
||||
Conversation,
|
||||
DeleteMessageUpdate,
|
||||
|
@ -203,6 +219,7 @@ import {
|
|||
ParsedUpdate,
|
||||
PartialExcept,
|
||||
PartialOnly,
|
||||
PeersIndex,
|
||||
Photo,
|
||||
Poll,
|
||||
PollUpdate,
|
||||
|
@ -219,17 +236,27 @@ import {
|
|||
User,
|
||||
UserStatusUpdate,
|
||||
UserTypingUpdate,
|
||||
UsersIndex,
|
||||
} from './types'
|
||||
import {
|
||||
AsyncLock,
|
||||
MaybeArray,
|
||||
MaybeAsync,
|
||||
TelegramConnection,
|
||||
} from '@mtcute/core'
|
||||
import { tdFileId } from '@mtcute/file-id'
|
||||
import { Logger } from '@mtcute/core/src/utils/logger'
|
||||
|
||||
// from methods/updates.ts
|
||||
interface PendingUpdateContainer {
|
||||
upd: tl.TypeUpdates
|
||||
seqStart: number
|
||||
seqEnd: number
|
||||
}
|
||||
// from methods/updates.ts
|
||||
interface PendingUpdate {
|
||||
update: tl.TypeUpdate
|
||||
channelId?: number
|
||||
pts?: number
|
||||
ptsBefore?: number
|
||||
qtsBefore?: number
|
||||
timeout?: number
|
||||
peers?: PeersIndex
|
||||
}
|
||||
|
||||
export interface TelegramClient extends BaseTelegramClient {
|
||||
/**
|
||||
* Register a raw update handler
|
||||
|
@ -241,8 +268,7 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
name: 'raw_update',
|
||||
handler: (
|
||||
upd: tl.TypeUpdate | tl.TypeMessage,
|
||||
users: UsersIndex,
|
||||
chats: ChatsIndex
|
||||
peers: PeersIndex
|
||||
) => void
|
||||
): this
|
||||
/**
|
||||
|
@ -3268,12 +3294,58 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
progressCallback?: (uploaded: number, total: number) => void
|
||||
}
|
||||
): Promise<StickerSet>
|
||||
/**
|
||||
* Enable RPS meter.
|
||||
* Only available in NodeJS v10.7.0 and newer
|
||||
*
|
||||
* > **Note**: This may have negative impact on performance
|
||||
*
|
||||
* @param size Sampling size
|
||||
* @param time Window time
|
||||
*/
|
||||
enableRps(size?: number, time?: number): void
|
||||
/**
|
||||
* Get current average incoming RPS
|
||||
*
|
||||
* Incoming RPS is calculated based on
|
||||
* incoming update containers. Normally,
|
||||
* they should be around the same, except
|
||||
* rare situations when processing rps
|
||||
* may peak.
|
||||
*
|
||||
*/
|
||||
getCurrentRpsIncoming(): number
|
||||
/**
|
||||
* Get current average processing RPS
|
||||
*
|
||||
* Processing RPS is calculated based on
|
||||
* dispatched updates. Normally,
|
||||
* they should be around the same, except
|
||||
* rare situations when processing rps
|
||||
* may peak.
|
||||
*
|
||||
*/
|
||||
getCurrentRpsProcessing(): number
|
||||
/**
|
||||
* **ADVANCED**
|
||||
*
|
||||
* Manually start updates loop.
|
||||
* Usually done automatically inside {@link start}
|
||||
*/
|
||||
startUpdatesLoop(): void
|
||||
/**
|
||||
* **ADVANCED**
|
||||
*
|
||||
* Manually stop updates loop.
|
||||
* Usually done automatically when stopping the client with {@link close}
|
||||
*/
|
||||
stopUpdatesLoop(): void
|
||||
_handleUpdate(update: tl.TypeUpdates, noDispatch?: boolean): void
|
||||
/**
|
||||
* Catch up with the server by loading missed updates.
|
||||
*
|
||||
*/
|
||||
catchUp(): Promise<void>
|
||||
catchUp(): void
|
||||
/**
|
||||
* Block a user
|
||||
*
|
||||
|
@ -3413,8 +3485,12 @@ export interface TelegramClient extends BaseTelegramClient {
|
|||
* Useful when an `InputPeer` is needed.
|
||||
*
|
||||
* @param peerId The peer identifier that you want to extract the `InputPeer` from.
|
||||
* @param force (default: `false`) Whether to force re-fetch the peer from the server
|
||||
*/
|
||||
resolvePeer(peerId: InputPeerLike): Promise<tl.TypeInputPeer>
|
||||
resolvePeer(
|
||||
peerId: InputPeerLike,
|
||||
force?: boolean
|
||||
): Promise<tl.TypeInputPeer>
|
||||
/**
|
||||
* Change user status to offline or online
|
||||
*
|
||||
|
@ -3483,11 +3559,21 @@ export class TelegramClient extends BaseTelegramClient {
|
|||
protected _selfUsername: string | null
|
||||
protected _pendingConversations: Record<number, Conversation[]>
|
||||
protected _hasConversations: boolean
|
||||
protected _downloadConnections: Record<number, TelegramConnection>
|
||||
protected _connectionsForInline: Record<number, TelegramConnection>
|
||||
protected _downloadConnections: Record<number, SessionConnection>
|
||||
protected _connectionsForInline: Record<number, SessionConnection>
|
||||
protected _parseModes: Record<string, IMessageEntityParser>
|
||||
protected _defaultParseMode: string | null
|
||||
protected _updatesLoopActive: boolean
|
||||
protected _updatesLoopCv: ConditionVariable
|
||||
protected _pendingUpdateContainers: SortedLinkedList<PendingUpdateContainer>
|
||||
protected _pendingPtsUpdates: SortedLinkedList<PendingUpdate>
|
||||
protected _pendingPtsUpdatesPostponed: SortedLinkedList<PendingUpdate>
|
||||
protected _pendingQtsUpdates: SortedLinkedList<PendingUpdate>
|
||||
protected _pendingQtsUpdatesPostponed: SortedLinkedList<PendingUpdate>
|
||||
protected _pendingUnorderedUpdates: Deque<PendingUpdate>
|
||||
protected _updLock: AsyncLock
|
||||
protected _rpsIncoming?: RpsMeter
|
||||
protected _rpsProcessing?: RpsMeter
|
||||
protected _pts?: number
|
||||
protected _qts?: number
|
||||
protected _date?: number
|
||||
|
@ -3506,12 +3592,33 @@ export class TelegramClient extends BaseTelegramClient {
|
|||
this._userId = null
|
||||
this._isBot = false
|
||||
this._selfUsername = null
|
||||
this.log.prefix = '[USER N/A] '
|
||||
this._pendingConversations = {}
|
||||
this._hasConversations = false
|
||||
this._downloadConnections = {}
|
||||
this._connectionsForInline = {}
|
||||
this._parseModes = {}
|
||||
this._defaultParseMode = null
|
||||
this._updatesLoopActive = false
|
||||
this._updatesLoopCv = new ConditionVariable()
|
||||
|
||||
this._pendingUpdateContainers = new SortedLinkedList(
|
||||
(a, b) => a.seqStart - b.seqStart
|
||||
)
|
||||
this._pendingPtsUpdates = new SortedLinkedList(
|
||||
(a, b) => a.ptsBefore! - b.ptsBefore!
|
||||
)
|
||||
this._pendingPtsUpdatesPostponed = new SortedLinkedList(
|
||||
(a, b) => a.ptsBefore! - b.ptsBefore!
|
||||
)
|
||||
this._pendingQtsUpdates = new SortedLinkedList(
|
||||
(a, b) => a.qtsBefore! - b.qtsBefore!
|
||||
)
|
||||
this._pendingQtsUpdatesPostponed = new SortedLinkedList(
|
||||
(a, b) => a.qtsBefore! - b.qtsBefore!
|
||||
)
|
||||
this._pendingUnorderedUpdates = new Deque()
|
||||
|
||||
this._updLock = new AsyncLock()
|
||||
// we dont need to initialize state fields since
|
||||
// they are always loaded either from the server, or from storage.
|
||||
|
@ -3527,7 +3634,6 @@ export class TelegramClient extends BaseTelegramClient {
|
|||
|
||||
this._updsLog = this.log.create('updates')
|
||||
}
|
||||
|
||||
acceptTos = acceptTos
|
||||
checkPassword = checkPassword
|
||||
getPasswordHint = getPasswordHint
|
||||
|
@ -3667,12 +3773,19 @@ export class TelegramClient extends BaseTelegramClient {
|
|||
getStickerSet = getStickerSet
|
||||
moveStickerInSet = moveStickerInSet
|
||||
setStickerSetThumb = setStickerSetThumb
|
||||
enableRps = enableRps
|
||||
getCurrentRpsIncoming = getCurrentRpsIncoming
|
||||
getCurrentRpsProcessing = getCurrentRpsProcessing
|
||||
protected _fetchUpdatesState = _fetchUpdatesState
|
||||
protected _loadStorage = _loadStorage
|
||||
startUpdatesLoop = startUpdatesLoop
|
||||
stopUpdatesLoop = stopUpdatesLoop
|
||||
protected _onStop = _onStop
|
||||
protected _saveStorage = _saveStorage
|
||||
protected _dispatchUpdate = _dispatchUpdate
|
||||
_handleUpdate = _handleUpdate
|
||||
catchUp = catchUp
|
||||
protected _updatesLoop = _updatesLoop
|
||||
protected _keepAliveAction = _keepAliveAction
|
||||
blockUser = blockUser
|
||||
deleteProfilePhotos = deleteProfilePhotos
|
||||
|
|
|
@ -32,8 +32,7 @@ import {
|
|||
Photo,
|
||||
ChatEvent,
|
||||
ChatInviteLink,
|
||||
UsersIndex,
|
||||
ChatsIndex,
|
||||
PeersIndex,
|
||||
GameHighScore,
|
||||
ArrayWithTotal,
|
||||
BotCommands,
|
||||
|
@ -60,7 +59,7 @@ import {
|
|||
import {
|
||||
MaybeArray,
|
||||
MaybeAsync,
|
||||
TelegramConnection,
|
||||
SessionConnection,
|
||||
AsyncLock,
|
||||
} from '@mtcute/core'
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
// @extension
|
||||
interface AuthState {
|
||||
|
@ -17,4 +18,5 @@ function _initializeAuthState(this: TelegramClient) {
|
|||
this._userId = null
|
||||
this._isBot = false
|
||||
this._selfUsername = null
|
||||
this.log.prefix = '[USER N/A] '
|
||||
}
|
||||
|
|
|
@ -37,11 +37,17 @@ export async function checkPassword(
|
|||
'user'
|
||||
)
|
||||
|
||||
this.log.prefix = `[USER ${this._userId}] `
|
||||
this._userId = res.user.id
|
||||
this._isBot = false
|
||||
this._selfChanged = true
|
||||
this._selfUsername = res.user.username ?? null
|
||||
await this._fetchUpdatesState()
|
||||
await this._saveStorage()
|
||||
|
||||
// telegram ignores invokeWithoutUpdates for auth methods
|
||||
if (this._disableUpdates) this.primaryConnection._resetSession()
|
||||
else this.startUpdatesLoop()
|
||||
|
||||
return new User(this, res.user)
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ export async function signInBot(
|
|||
'user'
|
||||
)
|
||||
|
||||
this.log.prefix = `[USER ${this._userId}] `
|
||||
this._userId = res.user.id
|
||||
this._isBot = true
|
||||
this._selfUsername = res.user.username!
|
||||
|
@ -40,5 +41,9 @@ export async function signInBot(
|
|||
await this._fetchUpdatesState()
|
||||
await this._saveStorage()
|
||||
|
||||
// telegram ignores invokeWithoutUpdates for auth methods
|
||||
if (this._disableUpdates) this.primaryConnection._resetSession()
|
||||
else this.startUpdatesLoop()
|
||||
|
||||
return new User(this, res.user)
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ export async function signIn(
|
|||
|
||||
assertTypeIs('signIn (@ auth.signIn -> user)', res.user, 'user')
|
||||
|
||||
this.log.prefix = `[USER ${this._userId}] `
|
||||
this._userId = res.user.id
|
||||
this._isBot = false
|
||||
this._selfChanged = true
|
||||
|
@ -48,5 +49,9 @@ export async function signIn(
|
|||
await this._fetchUpdatesState()
|
||||
await this._saveStorage()
|
||||
|
||||
// telegram ignores invokeWithoutUpdates for auth methods
|
||||
if (this._disableUpdates) this.primaryConnection._resetSession()
|
||||
else this.startUpdatesLoop()
|
||||
|
||||
return new User(this, res.user)
|
||||
}
|
||||
|
|
|
@ -32,11 +32,16 @@ export async function signUp(
|
|||
assertTypeIs('signUp (@ auth.signUp)', res, 'auth.authorization')
|
||||
assertTypeIs('signUp (@ auth.signUp -> user)', res.user, 'user')
|
||||
|
||||
this.log.prefix = `[USER ${this._userId}] `
|
||||
this._userId = res.user.id
|
||||
this._isBot = false
|
||||
this._selfChanged = true
|
||||
await this._fetchUpdatesState()
|
||||
await this._saveStorage()
|
||||
|
||||
// telegram ignores invokeWithoutUpdates for auth methods
|
||||
if (this._disableUpdates) this.primaryConnection._resetSession()
|
||||
else this.startUpdatesLoop()
|
||||
|
||||
return new User(this, res.user)
|
||||
}
|
||||
|
|
|
@ -148,15 +148,28 @@ export async function start(
|
|||
|
||||
// user is already authorized
|
||||
|
||||
this.log.prefix = `[USER ${me.id}] `
|
||||
this.log.info(
|
||||
'Logged in as %s (ID: %s, username: %s, bot: %s)',
|
||||
me.displayName,
|
||||
me.id,
|
||||
me.username,
|
||||
me.isBot
|
||||
)
|
||||
|
||||
if (!this._disableUpdates) {
|
||||
this._catchUpChannels = !!params.catchUp
|
||||
|
||||
if (params.catchUp) {
|
||||
await this.catchUp()
|
||||
} else {
|
||||
if (!params.catchUp) {
|
||||
// otherwise we will catch up as soon as we receive a new update
|
||||
await this._fetchUpdatesState()
|
||||
}
|
||||
|
||||
this.startUpdatesLoop()
|
||||
|
||||
if (params.catchUp) {
|
||||
this.catchUp()
|
||||
}
|
||||
}
|
||||
|
||||
return me
|
||||
|
@ -165,9 +178,7 @@ export async function start(
|
|||
}
|
||||
|
||||
if (!params.phone && !params.botToken)
|
||||
throw new MtArgumentError(
|
||||
'Neither phone nor bot token were provided'
|
||||
)
|
||||
throw new MtArgumentError('Neither phone nor bot token were provided')
|
||||
|
||||
let phone = params.phone ? await resolveMaybeDynamic(params.phone) : null
|
||||
if (phone) {
|
||||
|
@ -249,9 +260,7 @@ export async function start(
|
|||
result = await this.checkPassword(password)
|
||||
} catch (e) {
|
||||
if (typeof params.password !== 'function') {
|
||||
throw new MtArgumentError(
|
||||
'Provided password was invalid'
|
||||
)
|
||||
throw new MtArgumentError('Provided password was invalid')
|
||||
}
|
||||
|
||||
if (e instanceof PasswordHashInvalidError) {
|
||||
|
|
|
@ -3,12 +3,10 @@ import {
|
|||
InputPeerLike,
|
||||
MtInvalidPeerTypeError,
|
||||
GameHighScore,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import {
|
||||
createUsersChatsIndex,
|
||||
normalizeToInputUser,
|
||||
} from '../../utils/peer-utils'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
|
||||
/**
|
||||
* Get high scores of a game
|
||||
|
@ -43,9 +41,9 @@ export async function getGameHighScores(
|
|||
userId: user,
|
||||
})
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return res.scores.map((score) => new GameHighScore(this, score, users))
|
||||
return res.scores.map((score) => new GameHighScore(this, score, peers))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,7 +79,7 @@ export async function getInlineGameHighScores(
|
|||
{ connection }
|
||||
)
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return res.scores.map((score) => new GameHighScore(this, score, users))
|
||||
return res.scores.map((score) => new GameHighScore(this, score, peers))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { Chat, MtTypeAssertionError } from '../../types'
|
||||
import { Chat } from '../../types'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import { Chat, InputPeerLike, MtTypeAssertionError } from '../../types'
|
||||
import { Chat, InputPeerLike } from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { Chat, MtTypeAssertionError } from '../../types'
|
||||
import { Chat } from '../../types'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,16 +2,15 @@ import { TelegramClient } from '../../client'
|
|||
import {
|
||||
InputPeerLike,
|
||||
MtInvalidPeerTypeError,
|
||||
ChatEvent,
|
||||
ChatEvent, PeersIndex,
|
||||
} from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import bigInt from 'big-integer'
|
||||
import {
|
||||
createUsersChatsIndex,
|
||||
normalizeToInputChannel,
|
||||
normalizeToInputUser,
|
||||
} from '../../utils/peer-utils'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Get chat event log ("Recent actions" in official
|
||||
|
@ -89,8 +88,8 @@ export async function* getChatEventLog(
|
|||
if (!channel) throw new MtInvalidPeerTypeError(chatId, 'channel')
|
||||
|
||||
let current = 0
|
||||
let maxId = params.maxId ?? bigInt.zero
|
||||
const minId = params.minId ?? bigInt.zero
|
||||
let maxId = params.maxId ?? Long.ZERO
|
||||
const minId = params.minId ?? Long.ZERO
|
||||
const query = params.query ?? ''
|
||||
|
||||
const total = params.limit || Infinity
|
||||
|
@ -216,12 +215,12 @@ export async function* getChatEventLog(
|
|||
|
||||
if (!res.events.length) break
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
const last = res.events[res.events.length - 1]
|
||||
maxId = last.id
|
||||
|
||||
for (const evt of res.events) {
|
||||
const parsed = new ChatEvent(this, evt, users, chats)
|
||||
const parsed = new ChatEvent(this, evt, peers)
|
||||
|
||||
if (
|
||||
localFilter &&
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError } from '../../types'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types'
|
||||
import {
|
||||
createUsersChatsIndex,
|
||||
isInputPeerChannel,
|
||||
isInputPeerChat,
|
||||
isInputPeerUser,
|
||||
|
@ -48,15 +47,15 @@ export async function getChatMember(
|
|||
? []
|
||||
: res.fullChat.participants.participants
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
for (const m of members) {
|
||||
if (
|
||||
(user._ === 'inputPeerSelf' &&
|
||||
(users[m.userId] as tl.RawUser).self) ||
|
||||
(peers.user(m.userId) as tl.RawUser).self) ||
|
||||
(user._ === 'inputPeerUser' && m.userId === user.userId)
|
||||
) {
|
||||
return new ChatMember(this, m, users)
|
||||
return new ChatMember(this, m, peers)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,8 +67,8 @@ export async function getChatMember(
|
|||
participant: user,
|
||||
})
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return new ChatMember(this, res.participant, users)
|
||||
return new ChatMember(this, res.participant, peers)
|
||||
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@ import {
|
|||
ChatMember,
|
||||
InputPeerLike,
|
||||
MtInvalidPeerTypeError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
createUsersChatsIndex,
|
||||
isInputPeerChannel,
|
||||
isInputPeerChat,
|
||||
normalizeToInputChannel,
|
||||
|
@ -13,6 +13,7 @@ import {
|
|||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { ArrayWithTotal } from '../../types'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Get a chunk of members of some chat.
|
||||
|
@ -94,9 +95,11 @@ export async function getChatMembers(
|
|||
if (params.offset) members = members.slice(params.offset)
|
||||
if (params.limit) members = members.slice(0, params.limit)
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const ret = members.map((m) => new ChatMember(this, m, users)) as ArrayWithTotal<ChatMember>
|
||||
const ret = members.map(
|
||||
(m) => new ChatMember(this, m, peers)
|
||||
) as ArrayWithTotal<ChatMember>
|
||||
|
||||
ret.total = ret.length
|
||||
return ret
|
||||
|
@ -140,7 +143,7 @@ export async function getChatMembers(
|
|||
filter,
|
||||
offset: params.offset ?? 0,
|
||||
limit: params.limit ?? 200,
|
||||
hash: 0,
|
||||
hash: Long.ZERO,
|
||||
})
|
||||
|
||||
assertTypeIs(
|
||||
|
@ -149,9 +152,11 @@ export async function getChatMembers(
|
|||
'channels.channelParticipants'
|
||||
)
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const ret = res.participants.map((i) => new ChatMember(this, i, users)) as ArrayWithTotal<ChatMember>
|
||||
const ret = res.participants.map(
|
||||
(i) => new ChatMember(this, i, peers)
|
||||
) as ArrayWithTotal<ChatMember>
|
||||
ret.total = res.count
|
||||
return ret
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { Chat, MtTypeAssertionError } from '../../types'
|
||||
import { Chat } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
import { tl } from 'packages/tl'
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
Chat,
|
||||
InputPeerLike,
|
||||
MtNotFoundError,
|
||||
MtTypeAssertionError,
|
||||
} from '../../types'
|
||||
import { Chat, InputPeerLike, MtNotFoundError } from '../../types'
|
||||
import {
|
||||
INVITE_LINK_REGEX,
|
||||
normalizeToInputChannel,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { Chat, InputPeerLike, MtTypeAssertionError } from '../../types'
|
||||
import { Chat, InputPeerLike } from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
|
|
|
@ -2,11 +2,9 @@ import { TelegramClient } from '../../client'
|
|||
import {
|
||||
InputPeerLike,
|
||||
MtInvalidPeerTypeError,
|
||||
MtTypeAssertionError,
|
||||
User,
|
||||
} from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,11 +3,9 @@ import { MaybeArray } from '@mtcute/core'
|
|||
import {
|
||||
InputPeerLike,
|
||||
MtInvalidPeerTypeError,
|
||||
MtTypeAssertionError,
|
||||
User,
|
||||
} from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { User } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Get list of contacts from your Telegram contacts list.
|
||||
|
@ -10,7 +10,7 @@ import { tl } from '@mtcute/tl'
|
|||
export async function getContacts(this: TelegramClient): Promise<User[]> {
|
||||
const res = await this.call({
|
||||
_: 'contacts.getContacts',
|
||||
hash: 0,
|
||||
hash: Long.ZERO,
|
||||
})
|
||||
assertTypeIs('getContacts', res, 'contacts.contacts')
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { PartialOnly } from '@mtcute/core'
|
||||
import bigInt from 'big-integer'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Import contacts to your Telegram contacts list.
|
||||
|
@ -13,11 +13,11 @@ export async function importContacts(
|
|||
this: TelegramClient,
|
||||
contacts: PartialOnly<Omit<tl.RawInputPhoneContact, '_'>, 'clientId'>[]
|
||||
): Promise<tl.contacts.RawImportedContacts> {
|
||||
let seq = bigInt.zero
|
||||
let seq = Long.ZERO
|
||||
|
||||
const contactsNorm: tl.RawInputPhoneContact[] = contacts.map((input) => ({
|
||||
_: 'inputPhoneContact',
|
||||
clientId: (seq = seq.plus(1)),
|
||||
clientId: (seq = seq.add(1)),
|
||||
...input,
|
||||
}))
|
||||
|
||||
|
|
|
@ -2,12 +2,10 @@ import { TelegramClient } from '../../client'
|
|||
import {
|
||||
Dialog,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
} from '../../types'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Iterate over dialogs.
|
||||
|
@ -241,7 +239,7 @@ export async function* getDialogs(
|
|||
offsetPeer,
|
||||
|
||||
limit: chunkSize,
|
||||
hash: 0,
|
||||
hash: Long.ZERO,
|
||||
})
|
||||
)
|
||||
if (!dialogs.length) return
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { Dialog, MtTypeAssertionError } from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { Dialog, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
import { getMarkedPeerId } from '@mtcute/core'
|
||||
|
||||
/** @internal */
|
||||
|
@ -16,7 +15,7 @@ export function _parseDialogs(
|
|||
'messages.dialogsNotModified'
|
||||
)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const messages: Record<number, tl.TypeMessage> = {}
|
||||
res.messages.forEach((msg) => {
|
||||
|
@ -27,7 +26,5 @@ export function _parseDialogs(
|
|||
|
||||
return res.dialogs
|
||||
.filter((it) => it._ === 'dialog')
|
||||
.map(
|
||||
(it) => new Dialog(this, it as tl.RawDialog, users, chats, messages)
|
||||
)
|
||||
.map((it) => new Dialog(this, it as tl.RawDialog, peers, messages))
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { TelegramConnection } from '@mtcute/core'
|
||||
import { SessionConnection } from '@mtcute/core'
|
||||
|
||||
import { TelegramClient } from '../../client'
|
||||
|
||||
// @extension
|
||||
interface FilesExtension {
|
||||
_downloadConnections: Record<number, TelegramConnection>
|
||||
_downloadConnections: Record<number, SessionConnection>
|
||||
}
|
||||
|
||||
// @initialize
|
||||
|
|
|
@ -2,7 +2,6 @@ import { TelegramClient } from '../../client'
|
|||
import {
|
||||
InputMediaLike,
|
||||
isUploadedFile,
|
||||
MtArgumentError,
|
||||
UploadFileLike,
|
||||
} from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
@ -14,9 +13,9 @@ import {
|
|||
} from '@mtcute/file-id'
|
||||
import { extractFileName } from '../../utils/file-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import bigInt from 'big-integer'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
import { encodeWaveform } from '../../utils/voice-utils'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Normalize an {@link InputMediaLike} to `InputMedia`,
|
||||
|
@ -182,7 +181,7 @@ export async function _normalizeInputMedia(
|
|||
poll: {
|
||||
_: 'poll',
|
||||
closed: media.closed,
|
||||
id: bigInt.zero,
|
||||
id: Long.ZERO,
|
||||
publicVoters: media.public,
|
||||
multipleChoice: media.multiple,
|
||||
quiz: media.type === 'quiz',
|
||||
|
|
|
@ -7,11 +7,11 @@ import {
|
|||
import type { ReadStream } from 'fs'
|
||||
import { Readable } from 'stream'
|
||||
import { determinePartSize, isProbablyPlainText } from '../../utils/file-utils'
|
||||
import { randomUlong } from '../../utils/misc-utils'
|
||||
import { fromBuffer } from 'file-type'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { MtArgumentError, UploadFileLike, UploadedFile } from '../../types'
|
||||
import { TelegramClient } from '../../client'
|
||||
import { randomLong } from '@mtcute/core'
|
||||
|
||||
let fs: any = null
|
||||
let path: any = null
|
||||
|
@ -200,7 +200,7 @@ export async function uploadFile(
|
|||
const hash = this._crypto.createMd5()
|
||||
|
||||
const partCount = ~~((fileSize + partSize - 1) / partSize)
|
||||
this._baseLog.debug(
|
||||
this.log.debug(
|
||||
'uploading %d bytes file in %d chunks, each %d bytes',
|
||||
fileSize,
|
||||
partCount,
|
||||
|
@ -209,7 +209,7 @@ export async function uploadFile(
|
|||
|
||||
// why is the file id generated by the client?
|
||||
// isn't the server supposed to generate it and handle collisions?
|
||||
const fileId = randomUlong()
|
||||
const fileId = randomLong()
|
||||
let pos = 0
|
||||
|
||||
for (let idx = 0; idx < partCount; idx++) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { ChatInviteLink, InputPeerLike } from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
|
||||
/**
|
||||
|
@ -43,7 +42,7 @@ export async function editInviteLink(
|
|||
usageLimit: params.usageLimit,
|
||||
})
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return new ChatInviteLink(this, res.invite, users)
|
||||
return new ChatInviteLink(this, res.invite, peers)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { ChatInviteLink, InputPeerLike, User } from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { ChatInviteLink, InputPeerLike, PeersIndex, User } from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
/**
|
||||
|
@ -40,18 +39,18 @@ export async function* getInviteLinkMembers(
|
|||
|
||||
if (!res.importers.length) break
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const last = res.importers[res.importers.length - 1]
|
||||
offsetDate = last.date
|
||||
offsetUser = {
|
||||
_: 'inputUser',
|
||||
userId: last.userId,
|
||||
accessHash: (users[last.userId] as tl.RawUser).accessHash!,
|
||||
accessHash: (peers.user(last.userId) as tl.RawUser).accessHash!,
|
||||
}
|
||||
|
||||
for (const it of res.importers) {
|
||||
const user = new User(this, users[it.userId])
|
||||
const user = new User(this, peers.user(it.userId))
|
||||
|
||||
yield {
|
||||
user,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { ChatInviteLink, InputPeerLike } from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types'
|
||||
|
||||
/**
|
||||
* Get detailed information about an invite link
|
||||
|
@ -20,7 +19,7 @@ export async function getInviteLink(
|
|||
link,
|
||||
})
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return new ChatInviteLink(this, res.invite, users)
|
||||
return new ChatInviteLink(this, res.invite, peers)
|
||||
}
|
||||
|
|
|
@ -3,11 +3,9 @@ import {
|
|||
ChatInviteLink,
|
||||
InputPeerLike,
|
||||
MtInvalidPeerTypeError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import {
|
||||
createUsersChatsIndex,
|
||||
normalizeToInputUser,
|
||||
} from '../../utils/peer-utils'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
/**
|
||||
|
@ -74,14 +72,14 @@ export async function* getInviteLinks(
|
|||
|
||||
if (!res.invites.length) break
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const last = res.invites[res.invites.length - 1]
|
||||
offsetDate = last.date
|
||||
offsetLink = last.link
|
||||
|
||||
for (const it of res.invites) {
|
||||
yield new ChatInviteLink(this, it, users)
|
||||
yield new ChatInviteLink(this, it, peers)
|
||||
}
|
||||
|
||||
current += res.invites.length
|
||||
|
|
|
@ -2,9 +2,8 @@ import { TelegramClient } from '../../client'
|
|||
import {
|
||||
ChatInviteLink,
|
||||
InputPeerLike,
|
||||
MtTypeAssertionError,
|
||||
MtTypeAssertionError, PeersIndex,
|
||||
} from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
|
||||
/**
|
||||
* Get primary invite link of a chat
|
||||
|
@ -31,7 +30,7 @@ export async function getPrimaryInviteLink(
|
|||
'false'
|
||||
)
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return new ChatInviteLink(this, res.invites[0], users)
|
||||
return new ChatInviteLink(this, res.invites[0], peers)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { ChatInviteLink, InputPeerLike } from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types'
|
||||
|
||||
/**
|
||||
* Revoke an invite link.
|
||||
|
@ -25,12 +24,12 @@ export async function revokeInviteLink(
|
|||
revoked: true,
|
||||
})
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const invite =
|
||||
res._ === 'messages.exportedChatInviteReplaced'
|
||||
? res.newInvite
|
||||
: res.invite
|
||||
|
||||
return new ChatInviteLink(this, invite, users)
|
||||
return new ChatInviteLink(this, invite, peers)
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, MtTypeAssertionError, Poll } from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import bigInt from 'big-integer'
|
||||
import { InputPeerLike, MtTypeAssertionError, PeersIndex, Poll } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Close a poll sent by you.
|
||||
|
@ -28,7 +27,7 @@ export async function closePoll(
|
|||
_: 'inputMediaPoll',
|
||||
poll: {
|
||||
_: 'poll',
|
||||
id: bigInt.zero,
|
||||
id: Long.ZERO,
|
||||
closed: true,
|
||||
question: '',
|
||||
answers: [],
|
||||
|
@ -54,7 +53,7 @@ export async function closePoll(
|
|||
)
|
||||
}
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return new Poll(this, upd.poll, users, upd.results)
|
||||
return new Poll(this, upd.poll, peers, upd.results)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike } from '../../types'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import {
|
||||
isInputPeerChannel,
|
||||
normalizeToInputChannel,
|
||||
} from '../../utils/peer-utils'
|
||||
import { createDummyUpdate } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
* Delete scheduled messages.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { Message, MtTypeAssertionError } from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { Message, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/** @internal */
|
||||
|
@ -24,13 +23,12 @@ export function _findMessageInUpdate(
|
|||
u._ === 'updateNewChannelMessage' ||
|
||||
u._ === 'updateNewScheduledMessage'))
|
||||
) {
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return new Message(
|
||||
this,
|
||||
u.message,
|
||||
users,
|
||||
chats,
|
||||
peers,
|
||||
u._ === 'updateNewScheduledMessage'
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,12 +5,11 @@ import {
|
|||
InputPeerLike,
|
||||
Message,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import { MaybeArray, randomLong } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { normalizeDate, randomUlong } from '../../utils/misc-utils'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
@ -234,7 +233,7 @@ export async function forwardMessages(
|
|||
silent: params.silent,
|
||||
scheduleDate: normalizeDate(params.schedule),
|
||||
randomId: [...Array((messages as number[]).length)].map(() =>
|
||||
randomUlong()
|
||||
randomLong()
|
||||
),
|
||||
})
|
||||
|
||||
|
@ -242,7 +241,7 @@ export async function forwardMessages(
|
|||
|
||||
this._handleUpdate(res, true)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const forwarded: Message[] = []
|
||||
res.updates.forEach((upd) => {
|
||||
|
@ -250,7 +249,14 @@ export async function forwardMessages(
|
|||
case 'updateNewMessage':
|
||||
case 'updateNewChannelMessage':
|
||||
case 'updateNewScheduledMessage':
|
||||
forwarded.push(new Message(this, upd.message, users, chats))
|
||||
forwarded.push(
|
||||
new Message(
|
||||
this,
|
||||
upd.message,
|
||||
peers,
|
||||
upd._ === 'updateNewScheduledMessage'
|
||||
)
|
||||
)
|
||||
break
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, Message } from '../../types'
|
||||
import { InputPeerLike, Message, PeersIndex } from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
|
||||
/** @internal */
|
||||
export async function _getDiscussionMessage(
|
||||
|
@ -71,7 +70,7 @@ export async function getDiscussionMessage(
|
|||
return null
|
||||
|
||||
const msg = res.messages[0]
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return new Message(this, msg, users, chats)
|
||||
return new Message(this, msg, peers)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, Message, MtTypeAssertionError } from '../../types'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { InputPeerLike, Message, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
import { normalizeDate } from '../../utils/misc-utils'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Retrieve a chunk of the chat history.
|
||||
|
@ -70,7 +70,7 @@ export async function getHistory(
|
|||
limit,
|
||||
maxId: 0,
|
||||
minId: 0,
|
||||
hash: 0,
|
||||
hash: Long.ZERO,
|
||||
})
|
||||
|
||||
if (res._ === 'messages.messagesNotModified')
|
||||
|
@ -80,11 +80,11 @@ export async function getHistory(
|
|||
res._
|
||||
)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const msgs = res.messages
|
||||
.filter((msg) => msg._ !== 'messageEmpty')
|
||||
.map((msg) => new Message(this, msg, users, chats))
|
||||
.map((msg) => new Message(this, msg, peers))
|
||||
|
||||
if (params.reverse) msgs.reverse()
|
||||
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import {
|
||||
createUsersChatsIndex,
|
||||
} from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { Message, MtTypeAssertionError } from '../../types'
|
||||
import { Message, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
|
||||
/**
|
||||
* Get a single message from PM or legacy group by its ID.
|
||||
|
@ -73,13 +70,12 @@ export async function getMessagesUnsafe(
|
|||
res._
|
||||
)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const ret = res.messages
|
||||
.map((msg) => {
|
||||
const ret = res.messages.map((msg) => {
|
||||
if (msg._ === 'messageEmpty') return null
|
||||
|
||||
return new Message(this, msg, users, chats)
|
||||
return new Message(this, msg, peers)
|
||||
})
|
||||
|
||||
return isSingle ? ret[0] : ret
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import {
|
||||
createUsersChatsIndex,
|
||||
isInputPeerChannel,
|
||||
normalizeToInputChannel,
|
||||
} from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { Message, InputPeerLike, MtTypeAssertionError } from '../../types'
|
||||
import { Message, InputPeerLike, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
|
||||
/**
|
||||
* Get a single message in chat by its ID
|
||||
|
@ -84,7 +83,7 @@ export async function getMessages(
|
|||
res._
|
||||
)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const ret = res.messages.map((msg) => {
|
||||
if (msg._ === 'messageEmpty') return null
|
||||
|
@ -109,7 +108,7 @@ export async function getMessages(
|
|||
}
|
||||
}
|
||||
|
||||
return new Message(this, msg, users, chats)
|
||||
return new Message(this, msg, peers)
|
||||
})
|
||||
|
||||
return isSingle ? ret[0] : ret
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import {
|
||||
createUsersChatsIndex,
|
||||
isInputPeerChannel,
|
||||
normalizeToInputChannel,
|
||||
} from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { Message, InputPeerLike, MtTypeAssertionError } from '../../types'
|
||||
Message,
|
||||
InputPeerLike,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
} from '../../types'
|
||||
|
||||
/**
|
||||
* Get a single scheduled message in chat by its ID
|
||||
|
@ -60,12 +59,12 @@ export async function getScheduledMessages(
|
|||
res._
|
||||
)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const ret = res.messages.map((msg) => {
|
||||
if (msg._ === 'messageEmpty') return null
|
||||
|
||||
return new Message(this, msg, users, chats)
|
||||
return new Message(this, msg, peers, true)
|
||||
})
|
||||
|
||||
return isSingle ? ret[0] : ret
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { TelegramConnection } from '@mtcute/core'
|
||||
import { SessionConnection } from '@mtcute/core'
|
||||
import { parseInlineMessageId } from '../../utils/inline-utils'
|
||||
|
||||
// @extension
|
||||
interface InlineExtension {
|
||||
_connectionsForInline: Record<number, TelegramConnection>
|
||||
_connectionsForInline: Record<number, SessionConnection>
|
||||
}
|
||||
|
||||
// @initialize
|
||||
|
@ -17,7 +17,7 @@ function _initializeInline(this: TelegramClient) {
|
|||
export async function _normalizeInline(
|
||||
this: TelegramClient,
|
||||
id: string | tl.TypeInputBotInlineMessageID
|
||||
): Promise<[tl.TypeInputBotInlineMessageID, TelegramConnection]> {
|
||||
): Promise<[tl.TypeInputBotInlineMessageID, SessionConnection]> {
|
||||
if (typeof id === 'string') {
|
||||
id = parseInlineMessageId(id)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { Message, MtTypeAssertionError } from '../../types'
|
||||
import { Message, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { SearchFilters } from '../../types'
|
||||
|
||||
/**
|
||||
|
@ -77,11 +76,11 @@ export async function* searchGlobal(
|
|||
res._
|
||||
)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const msgs = res.messages
|
||||
.filter((msg) => msg._ !== 'messageEmpty')
|
||||
.map((msg) => new Message(this, msg, users, chats))
|
||||
.map((msg) => new Message(this, msg, peers))
|
||||
|
||||
if (!msgs.length) break
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, Message, MtTypeAssertionError } from '../../types'
|
||||
import { InputPeerLike, Message, MtTypeAssertionError, PeersIndex } from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { SearchFilters } from '../../types'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Search for messages inside a specific chat
|
||||
|
@ -88,7 +88,7 @@ export async function* searchMessages(
|
|||
minId: 0,
|
||||
maxId: 0,
|
||||
fromId: fromUser,
|
||||
hash: 0,
|
||||
hash: Long.ZERO,
|
||||
})
|
||||
|
||||
if (res._ === 'messages.messagesNotModified')
|
||||
|
@ -98,11 +98,11 @@ export async function* searchMessages(
|
|||
res._
|
||||
)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const msgs = res.messages
|
||||
.filter((msg) => msg._ !== 'messageEmpty')
|
||||
.map((msg) => new Message(this, msg, users, chats))
|
||||
.map((msg) => new Message(this, msg, peers))
|
||||
|
||||
if (!msgs.length) break
|
||||
|
||||
|
|
|
@ -3,18 +3,17 @@ import {
|
|||
BotKeyboard, InputFileLike,
|
||||
InputMediaLike,
|
||||
InputPeerLike,
|
||||
Message, MtArgumentError,
|
||||
Message, MtArgumentError, PeersIndex,
|
||||
ReplyMarkup,
|
||||
} from '../../types'
|
||||
import {
|
||||
normalizeDate,
|
||||
normalizeMessageId,
|
||||
randomUlong,
|
||||
} from '../../utils/misc-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { MessageNotFoundError } from '@mtcute/tl/errors'
|
||||
import { randomLong } from '@mtcute/core'
|
||||
|
||||
/**
|
||||
* Send a group of media.
|
||||
|
@ -165,7 +164,7 @@ export async function sendMediaGroup(
|
|||
|
||||
multiMedia.push({
|
||||
_: 'inputSingleMedia',
|
||||
randomId: randomUlong(),
|
||||
randomId: randomLong(),
|
||||
media: inputMedia,
|
||||
message,
|
||||
entities,
|
||||
|
@ -178,7 +177,7 @@ export async function sendMediaGroup(
|
|||
multiMedia,
|
||||
silent: params.silent,
|
||||
replyToMsgId: replyTo,
|
||||
randomId: randomUlong(),
|
||||
randomId: randomLong(),
|
||||
scheduleDate: normalizeDate(params.schedule),
|
||||
replyMarkup,
|
||||
clearDraft: params.clearDraft,
|
||||
|
@ -187,7 +186,7 @@ export async function sendMediaGroup(
|
|||
assertIsUpdatesGroup('_findMessageInUpdate', res)
|
||||
this._handleUpdate(res, true)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const msgs = res.updates
|
||||
.filter(
|
||||
|
@ -201,8 +200,7 @@ export async function sendMediaGroup(
|
|||
new Message(
|
||||
this,
|
||||
(u as any).message,
|
||||
users,
|
||||
chats,
|
||||
peers,
|
||||
u._ === 'updateNewScheduledMessage'
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import {
|
||||
BotKeyboard, FormattedString,
|
||||
BotKeyboard,
|
||||
FormattedString,
|
||||
InputMediaLike,
|
||||
InputPeerLike,
|
||||
Message, MtArgumentError,
|
||||
Message,
|
||||
MtArgumentError,
|
||||
ReplyMarkup,
|
||||
} from '../../types'
|
||||
import {
|
||||
normalizeDate,
|
||||
normalizeMessageId,
|
||||
randomUlong,
|
||||
} from '../../utils/misc-utils'
|
||||
import { normalizeDate, normalizeMessageId } from '../../utils/misc-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { MessageNotFoundError } from '@mtcute/tl/errors'
|
||||
import { randomLong } from '@mtcute/core'
|
||||
|
||||
/**
|
||||
* Send a single media (a photo or a document-based media)
|
||||
|
@ -157,8 +156,7 @@ export async function sendMedia(
|
|||
|
||||
const msg = await this.getMessages(peer, replyTo)
|
||||
|
||||
if (!msg)
|
||||
throw new MessageNotFoundError()
|
||||
if (!msg) throw new MessageNotFoundError()
|
||||
}
|
||||
|
||||
const res = await this.call({
|
||||
|
@ -167,7 +165,7 @@ export async function sendMedia(
|
|||
media: inputMedia,
|
||||
silent: params.silent,
|
||||
replyToMsgId: replyTo,
|
||||
randomId: randomUlong(),
|
||||
randomId: randomLong(),
|
||||
scheduleDate: normalizeDate(params.schedule),
|
||||
replyMarkup,
|
||||
message,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { InputPeerLike, Message } from '../../types'
|
||||
import { InputPeerLike, Message, PeersIndex } from '../../types'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import { TelegramClient } from '../../client'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
|
||||
/**
|
||||
* Send s previously scheduled message.
|
||||
|
@ -56,7 +55,7 @@ export async function sendScheduled(
|
|||
assertIsUpdatesGroup('sendScheduled', res)
|
||||
this._handleUpdate(res, true)
|
||||
|
||||
const { users, chats } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
const msgs = res.updates
|
||||
.filter(
|
||||
|
@ -69,8 +68,7 @@ export async function sendScheduled(
|
|||
new Message(
|
||||
this,
|
||||
(u as any).message,
|
||||
users,
|
||||
chats
|
||||
peers
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -4,19 +4,16 @@ import { inputPeerToPeer } from '../../utils/peer-utils'
|
|||
import {
|
||||
normalizeDate,
|
||||
normalizeMessageId,
|
||||
randomUlong,
|
||||
} from '../../utils/misc-utils'
|
||||
import {
|
||||
InputPeerLike,
|
||||
Message,
|
||||
BotKeyboard,
|
||||
ReplyMarkup,
|
||||
UsersIndex,
|
||||
MtTypeAssertionError,
|
||||
ChatsIndex,
|
||||
MtArgumentError, FormattedString,
|
||||
MtArgumentError, FormattedString, PeersIndex,
|
||||
} from '../../types'
|
||||
import { getMarkedPeerId, MessageNotFoundError } from '@mtcute/core'
|
||||
import { getMarkedPeerId, MessageNotFoundError, randomLong } from '@mtcute/core'
|
||||
import { createDummyUpdate } from '../../utils/updates-utils'
|
||||
|
||||
/**
|
||||
|
@ -143,7 +140,7 @@ export async function sendText(
|
|||
noWebpage: params.disableWebPreview,
|
||||
silent: params.silent,
|
||||
replyToMsgId: replyTo,
|
||||
randomId: randomUlong(),
|
||||
randomId: randomLong(),
|
||||
scheduleDate: normalizeDate(params.schedule),
|
||||
replyMarkup,
|
||||
message,
|
||||
|
@ -170,8 +167,7 @@ export async function sendText(
|
|||
this._date = res.date
|
||||
this._handleUpdate(createDummyUpdate(res.pts, res.ptsCount))
|
||||
|
||||
const users: UsersIndex = {}
|
||||
const chats: ChatsIndex = {}
|
||||
const peers = new PeersIndex()
|
||||
|
||||
const fetchPeer = async (
|
||||
peer: tl.TypePeer | tl.TypeInputPeer
|
||||
|
@ -206,13 +202,13 @@ export async function sendText(
|
|||
|
||||
switch (cached._) {
|
||||
case 'user':
|
||||
users[cached.id] = cached
|
||||
peers.users[cached.id] = cached
|
||||
break
|
||||
case 'chat':
|
||||
case 'chatForbidden':
|
||||
case 'channel':
|
||||
case 'channelForbidden':
|
||||
chats[cached.id] = cached
|
||||
peers.chats[cached.id] = cached
|
||||
break
|
||||
default:
|
||||
throw new MtTypeAssertionError(
|
||||
|
@ -226,7 +222,7 @@ export async function sendText(
|
|||
await fetchPeer(peer)
|
||||
await fetchPeer(msg.fromId!)
|
||||
|
||||
const ret = new Message(this, msg, users, chats)
|
||||
const ret = new Message(this, msg, peers)
|
||||
this._pushConversationMessage(ret)
|
||||
return ret
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ import {
|
|||
InputPeerLike,
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
PeersIndex,
|
||||
Poll,
|
||||
} from '../../types'
|
||||
import { MaybeArray, MessageNotFoundError } from '@mtcute/core'
|
||||
import { createUsersChatsIndex } from '../../utils/peer-utils'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||
|
||||
|
@ -74,7 +74,7 @@ export async function sendVote(
|
|||
)
|
||||
}
|
||||
|
||||
const { users } = createUsersChatsIndex(res)
|
||||
const peers = PeersIndex.from(res)
|
||||
|
||||
return new Poll(this, upd.poll, users, upd.results)
|
||||
return new Poll(this, upd.poll, peers, upd.results)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputFileLike, InputStickerSetItem, StickerSet } from '../../types'
|
||||
import { InputStickerSetItem, StickerSet } from '../../types'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
const MASK_POS = {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { StickerSet } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Get a list of all installed sticker packs
|
||||
|
@ -17,7 +18,7 @@ export async function getInstalledStickers(
|
|||
): Promise<StickerSet[]> {
|
||||
const res = await this.call({
|
||||
_: 'messages.getAllStickers',
|
||||
hash: 0,
|
||||
hash: Long.ZERO,
|
||||
})
|
||||
|
||||
assertTypeIs('getInstalledStickers', res, 'messages.allStickers')
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,6 +2,7 @@ import { InputPeerLike, MtInvalidPeerTypeError } from '../../types'
|
|||
import { TelegramClient } from '../../client'
|
||||
import { Chat } from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Get a list of common chats you have with a given user
|
||||
|
|
|
@ -15,9 +15,20 @@ export function getMe(this: TelegramClient): Promise<User> {
|
|||
_: 'inputUserSelf',
|
||||
},
|
||||
],
|
||||
}).then(([user]) => {
|
||||
}).then(async ([user]) => {
|
||||
assertTypeIs('getMe (@ users.getUsers)', user, 'user')
|
||||
|
||||
if (this._userId !== user.id) {
|
||||
// there is such possibility, e.g. when
|
||||
// using a string session without `self`,
|
||||
// or logging out and re-logging in
|
||||
// we need to update the fields accordingly,
|
||||
// and force-save the session
|
||||
this._userId = user.id
|
||||
this._isBot = !!user.bot
|
||||
await this._saveStorage()
|
||||
}
|
||||
|
||||
this._selfUsername = user.username ?? null
|
||||
|
||||
return new User(this, user)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { User } from '../../types'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
* Get currently authorized user's username.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, MtInvalidPeerTypeError, Photo } from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
import bigInt from 'big-integer'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Get a list of profile pictures of a user
|
||||
|
@ -40,7 +40,7 @@ export async function getProfilePhotos(
|
|||
userId: peer,
|
||||
offset: params.offset ?? 0,
|
||||
limit: params.limit ?? 100,
|
||||
maxId: bigInt.zero,
|
||||
maxId: Long.ZERO,
|
||||
})
|
||||
|
||||
return res.photos.map((it) => new Photo(this, it as tl.RawPhoto))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { InputPeerLike, User } from '../../types'
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MaybeArray } from '@mtcute/core'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@ import { TelegramClient } from '../../client'
|
|||
import { InputPeerLike, MtInvalidPeerTypeError, Photo } from '../../types'
|
||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import bigInt from 'big-integer'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* Iterate over profile photos
|
||||
|
@ -54,7 +54,7 @@ export async function* iterProfilePhotos(
|
|||
|
||||
const limit = Math.min(params.chunkSize || 100, total)
|
||||
|
||||
const maxId = params.maxId || bigInt.zero
|
||||
const maxId = params.maxId || Long.ZERO
|
||||
|
||||
for (;;) {
|
||||
const res = await this.call({
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
import { TelegramClient } from '../../client'
|
||||
import { InputPeerLike, MtNotFoundError } from '../../types'
|
||||
import { getBasicPeerType, getMarkedPeerId, MAX_CHANNEL_ID } from '@mtcute/core'
|
||||
import bigInt from 'big-integer'
|
||||
import { getBasicPeerType, getMarkedPeerId, toggleChannelIdMark } from '@mtcute/core'
|
||||
import { normalizeToInputPeer } from '../../utils/peer-utils'
|
||||
import Long from 'long'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
|
||||
/**
|
||||
|
@ -11,11 +11,13 @@ import { assertTypeIs } from '../../utils/type-assertion'
|
|||
* Useful when an `InputPeer` is needed.
|
||||
*
|
||||
* @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
|
||||
* @internal
|
||||
*/
|
||||
export async function resolvePeer(
|
||||
this: TelegramClient,
|
||||
peerId: InputPeerLike
|
||||
peerId: InputPeerLike,
|
||||
force = false
|
||||
): Promise<tl.TypeInputPeer> {
|
||||
// for convenience we also accept tl objects directly
|
||||
if (typeof peerId === 'object') {
|
||||
|
@ -26,7 +28,7 @@ export async function resolvePeer(
|
|||
}
|
||||
}
|
||||
|
||||
if (typeof peerId === 'number') {
|
||||
if (typeof peerId === 'number' && !force) {
|
||||
const fromStorage = await this.storage.getPeerById(peerId)
|
||||
if (fromStorage) return fromStorage
|
||||
}
|
||||
|
@ -42,7 +44,7 @@ export async function resolvePeer(
|
|||
|
||||
const res = await this.call({
|
||||
_: 'contacts.getContacts',
|
||||
hash: 0,
|
||||
hash: Long.ZERO,
|
||||
})
|
||||
|
||||
assertTypeIs('contacts.getContacts', res, 'contacts.contacts')
|
||||
|
@ -62,8 +64,10 @@ export async function resolvePeer(
|
|||
)
|
||||
} else {
|
||||
// username
|
||||
if (!force) {
|
||||
const fromStorage = await this.storage.getPeerByUsername(peerId)
|
||||
if (fromStorage) return fromStorage
|
||||
}
|
||||
|
||||
const res = await this.call({
|
||||
_: 'contacts.resolveUsername',
|
||||
|
@ -122,7 +126,7 @@ export async function resolvePeer(
|
|||
{
|
||||
_: 'inputUser',
|
||||
userId: peerId,
|
||||
accessHash: bigInt.zero,
|
||||
accessHash: Long.ZERO,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
@ -159,14 +163,15 @@ export async function resolvePeer(
|
|||
// break
|
||||
}
|
||||
case 'channel': {
|
||||
const id = MAX_CHANNEL_ID - peerId
|
||||
const id = toggleChannelIdMark(peerId as number)
|
||||
|
||||
const res = await this.call({
|
||||
_: 'channels.getChannels',
|
||||
id: [
|
||||
{
|
||||
_: 'inputChannel',
|
||||
channelId: MAX_CHANNEL_ID - peerId,
|
||||
accessHash: bigInt.zero,
|
||||
channelId: id,
|
||||
accessHash: Long.ZERO,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Message } from '../messages'
|
|||
import { MtArgumentError } from '../errors'
|
||||
import { BasicPeerType, getBasicPeerType, getMarkedPeerId } from '@mtcute/core'
|
||||
import { encodeInlineMessageId } from '../../utils/inline-utils'
|
||||
import { User, UsersIndex } from '../peers'
|
||||
import { User, PeersIndex } from '../peers'
|
||||
import { MessageNotFoundError } from '@mtcute/core'
|
||||
|
||||
/**
|
||||
|
@ -13,22 +13,13 @@ import { MessageNotFoundError } from '@mtcute/core'
|
|||
* of an inline keyboard.
|
||||
*/
|
||||
export class CallbackQuery {
|
||||
readonly client: TelegramClient
|
||||
constructor(
|
||||
readonly client: TelegramClient,
|
||||
readonly raw:
|
||||
| tl.RawUpdateBotCallbackQuery
|
||||
| tl.RawUpdateInlineBotCallbackQuery
|
||||
|
||||
readonly _users: UsersIndex
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.RawUpdateBotCallbackQuery | tl.RawUpdateInlineBotCallbackQuery,
|
||||
users: UsersIndex
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._users = users
|
||||
}
|
||||
| tl.RawUpdateInlineBotCallbackQuery,
|
||||
readonly _peers: PeersIndex
|
||||
) {}
|
||||
|
||||
/**
|
||||
* ID of this callback query
|
||||
|
@ -43,7 +34,10 @@ export class CallbackQuery {
|
|||
*/
|
||||
get user(): User {
|
||||
if (!this._user) {
|
||||
this._user = new User(this.client, this._users[this.raw.userId])
|
||||
this._user = new User(
|
||||
this.client,
|
||||
this._peers.user(this.raw.userId)
|
||||
)
|
||||
}
|
||||
|
||||
return this._user
|
||||
|
|
|
@ -1,26 +1,17 @@
|
|||
import { makeInspectable } from '../utils'
|
||||
import { TelegramClient } from '../../client'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { User, UsersIndex } from '../peers'
|
||||
import { PeersIndex, User } from '../peers'
|
||||
|
||||
/**
|
||||
* Game high score
|
||||
*/
|
||||
export class GameHighScore {
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.RawHighScore
|
||||
|
||||
readonly _users: UsersIndex
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.RawHighScore,
|
||||
users: UsersIndex
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._users = users
|
||||
}
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.RawHighScore,
|
||||
readonly _peers: PeersIndex
|
||||
) {}
|
||||
|
||||
private _user?: User
|
||||
/**
|
||||
|
@ -28,7 +19,10 @@ export class GameHighScore {
|
|||
*/
|
||||
get user(): User {
|
||||
if (!this._user) {
|
||||
this._user = new User(this.client, this._users[this.raw.userId])
|
||||
this._user = new User(
|
||||
this.client,
|
||||
this._peers.user(this.raw.userId)
|
||||
)
|
||||
}
|
||||
|
||||
return this._user
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { makeInspectable } from '../utils'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { PeerType, User, UsersIndex } from '../peers'
|
||||
import { PeersIndex, PeerType, User } from '../peers'
|
||||
import { TelegramClient } from '../../client'
|
||||
import { Location } from '../media'
|
||||
import { InputInlineResult } from './input'
|
||||
|
@ -14,20 +14,11 @@ const PEER_TYPE_MAP: Record<tl.TypeInlineQueryPeerType['_'], PeerType> = {
|
|||
}
|
||||
|
||||
export class InlineQuery {
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.RawUpdateBotInlineQuery
|
||||
|
||||
/** Map of users in this message. Mainly for internal use */
|
||||
readonly _users: UsersIndex
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.RawUpdateBotInlineQuery,
|
||||
users: UsersIndex
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.RawUpdateBotInlineQuery,
|
||||
readonly _peers: PeersIndex
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._users = users
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +34,7 @@ export class InlineQuery {
|
|||
*/
|
||||
get user(): User {
|
||||
if (!this._user) {
|
||||
this._user = new User(this.client, this._users[this.raw.userId])
|
||||
this._user = new User(this.client, this._peers.user(this.raw.userId))
|
||||
}
|
||||
|
||||
return this._user
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AsyncLock, getMarkedPeerId, MaybeAsync } from '@mtcute/core'
|
||||
import { AsyncLock, Deque, getMarkedPeerId, MaybeAsync } from '@mtcute/core'
|
||||
import {
|
||||
ControllablePromise,
|
||||
createControllablePromise,
|
||||
|
@ -12,7 +12,6 @@ import { FormattedString } from './parser'
|
|||
import { Message } from './messages'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { TimeoutError } from '@mtcute/tl/errors'
|
||||
import { Queue } from '../utils/queue'
|
||||
|
||||
interface QueuedHandler<T> {
|
||||
promise: ControllablePromise<T>
|
||||
|
@ -39,12 +38,12 @@ export class Conversation {
|
|||
private _lastMessage!: number
|
||||
private _lastReceivedMessage!: number
|
||||
|
||||
private _queuedNewMessage = new Queue<QueuedHandler<Message>>()
|
||||
private _pendingNewMessages = new Queue<Message>()
|
||||
private _queuedNewMessage = new Deque<QueuedHandler<Message>>()
|
||||
private _pendingNewMessages = new Deque<Message>()
|
||||
private _lock = new AsyncLock()
|
||||
|
||||
private _pendingEditMessage: Record<number, QueuedHandler<Message>> = {}
|
||||
private _recentEdits = new Queue<Message>(10)
|
||||
private _recentEdits = new Deque<Message>(10)
|
||||
|
||||
private _pendingRead: Record<number, QueuedHandler<void>> = {}
|
||||
|
||||
|
@ -276,7 +275,7 @@ export class Conversation {
|
|||
}, timeout)
|
||||
}
|
||||
|
||||
this._queuedNewMessage.push({
|
||||
this._queuedNewMessage.pushBack({
|
||||
promise,
|
||||
check: filter,
|
||||
timeout: timer,
|
||||
|
@ -476,12 +475,12 @@ export class Conversation {
|
|||
private _onNewMessage(msg: Message) {
|
||||
if (msg.chat.id !== this._chatId) return
|
||||
|
||||
if (this._queuedNewMessage.empty()) {
|
||||
this._pendingNewMessages.push(msg)
|
||||
if (!this._queuedNewMessage.length) {
|
||||
this._pendingNewMessages.pushBack(msg)
|
||||
return
|
||||
}
|
||||
|
||||
const it = this._queuedNewMessage.peek()!
|
||||
const it = this._queuedNewMessage.peekFront()!
|
||||
|
||||
// order does matter for new messages
|
||||
this._lock.acquire().then(async () => {
|
||||
|
@ -489,7 +488,7 @@ export class Conversation {
|
|||
if (!it.check || (await it.check(msg))) {
|
||||
if (it.timeout) clearTimeout(it.timeout)
|
||||
it.promise.resolve(msg)
|
||||
this._queuedNewMessage.pop()
|
||||
this._queuedNewMessage.popFront()
|
||||
}
|
||||
} catch (e) {
|
||||
this.client['_emitError'](e)
|
||||
|
@ -507,7 +506,7 @@ export class Conversation {
|
|||
|
||||
const it = this._pendingEditMessage[msg.id]
|
||||
if (!it && !fromRecent) {
|
||||
this._recentEdits.push(msg)
|
||||
this._recentEdits.pushBack(msg)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -536,21 +535,21 @@ export class Conversation {
|
|||
}
|
||||
|
||||
private _processPendingNewMessages() {
|
||||
if (this._pendingNewMessages.empty()) return
|
||||
if (!this._pendingNewMessages.length) return
|
||||
|
||||
let it
|
||||
while ((it = this._pendingNewMessages.pop())) {
|
||||
while ((it = this._pendingNewMessages.popFront())) {
|
||||
this._onNewMessage(it)
|
||||
}
|
||||
}
|
||||
|
||||
private _processRecentEdits() {
|
||||
if (this._recentEdits.empty()) return
|
||||
if (!this._recentEdits.length) return
|
||||
|
||||
let it = this._recentEdits.first
|
||||
do {
|
||||
if (!it) break
|
||||
this._onEditMessage(it.v, true)
|
||||
} while ((it = it.n))
|
||||
const iter = this._recentEdits.iter()
|
||||
let it
|
||||
while (!(it = iter.next()).done) {
|
||||
this._onEditMessage(it.value, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ import { makeInspectable } from '../utils'
|
|||
* including ones that are embedded directly into the entity.
|
||||
*/
|
||||
export class FileLocation {
|
||||
constructor(
|
||||
/**
|
||||
* Client that was used to create this object
|
||||
*/
|
||||
readonly client: TelegramClient
|
||||
|
||||
readonly client: TelegramClient,
|
||||
/**
|
||||
* Location of the file.
|
||||
*
|
||||
|
@ -32,35 +32,16 @@ export class FileLocation {
|
|||
| (() =>
|
||||
| tl.TypeInputFileLocation
|
||||
| tl.TypeInputWebFileLocation
|
||||
| Buffer)
|
||||
|
||||
| Buffer),
|
||||
/**
|
||||
* File size in bytes, when available
|
||||
*/
|
||||
readonly fileSize?: number
|
||||
|
||||
readonly fileSize?: number,
|
||||
/**
|
||||
* DC ID of the file, when available
|
||||
*/
|
||||
readonly dcId?: number
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
location:
|
||||
| tl.TypeInputFileLocation
|
||||
| tl.TypeInputWebFileLocation
|
||||
| Buffer
|
||||
| (() =>
|
||||
| tl.TypeInputFileLocation
|
||||
| tl.TypeInputWebFileLocation
|
||||
| Buffer),
|
||||
fileSize?: number,
|
||||
dcId?: number
|
||||
) {
|
||||
this.client = client
|
||||
this.location = location
|
||||
this.fileSize = fileSize
|
||||
this.dcId = dcId
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,9 +21,7 @@ const STUB_LOCATION = () => {
|
|||
* > To be sure, check `isDownloadable` property.
|
||||
*/
|
||||
export class WebDocument extends FileLocation {
|
||||
readonly raw: tl.TypeWebDocument
|
||||
|
||||
constructor(client: TelegramClient, raw: tl.TypeWebDocument) {
|
||||
constructor(client: TelegramClient, readonly raw: tl.TypeWebDocument) {
|
||||
super(
|
||||
client,
|
||||
raw._ === 'webDocument'
|
||||
|
|
|
@ -10,8 +10,6 @@ import { tdFileId } from '@mtcute/file-id'
|
|||
export class Audio extends RawDocument {
|
||||
readonly type = 'audio' as const
|
||||
|
||||
readonly attr: tl.RawDocumentAttributeAudio
|
||||
|
||||
protected _fileIdType(): tdFileId.FileType {
|
||||
return tdFileId.FileType.Audio
|
||||
}
|
||||
|
@ -19,10 +17,9 @@ export class Audio extends RawDocument {
|
|||
constructor(
|
||||
client: TelegramClient,
|
||||
doc: tl.RawDocument,
|
||||
attr: tl.RawDocumentAttributeAudio
|
||||
readonly attr: tl.RawDocumentAttributeAudio
|
||||
) {
|
||||
super(client, doc)
|
||||
this.attr = attr
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,11 +7,7 @@ import { makeInspectable } from '../utils'
|
|||
export class Contact {
|
||||
readonly type = 'contact' as const
|
||||
|
||||
readonly obj: tl.RawMessageMediaContact
|
||||
|
||||
constructor(obj: tl.RawMessageMediaContact) {
|
||||
this.obj = obj
|
||||
}
|
||||
constructor(readonly obj: tl.RawMessageMediaContact) {}
|
||||
|
||||
/**
|
||||
* Contact's phone number
|
||||
|
|
|
@ -7,8 +7,6 @@ import { makeInspectable } from '../utils'
|
|||
export class Dice {
|
||||
readonly type = 'dice' as const
|
||||
|
||||
readonly obj: tl.RawMessageMediaDice
|
||||
|
||||
/**
|
||||
* A simple 6-sided dice.
|
||||
*
|
||||
|
@ -138,9 +136,7 @@ export class Dice {
|
|||
*/
|
||||
static readonly TYPE_SLOTS = '🎰'
|
||||
|
||||
constructor(obj: tl.RawMessageMediaDice) {
|
||||
this.obj = obj
|
||||
}
|
||||
constructor(readonly obj: tl.RawMessageMediaDice) {}
|
||||
|
||||
/**
|
||||
* An emoji which was originally sent.
|
||||
|
|
|
@ -11,25 +11,20 @@ import { tdFileId as td, toFileId, toUniqueFileId } from '@mtcute/file-id'
|
|||
* This also includes audios, videos, voices etc.
|
||||
*/
|
||||
export class RawDocument extends FileLocation {
|
||||
/**
|
||||
* Raw TL object with the document itself
|
||||
*/
|
||||
readonly doc: tl.RawDocument
|
||||
|
||||
constructor(client: TelegramClient, doc: tl.RawDocument) {
|
||||
constructor(client: TelegramClient, readonly raw: tl.RawDocument) {
|
||||
super(
|
||||
client,
|
||||
{
|
||||
_: 'inputDocumentFileLocation',
|
||||
id: doc.id,
|
||||
fileReference: doc.fileReference,
|
||||
accessHash: doc.accessHash,
|
||||
id: raw.id,
|
||||
fileReference: raw.fileReference,
|
||||
accessHash: raw.accessHash,
|
||||
thumbSize: '',
|
||||
},
|
||||
doc.size,
|
||||
doc.dcId
|
||||
raw.size,
|
||||
raw.dcId
|
||||
)
|
||||
this.doc = doc
|
||||
this.raw = raw
|
||||
}
|
||||
|
||||
private _fileName?: string | null
|
||||
|
@ -39,7 +34,7 @@ export class RawDocument extends FileLocation {
|
|||
*/
|
||||
get fileName(): string | null {
|
||||
if (this._fileName === undefined) {
|
||||
const attr = this.doc.attributes.find(
|
||||
const attr = this.raw.attributes.find(
|
||||
(it) => it._ === 'documentAttributeFilename'
|
||||
)
|
||||
this._fileName = attr
|
||||
|
@ -54,14 +49,14 @@ export class RawDocument extends FileLocation {
|
|||
* File MIME type, as defined by the sender.
|
||||
*/
|
||||
get mimeType(): string {
|
||||
return this.doc.mimeType
|
||||
return this.raw.mimeType
|
||||
}
|
||||
|
||||
/**
|
||||
* Date the document was sent
|
||||
*/
|
||||
get date(): Date {
|
||||
return new Date(this.doc.date * 1000)
|
||||
return new Date(this.raw.date * 1000)
|
||||
}
|
||||
|
||||
private _thumbnails?: Thumbnail[]
|
||||
|
@ -72,9 +67,9 @@ export class RawDocument extends FileLocation {
|
|||
*/
|
||||
get thumbnails(): ReadonlyArray<Thumbnail> {
|
||||
if (!this._thumbnails) {
|
||||
this._thumbnails = this.doc.thumbs
|
||||
? this.doc.thumbs.map(
|
||||
(sz) => new Thumbnail(this.client, this.doc, sz)
|
||||
this._thumbnails = this.raw.thumbs
|
||||
? this.raw.thumbs.map(
|
||||
(sz) => new Thumbnail(this.client, this.raw, sz)
|
||||
)
|
||||
: []
|
||||
}
|
||||
|
@ -102,9 +97,9 @@ export class RawDocument extends FileLocation {
|
|||
get inputDocument(): tl.TypeInputDocument {
|
||||
return {
|
||||
_: 'inputDocument',
|
||||
id: this.doc.id,
|
||||
accessHash: this.doc.accessHash,
|
||||
fileReference: this.doc.fileReference,
|
||||
id: this.raw.id,
|
||||
accessHash: this.raw.accessHash,
|
||||
fileReference: this.raw.fileReference,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,12 +128,12 @@ export class RawDocument extends FileLocation {
|
|||
if (!this._fileId) {
|
||||
this._fileId = toFileId({
|
||||
type: this._fileIdType(),
|
||||
dcId: this.doc.dcId,
|
||||
fileReference: this.doc.fileReference,
|
||||
dcId: this.raw.dcId,
|
||||
fileReference: this.raw.fileReference,
|
||||
location: {
|
||||
_: 'common',
|
||||
id: this.doc.id,
|
||||
accessHash: this.doc.accessHash,
|
||||
id: this.raw.id,
|
||||
accessHash: this.raw.accessHash,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -154,7 +149,7 @@ export class RawDocument extends FileLocation {
|
|||
if (!this._uniqueFileId) {
|
||||
this._uniqueFileId = toUniqueFileId(td.FileType.Document, {
|
||||
_: 'common',
|
||||
id: this.doc.id,
|
||||
id: this.raw.id,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,7 @@ import { makeInspectable } from '../utils'
|
|||
export class Game {
|
||||
readonly type = 'game' as const
|
||||
|
||||
readonly game: tl.RawGame
|
||||
readonly client: TelegramClient
|
||||
|
||||
constructor(client: TelegramClient, game: tl.RawGame) {
|
||||
this.client = client
|
||||
this.game = game
|
||||
}
|
||||
constructor(readonly client: TelegramClient, readonly game: tl.RawGame) {}
|
||||
|
||||
/**
|
||||
* Unique identifier of the game.
|
||||
|
|
|
@ -10,13 +10,10 @@ import { MtArgumentError } from '../errors'
|
|||
export class Invoice {
|
||||
readonly type = 'invoice' as const
|
||||
|
||||
readonly client: TelegramClient
|
||||
constructor(
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.RawMessageMediaInvoice
|
||||
|
||||
constructor(client: TelegramClient, raw: tl.RawMessageMediaInvoice) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
}
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Whether the shipping address was requested
|
||||
|
|
|
@ -7,13 +7,10 @@ import { TelegramClient } from '../../client'
|
|||
* A point on the map
|
||||
*/
|
||||
export class RawLocation {
|
||||
readonly client: TelegramClient
|
||||
constructor(
|
||||
readonly client: TelegramClient,
|
||||
readonly geo: tl.RawGeoPoint
|
||||
|
||||
constructor(client: TelegramClient, geo: tl.RawGeoPoint) {
|
||||
this.client = client
|
||||
this.geo = geo
|
||||
}
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Geo point latitude
|
||||
|
@ -112,11 +109,8 @@ export class Location extends RawLocation {
|
|||
export class LiveLocation extends RawLocation {
|
||||
readonly type = 'live_location' as const
|
||||
|
||||
readonly live: tl.RawMessageMediaGeoLive
|
||||
|
||||
constructor(client: TelegramClient, live: tl.RawMessageMediaGeoLive) {
|
||||
constructor(client: TelegramClient, readonly live: tl.RawMessageMediaGeoLive) {
|
||||
super(client, live.geo as tl.RawGeoPoint)
|
||||
this.live = live
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,8 +2,8 @@ import { makeInspectable } from '../utils'
|
|||
import { tl } from '@mtcute/tl'
|
||||
import { TelegramClient } from '../../client'
|
||||
import { MessageEntity } from '../messages'
|
||||
import bigInt from 'big-integer'
|
||||
import { UsersIndex } from '../peers'
|
||||
import { PeersIndex } from '../peers'
|
||||
import Long from 'long'
|
||||
|
||||
export namespace Poll {
|
||||
export interface PollAnswer {
|
||||
|
@ -40,23 +40,12 @@ export namespace Poll {
|
|||
export class Poll {
|
||||
readonly type = 'poll' as const
|
||||
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.TypePoll
|
||||
readonly results?: tl.TypePollResults
|
||||
|
||||
readonly _users: UsersIndex
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.TypePoll,
|
||||
users: UsersIndex,
|
||||
results?: tl.TypePollResults
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._users = users
|
||||
this.results = results
|
||||
}
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.TypePoll,
|
||||
readonly _peers: PeersIndex,
|
||||
readonly results?: tl.TypePollResults
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Unique identifier of the poll
|
||||
|
@ -151,6 +140,7 @@ export class Poll {
|
|||
}
|
||||
|
||||
private _entities?: MessageEntity[]
|
||||
|
||||
/**
|
||||
* Format entities for {@link solution}, only available
|
||||
* in case you have already answered
|
||||
|
@ -206,7 +196,7 @@ export class Poll {
|
|||
poll: {
|
||||
_: 'poll',
|
||||
closed: false,
|
||||
id: bigInt.zero,
|
||||
id: Long.ZERO,
|
||||
publicVoters: this.raw.publicVoters,
|
||||
multipleChoice: this.raw.multipleChoice,
|
||||
question: this.raw.question,
|
||||
|
|
|
@ -42,9 +42,6 @@ const MASK_POS = ['forehead', 'eyes', 'mouth', 'chin'] as const
|
|||
export class Sticker extends RawDocument {
|
||||
readonly type = 'sticker' as const
|
||||
|
||||
readonly attr: tl.RawDocumentAttributeSticker
|
||||
readonly attrSize?: tl.RawDocumentAttributeImageSize
|
||||
|
||||
protected _fileIdType(): tdFileId.FileType {
|
||||
return tdFileId.FileType.Sticker
|
||||
}
|
||||
|
@ -52,12 +49,10 @@ export class Sticker extends RawDocument {
|
|||
constructor(
|
||||
client: TelegramClient,
|
||||
doc: tl.RawDocument,
|
||||
attr: tl.RawDocumentAttributeSticker,
|
||||
attrSize?: tl.RawDocumentAttributeImageSize
|
||||
readonly attr: tl.RawDocumentAttributeSticker,
|
||||
readonly attrSize?: tl.RawDocumentAttributeImageSize
|
||||
) {
|
||||
super(client, doc)
|
||||
this.attr = attr
|
||||
this.attrSize = attrSize
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,7 +172,7 @@ export class Sticker extends RawDocument {
|
|||
const set = await this.getStickerSet()
|
||||
if (!set) return ''
|
||||
|
||||
return set.stickers.find((it) => it.sticker.doc.id.eq(this.doc.id))!
|
||||
return set.stickers.find((it) => it.sticker.raw.id.eq(this.raw.id))!
|
||||
.emoji
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { MtArgumentError, MtTypeAssertionError } from '../errors'
|
|||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { tdFileId as td, toFileId, toUniqueFileId } from '@mtcute/file-id'
|
||||
import bigInt from 'big-integer'
|
||||
import Long from 'long'
|
||||
|
||||
/**
|
||||
* One size of some thumbnail
|
||||
|
@ -171,8 +171,8 @@ export class Thumbnail extends FileLocation {
|
|||
fileReference: null,
|
||||
location: {
|
||||
_: 'photo',
|
||||
id: bigInt.zero,
|
||||
accessHash: bigInt.zero,
|
||||
id: Long.ZERO,
|
||||
accessHash: Long.ZERO,
|
||||
source: {
|
||||
_: 'stickerSetThumbnailVersion',
|
||||
id: this._media.id,
|
||||
|
@ -226,7 +226,7 @@ export class Thumbnail extends FileLocation {
|
|||
if (this._media._ === 'stickerSet') {
|
||||
this._uniqueFileId = toUniqueFileId(td.FileType.Thumbnail, {
|
||||
_: 'photo',
|
||||
id: bigInt.zero,
|
||||
id: Long.ZERO,
|
||||
source: {
|
||||
_: 'stickerSetThumbnailVersion',
|
||||
id: this._media.id,
|
||||
|
|
|
@ -31,13 +31,10 @@ export namespace Venue {
|
|||
export class Venue {
|
||||
readonly type = 'venue' as const
|
||||
|
||||
readonly client: TelegramClient
|
||||
constructor(
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.RawMessageMediaVenue
|
||||
|
||||
constructor(client: TelegramClient, raw: tl.RawMessageMediaVenue) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
}
|
||||
) {}
|
||||
|
||||
private _location?: Location
|
||||
/**
|
||||
|
|
|
@ -12,10 +12,6 @@ import { tdFileId } from '@mtcute/file-id'
|
|||
export class Video extends RawDocument {
|
||||
readonly type = 'video' as const
|
||||
|
||||
readonly attr:
|
||||
| tl.RawDocumentAttributeVideo
|
||||
| tl.RawDocumentAttributeImageSize
|
||||
|
||||
protected _fileIdType(): tdFileId.FileType {
|
||||
return this.isRound
|
||||
? tdFileId.FileType.VideoNote
|
||||
|
@ -27,10 +23,11 @@ export class Video extends RawDocument {
|
|||
constructor(
|
||||
client: TelegramClient,
|
||||
doc: tl.RawDocument,
|
||||
attr: tl.RawDocumentAttributeVideo | tl.RawDocumentAttributeImageSize
|
||||
readonly attr:
|
||||
| tl.RawDocumentAttributeVideo
|
||||
| tl.RawDocumentAttributeImageSize
|
||||
) {
|
||||
super(client, doc)
|
||||
this.attr = attr
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,7 +62,7 @@ export class Video extends RawDocument {
|
|||
if (!this._isAnimation) {
|
||||
this._isAnimation =
|
||||
this.attr._ === 'documentAttributeImageSize' ||
|
||||
this.doc.attributes.some(
|
||||
this.raw.attributes.some(
|
||||
(it) => it._ === 'documentAttributeAnimated'
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,8 +11,6 @@ import { decodeWaveform } from '../../utils/voice-utils'
|
|||
export class Voice extends RawDocument {
|
||||
readonly type = 'voice' as const
|
||||
|
||||
readonly attr: tl.RawDocumentAttributeAudio
|
||||
|
||||
protected _fileIdType(): tdFileId.FileType {
|
||||
return tdFileId.FileType.VoiceNote
|
||||
}
|
||||
|
@ -20,10 +18,9 @@ export class Voice extends RawDocument {
|
|||
constructor(
|
||||
client: TelegramClient,
|
||||
doc: tl.RawDocument,
|
||||
attr: tl.RawDocumentAttributeAudio
|
||||
readonly attr: tl.RawDocumentAttributeAudio
|
||||
) {
|
||||
super(client, doc)
|
||||
this.attr = attr
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,13 +19,7 @@ import { MtArgumentError } from '../errors'
|
|||
export class WebPage {
|
||||
readonly type = 'web_page' as const
|
||||
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.RawWebPage
|
||||
|
||||
constructor(client: TelegramClient, raw: tl.RawWebPage) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
}
|
||||
constructor(readonly client: TelegramClient, readonly raw: tl.RawWebPage) {}
|
||||
|
||||
/**
|
||||
* Unique ID of the preview
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { TelegramClient } from '../../client'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { Chat, ChatsIndex, UsersIndex } from '../peers'
|
||||
import { Chat, PeersIndex } from '../peers'
|
||||
import { Message } from './message'
|
||||
import { DraftMessage } from './draft-message'
|
||||
import { makeInspectable } from '../utils'
|
||||
|
@ -13,31 +13,12 @@ import { getMarkedPeerId, MessageNotFoundError } from '@mtcute/core'
|
|||
* in Telegram's main window.
|
||||
*/
|
||||
export class Dialog {
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.RawDialog
|
||||
|
||||
/** Map of users in this object. Mainly for internal use */
|
||||
readonly _users: UsersIndex
|
||||
|
||||
/** Map of chats in this object. Mainly for internal use */
|
||||
readonly _chats: ChatsIndex
|
||||
|
||||
/** Map of messages in this object. Mainly for internal use */
|
||||
readonly _messages: Record<number, tl.TypeMessage>
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.RawDialog,
|
||||
users: UsersIndex,
|
||||
chats: ChatsIndex,
|
||||
messages: Record<number, tl.TypeMessage>
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._users = users
|
||||
this._chats = chats
|
||||
this._messages = messages
|
||||
}
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.RawDialog,
|
||||
readonly _peers: PeersIndex,
|
||||
readonly _messages: Record<number, tl.TypeMessage>
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Find pinned dialogs from a list of dialogs
|
||||
|
@ -172,12 +153,12 @@ export class Dialog {
|
|||
switch (peer._) {
|
||||
case 'peerChannel':
|
||||
case 'peerChat':
|
||||
chat = this._chats[
|
||||
chat = this._peers.chat(
|
||||
peer._ === 'peerChannel' ? peer.channelId : peer.chatId
|
||||
]
|
||||
)
|
||||
break
|
||||
default:
|
||||
chat = this._users[peer.userId]
|
||||
chat = this._peers.user(peer.userId)
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -200,8 +181,7 @@ export class Dialog {
|
|||
this._lastMessage = new Message(
|
||||
this.client,
|
||||
this._messages[cid],
|
||||
this._users,
|
||||
this._chats
|
||||
this._peers
|
||||
)
|
||||
} else {
|
||||
throw new MessageNotFoundError()
|
||||
|
|
|
@ -10,19 +10,11 @@ import { makeInspectable } from '../utils'
|
|||
import { InputMediaWithCaption } from '../media'
|
||||
|
||||
export class DraftMessage {
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.RawDraftMessage
|
||||
|
||||
private _chatId: InputPeerLike
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.RawDraftMessage,
|
||||
chatId: InputPeerLike
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.RawDraftMessage,
|
||||
readonly _chatId: InputPeerLike
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._chatId = chatId
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -69,7 +69,7 @@ export function _messageMediaFromTl(
|
|||
case 'messageMediaVenue':
|
||||
return new Venue(this.client, m)
|
||||
case 'messageMediaPoll':
|
||||
return new Poll(this.client, m.poll, this._users, m.results)
|
||||
return new Poll(this.client, m.poll, this._peers, m.results)
|
||||
case 'messageMediaInvoice':
|
||||
return new Invoice(this.client, m)
|
||||
default:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { User, Chat, InputPeerLike, UsersIndex, ChatsIndex } from '../peers'
|
||||
import { User, Chat, InputPeerLike, PeersIndex } from '../peers'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { BotKeyboard, ReplyMarkup } from '../bots'
|
||||
import { getMarkedPeerId, MAX_CHANNEL_ID } from '@mtcute/core'
|
||||
import { getMarkedPeerId, toggleChannelIdMark } from '@mtcute/core'
|
||||
import {
|
||||
MtArgumentError,
|
||||
MtTypeAssertionError,
|
||||
|
@ -96,43 +96,30 @@ export namespace Message {
|
|||
* A Telegram message.
|
||||
*/
|
||||
export class Message {
|
||||
/** Telegram client that received this message */
|
||||
readonly client: TelegramClient
|
||||
|
||||
/**
|
||||
* Raw TL object.
|
||||
*/
|
||||
readonly raw: tl.RawMessage | tl.RawMessageService
|
||||
|
||||
/** Map of users in this message. Mainly for internal use */
|
||||
readonly _users: UsersIndex
|
||||
/** Map of chats in this message. Mainly for internal use */
|
||||
readonly _chats: ChatsIndex
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
readonly client: TelegramClient,
|
||||
raw: tl.TypeMessage,
|
||||
users: UsersIndex,
|
||||
chats: ChatsIndex,
|
||||
isScheduled = false
|
||||
) {
|
||||
if (raw._ === 'messageEmpty')
|
||||
throw new MtTypeAssertionError('Message#ctor', 'not messageEmpty', 'messageEmpty')
|
||||
|
||||
this.client = client
|
||||
this._users = users
|
||||
this._chats = chats
|
||||
|
||||
this.raw = raw
|
||||
|
||||
this.isScheduled = isScheduled
|
||||
}
|
||||
|
||||
readonly _peers: PeersIndex,
|
||||
/**
|
||||
* Whether the message is scheduled.
|
||||
* If it is, then its {@link date} is set to future.
|
||||
*/
|
||||
readonly isScheduled: boolean
|
||||
readonly isScheduled = false
|
||||
) {
|
||||
if (raw._ === 'messageEmpty')
|
||||
throw new MtTypeAssertionError(
|
||||
'Message#ctor',
|
||||
'not messageEmpty',
|
||||
'messageEmpty'
|
||||
)
|
||||
|
||||
this.raw = raw
|
||||
}
|
||||
|
||||
/** Unique message identifier inside this chat */
|
||||
get id(): number {
|
||||
|
@ -197,7 +184,7 @@ export class Message {
|
|||
if (this.raw.peerId._ === 'peerUser') {
|
||||
this._sender = new User(
|
||||
this.client,
|
||||
this._users[this.raw.peerId.userId]
|
||||
this._peers.user(this.raw.peerId.userId)
|
||||
)
|
||||
} else {
|
||||
// anon admin, return the chat
|
||||
|
@ -208,13 +195,13 @@ export class Message {
|
|||
case 'peerChannel': // forwarded channel post
|
||||
this._sender = new Chat(
|
||||
this.client,
|
||||
this._chats[from.channelId]
|
||||
this._peers.chat(from.channelId)
|
||||
)
|
||||
break
|
||||
case 'peerUser':
|
||||
this._sender = new User(
|
||||
this.client,
|
||||
this._users[from.userId]
|
||||
this._peers.user(from.userId)
|
||||
)
|
||||
break
|
||||
default:
|
||||
|
@ -239,8 +226,7 @@ export class Message {
|
|||
this._chat = Chat._parseFromMessage(
|
||||
this.client,
|
||||
this.raw,
|
||||
this._users,
|
||||
this._chats
|
||||
this._peers
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -274,13 +260,13 @@ export class Message {
|
|||
case 'peerChannel':
|
||||
sender = new Chat(
|
||||
this.client,
|
||||
this._chats[fwd.fromId.channelId]
|
||||
this._peers.chat(fwd.fromId.channelId)
|
||||
)
|
||||
break
|
||||
case 'peerUser':
|
||||
sender = new User(
|
||||
this.client,
|
||||
this._users[fwd.fromId.userId]
|
||||
this._peers.user(fwd.fromId.userId)
|
||||
)
|
||||
break
|
||||
default:
|
||||
|
@ -329,7 +315,7 @@ export class Message {
|
|||
|
||||
if (r.comments) {
|
||||
const o = (obj as unknown) as Message.MessageCommentsInfo
|
||||
o.discussion = r.channelId!
|
||||
o.discussion = getMarkedPeerId(r.channelId!, 'channel')
|
||||
o.repliers =
|
||||
r.recentRepliers?.map((it) => getMarkedPeerId(it)) ?? []
|
||||
}
|
||||
|
@ -375,7 +361,7 @@ export class Message {
|
|||
} else {
|
||||
this._viaBot = new User(
|
||||
this.client,
|
||||
this._users[this.raw.viaBotId]
|
||||
this._peers.user(this.raw.viaBotId)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -515,7 +501,7 @@ export class Message {
|
|||
if (this.chat.username) {
|
||||
return `https://t.me/${this.chat.username}/${this.id}`
|
||||
} else {
|
||||
return `https://t.me/c/${MAX_CHANNEL_ID - this.chat.id}/${
|
||||
return `https://t.me/c/${toggleChannelIdMark(this.chat.id)}/${
|
||||
this.id
|
||||
}`
|
||||
}
|
||||
|
@ -547,8 +533,7 @@ export class Message {
|
|||
* this method will also return `null`.
|
||||
*/
|
||||
getReplyTo(): Promise<Message | null> {
|
||||
if (!this.replyToMessageId)
|
||||
return Promise.resolve(null)
|
||||
if (!this.replyToMessageId) return Promise.resolve(null)
|
||||
|
||||
if (this.raw.peerId._ === 'peerChannel')
|
||||
return this.client.getMessages(this.chat.inputPeer, this.id, true)
|
||||
|
@ -795,7 +780,7 @@ export class Message {
|
|||
* passing positional `text` as object field.
|
||||
*
|
||||
* @param text New message text
|
||||
* @param params Additional parameters
|
||||
* @param params? Additional parameters
|
||||
* @link TelegramClient.editMessage
|
||||
*/
|
||||
editText(
|
||||
|
@ -819,7 +804,12 @@ export class Message {
|
|||
peer: InputPeerLike,
|
||||
params?: Parameters<TelegramClient['forwardMessages']>[3]
|
||||
): Promise<Message> {
|
||||
return this.client.forwardMessages(peer, this.chat.inputPeer, this.id, params)
|
||||
return this.client.forwardMessages(
|
||||
peer,
|
||||
this.chat.inputPeer,
|
||||
this.id,
|
||||
params
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -885,7 +875,10 @@ export class Message {
|
|||
* message.
|
||||
*/
|
||||
async getDiscussionMessage(): Promise<Message | null> {
|
||||
return this.client.getDiscussionMessage(this.chat.inputPeer, this.raw.id)
|
||||
return this.client.getDiscussionMessage(
|
||||
this.chat.inputPeer,
|
||||
this.raw.id
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
/**
|
||||
* Search filters to be used in {@link TelegramClient.searchMessages}
|
||||
* and {@link TelegramClient.searchGlobal}.
|
||||
|
|
|
@ -32,7 +32,6 @@ export namespace StickerSet {
|
|||
* A stickerset (aka sticker pack)
|
||||
*/
|
||||
export class StickerSet {
|
||||
readonly client: TelegramClient
|
||||
readonly brief: tl.RawStickerSet
|
||||
readonly full?: tl.messages.RawStickerSet
|
||||
|
||||
|
@ -42,10 +41,9 @@ export class StickerSet {
|
|||
readonly isFull: boolean
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
readonly client: TelegramClient,
|
||||
raw: tl.RawStickerSet | tl.messages.RawStickerSet
|
||||
) {
|
||||
this.client = client
|
||||
if (raw._ === 'messages.stickerSet') {
|
||||
this.full = raw
|
||||
this.brief = raw.set
|
||||
|
|
|
@ -6,15 +6,15 @@ import { makeInspectable } from '../utils'
|
|||
* Account takeout session
|
||||
*/
|
||||
export class TakeoutSession {
|
||||
private client: TelegramClient
|
||||
|
||||
/**
|
||||
* Takeout session id
|
||||
*/
|
||||
readonly id: tl.Long
|
||||
|
||||
constructor(client: TelegramClient, session: tl.account.RawTakeout) {
|
||||
this.client = client
|
||||
constructor(
|
||||
readonly client: TelegramClient,
|
||||
session: tl.account.RawTakeout
|
||||
) {
|
||||
this.id = session.id
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@ import { Message } from '../messages'
|
|||
import { ChatPermissions } from './chat-permissions'
|
||||
import { ChatLocation } from './chat-location'
|
||||
import { ChatInviteLink } from './chat-invite-link'
|
||||
import { ChatsIndex, UsersIndex } from './index'
|
||||
import { PeersIndex } from './index'
|
||||
import { toggleChannelIdMark } from '../../../../core'
|
||||
|
||||
|
||||
export namespace ChatEvent {
|
||||
/** A user has joined the group (in the case of big groups, info of the user that has joined isn't shown) */
|
||||
|
@ -371,8 +373,7 @@ function _actionFromTl(
|
|||
message: new Message(
|
||||
this.client,
|
||||
e.message,
|
||||
this._users,
|
||||
this._chats
|
||||
this._peers
|
||||
),
|
||||
}
|
||||
case 'channelAdminLogEventActionEditMessage':
|
||||
|
@ -381,14 +382,12 @@ function _actionFromTl(
|
|||
old: new Message(
|
||||
this.client,
|
||||
e.prevMessage,
|
||||
this._users,
|
||||
this._chats
|
||||
this._peers
|
||||
),
|
||||
new: new Message(
|
||||
this.client,
|
||||
e.newMessage,
|
||||
this._users,
|
||||
this._chats
|
||||
this._peers
|
||||
),
|
||||
}
|
||||
case 'channelAdminLogEventActionDeleteMessage':
|
||||
|
@ -397,8 +396,7 @@ function _actionFromTl(
|
|||
message: new Message(
|
||||
this.client,
|
||||
e.message,
|
||||
this._users,
|
||||
this._chats
|
||||
this._peers
|
||||
),
|
||||
}
|
||||
case 'channelAdminLogEventActionParticipantLeave':
|
||||
|
@ -406,7 +404,7 @@ function _actionFromTl(
|
|||
case 'channelAdminLogEventActionParticipantInvite':
|
||||
return {
|
||||
type: 'user_invited',
|
||||
member: new ChatMember(this.client, e.participant, this._users),
|
||||
member: new ChatMember(this.client, e.participant, this._peers),
|
||||
}
|
||||
case 'channelAdminLogEventActionParticipantToggleBan':
|
||||
return {
|
||||
|
@ -414,9 +412,9 @@ function _actionFromTl(
|
|||
old: new ChatMember(
|
||||
this.client,
|
||||
e.prevParticipant,
|
||||
this._users
|
||||
this._peers
|
||||
),
|
||||
new: new ChatMember(this.client, e.newParticipant, this._users),
|
||||
new: new ChatMember(this.client, e.newParticipant, this._peers),
|
||||
}
|
||||
case 'channelAdminLogEventActionParticipantToggleAdmin':
|
||||
return {
|
||||
|
@ -424,9 +422,9 @@ function _actionFromTl(
|
|||
old: new ChatMember(
|
||||
this.client,
|
||||
e.prevParticipant,
|
||||
this._users
|
||||
this._peers
|
||||
),
|
||||
new: new ChatMember(this.client, e.newParticipant, this._users),
|
||||
new: new ChatMember(this.client, e.newParticipant, this._peers),
|
||||
}
|
||||
case 'channelAdminLogEventActionChangeStickerSet':
|
||||
return {
|
||||
|
@ -452,15 +450,14 @@ function _actionFromTl(
|
|||
message: new Message(
|
||||
this.client,
|
||||
e.message,
|
||||
this._users,
|
||||
this._chats
|
||||
this._peers
|
||||
),
|
||||
}
|
||||
case 'channelAdminLogEventActionChangeLinkedChat':
|
||||
return {
|
||||
type: 'linked_chat_changed',
|
||||
old: e.prevValue,
|
||||
new: e.newValue,
|
||||
old: toggleChannelIdMark(e.prevValue),
|
||||
new: toggleChannelIdMark(e.newValue),
|
||||
}
|
||||
case 'channelAdminLogEventActionChangeLocation':
|
||||
return {
|
||||
|
@ -503,23 +500,23 @@ function _actionFromTl(
|
|||
case 'channelAdminLogEventActionParticipantJoinByInvite':
|
||||
return {
|
||||
type: 'user_joined_invite',
|
||||
link: new ChatInviteLink(this.client, e.invite, this._users),
|
||||
link: new ChatInviteLink(this.client, e.invite, this._peers),
|
||||
}
|
||||
case 'channelAdminLogEventActionExportedInviteDelete':
|
||||
return {
|
||||
type: 'invite_deleted',
|
||||
link: new ChatInviteLink(this.client, e.invite, this._users),
|
||||
link: new ChatInviteLink(this.client, e.invite, this._peers),
|
||||
}
|
||||
case 'channelAdminLogEventActionExportedInviteRevoke':
|
||||
return {
|
||||
type: 'invite_revoked',
|
||||
link: new ChatInviteLink(this.client, e.invite, this._users),
|
||||
link: new ChatInviteLink(this.client, e.invite, this._peers),
|
||||
}
|
||||
case 'channelAdminLogEventActionExportedInviteEdit':
|
||||
return {
|
||||
type: 'invite_edited',
|
||||
old: new ChatInviteLink(this.client, e.prevInvite, this._users),
|
||||
new: new ChatInviteLink(this.client, e.newInvite, this._users),
|
||||
old: new ChatInviteLink(this.client, e.prevInvite, this._peers),
|
||||
new: new ChatInviteLink(this.client, e.newInvite, this._peers),
|
||||
}
|
||||
case 'channelAdminLogEventActionChangeHistoryTTL':
|
||||
return {
|
||||
|
@ -533,22 +530,11 @@ function _actionFromTl(
|
|||
}
|
||||
|
||||
export class ChatEvent {
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.TypeChannelAdminLogEvent
|
||||
|
||||
readonly _users: UsersIndex
|
||||
readonly _chats: ChatsIndex
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.TypeChannelAdminLogEvent,
|
||||
users: UsersIndex,
|
||||
chats: ChatsIndex
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.TypeChannelAdminLogEvent,
|
||||
readonly _peers: PeersIndex,
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._users = users
|
||||
this._chats = chats
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -574,7 +560,7 @@ export class ChatEvent {
|
|||
*/
|
||||
get actor(): User {
|
||||
if (!this._actor) {
|
||||
this._actor = new User(this.client, this._users[this.raw.userId])
|
||||
this._actor = new User(this.client, this._peers.user(this.raw.userId))
|
||||
}
|
||||
|
||||
return this._actor
|
||||
|
|
|
@ -2,7 +2,7 @@ import { makeInspectable } from '../utils'
|
|||
import { TelegramClient } from '../../client'
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { User } from './user'
|
||||
import { UsersIndex } from './index'
|
||||
import { PeersIndex } from './index'
|
||||
|
||||
export namespace ChatInviteLink {
|
||||
export interface JoinedMember {
|
||||
|
@ -15,19 +15,11 @@ export namespace ChatInviteLink {
|
|||
* An invite link
|
||||
*/
|
||||
export class ChatInviteLink {
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.RawChatInviteExported
|
||||
|
||||
readonly _users?: UsersIndex
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.RawChatInviteExported,
|
||||
users?: UsersIndex
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.RawChatInviteExported,
|
||||
readonly _peers?: PeersIndex
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._users = users
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,10 +37,13 @@ export class ChatInviteLink {
|
|||
* Creator of the invite link, if available
|
||||
*/
|
||||
get creator(): User | null {
|
||||
if (!this._users) return null
|
||||
if (!this._peers) return null
|
||||
|
||||
if (!this._creator) {
|
||||
this._creator = new User(this.client, this._users[this.raw.adminId])
|
||||
this._creator = new User(
|
||||
this.client,
|
||||
this._peers.user(this.raw.adminId)
|
||||
)
|
||||
}
|
||||
|
||||
return this._creator
|
||||
|
|
|
@ -7,13 +7,10 @@ import { makeInspectable } from '../utils'
|
|||
* Geolocation of a supergroup
|
||||
*/
|
||||
export class ChatLocation {
|
||||
readonly client: TelegramClient
|
||||
constructor(
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.RawChannelLocation
|
||||
|
||||
constructor(client: TelegramClient, raw: tl.RawChannelLocation) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
}
|
||||
) {}
|
||||
|
||||
private _location?: Location
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,7 @@ import { tl } from '@mtcute/tl'
|
|||
import { User } from './user'
|
||||
import { assertTypeIs } from '../../utils/type-assertion'
|
||||
import { ChatPermissions } from './chat-permissions'
|
||||
import { UsersIndex } from './index'
|
||||
import { PeersIndex } from './index'
|
||||
|
||||
export namespace ChatMember {
|
||||
/**
|
||||
|
@ -29,21 +29,11 @@ export namespace ChatMember {
|
|||
* Information about one chat member
|
||||
*/
|
||||
export class ChatMember {
|
||||
readonly client: TelegramClient
|
||||
readonly raw: tl.TypeChatParticipant | tl.TypeChannelParticipant
|
||||
|
||||
/** Map of users in this object. Mainly for internal use */
|
||||
readonly _users: UsersIndex
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
raw: tl.TypeChatParticipant | tl.TypeChannelParticipant,
|
||||
users: UsersIndex
|
||||
) {
|
||||
this.client = client
|
||||
this.raw = raw
|
||||
this._users = users
|
||||
}
|
||||
readonly client: TelegramClient,
|
||||
readonly raw: tl.TypeChatParticipant | tl.TypeChannelParticipant,
|
||||
readonly _peers: PeersIndex
|
||||
) {}
|
||||
|
||||
private _user?: User
|
||||
/**
|
||||
|
@ -59,15 +49,16 @@ export class ChatMember {
|
|||
this.raw.peer,
|
||||
'peerUser'
|
||||
)
|
||||
|
||||
this._user = new User(
|
||||
this.client,
|
||||
this._users[this.raw.peer.userId]
|
||||
this._peers.user(this.raw.peer.userId)
|
||||
)
|
||||
break
|
||||
default:
|
||||
this._user = new User(
|
||||
this.client,
|
||||
this._users[this.raw.userId]
|
||||
this._peers.user(this.raw.userId)
|
||||
)
|
||||
break
|
||||
}
|
||||
|
@ -148,7 +139,7 @@ export class ChatMember {
|
|||
if ('inviterId' in this.raw && this.raw.inviterId) {
|
||||
this._invitedBy = new User(
|
||||
this.client,
|
||||
this._users[this.raw.inviterId]
|
||||
this._peers.user(this.raw.inviterId)
|
||||
)
|
||||
} else {
|
||||
this._invitedBy = null
|
||||
|
@ -169,7 +160,7 @@ export class ChatMember {
|
|||
if (this.raw._ === 'channelParticipantAdmin') {
|
||||
this._promotedBy = new User(
|
||||
this.client,
|
||||
this._users[this.raw.promotedBy]
|
||||
this._peers.user(this.raw.promotedBy)
|
||||
)
|
||||
} else {
|
||||
this._promotedBy = null
|
||||
|
@ -190,7 +181,7 @@ export class ChatMember {
|
|||
if (this.raw._ === 'channelParticipantBanned') {
|
||||
this._restrictedBy = new User(
|
||||
this.client,
|
||||
this._users[this.raw.kickedBy]
|
||||
this._peers.user(this.raw.kickedBy)
|
||||
)
|
||||
} else {
|
||||
this._restrictedBy = null
|
||||
|
|
|
@ -4,23 +4,19 @@ import { TelegramClient } from '../../client'
|
|||
import { makeInspectable } from '../utils'
|
||||
import { strippedPhotoToJpg } from '../../utils/file-utils'
|
||||
import { tdFileId, toFileId, toUniqueFileId } from '@mtcute/file-id'
|
||||
import bigInt from 'big-integer'
|
||||
import { MAX_CHANNEL_ID } from '@mtcute/core'
|
||||
import { MtArgumentError } from '../errors'
|
||||
import Long from 'long'
|
||||
import { toggleChannelIdMark } from '../../../../core'
|
||||
|
||||
/**
|
||||
* A size of a chat photo
|
||||
*/
|
||||
export class ChatPhotoSize extends FileLocation {
|
||||
readonly obj: tl.RawUserProfilePhoto | tl.RawChatPhoto
|
||||
readonly peer: tl.TypeInputPeer
|
||||
readonly big: boolean
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
peer: tl.TypeInputPeer,
|
||||
obj: tl.RawUserProfilePhoto | tl.RawChatPhoto,
|
||||
big: boolean
|
||||
readonly client: TelegramClient,
|
||||
readonly peer: tl.TypeInputPeer,
|
||||
readonly obj: tl.RawUserProfilePhoto | tl.RawChatPhoto,
|
||||
readonly big: boolean
|
||||
) {
|
||||
super(
|
||||
client,
|
||||
|
@ -57,10 +53,10 @@ export class ChatPhotoSize extends FileLocation {
|
|||
break
|
||||
case 'inputPeerChat':
|
||||
id = -peer.chatId
|
||||
hash = bigInt.zero
|
||||
hash = Long.ZERO
|
||||
break
|
||||
case 'inputPeerChannel':
|
||||
id = MAX_CHANNEL_ID - peer.channelId
|
||||
id = toggleChannelIdMark(peer.channelId)
|
||||
hash = peer.accessHash
|
||||
break
|
||||
default:
|
||||
|
@ -75,11 +71,11 @@ export class ChatPhotoSize extends FileLocation {
|
|||
location: {
|
||||
_: 'photo',
|
||||
id: this.obj.photoId,
|
||||
accessHash: bigInt.zero,
|
||||
accessHash: Long.ZERO,
|
||||
source: {
|
||||
_: 'dialogPhoto',
|
||||
big: this.big,
|
||||
id: bigInt(id),
|
||||
id: id,
|
||||
accessHash: hash,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -16,19 +16,15 @@ export namespace ChatPreview {
|
|||
}
|
||||
|
||||
export class ChatPreview {
|
||||
readonly client: TelegramClient
|
||||
readonly invite: tl.RawChatInvite
|
||||
|
||||
constructor(
|
||||
readonly client: TelegramClient,
|
||||
readonly invite: tl.RawChatInvite,
|
||||
/**
|
||||
* Original invite link used to fetch
|
||||
* this preview
|
||||
* Original invite link used to fetch this preview
|
||||
*/
|
||||
readonly link: string
|
||||
|
||||
constructor(client: TelegramClient, raw: tl.RawChatInvite, link: string) {
|
||||
this.client = client
|
||||
this.invite = raw
|
||||
this.link = link
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,7 @@ import { TelegramClient } from '../../client'
|
|||
import { getMarkedPeerId, MaybeArray } from '@mtcute/core'
|
||||
import { MtArgumentError, MtTypeAssertionError } from '../errors'
|
||||
import { makeInspectable } from '../utils'
|
||||
import { ChatsIndex, InputPeerLike, User, UsersIndex } from './index'
|
||||
import { InputPeerLike, PeersIndex, User } from './index'
|
||||
import { ChatLocation } from './chat-location'
|
||||
import { InputMediaLike } from '../media'
|
||||
import { FormattedString } from '../parser'
|
||||
|
@ -33,9 +33,6 @@ export namespace Chat {
|
|||
* A chat.
|
||||
*/
|
||||
export class Chat {
|
||||
/** Telegram client used for this chat */
|
||||
readonly client: TelegramClient
|
||||
|
||||
/**
|
||||
* Raw peer object that this {@link Chat} represents.
|
||||
*/
|
||||
|
@ -46,15 +43,10 @@ export class Chat {
|
|||
| tl.RawChatForbidden
|
||||
| tl.RawChannelForbidden
|
||||
|
||||
/**
|
||||
* Raw full peer object that this {@link Chat} represents.
|
||||
*/
|
||||
readonly fullPeer?: tl.TypeUserFull | tl.TypeChatFull
|
||||
|
||||
constructor(
|
||||
client: TelegramClient,
|
||||
readonly client: TelegramClient,
|
||||
peer: tl.TypeUser | tl.TypeChat,
|
||||
fullPeer?: tl.TypeUserFull | tl.TypeChatFull
|
||||
readonly fullPeer?: tl.TypeUserFull | tl.TypeChatFull
|
||||
) {
|
||||
if (!peer) throw new MtArgumentError('peer is not available')
|
||||
|
||||
|
@ -478,27 +470,25 @@ export class Chat {
|
|||
static _parseFromMessage(
|
||||
client: TelegramClient,
|
||||
message: tl.RawMessage | tl.RawMessageService,
|
||||
users: UsersIndex,
|
||||
chats: ChatsIndex
|
||||
peers: PeersIndex
|
||||
): Chat {
|
||||
return Chat._parseFromPeer(client, message.peerId, users, chats)
|
||||
return Chat._parseFromPeer(client, message.peerId, peers)
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
static _parseFromPeer(
|
||||
client: TelegramClient,
|
||||
peer: tl.TypePeer,
|
||||
users: UsersIndex,
|
||||
chats: ChatsIndex
|
||||
peers: PeersIndex
|
||||
): Chat {
|
||||
switch (peer._) {
|
||||
case 'peerUser':
|
||||
return new Chat(client, users[peer.userId])
|
||||
return new Chat(client, peers.user(peer.userId))
|
||||
case 'peerChat':
|
||||
return new Chat(client, chats[peer.chatId])
|
||||
return new Chat(client, peers.chat(peer.chatId))
|
||||
}
|
||||
|
||||
return new Chat(client, chats[peer.channelId])
|
||||
return new Chat(client, peers.chat(peer.channelId))
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
|
|
@ -8,6 +8,7 @@ export * from './chat-member'
|
|||
export * from './chat-event'
|
||||
export * from './chat-invite-link'
|
||||
export * from './typing-status'
|
||||
export * from './peers-index'
|
||||
|
||||
/**
|
||||
* Peer types that have one-to-one relation to tl.Peer* types.
|
||||
|
@ -23,11 +24,14 @@ export type PeerType = 'user' | 'bot' | 'group' | 'channel' | 'supergroup'
|
|||
/**
|
||||
* Type that can be used as an input peer
|
||||
* to most of the high-level methods. Can be:
|
||||
* - `number`, representing peer's marked ID
|
||||
* - `number`, representing peer's marked ID*
|
||||
* - `string`, representing peer's username (w/out preceding `@`)
|
||||
* - `string`, representing user's phone number (only for contacts)
|
||||
* - `"me"` and `"self"` which will be replaced with the current user/bot
|
||||
* - Raw TL object
|
||||
*
|
||||
* > Telegram has moved to int64 IDs. Though, Levin [has confirmed](https://t.me/tdlibchat/25075)
|
||||
* > that new IDs *will* still fit into int53, meaning JS integers are fine.
|
||||
*/
|
||||
export type InputPeerLike =
|
||||
| string
|
||||
|
@ -36,6 +40,3 @@ export type InputPeerLike =
|
|||
| tl.TypeInputPeer
|
||||
| tl.TypeInputUser
|
||||
| tl.TypeInputChannel
|
||||
|
||||
export type UsersIndex = Record<number, tl.TypeUser>
|
||||
export type ChatsIndex = Record<number, tl.TypeChat>
|
||||
|
|
48
packages/client/src/types/peers/peers-index.ts
Normal file
48
packages/client/src/types/peers/peers-index.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
import { MtArgumentError } from '../errors'
|
||||
|
||||
const ERROR_MSG =
|
||||
'Given peer is not available in this index. This is most likely an internal library error.'
|
||||
|
||||
export class PeersIndex {
|
||||
readonly users: Record<number, tl.TypeUser> = Object.create(null)
|
||||
readonly chats: Record<number, tl.TypeChat> = Object.create(null)
|
||||
|
||||
hasMin = false
|
||||
|
||||
static from(obj: {
|
||||
users?: tl.TypeUser[]
|
||||
chats?: tl.TypeChat[]
|
||||
}): PeersIndex {
|
||||
const index = new PeersIndex()
|
||||
|
||||
obj.users?.forEach((user) => {
|
||||
index.users[user.id] = user
|
||||
if ((user as any).min) index.hasMin = true
|
||||
})
|
||||
obj.chats?.forEach((chat) => {
|
||||
index.chats[chat.id] = chat
|
||||
if ((chat as any).min) index.hasMin = true
|
||||
})
|
||||
|
||||
return index
|
||||
}
|
||||
|
||||
user(id: number): tl.TypeUser {
|
||||
const r = this.users[id]
|
||||
if (!r) {
|
||||
throw new MtArgumentError(ERROR_MSG)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
chat(id: number): tl.TypeChat {
|
||||
const r = this.chats[id]
|
||||
if (!r) {
|
||||
throw new MtArgumentError(ERROR_MSG)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue