From ed6c50621c97c1e587aa95bdd3ed805aeed5c48d Mon Sep 17 00:00:00 2001 From: Judson Junior Date: Tue, 23 Jan 2024 18:16:15 -0300 Subject: [PATCH] Improved the method of numbers validation --- package.json | 2 + src/whatsapp/services/whatsapp.service.ts | 73 ++++++++++++++++------- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 20ff59d9..a1477452 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "exiftool-vendored": "^22.0.0", "express": "^4.18.2", "express-async-errors": "^3.1.1", + "fast-levenshtein": "^3.0.0", "hbs": "^4.2.0", "https-proxy-agent": "^7.0.2", "jimp": "^0.16.13", @@ -88,6 +89,7 @@ "@types/compression": "^1.7.2", "@types/cors": "^2.8.13", "@types/express": "^4.17.17", + "@types/fast-levenshtein": "^0.0.4", "@types/js-yaml": "^4.0.5", "@types/jsonwebtoken": "^8.5.9", "@types/mime-types": "^2.1.1", diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 0d8fb5b2..76511260 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -38,6 +38,7 @@ import axios from 'axios'; import { exec, execSync } from 'child_process'; import { arrayUnique, isBase64, isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; +import levenshtein from 'fast-levenshtein'; import fs, { existsSync, readFileSync } from 'fs'; import Long from 'long'; import NodeCache from 'node-cache'; @@ -3126,31 +3127,63 @@ export class WAStartupService { public async whatsappNumber(data: WhatsAppNumberDto) { this.logger.verbose('Getting whatsapp number'); - const onWhatsapp: OnWhatsAppDto[] = []; - for await (const number of data.numbers) { - let jid = this.createJid(number); + const jids: { + groups: { number: string; jid: string }[]; + broadcast: { number: string; jid: string }[]; + users: { number: string; jid: string }[]; + } = { + groups: [], + broadcast: [], + users: [], + }; + + data.numbers.forEach((number) => { + const jid = this.createJid(number); if (isJidGroup(jid)) { + jids.groups.push({ number, jid }); + } else if (jid === 'status@broadcast') { + jids.broadcast.push({ number, jid }); + } else { + jids.users.push({ number, jid }); + } + }); + + const onWhatsapp: OnWhatsAppDto[] = []; + + // BROADCAST + onWhatsapp.push(...jids.broadcast.map(({ jid, number }) => new OnWhatsAppDto(jid, false, number))); + + // GROUPS + const groups = await Promise.all( + jids.groups.map(async ({ jid, number }) => { const group = await this.findGroup({ groupJid: jid }, 'inner'); - if (!group) throw new BadRequestException('Group not found'); - - onWhatsapp.push(new OnWhatsAppDto(group.id, !!group?.id, number, group?.subject)); - } else if (jid === 'status@broadcast') { - onWhatsapp.push(new OnWhatsAppDto(jid, false, number)); - } else { - jid = !jid.startsWith('+') ? `+${jid}` : jid; - const verify = await this.client.onWhatsApp(jid); - - const result = verify[0]; - - if (!result) { - onWhatsapp.push(new OnWhatsAppDto(jid, false, number)); - } else { - onWhatsapp.push(new OnWhatsAppDto(result.jid, result.exists, number)); + if (!group) { + new OnWhatsAppDto(jid, false, number); } - } - } + + return new OnWhatsAppDto(group.id, !!group?.id, number, group?.subject); + }), + ); + onWhatsapp.push(...groups); + + // USERS + const verify = await this.client.onWhatsApp( + ...jids.users.map(({ jid }) => (!jid.startsWith('+') ? `+${jid}` : jid)), + ); + const users: OnWhatsAppDto[] = jids.users.map((user) => { + const MAX_SIMILARITY_THRESHOLD = 0.0358; + const numberVerified = verify.find( + (v) => levenshtein.get(user.jid, v.jid) / Math.max(user.jid.length, v.jid.length) <= MAX_SIMILARITY_THRESHOLD, + ); + return { + exists: !!numberVerified?.exists, + jid: numberVerified?.jid || user.jid, + number: user.number, + }; + }); + onWhatsapp.push(...users); return onWhatsapp; }