From d52256718df45555567bb6e68b54fb859518f83e Mon Sep 17 00:00:00 2001 From: luiis716 <97978347+luiis716@users.noreply.github.com> Date: Sat, 3 May 2025 14:55:07 -0300 Subject: [PATCH 1/2] Findchat group name treatment ajusta para endpoint puxa o nome do grupo correntemente quando for grupo usando nomenclatura @g.us --- src/api/services/channel.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/services/channel.service.ts b/src/api/services/channel.service.ts index 0f30f0c99..f7e1eb9bc 100644 --- a/src/api/services/channel.service.ts +++ b/src/api/services/channel.service.ts @@ -694,7 +694,7 @@ export class ChannelStartupService { SELECT DISTINCT ON ("Contact"."remoteJid") "Contact"."id", "Contact"."remoteJid", - "Contact"."pushName", + "Chat"."name" as "pushName", "Contact"."profilePicUrl", COALESCE( to_timestamp("Message"."messageTimestamp"::double precision), From a449fdf0efb8bf6348189d211a8f4fe9626ebaca Mon Sep 17 00:00:00 2001 From: luiis716 <97978347+luiis716@users.noreply.github.com> Date: Mon, 12 May 2025 16:14:59 -0300 Subject: [PATCH 2/2] Findchat group name treatment --- src/api/services/channel.service.ts | 163 ++++++++++++++++------------ 1 file changed, 95 insertions(+), 68 deletions(-) diff --git a/src/api/services/channel.service.ts b/src/api/services/channel.service.ts index f7e1eb9bc..d33fcbd69 100644 --- a/src/api/services/channel.service.ts +++ b/src/api/services/channel.service.ts @@ -503,8 +503,29 @@ export class ChannelStartupService { where['remoteJid'] = remoteJid; } - return await this.prismaRepository.contact.findMany({ + const contactFindManyArgs: Prisma.ContactFindManyArgs = { where, + }; + + if (query.offset) contactFindManyArgs.take = query.offset; + if (query.page) { + const validPage = Math.max(query.page as number, 1); + contactFindManyArgs.skip = query.offset * (validPage - 1); + } + + const contacts = await this.prismaRepository.contact.findMany(contactFindManyArgs); + + return contacts.map((contact) => { + const remoteJid = contact.remoteJid; + const isGroup = remoteJid.endsWith('@g.us'); + const isSaved = !!contact.pushName || !!contact.profilePicUrl; + const type = isGroup ? 'group' : isSaved ? 'contact' : 'group_member'; + return { + ...contact, + isGroup, + isSaved, + type, + }; }); } @@ -685,88 +706,94 @@ export class ChannelStartupService { const timestampFilter = query?.where?.messageTimestamp?.gte && query?.where?.messageTimestamp?.lte ? Prisma.sql` - AND "Message"."messageTimestamp" >= ${Math.floor(new Date(query.where.messageTimestamp.gte).getTime() / 1000)} - AND "Message"."messageTimestamp" <= ${Math.floor(new Date(query.where.messageTimestamp.lte).getTime() / 1000)}` + AND "Message"."messageTimestamp" >= ${Math.floor(new Date(query.where.messageTimestamp.gte).getTime() / 1000)} + AND "Message"."messageTimestamp" <= ${Math.floor(new Date(query.where.messageTimestamp.lte).getTime() / 1000)}` : Prisma.sql``; + const limit = query?.take ? Prisma.sql`LIMIT ${query.take}` : Prisma.sql``; + const offset = query?.skip ? Prisma.sql`OFFSET ${query.skip}` : Prisma.sql``; + const results = await this.prismaRepository.$queryRaw` - WITH rankedMessages AS ( - SELECT DISTINCT ON ("Contact"."remoteJid") - "Contact"."id", - "Contact"."remoteJid", - "Chat"."name" as "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``} - ${timestampFilter} - ORDER BY - "Contact"."remoteJid", - "Message"."messageTimestamp" DESC - ) - SELECT * FROM rankedMessages - ORDER BY "updatedAt" DESC NULLS LAST; + WITH rankedMessages AS ( + SELECT DISTINCT ON ("Message"."key"->>'remoteJid') + "Contact"."id" as "contactId", + "Message"."key"->>'remoteJid' as "remoteJid", + COALESCE("Contact"."pushName", "Message"."pushName") as "pushName", + "Contact"."profilePicUrl", + COALESCE( + to_timestamp("Message"."messageTimestamp"::double precision), + "Contact"."updatedAt" + ) as "updatedAt", + "Chat"."name" as "pushName", + "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 "Message" + LEFT JOIN "Contact" ON "Contact"."remoteJid" = "Message"."key"->>'remoteJid' AND "Contact"."instanceId" = "Message"."instanceId" + LEFT JOIN "Chat" ON "Chat"."remoteJid" = "Message"."key"->>'remoteJid' AND "Chat"."instanceId" = "Message"."instanceId" + WHERE "Message"."instanceId" = ${this.instanceId} + ${remoteJid ? Prisma.sql`AND "Message"."key"->>'remoteJid' = ${remoteJid}` : Prisma.sql``} + ${timestampFilter} + ORDER BY "Message"."key"->>'remoteJid', "Message"."messageTimestamp" DESC + ) + SELECT * FROM rankedMessages + ORDER BY "updatedAt" DESC NULLS LAST + ${limit} + ${offset}; `; if (results && isArray(results) && results.length > 0) { - const mappedResults = results.map((contact) => { - const lastMessage = contact.lastMessageId + const mappedResults = results.map((item) => { + const lastMessage = item.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, + id: item.lastMessageId, + key: item.lastMessage_key, + pushName: item.lastMessagePushName, + participant: item.lastMessageParticipant, + messageType: item.lastMessageMessageType, + message: item.lastMessageMessage, + contextInfo: item.lastMessageContextInfo, + source: item.lastMessageSource, + messageTimestamp: item.lastMessageMessageTimestamp, + instanceId: item.lastMessageInstanceId, + sessionId: item.lastMessageSessionId, + status: item.lastMessageStatus, } : undefined; return { - id: contact.id, - remoteJid: contact.remoteJid, - pushName: contact.pushName, - profilePicUrl: contact.profilePicUrl, - updatedAt: contact.updatedAt, - windowStart: contact.windowStart, - windowExpires: contact.windowExpires, - windowActive: contact.windowActive, + id: item.contactId || null, + remoteJid: item.remoteJid, + pushName: item.pushName, + profilePicUrl: item.profilePicUrl, + updatedAt: item.updatedAt, + windowStart: item.windowStart, + windowExpires: item.windowExpires, + windowActive: item.windowActive, lastMessage: lastMessage ? this.cleanMessageData(lastMessage) : undefined, + unreadCount: 0, + isSaved: !!item.contactId, }; }); + if (query?.take && query?.skip) { + const skip = query.skip || 0; + const take = query.take || 20; + return mappedResults.slice(skip, skip + take); + } + return mappedResults; }