Unified unexpected disconnect & takeover events

This commit is contained in:
Adhiraj
2020-07-13 16:32:52 +05:30
parent 8b859b9376
commit d87e4e5897
5 changed files with 28 additions and 43 deletions

View File

@@ -27,14 +27,6 @@ async function example() {
fs.writeFileSync('./auth_info.json', JSON.stringify(authInfo, null, '\t')) // save this info to a file fs.writeFileSync('./auth_info.json', JSON.stringify(authInfo, null, '\t')) // save this info to a file
/* Note: one can take this auth_info.json file and login again from any computer without having to scan the QR code, /* Note: one can take this auth_info.json file and login again from any computer without having to scan the QR code,
and get full access to one's WhatsApp. Despite the convenience, be careful with this file */ and get full access to one's WhatsApp. Despite the convenience, be careful with this file */
client.setOnDisconnect (async kind => {
if (kind === 'replaced') {
// uncomment to reconnect whenever the connection gets taken over from somewhere else
// await client.connect ()
} else {
console.log ('oh no got logged out!')
}
})
client.setOnPresenceUpdate(json => console.log(json.id + ' presence is ' + json.type)) client.setOnPresenceUpdate(json => console.log(json.id + ' presence is ' + json.type))
client.setOnMessageStatusChange(json => { client.setOnMessageStatusChange(json => {
const participant = json.participant ? ' (' + json.participant + ')' : '' // participant exists when the message is from a group const participant = json.participant ? ' (' + json.participant + ')' : '' // participant exists when the message is from a group
@@ -121,7 +113,14 @@ async function example() {
const batterylevel = parseInt(batteryLevelStr) const batterylevel = parseInt(batteryLevelStr)
console.log('battery level: ' + batterylevel) console.log('battery level: ' + batterylevel)
}) })
client.setOnUnexpectedDisconnect(err => console.log('disconnected unexpectedly: ' + err)) client.setOnUnexpectedDisconnect(reason => {
if (reason === 'replaced') {
// uncomment to reconnect whenever the connection gets taken over from somewhere else
// await client.connect ()
} else {
console.log ('oh no got disconnected: ' + reason)
}
})
} }
example().catch((err) => console.log(`encountered error: ${err}`)) example().catch((err) => console.log(`encountered error: ${err}`))

View File

@@ -5,29 +5,10 @@ import {
WANode, WANode,
WAMetric, WAMetric,
WAFlag, WAFlag,
WAGroupCreateResponse,
WAGroupMetadata,
WAGroupModification,
MessageLogLevel, MessageLogLevel,
} from '../WAConnection/Constants' } from '../WAConnection/Constants'
import { generateMessageTag } from '../WAConnection/Utils'
export default class WhatsAppWebBase extends WAConnection { export default class WhatsAppWebBase extends WAConnection {
/** Set the callback for when the connection is taken over somewhere else or logged out */
setOnDisconnect(callback: (kind: 'replaced' | string | null) => void) {
this.registerCallback (['Cmd', 'type:disconnect'], json => {
this.log ('connection taken over elsewhere')
this.close ()
callback (json[1].kind)
})
}
/** Set the callback for unexpected disconnects */
setOnUnexpectedDisconnect(callback: (error: Error) => void) {
this.unexpectedDisconnect = (err) => {
this.close()
callback(err)
}
}
/** Set the callback for message status updates (when a message is delivered, read etc.) */ /** Set the callback for message status updates (when a message is delivered, read etc.) */
setOnMessageStatusChange(callback: (update: MessageStatusUpdate) => void) { setOnMessageStatusChange(callback: (update: MessageStatusUpdate) => void) {
const func = (json) => { const func = (json) => {

View File

@@ -51,7 +51,13 @@ export default class WAConnectionBase {
protected decoder = new Decoder() protected decoder = new Decoder()
/** What to do when you need the phone to authenticate the connection (generate QR code by default) */ /** What to do when you need the phone to authenticate the connection (generate QR code by default) */
onReadyForPhoneAuthentication = generateQRCode onReadyForPhoneAuthentication = generateQRCode
unexpectedDisconnect = (err) => this.close() unexpectedDisconnect = (err: string) => this.close()
/** Set the callback for unexpected disconnects including take over events, log out events etc. */
setOnUnexpectedDisconnect(callback: (error: string) => void) {
this.registerCallback (['Cmd', 'type:disconnect'], json => this.unexpectedDisconnect(json[1].kind))
this.unexpectedDisconnect = err => { this.close(); callback(err) }
}
/** /**
* base 64 encode the authentication credentials and return them * base 64 encode the authentication credentials and return them
* these can then be used to login again by passing the object to the connect () function. * these can then be used to login again by passing the object to the connect () function.

View File

@@ -39,18 +39,19 @@ export default class WAConnectionConnector extends WAConnectionValidator {
this.log('connected to WhatsApp Web, authenticating...') this.log('connected to WhatsApp Web, authenticating...')
// start sending keep alive requests (keeps the WebSocket alive & updates our last seen) // start sending keep alive requests (keeps the WebSocket alive & updates our last seen)
this.authenticate() this.authenticate()
.then((user) => { .then(user => {
this.startKeepAliveRequest() this.startKeepAliveRequest()
resolve(user)
}) this.conn.on ('error', null)
.catch(reject) this.conn.on ('close', () => this.unexpectedDisconnect ('closed'))
})
this.conn.on('message', (m) => this.onMessageRecieved(m)) // in WhatsAppWeb.Recv.js resolve(user)
this.conn.on('error', (error) => { })
// if there was an error in the WebSocket .catch(reject)
this.close()
reject(error)
}) })
this.conn.on('message', m => this.onMessageRecieved(m))
// if there was an error in the WebSocket
this.conn.on('error', error => { this.close(); reject(error) })
}) })
promise = Utils.promiseTimeout(timeoutMs, promise) promise = Utils.promiseTimeout(timeoutMs, promise)
return promise.catch(err => { return promise.catch(err => {

View File

@@ -53,9 +53,7 @@ export function randomBytes(length) {
} }
export const createTimeout = (timeout) => new Promise(resolve => setTimeout(resolve, timeout)) export const createTimeout = (timeout) => new Promise(resolve => setTimeout(resolve, timeout))
export function promiseTimeout<T>(ms: number, promise: Promise<T>) { export function promiseTimeout<T>(ms: number, promise: Promise<T>) {
if (!ms) { if (!ms) return promise
return promise
}
// Create a promise that rejects in <ms> milliseconds // Create a promise that rejects in <ms> milliseconds
const timeout = new Promise((_, reject) => { const timeout = new Promise((_, reject) => {
const id = setTimeout(() => { const id = setTimeout(() => {