Skip to content

Commit 1afa8df

Browse files
committed
refactor(chatwoot): simplify findContact method and update contact creation logic
1 parent bfb044b commit 1afa8df

File tree

2 files changed

+63
-105
lines changed

2 files changed

+63
-105
lines changed

src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -822,10 +822,10 @@ export class BaileysStartupService extends ChannelStartupService {
822822
if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled) {
823823
const instance = { instanceName: this.instance.name, instanceId: this.instance.id };
824824

825-
const findParticipant = await this.chatwootService.findContact(instance, {
826-
identifier: contact.remoteJid,
827-
phone_number: contact.remoteJid.split('@')[0],
828-
});
825+
const findParticipant = await this.chatwootService.findContact(
826+
instance,
827+
contact.remoteJid.split('@')[0],
828+
);
829829

830830
if (!findParticipant) {
831831
return;

src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts

Lines changed: 59 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,12 @@ export class ChatwootService {
226226

227227
this.logger.log('Creating chatwoot bot contact');
228228
const contact =
229-
(await this.findContact(instance, { phone_number: '123456', identifier: '123456' })) ||
229+
(await this.findContact(instance, '123456')) ||
230230
((await this.createContact(
231231
instance,
232-
{ phone_number: '123456', identifier: '123456' },
232+
'123456',
233233
inboxId,
234234
false,
235-
false,
236235
organization ? organization : 'EvolutionAPI',
237236
logo ? logo : 'https://evolution-api.com/files/evolution-api-favicon.png',
238237
)) as any);
@@ -289,10 +288,9 @@ export class ChatwootService {
289288

290289
public async createContact(
291290
instance: InstanceDto,
292-
phoneNumber: { phone_number: string; identifier: string },
291+
phoneNumber: string,
293292
inboxId: number,
294293
isGroup: boolean,
295-
isLid: boolean,
296294
name?: string,
297295
avatar_url?: string,
298296
jid?: string,
@@ -306,22 +304,22 @@ export class ChatwootService {
306304
}
307305

308306
let data: any = {};
309-
if (!isGroup && !isLid) {
307+
if (!isGroup) {
310308
data = {
311309
inbox_id: inboxId,
312-
name: name || phoneNumber.phone_number,
313-
identifier: phoneNumber.identifier,
310+
name: name || phoneNumber,
311+
identifier: jid,
314312
avatar_url: avatar_url,
315313
};
316314

317-
if (jid && jid.endsWith('@s.whatsapp.net')) {
318-
data['phone_number'] = `+${phoneNumber.phone_number}`;
315+
if ((jid && jid.includes('@')) || !jid) {
316+
data['phone_number'] = `+${phoneNumber}`;
319317
}
320318
} else {
321319
data = {
322320
inbox_id: inboxId,
323-
name: name || phoneNumber.phone_number,
324-
identifier: phoneNumber.identifier,
321+
name: name || phoneNumber,
322+
identifier: phoneNumber,
325323
avatar_url: avatar_url,
326324
};
327325
}
@@ -413,8 +411,7 @@ export class ChatwootService {
413411
}
414412
}
415413

416-
public async findContact(instance: InstanceDto, phoneNumber: { phone_number?: string; identifier: string }) {
417-
console.log('findContact phoneNumber', phoneNumber);
414+
public async findContact(instance: InstanceDto, phoneNumber: string) {
418415
const client = await this.clientCw(instance);
419416

420417
if (!client) {
@@ -423,18 +420,17 @@ export class ChatwootService {
423420
}
424421

425422
let query: any;
426-
const isGroup = phoneNumber.identifier?.includes('@g.us');
427-
const isLid = phoneNumber.identifier?.includes('@lid');
423+
const isGroup = phoneNumber.includes('@g.us');
428424

429-
if (!isGroup && !isLid) {
430-
query = `+${phoneNumber.phone_number}`;
425+
if (!isGroup) {
426+
query = `+${phoneNumber}`;
431427
} else {
432-
query = phoneNumber.identifier;
428+
query = phoneNumber;
433429
}
434430

435431
let contact: any;
436432

437-
if (isGroup || isLid) {
433+
if (isGroup) {
438434
contact = await client.contacts.search({
439435
accountId: this.provider.accountId,
440436
q: query,
@@ -449,25 +445,12 @@ export class ChatwootService {
449445
});
450446
}
451447

452-
// Se não encontrou e não é @lid, tenta buscar pelo número limpo
453-
if ((!contact || contact?.payload?.length === 0) && !isLid) {
454-
this.logger.verbose(`Contact not found by identifier, trying clean number: ${phoneNumber.phone_number}`);
455-
456-
contact = await chatwootRequest(this.getClientCwConfig(), {
457-
method: 'POST',
458-
url: `/api/v1/accounts/${this.provider.accountId}/contacts/filter`,
459-
body: {
460-
payload: this.getFilterPayload(phoneNumber.phone_number),
461-
},
462-
});
463-
}
464-
465-
if (!contact || contact?.payload?.length === 0) {
448+
if (!contact && contact?.payload?.length === 0) {
466449
this.logger.warn('contact not found');
467450
return null;
468451
}
469452

470-
if (!isGroup && !isLid) {
453+
if (!isGroup) {
471454
return contact.payload.length > 1 ? this.findContactInContactList(contact.payload, query) : contact.payload[0];
472455
} else {
473456
return contact.payload.find((contact) => contact.identifier === query);
@@ -565,46 +548,27 @@ export class ChatwootService {
565548
return filterPayload;
566549
}
567550

568-
private normalizeContactIdentifier(msg: any) {
569-
// Priority: senderLid > participantLid > remoteJid with @lid > normal number
570-
const normalizedContact = {
571-
phone_number: null,
572-
identifier: null,
573-
};
574-
575-
if (msg.key.remoteJid?.includes('@lid')) {
576-
if (msg.key.SenderPn && msg.key.SenderPn?.includes('@s.whatsapp.net')) {
577-
normalizedContact.phone_number = msg.key.SenderPn.split('@')[0];
578-
normalizedContact.identifier = msg.key.SenderPn;
579-
} else {
580-
normalizedContact.identifier = msg.key.remoteJid;
581-
}
582-
}
583-
584-
if (msg.key.remoteJid && msg.key.remoteJid?.includes('@s.whatsapp.net')) {
585-
normalizedContact.phone_number = msg.key.remoteJid.split('@')[0];
586-
normalizedContact.identifier = msg.key.remoteJid;
587-
}
588-
589-
if (msg.key.remoteJid && msg.key.remoteJid?.includes('@g.us')) {
590-
normalizedContact.identifier = msg.key.remoteJid;
591-
}
592-
593-
if (msg.key.participant && msg.key.participant?.includes('@s.whatsapp.net')) {
594-
normalizedContact.phone_number = msg.key.participant.split('@')[0];
595-
normalizedContact.identifier = msg.key.participant;
596-
}
597-
598-
return normalizedContact;
599-
}
600-
601551
public async createConversation(instance: InstanceDto, body: any) {
602-
const remoteJid = body.key.remoteJid;
552+
const isLid = body.key.remoteJid.includes('@lid') && body.key.senderPn;
553+
const remoteJid = isLid ? body.key.senderPn : body.key.remoteJid;
603554
const cacheKey = `${instance.instanceName}:createConversation-${remoteJid}`;
604555
const lockKey = `${instance.instanceName}:lock:createConversation-${remoteJid}`;
605556
const maxWaitTime = 5000; // 5 secounds
606557

607558
try {
559+
// Processa atualização de contatos já criados @lid
560+
if (body.key.remoteJid.includes('@lid') && body.key.senderPn && body.key.senderPn !== body.key.remoteJid) {
561+
const contact = await this.findContact(instance, body.key.remoteJid.split('@')[0]);
562+
if (contact && contact.identifier !== body.key.senderPn) {
563+
this.logger.verbose(
564+
`Identifier needs update: (contact.identifier: ${contact.identifier}, body.key.remoteJid: ${body.key.remoteJid}, body.key.senderPn: ${body.key.senderPn})`,
565+
);
566+
await this.updateContact(instance, contact.id, {
567+
identifier: body.key.senderPn,
568+
phone_number: `+${body.key.senderPn.split('@')[0]}`,
569+
});
570+
}
571+
}
608572
this.logger.verbose(`--- Start createConversation ---`);
609573
this.logger.verbose(`Instance: ${JSON.stringify(instance)}`);
610574

@@ -650,20 +614,14 @@ export class ChatwootService {
650614
if (!client) return null;
651615

652616
const isGroup = remoteJid.includes('@g.us');
653-
const isLid = remoteJid.includes('@lid');
654-
this.logger.verbose('is group: ' + isGroup);
655-
656-
const chat = this.normalizeContactIdentifier(body);
657-
this.logger.verbose('chat id: ' + chat.identifier);
658-
617+
const chatId = isGroup ? remoteJid : remoteJid.split('@')[0];
618+
let nameContact = !body.key.fromMe ? body.pushName : chatId;
659619
const filterInbox = await this.getInbox(instance);
660620
if (!filterInbox) return null;
661621

662-
let nameContact = !body.key.fromMe ? body.pushName : chat.phone_number;
663-
664-
if (isGroup || isLid) {
622+
if (isGroup) {
665623
this.logger.verbose(`Processing group conversation`);
666-
const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chat.identifier);
624+
const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId);
667625
this.logger.verbose(`Group metadata: ${JSON.stringify(group)}`);
668626

669627
nameContact = `${group.subject} (GROUP)`;
@@ -673,14 +631,11 @@ export class ChatwootService {
673631
);
674632
this.logger.verbose(`Participant profile picture URL: ${JSON.stringify(picture_url)}`);
675633

676-
const participantIdentifier = this.normalizeContactIdentifier(body);
677-
this.logger.verbose(`Normalized participant identifier: ${participantIdentifier}`);
678-
679-
const findParticipant = await this.findContact(instance, participantIdentifier);
634+
const findParticipant = await this.findContact(instance, body.key.participant.split('@')[0]);
680635
this.logger.verbose(`Found participant: ${JSON.stringify(findParticipant)}`);
681636

682637
if (findParticipant) {
683-
if (!findParticipant.name || findParticipant.name === chat.phone_number) {
638+
if (!findParticipant.name || findParticipant.name === chatId) {
684639
await this.updateContact(instance, findParticipant.id, {
685640
name: body.pushName,
686641
avatar_url: picture_url.profilePictureUrl || null,
@@ -689,20 +644,20 @@ export class ChatwootService {
689644
} else {
690645
await this.createContact(
691646
instance,
692-
participantIdentifier,
647+
body.key.participant.split('@')[0],
693648
filterInbox.id,
694-
false,
649+
isGroup,
695650
body.pushName,
696651
picture_url.profilePictureUrl || null,
697652
body.key.participant,
698653
);
699654
}
700655
}
701656

702-
const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chat.identifier);
657+
const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId);
703658
this.logger.verbose(`Contact profile picture URL: ${JSON.stringify(picture_url)}`);
704659

705-
let contact = await this.findContact(instance, chat);
660+
let contact = await this.findContact(instance, chatId);
706661

707662
if (contact) {
708663
this.logger.verbose(`Found contact: ${JSON.stringify(contact)}`);
@@ -713,16 +668,14 @@ export class ChatwootService {
713668
const pictureNeedsUpdate = waProfilePictureFile !== chatwootProfilePictureFile;
714669
const nameNeedsUpdate =
715670
!contact.name ||
716-
contact.name === chat.phone_number ||
717-
(`+${chat.phone_number}`.startsWith('+55')
718-
? this.getNumbers(`+${chat.phone_number}`).some(
671+
contact.name === chatId ||
672+
(`+${chatId}`.startsWith('+55')
673+
? this.getNumbers(`+${chatId}`).some(
719674
(v) => contact.name === v || contact.name === v.substring(3) || contact.name === v.substring(1),
720675
)
721676
: false);
722-
723677
this.logger.verbose(`Picture needs update: ${pictureNeedsUpdate}`);
724678
this.logger.verbose(`Name needs update: ${nameNeedsUpdate}`);
725-
726679
if (pictureNeedsUpdate || nameNeedsUpdate) {
727680
contact = await this.updateContact(instance, contact.id, {
728681
...(nameNeedsUpdate && { name: nameContact }),
@@ -732,13 +685,12 @@ export class ChatwootService {
732685
}
733686
}
734687
} else {
735-
const jid = body.key.remoteJid;
688+
const jid = isLid && body?.key?.senderPn ? body.key.senderPn : body.key.remoteJid;
736689
contact = await this.createContact(
737690
instance,
738-
chat,
691+
chatId,
739692
filterInbox.id,
740693
isGroup,
741-
isLid,
742694
nameContact,
743695
picture_url.profilePictureUrl || null,
744696
jid,
@@ -770,7 +722,6 @@ export class ChatwootService {
770722
if (inboxConversation) {
771723
if (this.provider.reopenConversation) {
772724
this.logger.verbose(`Found conversation in reopenConversation mode: ${JSON.stringify(inboxConversation)}`);
773-
774725
if (inboxConversation && this.provider.conversationPending && inboxConversation.status !== 'open') {
775726
await client.conversations.toggleStatus({
776727
accountId: this.provider.accountId,
@@ -804,6 +755,14 @@ export class ChatwootService {
804755
data['status'] = 'pending';
805756
}
806757

758+
/*
759+
Triple check after lock
760+
Utilizei uma nova verificação para evitar que outra thread execute entre o terminio do while e o set lock
761+
*/
762+
if (await this.cache.has(cacheKey)) {
763+
return (await this.cache.get(cacheKey)) as number;
764+
}
765+
807766
const conversation = await client.conversations.create({
808767
accountId: this.provider.accountId,
809768
data,
@@ -814,15 +773,14 @@ export class ChatwootService {
814773
return null;
815774
}
816775

817-
this.logger.verbose(`New conversation created with ID: ${conversation.id}`);
776+
this.logger.verbose(`New conversation created of ${remoteJid} with ID: ${conversation.id}`);
818777
this.cache.set(cacheKey, conversation.id);
819778
return conversation.id;
820779
} finally {
821780
await this.cache.delete(lockKey);
822781
this.logger.verbose(`Block released for: ${lockKey}`);
823782
}
824783
} catch (error) {
825-
console.log(error);
826784
this.logger.error(`Error in createConversation: ${error}`);
827785
return null;
828786
}
@@ -952,7 +910,7 @@ export class ChatwootService {
952910
return null;
953911
}
954912

955-
const contact = await this.findContact(instance, { phone_number: '123456', identifier: '123456' });
913+
const contact = await this.findContact(instance, '123456');
956914

957915
if (!contact) {
958916
this.logger.warn('contact not found');
@@ -1082,7 +1040,7 @@ export class ChatwootService {
10821040
return true;
10831041
}
10841042

1085-
const contact = await this.findContact(instance, { phone_number: '123456', identifier: '123456' });
1043+
const contact = await this.findContact(instance, '123456');
10861044

10871045
if (!contact) {
10881046
this.logger.warn('contact not found');

0 commit comments

Comments
 (0)