mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-13 07:04:50 -06:00
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.
This commit is contained in:
parent
c17b48bca0
commit
afc2927837
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "IsOnWhatsapp" ADD COLUMN "lid" VARCHAR(100);
|
@ -648,6 +648,7 @@ model IsOnWhatsapp {
|
|||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
remoteJid String @unique @db.VarChar(100)
|
remoteJid String @unique @db.VarChar(100)
|
||||||
jidOptions String
|
jidOptions String
|
||||||
|
lid String? @db.VarChar(100)
|
||||||
createdAt DateTime @default(now()) @db.Timestamp
|
createdAt DateTime @default(now()) @db.Timestamp
|
||||||
updatedAt DateTime @updatedAt @db.Timestamp
|
updatedAt DateTime @updatedAt @db.Timestamp
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ export class OnWhatsAppDto {
|
|||||||
public readonly exists: boolean,
|
public readonly exists: boolean,
|
||||||
public readonly number: string,
|
public readonly number: string,
|
||||||
public readonly name?: string,
|
public readonly name?: string,
|
||||||
|
public readonly lid?: string,
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,7 +1170,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
) {
|
) {
|
||||||
const chatwootSentMessage = await this.chatwootService.eventWhatsapp(
|
const chatwootSentMessage = await this.chatwootService.eventWhatsapp(
|
||||||
Events.MESSAGES_UPSERT,
|
Events.MESSAGES_UPSERT,
|
||||||
{ instanceName: this.instance.name, instanceId: this.instance.id },
|
{ instanceName: this.instance.name, instanceId: this.instanceId },
|
||||||
messageRaw,
|
messageRaw,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -3131,10 +3131,10 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
const group = await this.findGroup({ groupJid: jid }, 'inner');
|
const group = await this.findGroup({ groupJid: jid }, 'inner');
|
||||||
|
|
||||||
if (!group) {
|
if (!group) {
|
||||||
new OnWhatsAppDto(jid, false, number);
|
return new OnWhatsAppDto(jid, false, number);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new OnWhatsAppDto(group.id, !!group?.id, number, group?.subject);
|
return new OnWhatsAppDto(group.id, true, number, group?.subject);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
onWhatsapp.push(...groups);
|
onWhatsapp.push(...groups);
|
||||||
@ -3144,84 +3144,126 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
where: { instanceId: this.instanceId, remoteJid: { in: jids.users.map(({ jid }) => jid) } },
|
where: { instanceId: this.instanceId, remoteJid: { in: jids.users.map(({ jid }) => jid) } },
|
||||||
});
|
});
|
||||||
|
|
||||||
const numbersToVerify = jids.users.map(({ jid }) => jid.replace('+', ''));
|
// Separate @lid numbers from normal numbers
|
||||||
|
const lidUsers = jids.users.filter(({ jid }) => jid.includes('@lid'));
|
||||||
|
const normalUsers = jids.users.filter(({ jid }) => !jid.includes('@lid'));
|
||||||
|
|
||||||
const cachedNumbers = await getOnWhatsappCache(numbersToVerify);
|
// For normal numbers, use traditional Baileys verification
|
||||||
const filteredNumbers = numbersToVerify.filter(
|
let normalVerifiedUsers: OnWhatsAppDto[] = [];
|
||||||
(jid) => !cachedNumbers.some((cached) => cached.jidOptions.includes(jid)),
|
if (normalUsers.length > 0) {
|
||||||
);
|
console.log('normalUsers', normalUsers);
|
||||||
|
const numbersToVerify = normalUsers.map(({ jid }) => jid.replace('+', ''));
|
||||||
|
console.log('numbersToVerify', numbersToVerify);
|
||||||
|
|
||||||
const verify = await this.client.onWhatsApp(...filteredNumbers);
|
const cachedNumbers = await getOnWhatsappCache(numbersToVerify);
|
||||||
const users: OnWhatsAppDto[] = await Promise.all(
|
console.log('cachedNumbers', cachedNumbers);
|
||||||
jids.users.map(async (user) => {
|
|
||||||
let numberVerified: (typeof verify)[0] | null = null;
|
|
||||||
|
|
||||||
const cached = cachedNumbers.find((cached) => cached.jidOptions.includes(user.jid.replace('+', '')));
|
const filteredNumbers = numbersToVerify.filter(
|
||||||
if (cached) {
|
(jid) => !cachedNumbers.some((cached) => cached.jidOptions.includes(jid)),
|
||||||
return {
|
);
|
||||||
exists: true,
|
console.log('filteredNumbers', filteredNumbers);
|
||||||
jid: cached.remoteJid,
|
|
||||||
name: contacts.find((c) => c.remoteJid === cached.remoteJid)?.pushName,
|
|
||||||
number: user.number,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Brazilian numbers
|
const verify = await this.client.onWhatsApp(...filteredNumbers);
|
||||||
if (user.number.startsWith('55')) {
|
console.log('verify', verify);
|
||||||
const numberWithDigit =
|
normalVerifiedUsers = await Promise.all(
|
||||||
user.number.slice(4, 5) === '9' && user.number.length === 13
|
normalUsers.map(async (user) => {
|
||||||
? user.number
|
let numberVerified: (typeof verify)[0] | null = null;
|
||||||
: `${user.number.slice(0, 4)}9${user.number.slice(4)}`;
|
|
||||||
const numberWithoutDigit =
|
|
||||||
user.number.length === 12 ? user.number : user.number.slice(0, 4) + user.number.slice(5);
|
|
||||||
|
|
||||||
numberVerified = verify.find(
|
const cached = cachedNumbers.find((cached) => cached.jidOptions.includes(user.jid.replace('+', '')));
|
||||||
(v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,
|
if (cached) {
|
||||||
);
|
return new OnWhatsAppDto(
|
||||||
}
|
cached.remoteJid,
|
||||||
|
true,
|
||||||
// Mexican/Argentina numbers
|
user.number,
|
||||||
// Ref: https://faq.whatsapp.com/1294841057948784
|
contacts.find((c) => c.remoteJid === cached.remoteJid)?.pushName,
|
||||||
if (!numberVerified && (user.number.startsWith('52') || user.number.startsWith('54'))) {
|
cached.lid || (cached.remoteJid.includes('@lid') ? cached.remoteJid.split('@')[1] : undefined),
|
||||||
let prefix = '';
|
);
|
||||||
if (user.number.startsWith('52')) {
|
|
||||||
prefix = '';
|
|
||||||
}
|
|
||||||
if (user.number.startsWith('54')) {
|
|
||||||
prefix = '9';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const numberWithDigit =
|
// Brazilian numbers
|
||||||
user.number.slice(2, 3) === prefix && user.number.length === 13
|
if (user.number.startsWith('55')) {
|
||||||
? user.number
|
const numberWithDigit =
|
||||||
: `${user.number.slice(0, 2)}${prefix}${user.number.slice(2)}`;
|
user.number.slice(4, 5) === '9' && user.number.length === 13
|
||||||
const numberWithoutDigit =
|
? user.number
|
||||||
user.number.length === 12 ? user.number : user.number.slice(0, 2) + user.number.slice(3);
|
: `${user.number.slice(0, 4)}9${user.number.slice(4)}`;
|
||||||
|
const numberWithoutDigit =
|
||||||
|
user.number.length === 12 ? user.number : user.number.slice(0, 4) + user.number.slice(5);
|
||||||
|
|
||||||
numberVerified = verify.find(
|
numberVerified = verify.find(
|
||||||
(v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,
|
(v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mexican/Argentina numbers
|
||||||
|
// Ref: https://faq.whatsapp.com/1294841057948784
|
||||||
|
if (!numberVerified && (user.number.startsWith('52') || user.number.startsWith('54'))) {
|
||||||
|
let prefix = '';
|
||||||
|
if (user.number.startsWith('52')) {
|
||||||
|
prefix = '1';
|
||||||
|
}
|
||||||
|
if (user.number.startsWith('54')) {
|
||||||
|
prefix = '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
const numberWithDigit =
|
||||||
|
user.number.slice(2, 3) === prefix && user.number.length === 13
|
||||||
|
? user.number
|
||||||
|
: `${user.number.slice(0, 2)}${prefix}${user.number.slice(2)}`;
|
||||||
|
const numberWithoutDigit =
|
||||||
|
user.number.length === 12 ? user.number : user.number.slice(0, 2) + user.number.slice(3);
|
||||||
|
|
||||||
|
numberVerified = verify.find(
|
||||||
|
(v) => v.jid === `${numberWithDigit}@s.whatsapp.net` || v.jid === `${numberWithoutDigit}@s.whatsapp.net`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!numberVerified) {
|
||||||
|
numberVerified = verify.find((v) => v.jid === user.jid);
|
||||||
|
}
|
||||||
|
|
||||||
|
const numberJid = numberVerified?.jid || user.jid;
|
||||||
|
const lid =
|
||||||
|
typeof numberVerified?.lid === 'string'
|
||||||
|
? numberVerified.lid
|
||||||
|
: numberJid.includes('@lid')
|
||||||
|
? numberJid.split('@')[1]
|
||||||
|
: undefined;
|
||||||
|
return new OnWhatsAppDto(
|
||||||
|
numberJid,
|
||||||
|
!!numberVerified?.exists,
|
||||||
|
user.number,
|
||||||
|
contacts.find((c) => c.remoteJid === numberJid)?.pushName,
|
||||||
|
lid,
|
||||||
);
|
);
|
||||||
}
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!numberVerified) {
|
// For @lid numbers, always consider them as valid
|
||||||
numberVerified = verify.find((v) => v.jid === user.jid);
|
const lidVerifiedUsers: OnWhatsAppDto[] = lidUsers.map((user) => {
|
||||||
}
|
return new OnWhatsAppDto(
|
||||||
|
user.jid,
|
||||||
|
true,
|
||||||
|
user.number,
|
||||||
|
contacts.find((c) => c.remoteJid === user.jid)?.pushName,
|
||||||
|
user.jid.split('@')[1],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const numberJid = numberVerified?.jid || user.jid;
|
// Combine results
|
||||||
|
onWhatsapp.push(...normalVerifiedUsers, ...lidVerifiedUsers);
|
||||||
|
|
||||||
return {
|
// Save to cache only valid numbers
|
||||||
exists: !!numberVerified?.exists,
|
await saveOnWhatsappCache(
|
||||||
jid: numberJid,
|
onWhatsapp
|
||||||
name: contacts.find((c) => c.remoteJid === numberJid)?.pushName,
|
.filter((user) => user.exists)
|
||||||
number: user.number,
|
.map((user) => ({
|
||||||
};
|
remoteJid: user.jid,
|
||||||
}),
|
jidOptions: user.jid.replace('+', ''),
|
||||||
|
lid: user.lid,
|
||||||
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
await saveOnWhatsappCache(users.filter((user) => user.exists).map((user) => ({ remoteJid: user.jid })));
|
|
||||||
|
|
||||||
onWhatsapp.push(...users);
|
|
||||||
|
|
||||||
return onWhatsapp;
|
return onWhatsapp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,14 +46,19 @@ export class ChatRouter extends RouterBroker {
|
|||||||
super();
|
super();
|
||||||
this.router
|
this.router
|
||||||
.post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => {
|
.post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => {
|
||||||
const response = await this.dataValidate<WhatsAppNumberDto>({
|
try {
|
||||||
request: req,
|
const response = await this.dataValidate<WhatsAppNumberDto>({
|
||||||
schema: whatsappNumberSchema,
|
request: req,
|
||||||
ClassRef: WhatsAppNumberDto,
|
schema: whatsappNumberSchema,
|
||||||
execute: (instance, data) => chatController.whatsappNumber(instance, data),
|
ClassRef: WhatsAppNumberDto,
|
||||||
});
|
execute: (instance, data) => chatController.whatsappNumber(instance, data),
|
||||||
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return res.status(HttpStatus.BAD_REQUEST).json(error);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.post(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => {
|
.post(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => {
|
||||||
const response = await this.dataValidate<ReadMessageDto>({
|
const response = await this.dataValidate<ReadMessageDto>({
|
||||||
|
@ -52,7 +52,9 @@ function getAvailableNumbers(remoteJid: string) {
|
|||||||
|
|
||||||
interface ISaveOnWhatsappCacheParams {
|
interface ISaveOnWhatsappCacheParams {
|
||||||
remoteJid: string;
|
remoteJid: string;
|
||||||
|
lid?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) {
|
export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) {
|
||||||
if (configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) {
|
if (configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) {
|
||||||
const upsertsQuery = data.map((item) => {
|
const upsertsQuery = data.map((item) => {
|
||||||
@ -60,8 +62,15 @@ export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) {
|
|||||||
const numbersAvailable = getAvailableNumbers(remoteJid);
|
const numbersAvailable = getAvailableNumbers(remoteJid);
|
||||||
|
|
||||||
return prismaRepository.isOnWhatsapp.upsert({
|
return prismaRepository.isOnWhatsapp.upsert({
|
||||||
create: { remoteJid: remoteJid, jidOptions: numbersAvailable.join(',') },
|
create: {
|
||||||
update: { jidOptions: numbersAvailable.join(',') },
|
remoteJid: remoteJid,
|
||||||
|
jidOptions: numbersAvailable.join(','),
|
||||||
|
lid: item.lid,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
jidOptions: numbersAvailable.join(','),
|
||||||
|
lid: item.lid,
|
||||||
|
},
|
||||||
where: { remoteJid: remoteJid },
|
where: { remoteJid: remoteJid },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -75,6 +84,7 @@ export async function getOnWhatsappCache(remoteJids: string[]) {
|
|||||||
remoteJid: string;
|
remoteJid: string;
|
||||||
number: string;
|
number: string;
|
||||||
jidOptions: string[];
|
jidOptions: string[];
|
||||||
|
lid?: string;
|
||||||
}[] = [];
|
}[] = [];
|
||||||
|
|
||||||
if (configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) {
|
if (configService.get<Database>('DATABASE').SAVE_DATA.IS_ON_WHATSAPP) {
|
||||||
@ -93,6 +103,7 @@ export async function getOnWhatsappCache(remoteJids: string[]) {
|
|||||||
remoteJid: item.remoteJid,
|
remoteJid: item.remoteJid,
|
||||||
number: item.remoteJid.split('@')[0],
|
number: item.remoteJid.split('@')[0],
|
||||||
jidOptions: item.jidOptions.split(','),
|
jidOptions: item.jidOptions.split(','),
|
||||||
|
lid: item.lid,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user