diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 22839fd451..428d0362c5 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -4114,7 +4114,18 @@ export class BaileysStartupService extends ChannelStartupService { numberVerified = verify.find((v) => v.jid === user.jid); } - const numberJid = numberVerified?.jid || user.jid; + let numberJid = numberVerified?.jid || user.jid; + if ( + user.number.startsWith('55') && + user.number.length === 13 && + user.number[4] === '9' && + numberJid.includes('@s.whatsapp.net') + ) { + const jidNum = numberJid.split('@')[0]; + if (jidNum.length === 12) { + numberJid = `${user.number}@s.whatsapp.net`; + } + } return new OnWhatsAppDto( numberJid, diff --git a/src/api/services/channel.service.ts b/src/api/services/channel.service.ts index 3ba03d5a02..a413452bf2 100644 --- a/src/api/services/channel.service.ts +++ b/src/api/services/channel.service.ts @@ -13,7 +13,7 @@ import { Auth, Chatwoot, ConfigService, Database, HttpServer, Proxy } from '@con import { Logger } from '@config/logger.config'; import { NotFoundException } from '@exceptions'; import { Contact, Message, Prisma } from '@prisma/client'; -import { createJid } from '@utils/createJid'; +import { createJid, formatBRNumber } from '@utils/createJid'; import { WASocket } from 'baileys'; import { isArray } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; @@ -478,23 +478,8 @@ export class ChannelStartupService { return jid; } - // Check if the number is br - public formatBRNumber(jid: string) { - const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); - if (regexp.test(jid)) { - const match = regexp.exec(jid); - if (match && match[1] === '55') { - const joker = Number.parseInt(match[3][0]); - const ddd = Number.parseInt(match[2]); - if (joker < 7 || ddd < 31) { - return match[0]; - } - return match[1] + match[2] + match[3]; - } - return jid; - } else { - return jid; - } + public formatBRNumber(jid: string): string { + return formatBRNumber(jid); } public async fetchContacts(query: Query) { diff --git a/src/utils/createJid.ts b/src/utils/createJid.ts index 23a3afe1fa..0a3924ce46 100644 --- a/src/utils/createJid.ts +++ b/src/utils/createJid.ts @@ -13,23 +13,36 @@ function formatMXOrARNumber(jid: string): string { return jid; } -// Check if the number is br -function formatBRNumber(jid: string) { - const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/); - if (regexp.test(jid)) { - const match = regexp.exec(jid); - if (match && match[1] === '55') { - const joker = Number.parseInt(match[3][0]); - const ddd = Number.parseInt(match[2]); - if (joker < 7 || ddd < 31) { - return match[0]; - } - return match[1] + match[2] + match[3]; - } +const BRAZIL_COUNTRY_CODE = '55'; +const BRAZIL_PHONE_WITH_NINTH_DIGIT_LENGTH = 13; +const BRAZIL_PHONE_WITHOUT_NINTH_DIGIT_LENGTH = 12; +const BRAZIL_MOBILE_NINTH_DIGIT = '9'; +const COUNTRY_AND_AREA_CODE_LENGTH = 4; +const FIRST_SUBSCRIBER_DIGIT_INDEX = 4; +const MINIMUM_MOBILE_FIRST_DIGIT = 6; + +export function formatBRNumber(jid: string): string { + if (!jid.startsWith(BRAZIL_COUNTRY_CODE)) { return jid; - } else { + } + + if (jid.length === BRAZIL_PHONE_WITH_NINTH_DIGIT_LENGTH) { return jid; } + + if (jid.length === BRAZIL_PHONE_WITHOUT_NINTH_DIGIT_LENGTH) { + const firstSubscriberDigit = Number.parseInt(jid[FIRST_SUBSCRIBER_DIGIT_INDEX]); + const isMobileMissingNinthDigit = firstSubscriberDigit >= MINIMUM_MOBILE_FIRST_DIGIT; + + if (isMobileMissingNinthDigit) { + const countryAndAreaCode = jid.slice(0, COUNTRY_AND_AREA_CODE_LENGTH); + const subscriberNumber = jid.slice(COUNTRY_AND_AREA_CODE_LENGTH); + + return `${countryAndAreaCode}${BRAZIL_MOBILE_NINTH_DIGIT}${subscriberNumber}`; + } + } + + return jid; } export function createJid(number: string): string { diff --git a/src/utils/onWhatsappCache.ts b/src/utils/onWhatsappCache.ts index 8d7a2c16a7..05233d6ebf 100644 --- a/src/utils/onWhatsappCache.ts +++ b/src/utils/onWhatsappCache.ts @@ -22,12 +22,24 @@ function getAvailableNumbers(remoteJid: string) { // Brazilian numbers if (remoteJid.startsWith('55')) { - const numberWithDigit = - number.slice(4, 5) === '9' && number.length === 13 ? number : `${number.slice(0, 4)}9${number.slice(4)}`; - const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 4) + number.slice(5); + let numberWithDigit = number; + let numberWithoutDigit = number; + + if (number.length === 13 && number.slice(4, 5) === '9') { + numberWithDigit = number; + numberWithoutDigit = `${number.slice(0, 4)}${number.slice(5)}`; + } else if (number.length === 12) { + const firstDigit = Number.parseInt(number.slice(4, 5)); + if (firstDigit >= 6) { + numberWithDigit = `${number.slice(0, 4)}9${number.slice(4)}`; + numberWithoutDigit = number; + } + } numbersAvailable.push(numberWithDigit); - numbersAvailable.push(numberWithoutDigit); + if (numberWithoutDigit !== numberWithDigit) { + numbersAvailable.push(numberWithoutDigit); + } } // Mexican/Argentina numbers @@ -48,7 +60,9 @@ function getAvailableNumbers(remoteJid: string) { const numberWithoutDigit = number.length === 12 ? number : number.slice(0, 2) + number.slice(3); numbersAvailable.push(numberWithDigit); - numbersAvailable.push(numberWithoutDigit); + if (numberWithoutDigit !== numberWithDigit) { + numbersAvailable.push(numberWithoutDigit); + } } // Other countries @@ -129,8 +143,23 @@ export async function saveOnWhatsappCache(data: ISaveOnWhatsappCacheParams[]) { const newJidOptionsString = sortedJidOptions.join(','); const newLid = item.lid === 'lid' || item.remoteJid?.includes('@lid') ? 'lid' : null; + let targetRemoteJid = remoteJid; + if (existingRecord?.remoteJid) { + const existingNum = existingRecord.remoteJid.split('@')[0]; + const newNum = remoteJid.split('@')[0]; + if ( + existingNum.startsWith('55') && + existingNum.length === 13 && + existingNum[4] === '9' && + newNum.startsWith('55') && + newNum.length === 12 + ) { + targetRemoteJid = existingRecord.remoteJid; + } + } + const dataPayload = { - remoteJid: remoteJid, + remoteJid: targetRemoteJid, jidOptions: newJidOptionsString, lid: newLid, };