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