Skip to content

Commit afc2927

Browse files
committed
feat(IsOnWhatsapp): add optional lid field and update related logic
- Introduced a new optional `lid` field in the IsOnWhatsapp model to enhance data tracking. - Updated migration script to add the `lid` column to the database. - Modified OnWhatsAppDto to include the `lid` property for better integration with WhatsApp user data. - Enhanced the WhatsApp Baileys service to handle `lid` numbers separately and improve user verification logic. - Updated cache handling functions to support the new `lid` field for consistent data management.
1 parent c17b48b commit afc2927

File tree

6 files changed

+139
-77
lines changed

6 files changed

+139
-77
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "IsOnWhatsapp" ADD COLUMN "lid" VARCHAR(100);

prisma/postgresql-schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ model IsOnWhatsapp {
648648
id String @id @default(cuid())
649649
remoteJid String @unique @db.VarChar(100)
650650
jidOptions String
651+
lid String? @db.VarChar(100)
651652
createdAt DateTime @default(now()) @db.Timestamp
652653
updatedAt DateTime @updatedAt @db.Timestamp
653654
}

src/api/dto/chat.dto.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class OnWhatsAppDto {
1313
public readonly exists: boolean,
1414
public readonly number: string,
1515
public readonly name?: string,
16+
public readonly lid?: string,
1617
) {}
1718
}
1819

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

Lines changed: 110 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,7 +1170,7 @@ export class BaileysStartupService extends ChannelStartupService {
11701170
) {
11711171
const chatwootSentMessage = await this.chatwootService.eventWhatsapp(
11721172
Events.MESSAGES_UPSERT,
1173-
{ instanceName: this.instance.name, instanceId: this.instance.id },
1173+
{ instanceName: this.instance.name, instanceId: this.instanceId },
11741174
messageRaw,
11751175
);
11761176

@@ -3131,10 +3131,10 @@ export class BaileysStartupService extends ChannelStartupService {
31313131
const group = await this.findGroup({ groupJid: jid }, 'inner');
31323132

31333133
if (!group) {
3134-
new OnWhatsAppDto(jid, false, number);
3134+
return new OnWhatsAppDto(jid, false, number);
31353135
}
31363136

3137-
return new OnWhatsAppDto(group.id, !!group?.id, number, group?.subject);
3137+
return new OnWhatsAppDto(group.id, true, number, group?.subject);
31383138
}),
31393139
);
31403140
onWhatsapp.push(...groups);
@@ -3144,83 +3144,125 @@ export class BaileysStartupService extends ChannelStartupService {
31443144
where: { instanceId: this.instanceId, remoteJid: { in: jids.users.map(({ jid }) => jid) } },
31453145
});
31463146

3147-
const numbersToVerify = jids.users.map(({ jid }) => jid.replace('+', ''));
3147+
// Separate @lid numbers from normal numbers
3148+
const lidUsers = jids.users.filter(({ jid }) => jid.includes('@lid'));
3149+
const normalUsers = jids.users.filter(({ jid }) => !jid.includes('@lid'));
31483150

3149-
const cachedNumbers = await getOnWhatsappCache(numbersToVerify);
3150-
const filteredNumbers = numbersToVerify.filter(
3151-
(jid) => !cachedNumbers.some((cached) => cached.jidOptions.includes(jid)),
3152-
);
3151+
// For normal numbers, use traditional Baileys verification
3152+
let normalVerifiedUsers: OnWhatsAppDto[] = [];
3153+
if (normalUsers.length > 0) {
3154+
console.log('normalUsers', normalUsers);
3155+
const numbersToVerify = normalUsers.map(({ jid }) => jid.replace('+', ''));
3156+
console.log('numbersToVerify', numbersToVerify);
31533157

3154-
const verify = await this.client.onWhatsApp(...filteredNumbers);
3155-
const users: OnWhatsAppDto[] = await Promise.all(
3156-
jids.users.map(async (user) => {
3157-
let numberVerified: (typeof verify)[0] | null = null;
3158+
const cachedNumbers = await getOnWhatsappCache(numbersToVerify);
3159+
console.log('cachedNumbers', cachedNumbers);
31583160

3159-
const cached = cachedNumbers.find((cached) => cached.jidOptions.includes(user.jid.replace('+', '')));
3160-
if (cached) {
3161-
return {
3162-
exists: true,
3163-
jid: cached.remoteJid,
3164-
name: contacts.find((c) => c.remoteJid === cached.remoteJid)?.pushName,
3165-
number: user.number,
3166-
};
3167-
}
3168-
3169-
// Brazilian numbers
3170-
if (user.number.startsWith('55')) {
3171-
const numberWithDigit =
3172-
user.number.slice(4, 5) === '9' && user.number.length === 13
3173-
? user.number
3174-
: `${user.number.slice(0, 4)}9${user.number.slice(4)}`;
3175-
const numberWithoutDigit =
3176-
user.number.length === 12 ? user.number : user.number.slice(0, 4) + user.number.slice(5);
3177-
3178-
numberVerified = verify.find(
3179-
(v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,
3180-
);
3181-
}
3182-
3183-
// Mexican/Argentina numbers
3184-
// Ref: https://faq.whatsapp.com/1294841057948784
3185-
if (!numberVerified && (user.number.startsWith('52') || user.number.startsWith('54'))) {
3186-
let prefix = '';
3187-
if (user.number.startsWith('52')) {
3188-
prefix = '';
3161+
const filteredNumbers = numbersToVerify.filter(
3162+
(jid) => !cachedNumbers.some((cached) => cached.jidOptions.includes(jid)),
3163+
);
3164+
console.log('filteredNumbers', filteredNumbers);
3165+
3166+
const verify = await this.client.onWhatsApp(...filteredNumbers);
3167+
console.log('verify', verify);
3168+
normalVerifiedUsers = await Promise.all(
3169+
normalUsers.map(async (user) => {
3170+
let numberVerified: (typeof verify)[0] | null = null;
3171+
3172+
const cached = cachedNumbers.find((cached) => cached.jidOptions.includes(user.jid.replace('+', '')));
3173+
if (cached) {
3174+
return new OnWhatsAppDto(
3175+
cached.remoteJid,
3176+
true,
3177+
user.number,
3178+
contacts.find((c) => c.remoteJid === cached.remoteJid)?.pushName,
3179+
cached.lid || (cached.remoteJid.includes('@lid') ? cached.remoteJid.split('@')[1] : undefined),
3180+
);
31893181
}
3190-
if (user.number.startsWith('54')) {
3191-
prefix = '9';
3182+
3183+
// Brazilian numbers
3184+
if (user.number.startsWith('55')) {
3185+
const numberWithDigit =
3186+
user.number.slice(4, 5) === '9' && user.number.length === 13
3187+
? user.number
3188+
: `${user.number.slice(0, 4)}9${user.number.slice(4)}`;
3189+
const numberWithoutDigit =
3190+
user.number.length === 12 ? user.number : user.number.slice(0, 4) + user.number.slice(5);
3191+
3192+
numberVerified = verify.find(
3193+
(v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,
3194+
);
31923195
}
31933196

3194-
const numberWithDigit =
3195-
user.number.slice(2, 3) === prefix && user.number.length === 13
3196-
? user.number
3197-
: `${user.number.slice(0, 2)}${prefix}${user.number.slice(2)}`;
3198-
const numberWithoutDigit =
3199-
user.number.length === 12 ? user.number : user.number.slice(0, 2) + user.number.slice(3);
3197+
// Mexican/Argentina numbers
3198+
// Ref: https://faq.whatsapp.com/1294841057948784
3199+
if (!numberVerified && (user.number.startsWith('52') || user.number.startsWith('54'))) {
3200+
let prefix = '';
3201+
if (user.number.startsWith('52')) {
3202+
prefix = '1';
3203+
}
3204+
if (user.number.startsWith('54')) {
3205+
prefix = '9';
3206+
}
32003207

3201-
numberVerified = verify.find(
3202-
(v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,
3203-
);
3204-
}
3208+
const numberWithDigit =
3209+
user.number.slice(2, 3) === prefix && user.number.length === 13
3210+
? user.number
3211+
: `${user.number.slice(0, 2)}${prefix}${user.number.slice(2)}`;
3212+
const numberWithoutDigit =
3213+
user.number.length === 12 ? user.number : user.number.slice(0, 2) + user.number.slice(3);
32053214

3206-
if (!numberVerified) {
3207-
numberVerified = verify.find((v) => v.jid === user.jid);
3208-
}
3215+
numberVerified = verify.find(
3216+
(v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,
3217+
);
3218+
}
32093219

3210-
const numberJid = numberVerified?.jid || user.jid;
3220+
if (!numberVerified) {
3221+
numberVerified = verify.find((v) => v.jid === user.jid);
3222+
}
32113223

3212-
return {
3213-
exists: !!numberVerified?.exists,
3214-
jid: numberJid,
3215-
name: contacts.find((c) => c.remoteJid === numberJid)?.pushName,
3216-
number: user.number,
3217-
};
3218-
}),
3219-
);
3224+
const numberJid = numberVerified?.jid || user.jid;
3225+
const lid =
3226+
typeof numberVerified?.lid === 'string'
3227+
? numberVerified.lid
3228+
: numberJid.includes('@lid')
3229+
? numberJid.split('@')[1]
3230+
: undefined;
3231+
return new OnWhatsAppDto(
3232+
numberJid,
3233+
!!numberVerified?.exists,
3234+
user.number,
3235+
contacts.find((c) => c.remoteJid === numberJid)?.pushName,
3236+
lid,
3237+
);
3238+
}),
3239+
);
3240+
}
32203241

3221-
await saveOnWhatsappCache(users.filter((user) => user.exists).map((user) => ({ remoteJid: user.jid })));
3242+
// For @lid numbers, always consider them as valid
3243+
const lidVerifiedUsers: OnWhatsAppDto[] = lidUsers.map((user) => {
3244+
return new OnWhatsAppDto(
3245+
user.jid,
3246+
true,
3247+
user.number,
3248+
contacts.find((c) => c.remoteJid === user.jid)?.pushName,
3249+
user.jid.split('@')[1],
3250+
);
3251+
});
32223252

3223-
onWhatsapp.push(...users);
3253+
// Combine results
3254+
onWhatsapp.push(...normalVerifiedUsers, ...lidVerifiedUsers);
3255+
3256+
// Save to cache only valid numbers
3257+
await saveOnWhatsappCache(
3258+
onWhatsapp
3259+
.filter((user) => user.exists)
3260+
.map((user) => ({
3261+
remoteJid: user.jid,
3262+
jidOptions: user.jid.replace('+', ''),
3263+
lid: user.lid,
3264+
})),
3265+
);
32243266

32253267
return onWhatsapp;
32263268
}

src/api/routes/chat.router.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,19 @@ export class ChatRouter extends RouterBroker {
4646
super();
4747
this.router
4848
.post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => {
49-
const response = await this.dataValidate<WhatsAppNumberDto>({
50-
request: req,
51-
schema: whatsappNumberSchema,
52-
ClassRef: WhatsAppNumberDto,
53-
execute: (instance, data) => chatController.whatsappNumber(instance, data),
54-
});
49+
try {
50+
const response = await this.dataValidate<WhatsAppNumberDto>({
51+
request: req,
52+
schema: whatsappNumberSchema,
53+
ClassRef: WhatsAppNumberDto,
54+
execute: (instance, data) => chatController.whatsappNumber(instance, data),
55+
});
5556

56-
return res.status(HttpStatus.OK).json(response);
57+
return res.status(HttpStatus.OK).json(response);
58+
} catch (error) {
59+
console.log(error);
60+
return res.status(HttpStatus.BAD_REQUEST).json(error);
61+
}
5762
})
5863
.post(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => {
5964
const response = await this.dataValidate<ReadMessageDto>({

src/utils/onWhatsappCache.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,25 @@ function getAvailableNumbers(remoteJid: string) {
5252

5353
interface ISaveOnWhatsappCacheParams {
5454
remoteJid: string;
55+
lid?: string;
5556
}
57+
5658
export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) {
5759
if (configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) {
5860
const upsertsQuery = data.map((item) => {
5961
const remoteJid = item.remoteJid.startsWith('+') ? item.remoteJid.slice(1) : item.remoteJid;
6062
const numbersAvailable = getAvailableNumbers(remoteJid);
6163

6264
return prismaRepository.isOnWhatsapp.upsert({
63-
create: { remoteJid: remoteJid, jidOptions: numbersAvailable.join(',') },
64-
update: { jidOptions: numbersAvailable.join(',') },
65+
create: {
66+
remoteJid: remoteJid,
67+
jidOptions: numbersAvailable.join(','),
68+
lid: item.lid,
69+
},
70+
update: {
71+
jidOptions: numbersAvailable.join(','),
72+
lid: item.lid,
73+
},
6574
where: { remoteJid: remoteJid },
6675
});
6776
});
@@ -75,6 +84,7 @@ export async function getOnWhatsappCache(remoteJids: string[]) {
7584
remoteJid: string;
7685
number: string;
7786
jidOptions: string[];
87+
lid?: string;
7888
}[] = [];
7989

8090
if (configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) {
@@ -93,6 +103,7 @@ export async function getOnWhatsappCache(remoteJids: string[]) {
93103
remoteJid: item.remoteJid,
94104
number: item.remoteJid.split('@')[0],
95105
jidOptions: item.jidOptions.split(','),
106+
lid: item.lid,
96107
}));
97108
}
98109

0 commit comments

Comments
 (0)