From 482fa7090b4dc33bf658da9137828578851f0c1a Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Fri, 12 Feb 2021 16:54:31 +0530 Subject: [PATCH] Remove depracations + add chat ping loop --- src/WAConnection/0.Base.ts | 18 ++++++++---------- src/WAConnection/1.Validation.ts | 16 +++++++++++++++- src/WAConnection/3.Connect.ts | 3 ++- src/WAConnection/4.Events.ts | 2 ++ src/WAConnection/Constants.ts | 10 +++++----- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/WAConnection/0.Base.ts b/src/WAConnection/0.Base.ts index 0f09986..209a2b1 100644 --- a/src/WAConnection/0.Base.ts +++ b/src/WAConnection/0.Base.ts @@ -46,7 +46,8 @@ export class WAConnection extends EventEmitter { maxRetries: 10, connectCooldownMs: 4000, phoneResponseTime: 15_000, - alwaysUseTakeover: true + alwaysUseTakeover: true, + queryChatsTillReceived: true } /** When to auto-reconnect */ autoReconnect = ReconnectMode.onConnectionLost @@ -62,28 +63,23 @@ export class WAConnection extends EventEmitter { messageLog: { tag: string, json: string, fromMe: boolean, binaryTags?: any[] }[] = [] maxCachedMessages = 50 - /** - * @deprecated - * does not do anything - * */ - loadProfilePicturesForChatsAutomatically = false lastChatsReceived: Date chats = new KeyedDB (Utils.waChatKey(false), value => value.jid) contacts: { [k: string]: WAContact } = {} - blocklist: string[] = []; + blocklist: string[] = [] /** Data structure of tokens & IDs used to establish one's identiy to WhatsApp Web */ - protected authInfo: AuthenticationCredentials = null + protected authInfo: AuthenticationCredentials /** Curve keys to initially authenticate */ protected curveKeys: { private: Uint8Array; public: Uint8Array } /** The websocket connection */ - protected conn: WS = null + protected conn: WS protected msgCount = 0 protected keepAliveReq: NodeJS.Timeout protected encoder = new Encoder() protected decoder = new Decoder() - protected phoneCheckInterval = undefined + protected phoneCheckInterval protected phoneCheckListeners = 0 protected referenceDate = new Date () // used for generating tags @@ -99,6 +95,7 @@ export class WAConnection extends EventEmitter { () => this.state === 'connecting' && this.endConnection(DisconnectReason.timedOut) ) protected messagesDebounceTimeout = Utils.debouncedTimeout(2000) + protected chatsDebounceTimeout = Utils.debouncedTimeout(10_000) /** * Connect to WhatsAppWeb * @param options the connect options @@ -432,6 +429,7 @@ export class WAConnection extends EventEmitter { this.initTimeout && clearTimeout (this.initTimeout) this.connectionDebounceTimeout.cancel() this.messagesDebounceTimeout.cancel() + this.chatsDebounceTimeout.cancel() this.keepAliveReq && clearInterval(this.keepAliveReq) this.phoneCheckListeners = 0 this.clearPhoneCheckInterval () diff --git a/src/WAConnection/1.Validation.ts b/src/WAConnection/1.Validation.ts index 252ea58..ad80573 100644 --- a/src/WAConnection/1.Validation.ts +++ b/src/WAConnection/1.Validation.ts @@ -107,12 +107,26 @@ export class WAConnection extends Base { */ sendPostConnectQueries () { this.sendBinary (['query', {type: 'contacts', epoch: '1'}, null], [ WAMetric.queryContact, WAFlag.ignore ]) - this.sendBinary (['query', {type: 'chat', epoch: '1'}, null], [ WAMetric.queryChat, WAFlag.ignore ]) this.sendBinary (['query', {type: 'status', epoch: '1'}, null], [ WAMetric.queryStatus, WAFlag.ignore ]) this.sendBinary (['query', {type: 'quick_reply', epoch: '1'}, null], [ WAMetric.queryQuickReply, WAFlag.ignore ]) this.sendBinary (['query', {type: 'label', epoch: '1'}, null], [ WAMetric.queryLabel, WAFlag.ignore ]) this.sendBinary (['query', {type: 'emoji', epoch: '1'}, null], [ WAMetric.queryEmoji, WAFlag.ignore ]) this.sendBinary (['action', {type: 'set', epoch: '1'}, [['presence', {type: Presence.available}, null]] ], [ WAMetric.presence, WAFlag.available ]) + + if(this.connectOptions.queryChatsTillReceived) { + this.chatsDebounceTimeout.start( + undefined, + () => { + this.logger.debug('pinging with chats query') + this.sendChatsQuery(this.msgCount) + } + ) + } else { + this.sendChatsQuery(1) + } + } + protected sendChatsQuery(epoch: number) { + return this.sendBinary(['query', {type: 'chat', epoch: epoch.toString()}, null], [ WAMetric.queryChat, WAFlag.ignore ]) } /** * Refresh QR Code diff --git a/src/WAConnection/3.Connect.ts b/src/WAConnection/3.Connect.ts index 147bb2d..0dc4f56 100644 --- a/src/WAConnection/3.Connect.ts +++ b/src/WAConnection/3.Connect.ts @@ -94,12 +94,13 @@ export class WAConnection extends Base { this.logger.info(`connected to WhatsApp Web server, authenticating via ${reconnectID ? 'reconnect' : 'takeover'}`) try { + this.connectionDebounceTimeout.setInterval(this.connectOptions.maxIdleTimeMs) const authResult = await this.authenticate(reconnectID) this.conn .removeAllListeners('error') .removeAllListeners('close') - this.connectionDebounceTimeout.start(this.connectOptions.maxIdleTimeMs) + this.connectionDebounceTimeout.start() resolve(authResult as WAOpenResult) } catch (error) { reject(error) diff --git a/src/WAConnection/4.Events.ts b/src/WAConnection/4.Events.ts index 920ea2f..e6107ee 100644 --- a/src/WAConnection/4.Events.ts +++ b/src/WAConnection/4.Events.ts @@ -26,6 +26,8 @@ export class WAConnection extends Base { // chats received this.on('CB:response,type:chat', json => { if (json[1].duplicate || !json[2]) return + + this.chatsDebounceTimeout.cancel() const chats = new KeyedDB(this.chatOrderingKey, c => c.jid) json[2].forEach(([item, chat]: [any, WAChat]) => { diff --git a/src/WAConnection/Constants.ts b/src/WAConnection/Constants.ts index 98339d3..c7801ef 100644 --- a/src/WAConnection/Constants.ts +++ b/src/WAConnection/Constants.ts @@ -85,11 +85,6 @@ export enum ReconnectMode { export type WALoadChatOptions = { searchString?: string custom?: (c: WAChat) => boolean - /** - * @deprecated - * does not do anything now - */ - loadProfilePicture?: boolean } export type WAConnectOptions = { /** fails the connection if no data is received for X seconds */ @@ -105,6 +100,11 @@ export type WAConnectOptions = { fetchAgent?: Agent /** Always uses takeover for connections */ alwaysUseTakeover?: boolean + /** + * Sometimes WA does not send the chats, + * this keeps pinging the phone to send the chats over + * */ + queryChatsTillReceived?: boolean } /** from: https://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url */ export const URL_REGEX = /[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)?/gi