From dd91c9a0d9fb32ab0e9ce77d792d9df3d78c3e6c Mon Sep 17 00:00:00 2001 From: Adhiraj Date: Thu, 27 Aug 2020 16:14:24 +0530 Subject: [PATCH] bug fix where phonePoll wasn't clearing --- src/Tests/Tests.Connect.ts | 13 ++++++++----- src/WAConnection/0.Base.ts | 10 +++++----- src/WAConnection/3.Connect.ts | 30 +++++++++++++++++++++++------- src/WAConnection/4.Events.ts | 13 ------------- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/Tests/Tests.Connect.ts b/src/Tests/Tests.Connect.ts index 9bb3810..4d0569b 100644 --- a/src/Tests/Tests.Connect.ts +++ b/src/Tests/Tests.Connect.ts @@ -5,9 +5,9 @@ import { delay } from '../WAConnection/Utils' describe('QR Generation', () => { it('should generate QR', async () => { - const conn = new WAConnection() conn.regenerateQRIntervalMs = 5000 + let calledQR = 0 conn.removeAllListeners ('qr') conn.on ('qr', qr => calledQR += 1) @@ -17,8 +17,11 @@ describe('QR Generation', () => { .catch (error => { assert.equal (error.message, 'timed out') }) - assert.equal (conn['pendingRequests'].length, 0) - assert.equal (Object.keys(conn['callbacks']).filter(key => !key.startsWith('function:')).length, 0) + assert.deepEqual (conn['pendingRequests'], []) + assert.deepEqual ( + Object.keys(conn['callbacks']).filter(key => !key.startsWith('function:')), + [] + ) assert.ok(calledQR >= 2, 'QR not called') }) }) @@ -29,7 +32,7 @@ describe('Test Connect', () => { console.log('please be ready to scan with your phone') const conn = new WAConnection() - await conn.connect (null) + await conn.connect () assert.ok(conn.user?.id) assert.ok(conn.user?.phone) assert.ok (conn.user?.imgUrl || conn.user.imgUrl === '') @@ -114,7 +117,7 @@ describe ('Reconnects', () => { closes += 1 // let it fail reconnect a few times - if (closes > 4) { + if (closes > 3) { conn.removeAllListeners ('close') conn.removeAllListeners ('connecting') resolve () diff --git a/src/WAConnection/0.Base.ts b/src/WAConnection/0.Base.ts index 8ab70b5..c039287 100644 --- a/src/WAConnection/0.Base.ts +++ b/src/WAConnection/0.Base.ts @@ -77,9 +77,7 @@ export class WAConnection extends EventEmitter { const willReconnect = (this.autoReconnect === ReconnectMode.onAllErrors || (this.autoReconnect === ReconnectMode.onConnectionLost && (error !== 'replaced'))) && - error !== 'invalid_session' - - this.log (`got disconnected, reason ${error}${willReconnect ? ', reconnecting in a few seconds...' : ''}`, MessageLogLevel.info) + error !== 'invalid_session' this.closeInternal(error, willReconnect) willReconnect && !this.cancelReconnect && this.reconnectLoop () @@ -283,6 +281,7 @@ export class WAConnection extends EventEmitter { //throw new Error("You're not even connected, you can't log out") await new Promise(resolve => this.conn.send('goodbye,["admin","Conn","disconnect"]', null, resolve)) } + this.user = null this.close() } /** Close the connection to WhatsApp Web */ @@ -291,9 +290,11 @@ export class WAConnection extends EventEmitter { this.cancelReconnect && this.cancelReconnect () } protected closeInternal (reason?: DisconnectReason, isReconnecting: boolean=false) { + this.log (`closed connection, reason ${reason}${isReconnecting ? ', reconnecting in a few seconds...' : ''}`, MessageLogLevel.info) + this.qrTimeout && clearTimeout (this.qrTimeout) this.phoneCheck && clearTimeout (this.phoneCheck) - + this.state = 'close' this.msgCount = 0 this.conn?.removeAllListeners ('close') @@ -315,7 +316,6 @@ export class WAConnection extends EventEmitter { } }) if (this.keepAliveReq) clearInterval(this.keepAliveReq) - // reconnecting if the timeout is active for the reconnect loop this.emit ('close', { reason, isReconnecting: this.cancelReconnect || isReconnecting}) } diff --git a/src/WAConnection/3.Connect.ts b/src/WAConnection/3.Connect.ts index c38d17f..0244bda 100644 --- a/src/WAConnection/3.Connect.ts +++ b/src/WAConnection/3.Connect.ts @@ -42,16 +42,17 @@ export class WAConnection extends Base { const waitForChats = typeof options?.waitForChats === 'undefined' ? true : options?.waitForChats if (waitForChats) tasks.push (this.receiveChatsAndContacts(options?.timeoutMs, true)) - await Promise.all (tasks) - + await Promise.all (tasks) + this.phoneConnected = true this.state = 'open' - + this.user.imgUrl = await this.getProfilePicture (this.user.id).catch (err => '') + this.registerPhoneConnectionPoll () this.emit ('open') - this.releasePendingRequests () + this.log ('opened connection to WhatsApp Web', MessageLogLevel.info) return this @@ -117,7 +118,7 @@ export class WAConnection extends Base { this.registerCallback(['action', 'add:before'], chatUpdate) this.registerCallback(['action', 'add:unread'], chatUpdate) } - + // get chats this.registerCallback(['response', 'type:chat'], json => { if (json[1].duplicate || !json[2]) return @@ -163,7 +164,8 @@ export class WAConnection extends Base { this.off ('close', rejectTask) } this.on ('close', rejectTask) - }).finally (deregisterCallbacks) + }) + .finally (deregisterCallbacks) this.chats .all () @@ -280,13 +282,27 @@ export class WAConnection extends Base { } } + protected registerPhoneConnectionPoll () { + this.phoneCheck = setInterval (() => { + this.checkPhoneConnection (5000) // 5000 ms for timeout + .then (connected => { + if (this.phoneConnected != connected) { + this.emit ('connection-phone-change', {connected}) + } + this.phoneConnected = connected + }) + .catch (error => this.log(`error in getting phone connection: ${error}`, MessageLogLevel.info)) + }, 15000) + } /** * Check if your phone is connected * @param timeoutMs max time for the phone to respond */ async checkPhoneConnection(timeoutMs = 5000) { + if (this.state !== 'open') return false + try { - const response = await this.query({json: ['admin', 'test'], timeoutMs}) + const response = await this.query({json: ['admin', 'test'], timeoutMs, waitForOpen: false}) return response[1] as boolean } catch (error) { return false diff --git a/src/WAConnection/4.Events.ts b/src/WAConnection/4.Events.ts index dfee878..a28f462 100644 --- a/src/WAConnection/4.Events.ts +++ b/src/WAConnection/4.Events.ts @@ -11,7 +11,6 @@ export class WAConnection extends Base { this.registerOnMessageStatusChange () this.registerOnUnreadMessage () this.registerOnPresenceUpdate () - this.registerPhoneConnectionPoll () // If a message has been updated (usually called when a video message gets its upload url) this.registerCallback (['action', 'add:update', 'message'], json => { @@ -266,18 +265,6 @@ export class WAConnection extends Base { protected async setProfilePicture (chat: WAChat) { chat.imgUrl = await this.getProfilePicture (chat.jid).catch (err => '') } - protected registerPhoneConnectionPoll () { - this.phoneCheck = setInterval (() => { - this.checkPhoneConnection (5000) // 5000 ms for timeout - .then (connected => { - if (this.phoneConnected != connected) { - this.emit ('connection-phone-change', {connected}) - } - this.phoneConnected = connected - }) - .catch (error => this.log(`error in getting phone connection: ${error}`, MessageLogLevel.info)) - }, 15000) - } // Add all event types