From 210b467b6808f6fe362b53045554634aac733105 Mon Sep 17 00:00:00 2001 From: Adhiraj Singh Date: Sun, 11 Oct 2020 23:08:48 +0530 Subject: [PATCH] Close before terminate + update presence on message receive --- Example/example.ts | 5 +---- README.md | 33 +++++++++++++++++++++++++++++++- src/WAConnection/0.Base.ts | 15 ++++++++++----- src/WAConnection/1.Validation.ts | 1 - src/WAConnection/3.Connect.ts | 5 +++-- src/WAConnection/4.Events.ts | 10 ++++++++-- 6 files changed, 54 insertions(+), 15 deletions(-) diff --git a/Example/example.ts b/Example/example.ts index ff6dc9a..f16024d 100644 --- a/Example/example.ts +++ b/Example/example.ts @@ -17,10 +17,7 @@ async function example() { const conn = new WAConnection() // instantiate conn.autoReconnect = ReconnectMode.onConnectionLost // only automatically reconnect when the connection breaks conn.logLevel = MessageLogLevel.info // set to unhandled to see what kind of stuff you can implement - // if the gap between two messages is greater than 10s, fail the connection - conn.connectOptions.maxIdleTimeMs = 10*1000 - conn.connectOptions.regenerateQRIntervalMs = 5000 - // attempt to reconnect at most 10 times + // attempt to reconnect at most 10 times in a row conn.connectOptions.maxRetries = 10 conn.chatOrderingKey = waChatKey(true) // order chats such that pinned chats are on top diff --git a/README.md b/README.md index bab09ed..9759e6a 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,9 @@ Do note, the `chats` object returned is now a [KeyedDB](https://github.com/adiwa - Most applications require pagination of chats (Use `chats.paginated()`) - Most applications require **O(1)** access to chats via the chat ID. (Use `chats.get(jid)` with `KeyedDB`) -## Connecting via an HTTPS proxy +## Configuring the Connection + +You can configure the connection via the `connectOptions` property. You can even specify an HTTPS proxy. For example: ``` ts import { WAConnection, ProxyAgent } from '@adiwajshing/baileys' @@ -80,6 +82,35 @@ await conn.connect () console.log ("oh hello " + conn.user.name + "! You connected via a proxy") ``` +The entire `WAConnectOptions` struct is mentioned here with default values: +``` ts +conn.connectOptions = { + /** New QR generation interval, set to null if you don't want to regenerate */ + regenerateQRIntervalMs?: 30_000 + /** fails the connection if no data is received for X seconds */ + maxIdleTimeMs?: 15_000 + /** maximum attempts to connect */ + maxRetries?: 5 + /** should the chats be waited for; + * should generally keep this as true, unless you only care about sending & receiving new messages + * & don't care about chat history + * */ + waitForChats?: true + /** if set to true, the connect only waits for the last message of the chat + * setting to false, generally yields a faster connect + */ + waitOnlyForLastMessage?: false + /** max time for the phone to respond to a connectivity test */ + phoneResponseTime?: 7500 + /** minimum time between new connections */ + connectCooldownMs?: 3000 + /** agent used for WS connections (could be a proxy agent) */ + agent?: Agent = undefined + /** agent used for fetch requests -- uploading/downloading media */ + fetchAgent?: Agent = undefined +} as WAConnectOptions +``` + ## Saving & Restoring Sessions You obviously don't want to keep scanning the QR code every time you want to connect. diff --git a/src/WAConnection/0.Base.ts b/src/WAConnection/0.Base.ts index 9d327aa..0561470 100644 --- a/src/WAConnection/0.Base.ts +++ b/src/WAConnection/0.Base.ts @@ -30,7 +30,7 @@ import { STATUS_CODES, Agent } from 'http' export class WAConnection extends EventEmitter { /** The version of WhatsApp Web we're telling the servers we are */ - version: [number, number, number] = [2, 2039, 9] + version: [number, number, number] = [2, 2041, 6] /** The Browser we're telling the WhatsApp Web servers we are */ browserDescription: [string, string, string] = Utils.Browsers.baileys ('Chrome') /** Metadata like WhatsApp id, name set on WhatsApp etc. */ @@ -47,7 +47,7 @@ export class WAConnection extends EventEmitter { waitOnlyForLastMessage: false, waitForChats: true, maxRetries: 5, - connectCooldownMs: 2250, + connectCooldownMs: 3000, phoneResponseTime: 7500 } /** When to auto-reconnect */ @@ -333,7 +333,6 @@ export class WAConnection extends EventEmitter { this.log (`closed connection, reason ${reason}${isReconnecting ? ', reconnecting in a few seconds...' : ''}`, MessageLogLevel.info) this.qrTimeout && clearTimeout (this.qrTimeout) - this.keepAliveReq && clearInterval(this.keepAliveReq) this.debounceTimeout && clearTimeout (this.debounceTimeout) this.state = 'close' @@ -355,8 +354,14 @@ export class WAConnection extends EventEmitter { this.conn?.removeAllListeners ('error') this.conn?.removeAllListeners ('open') this.conn?.removeAllListeners ('message') - - this.conn?.terminate() + + this.keepAliveReq && clearInterval(this.keepAliveReq) + try { + this.conn?.close() + this.conn?.terminate() + } catch { + + } this.conn = null this.lastSeen = null this.msgCount = 0 diff --git a/src/WAConnection/1.Validation.ts b/src/WAConnection/1.Validation.ts index 3114784..b5beca6 100644 --- a/src/WAConnection/1.Validation.ts +++ b/src/WAConnection/1.Validation.ts @@ -115,7 +115,6 @@ export class WAConnection extends Base { let credsChanged = false // if we didn't get a secret, we don't need it, we're validated if (json.clientToken && json.clientToken !== this.authInfo.clientToken) { - console.log (`change: ${this.authInfo.clientToken}, ${json.clientToken}`) this.authInfo = { ...this.authInfo, clientToken: json.clientToken } credsChanged = true } diff --git a/src/WAConnection/3.Connect.ts b/src/WAConnection/3.Connect.ts index bc89ebf..b193a5a 100644 --- a/src/WAConnection/3.Connect.ts +++ b/src/WAConnection/3.Connect.ts @@ -52,7 +52,6 @@ export class WAConnection extends Base { this.emit ('open', result) this.releasePendingRequests () - this.startKeepAliveRequest() this.log ('opened connection to WhatsApp Web', MessageLogLevel.info) @@ -114,6 +113,9 @@ export class WAConnection extends Base { } try { await this.authenticate (startDebouncedTimeout, stopDebouncedTimeout, reconnectID) + + this.startKeepAliveRequest() + this.conn .removeAllListeners ('error') .removeAllListeners ('close') @@ -269,7 +271,6 @@ export class WAConnection extends Base { resolveTask = resolve cancelChats = () => reject (CancelledError()) }) - console.log ('resolved task') const oldChats = this.chats const updatedChats: { [k: string]: Partial } = {} diff --git a/src/WAConnection/4.Events.ts b/src/WAConnection/4.Events.ts index b982a66..2948e0a 100644 --- a/src/WAConnection/4.Events.ts +++ b/src/WAConnection/4.Events.ts @@ -221,8 +221,14 @@ export class WAConnection extends Base { } protected chatAddMessage (message: WAMessage, chat: WAChat) { // add to count if the message isn't from me & there exists a message - if (!message.key.fromMe && message.message) chat.count += 1 - + if (!message.key.fromMe && message.message) { + chat.count += 1 + const contact = this.contacts[chat.jid] + if (contact && contact.lastKnownPresence === Presence.composing) { // update presence + contact.lastKnownPresence = Presence.available // emit change + this.emit ('user-presence-update', { id: chat.jid, presence: Presence.available, participant: message.participant }) + } + } const protocolMessage = message.message?.protocolMessage // if it's a message to delete another message if (protocolMessage) {