From ab5eb80edd174566e3e4a15f11ba81ecb6c5dc58 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 22 Jan 2025 10:16:48 -0300 Subject: [PATCH] Refactor JID creation and fetch chats - Introduced a new utility function `createJid` to standardize JID creation across the application, replacing the previous method in `ChannelStartupService`. - Updated multiple services to utilize the new `createJid` function for improved consistency and maintainability. - Added a `cleanMessageData` method in `ChannelStartupService` to sanitize message objects before processing. - Updated CHANGELOG to reflect the refactor on chat fetching logic and the introduction of the new JID utility. --- CHANGELOG.md | 1 + .../evolution/evolution.channel.service.ts | 3 +- .../channel/meta/whatsapp.business.service.ts | 13 +- .../whatsapp/whatsapp.baileys.service.ts | 75 ++--- src/api/services/channel.service.ts | 277 +++++++++--------- src/utils/createJid.ts | 71 +++++ 6 files changed, 263 insertions(+), 177 deletions(-) create mode 100644 src/utils/createJid.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index b6d33e0a..33a9cbae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Correction of webhook global * Fixed send audio with whatsapp cloud api +* Refactor on fetch chats # 2.2.0 (2024-10-18 10:00) diff --git a/src/api/integrations/channel/evolution/evolution.channel.service.ts b/src/api/integrations/channel/evolution/evolution.channel.service.ts index 580426cb..e5acf65a 100644 --- a/src/api/integrations/channel/evolution/evolution.channel.service.ts +++ b/src/api/integrations/channel/evolution/evolution.channel.service.ts @@ -7,6 +7,7 @@ import { ChannelStartupService } from '@api/services/channel.service'; import { Events, wa } from '@api/types/wa.types'; import { Chatwoot, ConfigService, Openai } from '@config/env.config'; import { BadRequestException, InternalServerErrorException } from '@exceptions'; +import { createJid } from '@utils/createJid'; import { status } from '@utils/renderStatus'; import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; @@ -57,7 +58,7 @@ export class EvolutionStartupService extends ChannelStartupService { } public async profilePicture(number: string) { - const jid = this.createJid(number); + const jid = createJid(number); return { wuid: jid, diff --git a/src/api/integrations/channel/meta/whatsapp.business.service.ts b/src/api/integrations/channel/meta/whatsapp.business.service.ts index b79e0222..5360b9e4 100644 --- a/src/api/integrations/channel/meta/whatsapp.business.service.ts +++ b/src/api/integrations/channel/meta/whatsapp.business.service.ts @@ -22,6 +22,7 @@ import { ChannelStartupService } from '@api/services/channel.service'; import { Events, wa } from '@api/types/wa.types'; import { Chatwoot, ConfigService, Database, Openai, S3, WaBusiness } from '@config/env.config'; import { BadRequestException, InternalServerErrorException } from '@exceptions'; +import { createJid } from '@utils/createJid'; import { status } from '@utils/renderStatus'; import axios from 'axios'; import { arrayUnique, isURL } from 'class-validator'; @@ -88,7 +89,7 @@ export class BusinessStartupService extends ChannelStartupService { } public async profilePicture(number: string) { - const jid = this.createJid(number); + const jid = createJid(number); return { wuid: jid, @@ -132,9 +133,7 @@ export class BusinessStartupService extends ChannelStartupService { this.eventHandler(content); - this.phoneNumber = this.createJid( - content.messages ? content.messages[0].from : content.statuses[0]?.recipient_id, - ); + this.phoneNumber = createJid(content.messages ? content.messages[0].from : content.statuses[0]?.recipient_id); } catch (error) { this.logger.error(error); throw new InternalServerErrorException(error?.toString()); @@ -231,7 +230,7 @@ export class BusinessStartupService extends ChannelStartupService { } if (!contact.phones[0]?.wa_id) { - contact.phones[0].wa_id = this.createJid(contact.phones[0].phone); + contact.phones[0].wa_id = createJid(contact.phones[0].phone); } result += @@ -915,7 +914,7 @@ export class BusinessStartupService extends ChannelStartupService { } const messageRaw: any = { - key: { fromMe: true, id: messageSent?.messages[0]?.id, remoteJid: this.createJid(number) }, + key: { fromMe: true, id: messageSent?.messages[0]?.id, remoteJid: createJid(number) }, message: this.convertMessageToRaw(message, content), messageType: this.renderMessageType(content.type), messageTimestamp: (messageSent?.messages[0]?.timestamp as number) || Math.round(new Date().getTime() / 1000), @@ -1274,7 +1273,7 @@ export class BusinessStartupService extends ChannelStartupService { } if (!contact.wuid) { - contact.wuid = this.createJid(contact.phoneNumber); + contact.wuid = createJid(contact.phoneNumber); } result += `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + 'END:VCARD'; diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index d830c632..2de39434 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -78,6 +78,7 @@ import ffmpegPath from '@ffmpeg-installer/ffmpeg'; import { Boom } from '@hapi/boom'; import { createId as cuid } from '@paralleldrive/cuid2'; import { Instance } from '@prisma/client'; +import { createJid } from '@utils/createJid'; import { makeProxyAgent } from '@utils/makeProxyAgent'; import { getOnWhatsappCache, saveOnWhatsappCache } from '@utils/onWhatsappCache'; import { status } from '@utils/renderStatus'; @@ -1323,17 +1324,21 @@ export class BaileysStartupService extends ChannelStartupService { if (this.localWebhook.enabled) { if (isMedia && this.localWebhook.webhookBase64) { - const buffer = await downloadMediaMessage( - { key: received.key, message: received?.message }, - 'buffer', - {}, - { - logger: P({ level: 'error' }) as any, - reuploadRequest: this.client.updateMediaMessage, - }, - ); + try { + const buffer = await downloadMediaMessage( + { key: received.key, message: received?.message }, + 'buffer', + {}, + { + logger: P({ level: 'error' }) as any, + reuploadRequest: this.client.updateMediaMessage, + }, + ); - messageRaw.message.base64 = buffer ? buffer.toString('base64') : undefined; + messageRaw.message.base64 = buffer ? buffer.toString('base64') : undefined; + } catch (error) { + this.logger.error(['Error converting media to base64', error?.message]); + } } } @@ -1809,7 +1814,7 @@ export class BaileysStartupService extends ChannelStartupService { } public async profilePicture(number: string) { - const jid = this.createJid(number); + const jid = createJid(number); try { const profilePictureUrl = await this.client.profilePictureUrl(jid, 'image'); @@ -1827,7 +1832,7 @@ export class BaileysStartupService extends ChannelStartupService { } public async getStatus(number: string) { - const jid = this.createJid(number); + const jid = createJid(number); try { return { @@ -1843,7 +1848,7 @@ export class BaileysStartupService extends ChannelStartupService { } public async fetchProfile(instanceName: string, number?: string) { - const jid = number ? this.createJid(number) : this.client?.user?.id; + const jid = number ? createJid(number) : this.client?.user?.id; const onWhatsapp = (await this.whatsappNumber({ numbers: [jid] }))?.shift(); @@ -1899,7 +1904,7 @@ export class BaileysStartupService extends ChannelStartupService { } public async offerCall({ number, isVideo, callDuration }: OfferCallDto) { - const jid = this.createJid(number); + const jid = createJid(number); try { const call = await this.client.offerCall(jid, isVideo); @@ -2170,7 +2175,7 @@ export class BaileysStartupService extends ChannelStartupService { mentions = group.participants.map((participant) => participant.id); } else if (options?.mentioned?.length) { mentions = options.mentioned.map((mention) => { - const jid = this.createJid(mention); + const jid = createJid(mention); if (isJidGroup(jid)) { return null; } @@ -2292,17 +2297,21 @@ export class BaileysStartupService extends ChannelStartupService { if (this.localWebhook.enabled) { if (isMedia && this.localWebhook.webhookBase64) { - const buffer = await downloadMediaMessage( - { key: messageRaw.key, message: messageRaw?.message }, - 'buffer', - {}, - { - logger: P({ level: 'error' }) as any, - reuploadRequest: this.client.updateMediaMessage, - }, - ); + try { + const buffer = await downloadMediaMessage( + { key: messageRaw.key, message: messageRaw?.message }, + 'buffer', + {}, + { + logger: P({ level: 'error' }) as any, + reuploadRequest: this.client.updateMediaMessage, + }, + ); - messageRaw.message.base64 = buffer ? buffer.toString('base64') : undefined; + messageRaw.message.base64 = buffer ? buffer.toString('base64') : undefined; + } catch (error) { + this.logger.error(['Error converting media to base64', error?.message]); + } } } @@ -3240,7 +3249,7 @@ export class BaileysStartupService extends ChannelStartupService { } if (!contact.wuid) { - contact.wuid = this.createJid(contact.phoneNumber); + contact.wuid = createJid(contact.phoneNumber); } result += `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + 'END:VCARD'; @@ -3290,7 +3299,7 @@ export class BaileysStartupService extends ChannelStartupService { }; data.numbers.forEach((number) => { - const jid = this.createJid(number); + const jid = createJid(number); if (isJidGroup(jid)) { jids.groups.push({ number, jid }); @@ -3483,7 +3492,7 @@ export class BaileysStartupService extends ChannelStartupService { archive: data.archive, lastMessages: [last_message], }, - this.createJid(number), + createJid(number), ); return { @@ -3520,7 +3529,7 @@ export class BaileysStartupService extends ChannelStartupService { markRead: false, lastMessages: [last_message], }, - this.createJid(number), + createJid(number), ); return { @@ -3725,7 +3734,7 @@ export class BaileysStartupService extends ChannelStartupService { public async fetchBusinessProfile(number: string): Promise { try { - const jid = number ? this.createJid(number) : this.instance.wuid; + const jid = number ? createJid(number) : this.instance.wuid; const profile = await this.client.getBusinessProfile(jid); @@ -3873,7 +3882,7 @@ export class BaileysStartupService extends ChannelStartupService { } public async updateMessage(data: UpdateMessageDto) { - const jid = this.createJid(data.number); + const jid = createJid(data.number); const options = await this.formatUpdateMessage(data); @@ -4163,7 +4172,7 @@ export class BaileysStartupService extends ChannelStartupService { const inviteUrl = inviteCode.inviteUrl; - const numbers = id.numbers.map((number) => this.createJid(number)); + const numbers = id.numbers.map((number) => createJid(number)); const description = id.description ?? ''; const msg = `${description}\n\n${inviteUrl}`; @@ -4234,7 +4243,7 @@ export class BaileysStartupService extends ChannelStartupService { public async updateGParticipant(update: GroupUpdateParticipantDto) { try { - const participants = update.participants.map((p) => this.createJid(p)); + const participants = update.participants.map((p) => createJid(p)); const updateParticipants = await this.client.groupParticipantsUpdate( update.groupJid, participants, diff --git a/src/api/services/channel.service.ts b/src/api/services/channel.service.ts index e9d2e22d..d2a4d8b1 100644 --- a/src/api/services/channel.service.ts +++ b/src/api/services/channel.service.ts @@ -12,7 +12,8 @@ import { Events, wa } from '@api/types/wa.types'; import { Auth, Chatwoot, ConfigService, HttpServer } from '@config/env.config'; import { Logger } from '@config/logger.config'; import { NotFoundException } from '@exceptions'; -import { Contact, Message } from '@prisma/client'; +import { Contact, Message, Prisma } from '@prisma/client'; +import { createJid } from '@utils/createJid'; import { WASocket } from 'baileys'; import { isArray } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; @@ -487,47 +488,11 @@ export class ChannelStartupService { } } - public createJid(number: string): string { - if (number.includes('@g.us') || number.includes('@s.whatsapp.net') || number.includes('@lid')) { - return number; - } - - if (number.includes('@broadcast')) { - return number; - } - - number = number - ?.replace(/\s/g, '') - .replace(/\+/g, '') - .replace(/\(/g, '') - .replace(/\)/g, '') - .split(':')[0] - .split('@')[0]; - - if (number.includes('-') && number.length >= 24) { - number = number.replace(/[^\d-]/g, ''); - return `${number}@g.us`; - } - - number = number.replace(/\D/g, ''); - - if (number.length >= 18) { - number = number.replace(/[^\d-]/g, ''); - return `${number}@g.us`; - } - - number = this.formatMXOrARNumber(number); - - number = this.formatBRNumber(number); - - return `${number}@s.whatsapp.net`; - } - public async fetchContacts(query: Query) { const remoteJid = query?.where?.remoteJid ? query?.where?.remoteJid.includes('@') ? query.where?.remoteJid - : this.createJid(query.where?.remoteJid) + : createJid(query.where?.remoteJid) : null; const where = { @@ -543,6 +508,64 @@ export class ChannelStartupService { }); } + public cleanMessageData(message: any) { + if (!message) return message; + + const cleanedMessage = { ...message }; + + const mediaUrl = cleanedMessage.message.mediaUrl; + + delete cleanedMessage.message.base64; + + if (cleanedMessage.message) { + // Limpa imageMessage + if (cleanedMessage.message.imageMessage) { + cleanedMessage.message.imageMessage = { + caption: cleanedMessage.message.imageMessage.caption, + }; + } + + // Limpa videoMessage + if (cleanedMessage.message.videoMessage) { + cleanedMessage.message.videoMessage = { + caption: cleanedMessage.message.videoMessage.caption, + }; + } + + // Limpa audioMessage + if (cleanedMessage.message.audioMessage) { + cleanedMessage.message.audioMessage = { + seconds: cleanedMessage.message.audioMessage.seconds, + }; + } + + // Limpa stickerMessage + if (cleanedMessage.message.stickerMessage) { + cleanedMessage.message.stickerMessage = {}; + } + + // Limpa documentMessage + if (cleanedMessage.message.documentMessage) { + cleanedMessage.message.documentMessage = { + caption: cleanedMessage.message.documentMessage.caption, + name: cleanedMessage.message.documentMessage.name, + }; + } + + // Limpa documentWithCaptionMessage + if (cleanedMessage.message.documentWithCaptionMessage) { + cleanedMessage.message.documentWithCaptionMessage = { + caption: cleanedMessage.message.documentWithCaptionMessage.caption, + name: cleanedMessage.message.documentWithCaptionMessage.name, + }; + } + } + + if (mediaUrl) cleanedMessage.message.mediaUrl = mediaUrl; + + return cleanedMessage; + } + public async fetchMessages(query: Query) { const keyFilters = query?.where?.key as { id?: string; @@ -648,113 +671,95 @@ export class ChannelStartupService { const remoteJid = query?.where?.remoteJid ? query?.where?.remoteJid.includes('@') ? query.where?.remoteJid - : this.createJid(query.where?.remoteJid) + : createJid(query.where?.remoteJid) : null; - let results = []; + const where = { + instanceId: this.instanceId, + }; - if (!remoteJid) { - results = await this.prismaRepository.$queryRaw` - SELECT - "Chat"."id", - "Chat"."remoteJid", - "Chat"."name", - "Chat"."labels", - "Chat"."createdAt", - "Chat"."updatedAt", - "Contact"."pushName", - "Contact"."profilePicUrl", - "Chat"."unreadMessages", - (ARRAY_AGG("Message"."id" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_id, - (ARRAY_AGG("Message"."key" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_key, - (ARRAY_AGG("Message"."pushName" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_push_name, - (ARRAY_AGG("Message"."participant" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_participant, - (ARRAY_AGG("Message"."messageType" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_message_type, - (ARRAY_AGG("Message"."message" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_message, - (ARRAY_AGG("Message"."contextInfo" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_context_info, - (ARRAY_AGG("Message"."source" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_source, - (ARRAY_AGG("Message"."messageTimestamp" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_message_timestamp, - (ARRAY_AGG("Message"."instanceId" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_instance_id, - (ARRAY_AGG("Message"."sessionId" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_session_id, - (ARRAY_AGG("Message"."status" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_status - FROM "Chat" - LEFT JOIN "Message" ON "Message"."messageType" != 'reactionMessage' and "Message"."key"->>'remoteJid' = "Chat"."remoteJid" AND "Chat"."instanceId" = "Message"."instanceId" - LEFT JOIN "Contact" ON "Chat"."remoteJid" = "Contact"."remoteJid" AND "Chat"."instanceId" = "Contact"."instanceId" - WHERE - "Chat"."instanceId" = ${this.instanceId} - GROUP BY - "Chat"."id", - "Chat"."remoteJid", - "Contact"."id" - ORDER BY last_message_message_timestamp DESC NULLS LAST, "Chat"."updatedAt" DESC; - `; - } else { - results = await this.prismaRepository.$queryRaw` - SELECT - "Chat"."id", - "Chat"."remoteJid", - "Chat"."name", - "Chat"."labels", - "Chat"."createdAt", - "Chat"."updatedAt", - "Contact"."pushName", - "Contact"."profilePicUrl", - "Chat"."unreadMessages", - (ARRAY_AGG("Message"."id" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_id, - (ARRAY_AGG("Message"."key" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_key, - (ARRAY_AGG("Message"."pushName" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_push_name, - (ARRAY_AGG("Message"."participant" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_participant, - (ARRAY_AGG("Message"."messageType" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_message_type, - (ARRAY_AGG("Message"."message" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_message, - (ARRAY_AGG("Message"."contextInfo" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_context_info, - (ARRAY_AGG("Message"."source" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_source, - (ARRAY_AGG("Message"."messageTimestamp" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_message_timestamp, - (ARRAY_AGG("Message"."instanceId" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_instance_id, - (ARRAY_AGG("Message"."sessionId" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_session_id, - (ARRAY_AGG("Message"."status" ORDER BY "Message"."messageTimestamp" DESC))[1] AS last_message_status - FROM "Chat" - LEFT JOIN "Message" ON "Message"."messageType" != 'reactionMessage' and "Message"."key"->>'remoteJid' = "Chat"."remoteJid" AND "Chat"."instanceId" = "Message"."instanceId" - LEFT JOIN "Contact" ON "Chat"."remoteJid" = "Contact"."remoteJid" AND "Chat"."instanceId" = "Contact"."instanceId" - WHERE - "Chat"."instanceId" = ${this.instanceId} AND "Chat"."remoteJid" = ${remoteJid} and "Message"."messageType" != 'reactionMessage' - GROUP BY - "Chat"."id", - "Chat"."remoteJid", - "Contact"."id" - ORDER BY last_message_message_timestamp DESC NULLS LAST, "Chat"."updatedAt" DESC; - `; + if (remoteJid) { + where['remoteJid'] = remoteJid; } + const results = await this.prismaRepository.$queryRaw` + WITH rankedMessages AS ( + SELECT DISTINCT ON ("Contact"."remoteJid") + "Contact"."id", + "Contact"."remoteJid", + "Contact"."pushName", + "Contact"."profilePicUrl", + COALESCE( + to_timestamp("Message"."messageTimestamp"::double precision), + "Contact"."updatedAt" + ) as "updatedAt", + "Chat"."createdAt" as "windowStart", + "Chat"."createdAt" + INTERVAL '24 hours' as "windowExpires", + CASE + WHEN "Chat"."createdAt" + INTERVAL '24 hours' > NOW() THEN true + ELSE false + END as "windowActive", + "Message"."id" AS lastMessageId, + "Message"."key" AS lastMessage_key, + "Message"."pushName" AS lastMessagePushName, + "Message"."participant" AS lastMessageParticipant, + "Message"."messageType" AS lastMessageMessageType, + "Message"."message" AS lastMessageMessage, + "Message"."contextInfo" AS lastMessageContextInfo, + "Message"."source" AS lastMessageSource, + "Message"."messageTimestamp" AS lastMessageMessageTimestamp, + "Message"."instanceId" AS lastMessageInstanceId, + "Message"."sessionId" AS lastMessageSessionId, + "Message"."status" AS lastMessageStatus + FROM "Contact" + INNER JOIN "Message" ON "Message"."key"->>'remoteJid' = "Contact"."remoteJid" + LEFT JOIN "Chat" ON "Chat"."remoteJid" = "Contact"."remoteJid" + AND "Chat"."instanceId" = "Contact"."instanceId" + WHERE + "Contact"."instanceId" = ${this.instanceId} + AND "Message"."instanceId" = ${this.instanceId} + ${remoteJid ? Prisma.sql`AND "Contact"."remoteJid" = ${remoteJid}` : Prisma.sql``} + ORDER BY + "Contact"."remoteJid", + "Message"."messageTimestamp" DESC + ) + SELECT * FROM rankedMessages + ORDER BY updatedAt DESC NULLS LAST; + `; + if (results && isArray(results) && results.length > 0) { - return results.map((chat) => { + const mappedResults = results.map((contact) => { + const lastMessage = contact.lastMessageId + ? { + id: contact.lastMessageId, + key: contact.lastMessageKey, + pushName: contact.lastMessagePushName, + participant: contact.lastMessageParticipant, + messageType: contact.lastMessageMessageType, + message: contact.lastMessageMessage, + contextInfo: contact.lastMessageContextInfo, + source: contact.lastMessageSource, + messageTimestamp: contact.lastMessageMessageTimestamp, + instanceId: contact.lastMessageInstanceId, + sessionId: contact.lastMessageSessionId, + status: contact.lastMessageStatus, + } + : undefined; + return { - id: chat.id, - remoteJid: chat.remoteJid, - name: chat.name, - labels: chat.labels, - createdAt: chat.createdAt, - updatedAt: chat.updatedAt, - pushName: chat.pushName, - profilePicUrl: chat.profilePicUrl, - unreadMessages: chat.unreadMessages, - lastMessage: chat.last_message_id - ? { - id: chat.last_message_id, - key: chat.last_message_key, - pushName: chat.last_message_push_name, - participant: chat.last_message_participant, - messageType: chat.last_message_message_type, - message: chat.last_message_message, - contextInfo: chat.last_message_context_info, - source: chat.last_message_source, - messageTimestamp: chat.last_message_message_timestamp, - instanceId: chat.last_message_instance_id, - sessionId: chat.last_message_session_id, - status: chat.last_message_status, - } - : undefined, + id: contact.id, + remoteJid: contact.remoteJid, + pushName: contact.pushName, + profilePicUrl: contact.profilePicUrl, + updatedAt: contact.updatedAt, + windowStart: contact.windowStart, + windowExpires: contact.windowExpires, + windowActive: contact.windowActive, + lastMessage: lastMessage ? this.cleanMessageData(lastMessage) : undefined, }; }); + + return mappedResults; } return []; diff --git a/src/utils/createJid.ts b/src/utils/createJid.ts new file mode 100644 index 00000000..a680e821 --- /dev/null +++ b/src/utils/createJid.ts @@ -0,0 +1,71 @@ +// Check if the number is MX or AR +function formatMXOrARNumber(jid: string): string { + const countryCode = jid.substring(0, 2); + + if (Number(countryCode) === 52 || Number(countryCode) === 54) { + if (jid.length === 13) { + const number = countryCode + jid.substring(3); + return number; + } + + return jid; + } + 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]; + } + return jid; + } else { + return jid; + } +} + +export function createJid(number: string): string { + number = number.replace(/:\d+/, ''); + + if (number.includes('@g.us') || number.includes('@s.whatsapp.net') || number.includes('@lid')) { + return number; + } + + if (number.includes('@broadcast')) { + return number; + } + + number = number + ?.replace(/\s/g, '') + .replace(/\+/g, '') + .replace(/\(/g, '') + .replace(/\)/g, '') + .split(':')[0] + .split('@')[0]; + + if (number.includes('-') && number.length >= 24) { + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + + number = number.replace(/\D/g, ''); + + if (number.length >= 18) { + number = number.replace(/[^\d-]/g, ''); + return `${number}@g.us`; + } + + number = formatMXOrARNumber(number); + + number = formatBRNumber(number); + + return `${number}@s.whatsapp.net`; +}