diff --git a/src/api/controllers/chat.controller.ts b/src/api/controllers/chat.controller.ts index c224ef92..27feca83 100644 --- a/src/api/controllers/chat.controller.ts +++ b/src/api/controllers/chat.controller.ts @@ -121,5 +121,8 @@ export class ChatController { remoteJid: data.remoteJid, }; return await this.waMonitor.waInstances[instanceName].baileysDecryptPollVote(pollCreationMessageKey); + + public async fetchChannels({ instanceName }: InstanceDto, query: Query) { + return await this.waMonitor.waInstances[instanceName].fetchChannels(query); } } diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index cf45a931..aad88a37 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -3511,9 +3511,24 @@ export class BaileysStartupService extends ChannelStartupService { users: { number: string; jid: string; name?: string }[]; } = { groups: [], broadcast: [], users: [] }; + const onWhatsapp: OnWhatsAppDto[] = []; + data.numbers.forEach((number) => { const jid = createJid(number); + if (isJidNewsletter(jid)) { + onWhatsapp.push( + new OnWhatsAppDto( + jid, + true, // Newsletters are always valid + number, + undefined, // Can be fetched later if needed + 'newsletter', // Indicate it's a newsletter type + ), + ); + return; + } + if (isJidGroup(jid)) { jids.groups.push({ number, jid }); } else if (jid === 'status@broadcast') { @@ -3523,8 +3538,6 @@ export class BaileysStartupService extends ChannelStartupService { } }); - const onWhatsapp: OnWhatsAppDto[] = []; - // BROADCAST onWhatsapp.push(...jids.broadcast.map(({ jid, number }) => new OnWhatsAppDto(jid, false, number))); @@ -4700,6 +4713,10 @@ export class BaileysStartupService extends ChannelStartupService { } } + if (isJidNewsletter(message.key.remoteJid) && message.key.fromMe) { + messageRaw.status = status[3]; // DELIVERED MESSAGE TO NEWSLETTER CHANNEL + } + return messageRaw; } @@ -5365,5 +5382,52 @@ export class BaileysStartupService extends ChannelStartupService { this.logger.error(`Error decrypting poll votes: ${error}`); throw new InternalServerErrorException('Error decrypting poll votes', error.toString()); } + + public async fetchChannels(query: Query) { + const page = Number((query as any)?.page ?? 1); + const limit = Number((query as any)?.limit ?? (query as any)?.rows ?? 50); + const skip = (page - 1) * limit; + + const messages = await this.prismaRepository.message.findMany({ + where: { + instanceId: this.instanceId, + AND: [{ key: { path: ['remoteJid'], not: null } }], + }, + orderBy: { messageTimestamp: 'desc' }, + select: { + key: true, + messageTimestamp: true, + }, + }); + + const channelMap = new Map(); + + for (const msg of messages) { + const key = msg.key as any; + const remoteJid = key?.remoteJid as string | undefined; + if (!remoteJid || !isJidNewsletter(remoteJid)) continue; + + if (!channelMap.has(remoteJid)) { + channelMap.set(remoteJid, { + remoteJid, + pushName: undefined, // Push name is never stored for channels, so we set it as undefined + lastMessageTimestamp: msg.messageTimestamp, + }); + } + } + + const allChannels = Array.from(channelMap.values()); + + const total = allChannels.length; + const pages = Math.ceil(total / limit); + const records = allChannels.slice(skip, skip + limit); + + return { + total, + pages, + currentPage: page, + limit, + records, + }; } } diff --git a/src/api/routes/chat.router.ts b/src/api/routes/chat.router.ts index e374b6d6..d90f9b36 100644 --- a/src/api/routes/chat.router.ts +++ b/src/api/routes/chat.router.ts @@ -290,6 +290,12 @@ export class ChatRouter extends RouterBroker { schema: decryptPollVoteSchema, ClassRef: DecryptPollVoteDto, execute: (instance, data) => chatController.decryptPollVote(instance, data), + .post(this.routerPath('findChannels'), ...guards, async (req, res) => { + const response = await this.dataValidate({ + request: req, + schema: contactValidateSchema, + ClassRef: Query, + execute: (instance, query) => chatController.fetchChannels(instance, query as any), }); return res.status(HttpStatus.OK).json(response); diff --git a/src/utils/createJid.ts b/src/utils/createJid.ts index a680e821..23a3afe1 100644 --- a/src/utils/createJid.ts +++ b/src/utils/createJid.ts @@ -35,7 +35,12 @@ function formatBRNumber(jid: string) { export function createJid(number: string): string { number = number.replace(/:\d+/, ''); - if (number.includes('@g.us') || number.includes('@s.whatsapp.net') || number.includes('@lid')) { + if ( + number.includes('@g.us') || + number.includes('@s.whatsapp.net') || + number.includes('@lid') || + number.includes('@newsletter') + ) { return number; }