mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-16 12:12:55 -06:00
Merge pull request #1449 from gomessguii/feature/enhance-message-fetching
feat(whatsapp): enhance message fetching and processing logic
This commit is contained in:
commit
a1cc504777
@ -55,7 +55,7 @@ import {
|
|||||||
import { chatwootImport } from '@api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper';
|
import { chatwootImport } from '@api/integrations/chatbot/chatwoot/utils/chatwoot-import-helper';
|
||||||
import * as s3Service from '@api/integrations/storage/s3/libs/minio.server';
|
import * as s3Service from '@api/integrations/storage/s3/libs/minio.server';
|
||||||
import { ProviderFiles } from '@api/provider/sessions';
|
import { ProviderFiles } from '@api/provider/sessions';
|
||||||
import { PrismaRepository } from '@api/repository/repository.service';
|
import { PrismaRepository, Query } from '@api/repository/repository.service';
|
||||||
import { chatbotController, waMonitor } from '@api/server.module';
|
import { chatbotController, waMonitor } from '@api/server.module';
|
||||||
import { CacheService } from '@api/services/cache.service';
|
import { CacheService } from '@api/services/cache.service';
|
||||||
import { ChannelStartupService } from '@api/services/channel.service';
|
import { ChannelStartupService } from '@api/services/channel.service';
|
||||||
@ -78,7 +78,7 @@ import { BadRequestException, InternalServerErrorException, NotFoundException }
|
|||||||
import ffmpegPath from '@ffmpeg-installer/ffmpeg';
|
import ffmpegPath from '@ffmpeg-installer/ffmpeg';
|
||||||
import { Boom } from '@hapi/boom';
|
import { Boom } from '@hapi/boom';
|
||||||
import { createId as cuid } from '@paralleldrive/cuid2';
|
import { createId as cuid } from '@paralleldrive/cuid2';
|
||||||
import { Instance } from '@prisma/client';
|
import { Instance, Message } from '@prisma/client';
|
||||||
import { createJid } from '@utils/createJid';
|
import { createJid } from '@utils/createJid';
|
||||||
import { makeProxyAgent } from '@utils/makeProxyAgent';
|
import { makeProxyAgent } from '@utils/makeProxyAgent';
|
||||||
import { getOnWhatsappCache, saveOnWhatsappCache } from '@utils/onWhatsappCache';
|
import { getOnWhatsappCache, saveOnWhatsappCache } from '@utils/onWhatsappCache';
|
||||||
@ -664,6 +664,10 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
qrTimeout: 45_000,
|
qrTimeout: 45_000,
|
||||||
emitOwnEvents: false,
|
emitOwnEvents: false,
|
||||||
shouldIgnoreJid: (jid) => {
|
shouldIgnoreJid: (jid) => {
|
||||||
|
if (this.localSettings.syncFullHistory && isJidGroup(jid)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const isGroupJid = this.localSettings.groupsIgnore && isJidGroup(jid);
|
const isGroupJid = this.localSettings.groupsIgnore && isJidGroup(jid);
|
||||||
const isBroadcast = !this.localSettings.readStatus && isJidBroadcast(jid);
|
const isBroadcast = !this.localSettings.readStatus && isJidBroadcast(jid);
|
||||||
const isNewsletter = isJidNewsletter(jid);
|
const isNewsletter = isJidNewsletter(jid);
|
||||||
@ -991,6 +995,17 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contactsMap = new Map();
|
||||||
|
|
||||||
|
for (const contact of contacts) {
|
||||||
|
if (contact.id && (contact.notify || contact.name)) {
|
||||||
|
contactsMap.set(contact.id, {
|
||||||
|
name: contact.name ?? contact.notify,
|
||||||
|
jid: contact.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const chatsRaw: { remoteJid: string; instanceId: string; name?: string }[] = [];
|
const chatsRaw: { remoteJid: string; instanceId: string; name?: string }[] = [];
|
||||||
const chatsRepository = new Set(
|
const chatsRepository = new Set(
|
||||||
(
|
(
|
||||||
@ -1062,6 +1077,15 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m.pushName && !m.key.fromMe) {
|
||||||
|
const participantJid = m.participant || m.key.participant || m.key.remoteJid;
|
||||||
|
if (participantJid && contactsMap.has(participantJid)) {
|
||||||
|
m.pushName = contactsMap.get(participantJid).name;
|
||||||
|
} else if (participantJid) {
|
||||||
|
m.pushName = participantJid.split('@')[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
messagesRaw.push(this.prepareMessage(m));
|
messagesRaw.push(this.prepareMessage(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1173,25 +1197,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (received.messageStubParameters && received.messageStubParameters[0] === 'Message absent from node') {
|
|
||||||
// this.logger.info(`Recovering message lost messageId: ${received.key.id}`);
|
|
||||||
|
|
||||||
// await this.baileysCache.set(received.key.id, {
|
|
||||||
// message: received,
|
|
||||||
// retry: 0,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const retryCache = (await this.baileysCache.get(received.key.id)) || null;
|
|
||||||
|
|
||||||
// if (retryCache) {
|
|
||||||
// this.logger.info('Recovered message lost');
|
|
||||||
// await this.baileysCache.delete(received.key.id);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Cache to avoid duplicate messages
|
|
||||||
const messageKey = `${this.instance.id}_${received.key.id}`;
|
const messageKey = `${this.instance.id}_${received.key.id}`;
|
||||||
const cached = await this.baileysCache.get(messageKey);
|
const cached = await this.baileysCache.get(messageKey);
|
||||||
|
|
||||||
@ -1218,6 +1223,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
if (settings?.groupsIgnore && received.key.remoteJid.includes('@g.us')) {
|
if (settings?.groupsIgnore && received.key.remoteJid.includes('@g.us')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingChat = await this.prismaRepository.chat.findFirst({
|
const existingChat = await this.prismaRepository.chat.findFirst({
|
||||||
where: { instanceId: this.instanceId, remoteJid: received.key.remoteJid },
|
where: { instanceId: this.instanceId, remoteJid: received.key.remoteJid },
|
||||||
select: { id: true, name: true },
|
select: { id: true, name: true },
|
||||||
@ -4481,7 +4487,11 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
|
|
||||||
const messageRaw = {
|
const messageRaw = {
|
||||||
key: message.key,
|
key: message.key,
|
||||||
pushName: message.pushName,
|
pushName:
|
||||||
|
message.pushName ||
|
||||||
|
(message.key.fromMe
|
||||||
|
? 'Você'
|
||||||
|
: message?.participant || (message.key?.participant ? message.key.participant.split('@')[0] : null)),
|
||||||
status: status[message.status],
|
status: status[message.status],
|
||||||
message: { ...message.message },
|
message: { ...message.message },
|
||||||
contextInfo: contentMsg?.contextInfo,
|
contextInfo: contentMsg?.contextInfo,
|
||||||
@ -4849,4 +4859,112 @@ export class BaileysStartupService extends ChannelStartupService {
|
|||||||
throw new InternalServerErrorException('Error getCatalog', error.toString());
|
throw new InternalServerErrorException('Error getCatalog', error.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async fetchMessages(query: Query<Message>) {
|
||||||
|
const keyFilters = query?.where?.key as {
|
||||||
|
id?: string;
|
||||||
|
fromMe?: boolean;
|
||||||
|
remoteJid?: string;
|
||||||
|
participants?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const timestampFilter = {};
|
||||||
|
if (query?.where?.messageTimestamp) {
|
||||||
|
if (query.where.messageTimestamp['gte'] && query.where.messageTimestamp['lte']) {
|
||||||
|
timestampFilter['messageTimestamp'] = {
|
||||||
|
gte: Math.floor(new Date(query.where.messageTimestamp['gte']).getTime() / 1000),
|
||||||
|
lte: Math.floor(new Date(query.where.messageTimestamp['lte']).getTime() / 1000),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const count = await this.prismaRepository.message.count({
|
||||||
|
where: {
|
||||||
|
instanceId: this.instanceId,
|
||||||
|
id: query?.where?.id,
|
||||||
|
source: query?.where?.source,
|
||||||
|
messageType: query?.where?.messageType,
|
||||||
|
...timestampFilter,
|
||||||
|
AND: [
|
||||||
|
keyFilters?.id ? { key: { path: ['id'], equals: keyFilters?.id } } : {},
|
||||||
|
keyFilters?.fromMe ? { key: { path: ['fromMe'], equals: keyFilters?.fromMe } } : {},
|
||||||
|
keyFilters?.remoteJid ? { key: { path: ['remoteJid'], equals: keyFilters?.remoteJid } } : {},
|
||||||
|
keyFilters?.participants ? { key: { path: ['participants'], equals: keyFilters?.participants } } : {},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!query?.offset) {
|
||||||
|
query.offset = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query?.page) {
|
||||||
|
query.page = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = await this.prismaRepository.message.findMany({
|
||||||
|
where: {
|
||||||
|
instanceId: this.instanceId,
|
||||||
|
id: query?.where?.id,
|
||||||
|
source: query?.where?.source,
|
||||||
|
messageType: query?.where?.messageType,
|
||||||
|
...timestampFilter,
|
||||||
|
AND: [
|
||||||
|
keyFilters?.id ? { key: { path: ['id'], equals: keyFilters?.id } } : {},
|
||||||
|
keyFilters?.fromMe ? { key: { path: ['fromMe'], equals: keyFilters?.fromMe } } : {},
|
||||||
|
keyFilters?.remoteJid ? { key: { path: ['remoteJid'], equals: keyFilters?.remoteJid } } : {},
|
||||||
|
keyFilters?.participants ? { key: { path: ['participants'], equals: keyFilters?.participants } } : {},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
messageTimestamp: 'desc',
|
||||||
|
},
|
||||||
|
skip: query.offset * (query?.page === 1 ? 0 : (query?.page as number) - 1),
|
||||||
|
take: query.offset,
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
key: true,
|
||||||
|
pushName: true,
|
||||||
|
messageType: true,
|
||||||
|
message: true,
|
||||||
|
messageTimestamp: true,
|
||||||
|
instanceId: true,
|
||||||
|
source: true,
|
||||||
|
contextInfo: true,
|
||||||
|
MessageUpdate: {
|
||||||
|
select: {
|
||||||
|
status: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const formattedMessages = messages.map((message) => {
|
||||||
|
const messageKey = message.key as { fromMe: boolean; remoteJid: string; id: string; participant?: string };
|
||||||
|
|
||||||
|
if (!message.pushName) {
|
||||||
|
if (messageKey.fromMe) {
|
||||||
|
message.pushName = 'Você';
|
||||||
|
} else if (message.contextInfo) {
|
||||||
|
const contextInfo = message.contextInfo as { participant?: string };
|
||||||
|
if (contextInfo.participant) {
|
||||||
|
message.pushName = contextInfo.participant.split('@')[0];
|
||||||
|
} else if (messageKey.participant) {
|
||||||
|
message.pushName = messageKey.participant.split('@')[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
messages: {
|
||||||
|
total: count,
|
||||||
|
pages: Math.ceil(count / query.offset),
|
||||||
|
currentPage: query.page,
|
||||||
|
records: formattedMessages,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user