fix: various fixes, improved updates handing
This commit is contained in:
parent
8504e3bf14
commit
b7751f0a57
6 changed files with 45 additions and 19 deletions
|
@ -149,6 +149,7 @@ import {
|
||||||
_dispatchUpdate,
|
_dispatchUpdate,
|
||||||
_fetchUpdatesState,
|
_fetchUpdatesState,
|
||||||
_handleUpdate,
|
_handleUpdate,
|
||||||
|
_keepAliveAction,
|
||||||
_loadStorage,
|
_loadStorage,
|
||||||
_saveStorage,
|
_saveStorage,
|
||||||
catchUp,
|
catchUp,
|
||||||
|
@ -172,6 +173,7 @@ import { Readable } from 'stream'
|
||||||
import {
|
import {
|
||||||
ArrayWithTotal,
|
ArrayWithTotal,
|
||||||
BotCommands,
|
BotCommands,
|
||||||
|
BotStoppedUpdate,
|
||||||
CallbackQuery,
|
CallbackQuery,
|
||||||
Chat,
|
Chat,
|
||||||
ChatEvent,
|
ChatEvent,
|
||||||
|
@ -339,6 +341,13 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
* @param handler History read handler
|
* @param handler History read handler
|
||||||
*/
|
*/
|
||||||
on(name: 'history_read', handler: (upd: HistoryReadUpdate) => void): this
|
on(name: 'history_read', handler: (upd: HistoryReadUpdate) => void): this
|
||||||
|
/**
|
||||||
|
* Register a bot stopped handler
|
||||||
|
*
|
||||||
|
* @param name Event name
|
||||||
|
* @param handler Bot stopped handler
|
||||||
|
*/
|
||||||
|
on(name: 'bot_stopped', handler: (upd: BotStoppedUpdate) => void): this
|
||||||
/**
|
/**
|
||||||
* Accept the given TOS
|
* Accept the given TOS
|
||||||
*
|
*
|
||||||
|
@ -3660,6 +3669,7 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
protected _dispatchUpdate = _dispatchUpdate
|
protected _dispatchUpdate = _dispatchUpdate
|
||||||
_handleUpdate = _handleUpdate
|
_handleUpdate = _handleUpdate
|
||||||
catchUp = catchUp
|
catchUp = catchUp
|
||||||
|
protected _keepAliveAction = _keepAliveAction
|
||||||
blockUser = blockUser
|
blockUser = blockUser
|
||||||
deleteProfilePhotos = deleteProfilePhotos
|
deleteProfilePhotos = deleteProfilePhotos
|
||||||
getCommonChats = getCommonChats
|
getCommonChats = getCommonChats
|
||||||
|
|
|
@ -52,7 +52,8 @@ import {
|
||||||
PollVoteUpdate,
|
PollVoteUpdate,
|
||||||
UserStatusUpdate,
|
UserStatusUpdate,
|
||||||
UserTypingUpdate,
|
UserTypingUpdate,
|
||||||
Conversation
|
Conversation,
|
||||||
|
BotStoppedUpdate
|
||||||
} from '../types'
|
} from '../types'
|
||||||
|
|
||||||
// @copy
|
// @copy
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
getBarePeerId,
|
getBarePeerId,
|
||||||
getMarkedPeerId,
|
getMarkedPeerId,
|
||||||
markedPeerIdToBare,
|
markedPeerIdToBare,
|
||||||
MAX_CHANNEL_ID,
|
MAX_CHANNEL_ID, RpcError,
|
||||||
} from '@mtqt/core'
|
} from '@mtqt/core'
|
||||||
import { isDummyUpdate, isDummyUpdates } from '../utils/updates-utils'
|
import { isDummyUpdate, isDummyUpdates } from '../utils/updates-utils'
|
||||||
import { ChatsIndex, UsersIndex } from '../types'
|
import { ChatsIndex, UsersIndex } from '../types'
|
||||||
|
@ -1002,3 +1002,9 @@ export function catchUp(this: TelegramClient): Promise<void> {
|
||||||
.then(() => this._updLock.release())
|
.then(() => this._updLock.release())
|
||||||
.then(() => this._saveStorage())
|
.then(() => this._saveStorage())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export function _keepAliveAction(this: TelegramClient): void {
|
||||||
|
debug('no updates for >15 minutes, catching up')
|
||||||
|
this.catchUp().catch((err) => this._emitError(err))
|
||||||
|
}
|
||||||
|
|
|
@ -236,7 +236,7 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
readonly _layer: number
|
readonly _layer: number
|
||||||
|
|
||||||
private _keepAliveInterval?: NodeJS.Timeout
|
private _keepAliveInterval?: NodeJS.Timeout
|
||||||
private _lastRequestTime = 0
|
protected _lastUpdateTime = 0
|
||||||
private _floodWaitedRequests: Record<string, number> = {}
|
private _floodWaitedRequests: Record<string, number> = {}
|
||||||
|
|
||||||
protected _config?: tl.RawConfig
|
protected _config?: tl.RawConfig
|
||||||
|
@ -332,6 +332,19 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
await this.storage.save?.()
|
await this.storage.save?.()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected _keepAliveAction(): void {
|
||||||
|
// telegram asks to fetch pending updates
|
||||||
|
// if there are no updates for 15 minutes.
|
||||||
|
// core does not have update handling,
|
||||||
|
// so we just use getState so the server knows
|
||||||
|
// we still do need updates
|
||||||
|
this.call({ _: 'updates.getState' }).catch((e) => {
|
||||||
|
if (!(e instanceof RpcError)) {
|
||||||
|
this.primaryConnection.reconnect()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private _cleanupPrimaryConnection(forever = false): void {
|
private _cleanupPrimaryConnection(forever = false): void {
|
||||||
if (forever && this.primaryConnection) this.primaryConnection.destroy()
|
if (forever && this.primaryConnection) this.primaryConnection.destroy()
|
||||||
if (this._keepAliveInterval) clearInterval(this._keepAliveInterval)
|
if (this._keepAliveInterval) clearInterval(this._keepAliveInterval)
|
||||||
|
@ -349,25 +362,19 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
reconnectionStrategy: this._reconnectionStrategy,
|
reconnectionStrategy: this._reconnectionStrategy,
|
||||||
layer: this._layer,
|
layer: this._layer,
|
||||||
})
|
})
|
||||||
this.primaryConnection.on('usable', async () => {
|
this.primaryConnection.on('usable', async (isReconnection: boolean) => {
|
||||||
|
this._lastUpdateTime = Date.now()
|
||||||
|
|
||||||
this._keepAliveInterval = setInterval(async () => {
|
this._keepAliveInterval = setInterval(async () => {
|
||||||
// according to telethon, "We need to send some content-related request at least hourly
|
if (Date.now() - this._lastUpdateTime > 900_000) {
|
||||||
// for Telegram to keep delivering updates, otherwise they will just stop even if we're connected.
|
this._keepAliveAction()
|
||||||
// Do so every 30 minutes"
|
this._lastUpdateTime = Date.now()
|
||||||
if (Date.now() - this._lastRequestTime > 1800_000) {
|
|
||||||
try {
|
|
||||||
await this.call({ _: 'updates.getState' })
|
|
||||||
} catch (e) {
|
|
||||||
if (!(e instanceof RpcError)) {
|
|
||||||
this.primaryConnection.reconnect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, 60_000)
|
}, 60_000)
|
||||||
|
|
||||||
// on reconnection we need to call updates.getState so Telegram
|
// on reconnection we need to call updates.getState so Telegram
|
||||||
// knows we still want the updates
|
// knows we still want the updates
|
||||||
if (!this._disableUpdates) {
|
if (isReconnection && !this._disableUpdates) {
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
await this.call({ _: 'updates.getState' })
|
await this.call({ _: 'updates.getState' })
|
||||||
|
@ -380,6 +387,7 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.primaryConnection.on('update', (update) => {
|
this.primaryConnection.on('update', (update) => {
|
||||||
|
this._lastUpdateTime = Date.now()
|
||||||
this._handleUpdate(update)
|
this._handleUpdate(update)
|
||||||
})
|
})
|
||||||
this.primaryConnection.on('wait', () =>
|
this.primaryConnection.on('wait', () =>
|
||||||
|
@ -568,8 +576,6 @@ export class BaseTelegramClient extends EventEmitter {
|
||||||
} as any // who cares
|
} as any // who cares
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lastRequestTime = Date.now()
|
|
||||||
|
|
||||||
const connection = params?.connection ?? this.primaryConnection
|
const connection = params?.connection ?? this.primaryConnection
|
||||||
|
|
||||||
let lastError: Error | null = null
|
let lastError: Error | null = null
|
||||||
|
|
|
@ -82,12 +82,14 @@ export abstract class PersistentConnection extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onConnectionUsable(): void {
|
protected onConnectionUsable(): void {
|
||||||
|
const isReconnection = this._consequentFails > 0
|
||||||
|
|
||||||
// reset reconnection related state
|
// reset reconnection related state
|
||||||
this._lastError = null
|
this._lastError = null
|
||||||
this._consequentFails = 0
|
this._consequentFails = 0
|
||||||
this._previousWait = null
|
this._previousWait = null
|
||||||
this._usable = true
|
this._usable = true
|
||||||
this.emit('usable')
|
this.emit('usable', isReconnection)
|
||||||
this._rescheduleInactivity()
|
this._rescheduleInactivity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,7 @@ export class TelegramConnection extends PersistentConnection {
|
||||||
it.promise.reject(new Error('Connection destroyed'))
|
it.promise.reject(new Error('Connection destroyed'))
|
||||||
)
|
)
|
||||||
this._mtproto.reset()
|
this._mtproto.reset()
|
||||||
|
this.removeAllListeners()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue