diff --git a/src/Tests/Tests.Connect.ts b/src/Tests/Tests.Connect.ts index 4bf83a4..7f69927 100644 --- a/src/Tests/Tests.Connect.ts +++ b/src/Tests/Tests.Connect.ts @@ -1,6 +1,6 @@ import * as assert from 'assert' import {WAConnection} from '../WAConnection/WAConnection' -import { AuthenticationCredentialsBase64, BaileysError, ReconnectMode, DisconnectReason, WAChat } from '../WAConnection/Constants' +import { AuthenticationCredentialsBase64, BaileysError, ReconnectMode, DisconnectReason, WAChat, WAContact } from '../WAConnection/Constants' import { delay } from '../WAConnection/Utils' import { assertChatDBIntegrity, makeConnection, testJid } from './Common' @@ -285,7 +285,7 @@ describe ('Reconnects', () => { }) describe ('Pending Requests', () => { - it ('should correctly send updates', async () => { + it ('should correctly send updates for chats', async () => { const conn = makeConnection () conn.pendingRequestTimeoutMs = null conn.loadAuthInfo('./auth_info.json') @@ -315,6 +315,42 @@ describe ('Pending Requests', () => { conn.close () }) + it ('should correctly send updates for contacts', async () => { + const conn = makeConnection () + conn.pendingRequestTimeoutMs = null + conn.loadAuthInfo('./auth_info.json') + + const task: any = new Promise(resolve => conn.once('contacts-received', resolve)) + await conn.connect () + const initialResult = await task + assert.strictEqual( + initialResult.updatedContacts.length, + Object.keys(conn.contacts).length + ) + + + conn.close () + + const [jid] = Object.keys(conn.contacts) + const oldContact = conn.contacts[jid] + oldContact.name = 'Lol' + oldContact.index = 'L' + + const promise = new Promise(resolve => conn.once('contacts-received', resolve)) + + const result = await conn.connect () + assert.ok (!result.newConnection) + + const {updatedContacts} = await promise as { updatedContacts: Partial[] } + const contact = updatedContacts.find (c => c.jid === jid) + assert.ok (contact) + + assert.ok ('name' in contact) + assert.strictEqual (Object.keys(contact).length, 3) + assert.strictEqual (Object.keys(updatedContacts).length, 1) + + conn.close () + }) it('should queue requests when closed', async () => { const conn = makeConnection () //conn.pendingRequestTimeoutMs = null diff --git a/src/Tests/Tests.Misc.ts b/src/Tests/Tests.Misc.ts index cbed89c..047f95d 100644 --- a/src/Tests/Tests.Misc.ts +++ b/src/Tests/Tests.Misc.ts @@ -203,7 +203,7 @@ WAConnectionTest('Misc', conn => { if (!chat) { // wait for chats await new Promise(resolve => ( - conn.once('chats-received', () => resolve()) + conn.once('chats-received', resolve) )) chat = conn.chats.get(testJid) } diff --git a/src/WAConnection/3.Connect.ts b/src/WAConnection/3.Connect.ts index 20b1ef3..ce36e2f 100644 --- a/src/WAConnection/3.Connect.ts +++ b/src/WAConnection/3.Connect.ts @@ -41,7 +41,7 @@ export class WAConnection extends Base { const willReconnect = !loggedOut && (tries < options?.maxRetries) && (this.state === 'connecting') const reason = loggedOut ? DisconnectReason.invalidSession : error.message - this.logger.warn ({ error }, `connect attempt ${tries} failed${ willReconnect ? ', retrying...' : ''}`) + this.logger.warn ({ error }, `connect attempt ${tries} failed: ${error}${ willReconnect ? ', retrying...' : ''}`) if ((this.state as string) !== 'close' && !willReconnect) { this.closeInternal (reason) diff --git a/src/WAConnection/4.Events.ts b/src/WAConnection/4.Events.ts index 574ecb9..2cb3591 100644 --- a/src/WAConnection/4.Events.ts +++ b/src/WAConnection/4.Events.ts @@ -141,13 +141,22 @@ export class WAConnection extends Base { // contacts received this.on('CB:response,type:contacts', json => { if (json[1].duplicate || !json[2]) return - const contacts: { [_: string]: WAContact } = {} + const contacts = this.contacts + const updatedContacts: WAContact[] = [] json[2].forEach(([type, contact]: ['user', WAContact]) => { if (!contact) return this.logger.info (`unexpectedly got null contact: ${type}`, contact) contact.jid = whatsappID (contact.jid) - contacts[contact.jid] = contact + const presentContact = contacts[contact.jid] + if (presentContact) { + const changes = shallowChanges(presentContact, contact) + if (changes && Object.keys(changes).length > 0) { + updatedContacts.push({ ...changes, jid: contact.jid }) + } + } else updatedContacts.push(contact) + + contacts[contact.jid] = { ...(presentContact || {}), ...contact } }) // update chat names const updatedChats = [] @@ -165,7 +174,7 @@ export class WAConnection extends Base { this.logger.info (`received ${json[2].length} contacts`) this.contacts = contacts - this.emit('contacts-received') + this.emit('contacts-received', { updatedContacts }) }) // new messages @@ -621,7 +630,7 @@ export class WAConnection extends Base { /** when a new chat is added */ on (event: 'chat-new', listener: (chat: WAChat) => void): this /** when contacts are sent by WA */ - on (event: 'contacts-received', listener: () => void): this + on (event: 'contacts-received', listener: (u: { updatedContacts: Partial[] }) => void): this /** when chats are sent by WA, and when all messages are received */ on (event: 'chats-received', listener: (update: {hasNewChats?: boolean, hasReceivedLastMessage?: boolean, chatsWithMissingMessages: { jid: string, count: number }[] }) => void): this /** when multiple chats are updated (new message, updated message, deleted, pinned, etc) */