mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
Idle timeout
This commit is contained in:
@@ -45,6 +45,7 @@ export class WAConnection extends EventEmitter {
|
||||
regenerateQRIntervalMs = 30*1000
|
||||
connectOptions: WAConnectOptions = {
|
||||
timeoutMs: 60*1000,
|
||||
maxIdleTimeMs: 10*1000,
|
||||
waitForChats: true,
|
||||
maxRetries: 5,
|
||||
connectCooldownMs: 2250,
|
||||
@@ -80,6 +81,7 @@ export class WAConnection extends EventEmitter {
|
||||
protected lastDisconnectReason: DisconnectReason
|
||||
|
||||
protected mediaConn: MediaConnInfo
|
||||
protected debounceTimeout: NodeJS.Timeout
|
||||
|
||||
constructor () {
|
||||
super ()
|
||||
@@ -101,7 +103,10 @@ export class WAConnection extends EventEmitter {
|
||||
error !== DisconnectReason.invalidSession // do not reconnect if credentials have been invalidated
|
||||
|
||||
this.closeInternal(error, willReconnect)
|
||||
willReconnect && this.connect ()
|
||||
willReconnect && (
|
||||
this.connect ()
|
||||
.catch(err => {}) // prevent unhandled exeception
|
||||
)
|
||||
}
|
||||
/**
|
||||
* base 64 encode the authentication credentials and return them
|
||||
@@ -316,6 +321,7 @@ export class WAConnection extends EventEmitter {
|
||||
|
||||
this.qrTimeout && clearTimeout (this.qrTimeout)
|
||||
this.keepAliveReq && clearInterval(this.keepAliveReq)
|
||||
this.debounceTimeout && clearTimeout (this.debounceTimeout)
|
||||
|
||||
this.state = 'close'
|
||||
this.msgCount = 0
|
||||
|
||||
@@ -6,7 +6,7 @@ import { MessageLogLevel, WAMetric, WAFlag, BaileysError, Presence, WAUser } fro
|
||||
export class WAConnection extends Base {
|
||||
|
||||
/** Authenticate the connection */
|
||||
protected async authenticate (reconnect?: string) {
|
||||
protected async authenticate (onConnectionValidated: () => void, reconnect?: string) {
|
||||
// if no auth info is present, that is, a new session has to be established
|
||||
// generate a client ID
|
||||
if (!this.authInfo?.clientID) {
|
||||
@@ -56,9 +56,9 @@ export class WAConnection extends Base {
|
||||
}
|
||||
|
||||
const validationJSON = (await Promise.all (initQueries)).slice(-1)[0] // get the last result
|
||||
|
||||
this.user = await this.validateNewConnection(validationJSON[1]) // validate the connection
|
||||
|
||||
onConnectionValidated ()
|
||||
this.log('validated connection successfully', MessageLogLevel.info)
|
||||
|
||||
const response = await this.query({ json: ['query', 'ProfilePicThumb', this.user.jid], waitForOpen: false, expect200: false })
|
||||
|
||||
@@ -68,13 +68,18 @@ export class WAConnection extends Base {
|
||||
let cancel: () => void
|
||||
const task = Utils.promiseTimeout(timeoutMs, (resolve, reject) => {
|
||||
let task: Promise<any> = Promise.resolve ()
|
||||
const checkIdleTime = () => {
|
||||
this.debounceTimeout && clearTimeout (this.debounceTimeout)
|
||||
this.debounceTimeout = setTimeout (() => rejectSafe (TimedOutError()), this.connectOptions.maxIdleTimeMs)
|
||||
}
|
||||
const debouncedTimeout = () => this.connectOptions.maxIdleTimeMs && this.conn.addEventListener ('message', checkIdleTime)
|
||||
|
||||
// add wait for chats promise if required
|
||||
if (typeof options?.waitForChats === 'undefined' ? true : options?.waitForChats) {
|
||||
const {waitForChats, cancelChats} = this.receiveChatsAndContacts()
|
||||
task = waitForChats
|
||||
cancel = cancelChats
|
||||
}
|
||||
|
||||
// determine whether reconnect should be used or not
|
||||
const shouldUseReconnect = this.lastDisconnectReason !== DisconnectReason.replaced &&
|
||||
this.lastDisconnectReason !== DisconnectReason.unknown &&
|
||||
@@ -83,16 +88,17 @@ export class WAConnection extends Base {
|
||||
|
||||
const reconnectID = shouldUseReconnect ? this.user.jid.replace ('@s.whatsapp.net', '@c.us') : null
|
||||
|
||||
this.conn = new WS(WS_URL, null, { origin: DEFAULT_ORIGIN, timeout: timeoutMs, agent: options.agent })
|
||||
this.conn.on('message', data => this.onMessageRecieved(data as any))
|
||||
|
||||
this.conn = new WS(WS_URL, null, { origin: DEFAULT_ORIGIN, timeout: this.connectOptions.maxIdleTimeMs, agent: options.agent })
|
||||
this.conn.addEventListener('message', ({data}) => this.onMessageRecieved(data as any))
|
||||
|
||||
this.conn.on ('open', async () => {
|
||||
this.log(`connected to WhatsApp Web server, authenticating via ${reconnectID ? 'reconnect' : 'takeover'}`, MessageLogLevel.info)
|
||||
|
||||
try {
|
||||
task = Promise.all ([
|
||||
task,
|
||||
this.authenticate (reconnectID)
|
||||
// debounce the timeout once validated
|
||||
this.authenticate (debouncedTimeout, reconnectID)
|
||||
.then (
|
||||
() => {
|
||||
this.conn
|
||||
@@ -102,12 +108,14 @@ export class WAConnection extends Base {
|
||||
)
|
||||
])
|
||||
const [result] = await task
|
||||
|
||||
this.conn.removeEventListener ('message', checkIdleTime)
|
||||
|
||||
resolve (result)
|
||||
} catch (error) {
|
||||
reject (error)
|
||||
}
|
||||
})
|
||||
|
||||
const rejectSafe = error => {
|
||||
task = task.catch (() => {})
|
||||
reject (error)
|
||||
@@ -138,7 +146,7 @@ export class WAConnection extends Base {
|
||||
const result = connect ()
|
||||
cancellations.push (result.cancel)
|
||||
|
||||
const final = await result.promise
|
||||
const final = await result.promise
|
||||
return final
|
||||
} catch (error) {
|
||||
this.endConnection ()
|
||||
|
||||
@@ -67,6 +67,8 @@ export enum ReconnectMode {
|
||||
export type WAConnectOptions = {
|
||||
/** timeout after which the connect attempt will fail, set to null for default timeout value */
|
||||
timeoutMs?: number
|
||||
/** */
|
||||
maxIdleTimeMs?: number
|
||||
/** maximum attempts to connect */
|
||||
maxRetries?: number
|
||||
/** should the chats be waited for */
|
||||
|
||||
Reference in New Issue
Block a user