diff --git a/CHANGELOG.md b/CHANGELOG.md index f74648ee..ca2885d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,14 @@ ### Features * Route to send status broadcast +* Added verbose logs +* Insert allContacts in payload of endpoint sendStatus ### Fixed * Adjusted set in webhook to go empty when enabled false * Adjust in store files -* Added verbose logs +* Fixed the problem when do not save contacts when receive messages # 1.1.3 (2023-07-06 11:43) diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index e9a45679..9cf411e5 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -211,9 +211,10 @@ export const statusMessageSchema: JSONSchema7 = { description: '"statusJidList" must be an array of numeric strings', }, }, + allContacts: { type: 'boolean', enum: [true, false] }, }, - required: ['type', 'content', 'statusJidList'], - ...isNotEmpty('type', 'content', 'statusJidList'), + required: ['type', 'content'], + ...isNotEmpty('type', 'content'), }, }, required: ['statusMessage'], diff --git a/src/whatsapp/abstract/abstract.repository.ts b/src/whatsapp/abstract/abstract.repository.ts index 8e56148e..a7215383 100644 --- a/src/whatsapp/abstract/abstract.repository.ts +++ b/src/whatsapp/abstract/abstract.repository.ts @@ -7,6 +7,7 @@ export type IInsert = { insertCount: number }; export interface IRepository { insert(data: any, instanceName: string, saveDb?: boolean): Promise; + update(data: any, instanceName: string, saveDb?: boolean): Promise; find(query: any): Promise; delete(query: any, force?: boolean): Promise; @@ -48,6 +49,11 @@ export abstract class Repository implements IRepository { public insert(data: any, instanceName: string, saveDb = false): Promise { throw new Error('Method not implemented.'); } + + public update(data: any, instanceName: string, saveDb = false): Promise { + throw new Error('Method not implemented.'); + } + public find(query: any): Promise { throw new Error('Method not implemented.'); } diff --git a/src/whatsapp/dto/sendMessage.dto.ts b/src/whatsapp/dto/sendMessage.dto.ts index 61d4379c..4f1ff88b 100644 --- a/src/whatsapp/dto/sendMessage.dto.ts +++ b/src/whatsapp/dto/sendMessage.dto.ts @@ -35,7 +35,8 @@ class linkPreviewMessage { export class StatusMessage { type: string; content: string; - statusJidList: string[]; + statusJidList?: string[]; + allContacts?: boolean; caption?: string; backgroundColor?: string; font?: number; diff --git a/src/whatsapp/repository/contact.repository.ts b/src/whatsapp/repository/contact.repository.ts index 59d8947f..67c51dff 100644 --- a/src/whatsapp/repository/contact.repository.ts +++ b/src/whatsapp/repository/contact.repository.ts @@ -53,6 +53,40 @@ export class ContactRepository extends Repository { } } + public async update( + data: ContactRaw, + instanceName: string, + saveDb = false, + ): Promise { + try { + if (this.dbSettings.ENABLED && saveDb) { + const contact = await this.contactModel.findOneAndUpdate( + { id: data.id }, + { ...data }, + ); + return { insertCount: contact ? 1 : 0 }; + } + + const store = this.configService.get('STORE'); + + if (store.CONTACTS) { + this.writeStore({ + path: join(this.storePath, 'contacts', instanceName), + fileName: data.id, + data, + }); + + return { insertCount: 1 }; + } + + return { insertCount: 0 }; + } catch (error) { + return error; + } finally { + data = undefined; + } + } + public async find(query: ContactQuery): Promise { try { if (this.dbSettings.ENABLED) { diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index c90b0b54..94efbc91 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -770,7 +770,7 @@ export class WAStartupService { ); }, - 'contacts.update': async (contacts: Partial[]) => { + 'contacts.update': async (contacts: Partial[], database: Database) => { this.logger.verbose('Event received: contacts.update'); this.logger.verbose('Verifying if contacts exists in database to update'); @@ -782,6 +782,18 @@ export class WAStartupService { profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, owner: this.instance.wuid, }); + + this.logger.verbose('Updating contacts in database'); + await this.repository.contact.update( + { + id: contact.id, + pushName: contact?.name ?? contact?.verifiedName, + profilePictureUrl: (await this.profilePicture(contact.id)).profilePictureUrl, + owner: this.instance.wuid, + }, + this.instance.name, + database.SAVE_DATA.CONTACTS, + ); } this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); @@ -909,6 +921,52 @@ export class WAStartupService { this.instance.name, database.SAVE_DATA.NEW_MESSAGE, ); + + this.logger.verbose('Verifying contact from message'); + const contact = await this.repository.contact.find({ + where: { owner: this.instance.wuid, id: received.key.remoteJid }, + }); + + if (contact?.length) { + this.logger.verbose('Contact found in database'); + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: contact[0].pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) + .profilePictureUrl, + owner: this.instance.wuid, + }; + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE'); + await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactRaw); + + this.logger.verbose('Updating contact in database'); + await this.repository.contact.update( + contactRaw, + this.instance.name, + database.SAVE_DATA.CONTACTS, + ); + return; + } + + this.logger.verbose('Contact not found in database'); + const contactRaw: ContactRaw = { + id: received.key.remoteJid, + pushName: received.pushName, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) + .profilePictureUrl, + owner: this.instance.wuid, + }; + + this.logger.verbose('Sending data to webhook in event CONTACTS_UPSERT'); + await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); + + this.logger.verbose('Inserting contact in database'); + await this.repository.contact.insert( + [contactRaw], + this.instance.name, + database.SAVE_DATA.CONTACTS, + ); }, 'messages.update': async (args: WAMessageUpdate[], database: Database) => { @@ -1072,7 +1130,7 @@ export class WAStartupService { if (events['contacts.update']) { this.logger.verbose('Listening event: contacts.update'); const payload = events['contacts.update']; - this.contactHandle['contacts.update'](payload); + this.contactHandle['contacts.update'](payload, database); } } }); @@ -1386,12 +1444,22 @@ export class WAStartupService { throw new BadRequestException('Content is required'); } - if ( - !status.statusJidList || - !Array.isArray(status.statusJidList) || - !status.statusJidList.length - ) { - throw new BadRequestException('Status jid list is required'); + if (status.allContacts) { + const contacts = await this.repository.contact.find({ + where: { owner: this.instance.wuid }, + }); + + if (!contacts.length) { + throw new BadRequestException('Contacts not found'); + } + + status.statusJidList = contacts + .filter((contact) => contact.pushName) + .map((contact) => contact.id); + } + + if (!status.statusJidList?.length && !status.allContacts) { + throw new BadRequestException('StatusJidList is required'); } if (status.type === 'text') {