Skip to content

Commit bfb044b

Browse files
committed
feat(whatsapp): enhance contact handling and configuration logic
- Added support for `lid` in WhatsApp numbers router to improve contact identification. - Updated the contact retrieval logic to accept an object with `phone_number` and `identifier` for better clarity and consistency. - Enhanced error handling and logging in the Chatwoot service for improved traceability during contact creation and updates. - Implemented automatic search for the latest WhatsApp version if the CONFIG_SESSION_PHONE_VERSION variable is not set, ensuring users have the most up-to-date integration.
1 parent ae99ec7 commit bfb044b

File tree

3 files changed

+97
-73
lines changed

3 files changed

+97
-73
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
* Ensure full WhatsApp compatibility for audio conversion (libopus, 48kHz, mono)
2323
* Enhance message fetching and processing logic
2424
* Fixed issue with @lid in chatwoot
25+
* Added lid on whatsapp numbers router
26+
* Now if the CONFIG_SESSION_PHONE_VERSION variable is not filled in it automatically searches for the most updated version
2527

2628
### Security
2729

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

830830
if (!findParticipant) {
831831
return;

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

Lines changed: 91 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,10 @@ export class ChatwootService {
226226

227227
this.logger.log('Creating chatwoot bot contact');
228228
const contact =
229-
(await this.findContact(instance, '123456')) ||
229+
(await this.findContact(instance, { phone_number: '123456', identifier: '123456' })) ||
230230
((await this.createContact(
231231
instance,
232-
'123456',
232+
{ phone_number: '123456', identifier: '123456' },
233233
inboxId,
234234
false,
235235
false,
@@ -289,59 +289,65 @@ export class ChatwootService {
289289

290290
public async createContact(
291291
instance: InstanceDto,
292-
phoneNumber: string,
292+
phoneNumber: { phone_number: string; identifier: string },
293293
inboxId: number,
294294
isGroup: boolean,
295295
isLid: boolean,
296296
name?: string,
297297
avatar_url?: string,
298298
jid?: string,
299299
) {
300-
const client = await this.clientCw(instance);
300+
try {
301+
const client = await this.clientCw(instance);
301302

302-
if (!client) {
303-
this.logger.warn('client not found');
304-
return null;
305-
}
303+
if (!client) {
304+
this.logger.warn('client not found');
305+
return null;
306+
}
306307

307-
let data: any = {};
308-
if (!isGroup && !isLid) {
309-
data = {
310-
inbox_id: inboxId,
311-
name: name || phoneNumber,
312-
identifier: jid,
313-
avatar_url: avatar_url,
314-
};
308+
let data: any = {};
309+
if (!isGroup && !isLid) {
310+
data = {
311+
inbox_id: inboxId,
312+
name: name || phoneNumber.phone_number,
313+
identifier: phoneNumber.identifier,
314+
avatar_url: avatar_url,
315+
};
315316

316-
if ((jid && jid.includes('@')) || !jid) {
317-
data['phone_number'] = `+${phoneNumber}`;
317+
if (jid && jid.endsWith('@s.whatsapp.net')) {
318+
data['phone_number'] = `+${phoneNumber.phone_number}`;
319+
}
320+
} else {
321+
data = {
322+
inbox_id: inboxId,
323+
name: name || phoneNumber.phone_number,
324+
identifier: phoneNumber.identifier,
325+
avatar_url: avatar_url,
326+
};
318327
}
319-
} else {
320-
data = {
321-
inbox_id: inboxId,
322-
name: name || phoneNumber,
323-
identifier: phoneNumber,
324-
avatar_url: avatar_url,
325-
};
326-
}
327328

328-
const contact = await client.contacts.create({
329-
accountId: this.provider.accountId,
330-
data,
331-
});
329+
const contact = await client.contacts.create({
330+
accountId: this.provider.accountId,
331+
data,
332+
});
332333

333-
if (!contact) {
334-
this.logger.warn('contact not found');
335-
return null;
336-
}
334+
if (!contact) {
335+
this.logger.warn('contact not found');
336+
return null;
337+
}
337338

338-
const findContact = await this.findContact(instance, phoneNumber);
339+
const findContact = await this.findContact(instance, phoneNumber);
339340

340-
const contactId = findContact?.id;
341+
const contactId = findContact?.id;
341342

342-
await this.addLabelToContact(this.provider.nameInbox, contactId);
343+
await this.addLabelToContact(this.provider.nameInbox, contactId);
343344

344-
return contact;
345+
return contact;
346+
} catch (error) {
347+
this.logger.error('Error creating contact');
348+
console.log(error);
349+
return null;
350+
}
345351
}
346352

347353
public async updateContact(instance: InstanceDto, id: number, data: any) {
@@ -407,7 +413,8 @@ export class ChatwootService {
407413
}
408414
}
409415

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

413420
if (!client) {
@@ -416,13 +423,13 @@ export class ChatwootService {
416423
}
417424

418425
let query: any;
419-
const isGroup = phoneNumber.includes('@g.us');
420-
const isLid = phoneNumber.includes('@lid');
426+
const isGroup = phoneNumber.identifier?.includes('@g.us');
427+
const isLid = phoneNumber.identifier?.includes('@lid');
421428

422429
if (!isGroup && !isLid) {
423-
query = `+${phoneNumber}`;
430+
query = `+${phoneNumber.phone_number}`;
424431
} else {
425-
query = phoneNumber;
432+
query = phoneNumber.identifier;
426433
}
427434

428435
let contact: any;
@@ -444,14 +451,13 @@ export class ChatwootService {
444451

445452
// Se não encontrou e não é @lid, tenta buscar pelo número limpo
446453
if ((!contact || contact?.payload?.length === 0) && !isLid) {
447-
const cleanNumber = `+${phoneNumber.replace('@lid', '')}`;
448-
this.logger.verbose(`Contact not found by identifier, trying clean number: ${cleanNumber}`);
454+
this.logger.verbose(`Contact not found by identifier, trying clean number: ${phoneNumber.phone_number}`);
449455

450456
contact = await chatwootRequest(this.getClientCwConfig(), {
451457
method: 'POST',
452458
url: `/api/v1/accounts/${this.provider.accountId}/contacts/filter`,
453459
body: {
454-
payload: this.getFilterPayload(cleanNumber),
460+
payload: this.getFilterPayload(phoneNumber.phone_number),
455461
},
456462
});
457463
}
@@ -561,20 +567,35 @@ export class ChatwootService {
561567

562568
private normalizeContactIdentifier(msg: any) {
563569
// Priority: senderLid > participantLid > remoteJid with @lid > normal number
564-
const lidIdentifier =
565-
msg.key.senderLid || msg.key.participantLid || (msg.key.remoteJid?.includes('@lid') ? msg.key.remoteJid : null);
570+
const normalizedContact = {
571+
phone_number: null,
572+
identifier: null,
573+
};
566574

567-
if (lidIdentifier) {
568-
return lidIdentifier;
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+
}
569582
}
570583

571-
// If it doesn't have @lid, return the normal number
572-
// Try to get the number from senderPn first, then participant, then remoteJid
573-
const getNumber = (value: string) => {
574-
return value?.includes('@s.whatsapp.net') ? value.split('@')[0] : value;
575-
};
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+
}
576597

577-
return getNumber(msg.key.senderPn) || getNumber(msg.key.participant) || getNumber(msg.key.remoteJid);
598+
return normalizedContact;
578599
}
579600

580601
public async createConversation(instance: InstanceDto, body: any) {
@@ -632,17 +653,17 @@ export class ChatwootService {
632653
const isLid = remoteJid.includes('@lid');
633654
this.logger.verbose('is group: ' + isGroup);
634655

635-
const chatId = this.normalizeContactIdentifier(body);
636-
this.logger.verbose('chat id: ' + chatId);
656+
const chat = this.normalizeContactIdentifier(body);
657+
this.logger.verbose('chat id: ' + chat.identifier);
637658

638659
const filterInbox = await this.getInbox(instance);
639660
if (!filterInbox) return null;
640661

641-
let nameContact = !body.key.fromMe ? body.pushName : chatId;
662+
let nameContact = !body.key.fromMe ? body.pushName : chat.phone_number;
642663

643664
if (isGroup || isLid) {
644665
this.logger.verbose(`Processing group conversation`);
645-
const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId);
666+
const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chat.identifier);
646667
this.logger.verbose(`Group metadata: ${JSON.stringify(group)}`);
647668

648669
nameContact = `${group.subject} (GROUP)`;
@@ -659,7 +680,7 @@ export class ChatwootService {
659680
this.logger.verbose(`Found participant: ${JSON.stringify(findParticipant)}`);
660681

661682
if (findParticipant) {
662-
if (!findParticipant.name || findParticipant.name === chatId) {
683+
if (!findParticipant.name || findParticipant.name === chat.phone_number) {
663684
await this.updateContact(instance, findParticipant.id, {
664685
name: body.pushName,
665686
avatar_url: picture_url.profilePictureUrl || null,
@@ -678,10 +699,10 @@ export class ChatwootService {
678699
}
679700
}
680701

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

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

686707
if (contact) {
687708
this.logger.verbose(`Found contact: ${JSON.stringify(contact)}`);
@@ -692,9 +713,9 @@ export class ChatwootService {
692713
const pictureNeedsUpdate = waProfilePictureFile !== chatwootProfilePictureFile;
693714
const nameNeedsUpdate =
694715
!contact.name ||
695-
contact.name === chatId ||
696-
(`+${chatId}`.startsWith('+55')
697-
? this.getNumbers(`+${chatId}`).some(
716+
contact.name === chat.phone_number ||
717+
(`+${chat.phone_number}`.startsWith('+55')
718+
? this.getNumbers(`+${chat.phone_number}`).some(
698719
(v) => contact.name === v || contact.name === v.substring(3) || contact.name === v.substring(1),
699720
)
700721
: false);
@@ -714,7 +735,7 @@ export class ChatwootService {
714735
const jid = body.key.remoteJid;
715736
contact = await this.createContact(
716737
instance,
717-
chatId,
738+
chat,
718739
filterInbox.id,
719740
isGroup,
720741
isLid,
@@ -801,6 +822,7 @@ export class ChatwootService {
801822
this.logger.verbose(`Block released for: ${lockKey}`);
802823
}
803824
} catch (error) {
825+
console.log(error);
804826
this.logger.error(`Error in createConversation: ${error}`);
805827
return null;
806828
}
@@ -930,7 +952,7 @@ export class ChatwootService {
930952
return null;
931953
}
932954

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

935957
if (!contact) {
936958
this.logger.warn('contact not found');
@@ -1060,7 +1082,7 @@ export class ChatwootService {
10601082
return true;
10611083
}
10621084

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

10651087
if (!contact) {
10661088
this.logger.warn('contact not found');

0 commit comments

Comments
 (0)