mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-18 19:32:21 -06:00
Merge branch 'EvolutionAPI:v2.0.0' into v2.0.0
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { InstanceDto } from '@api/dto/instance.dto';
|
||||
import { cache, waMonitor } from '@api/server.module';
|
||||
import { cache, prismaRepository, waMonitor } from '@api/server.module';
|
||||
import { CacheConf, configService } from '@config/env.config';
|
||||
import { BadRequestException, ForbiddenException, InternalServerErrorException, NotFoundException } from '@exceptions';
|
||||
import { prismaServer } from '@libs/prisma.connect';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
|
||||
async function getInstance(instanceName: string) {
|
||||
@@ -17,9 +16,7 @@ async function getInstance(instanceName: string) {
|
||||
return exists || keyExists;
|
||||
}
|
||||
|
||||
const prisma = prismaServer;
|
||||
|
||||
return exists || (await prisma.instance.findMany({ where: { name: instanceName } })).length > 0;
|
||||
return exists || (await prismaRepository.instance.findMany({ where: { name: instanceName } })).length > 0;
|
||||
} catch (error) {
|
||||
throw new InternalServerErrorException(error?.toString());
|
||||
}
|
||||
|
||||
@@ -1195,10 +1195,11 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
);
|
||||
}
|
||||
|
||||
this.prismaRepository.contact.updateMany({
|
||||
where: { remoteJid: received.key.remoteJid, instanceId: this.instanceId },
|
||||
data: contactRaw,
|
||||
});
|
||||
if (this.configService.get<Database>('DATABASE').SAVE_DATA.CONTACTS)
|
||||
await this.prismaRepository.contact.create({
|
||||
data: contactRaw,
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1743,9 +1744,25 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
}
|
||||
|
||||
if (sender === 'status@broadcast') {
|
||||
const jidList = message['status'].option.statusJidList;
|
||||
let jidList;
|
||||
if (message['status'].option.allContacts) {
|
||||
const contacts = await this.prismaRepository.contact.findMany({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
remoteJid: {
|
||||
not: {
|
||||
endsWith: '@g.us',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const batchSize = 500;
|
||||
jidList = contacts.map((contact) => contact.remoteJid);
|
||||
} else {
|
||||
jidList = message['status'].option.statusJidList;
|
||||
}
|
||||
|
||||
const batchSize = 10;
|
||||
|
||||
const batches = Array.from({ length: Math.ceil(jidList.length / batchSize) }, (_, i) =>
|
||||
jidList.slice(i * batchSize, i * batchSize + batchSize),
|
||||
@@ -2736,7 +2753,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
if (!numberVerified && (user.number.startsWith('52') || user.number.startsWith('54'))) {
|
||||
let prefix = '';
|
||||
if (user.number.startsWith('52')) {
|
||||
prefix = '1';
|
||||
prefix = '';
|
||||
}
|
||||
if (user.number.startsWith('54')) {
|
||||
prefix = '9';
|
||||
|
||||
@@ -538,26 +538,37 @@ export class ChatwootService {
|
||||
|
||||
public async createConversation(instance: InstanceDto, body: any) {
|
||||
try {
|
||||
this.logger.verbose('--- Start createConversation ---');
|
||||
this.logger.verbose(`Instance: ${JSON.stringify(instance)}`);
|
||||
this.logger.verbose(`Body: ${JSON.stringify(body)}`);
|
||||
|
||||
const client = await this.clientCw(instance);
|
||||
|
||||
if (!client) {
|
||||
this.logger.warn('client not found');
|
||||
this.logger.warn(`Client not found for instance: ${JSON.stringify(instance)}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const cacheKey = `${instance.instanceName}:createConversation-${body.key.remoteJid}`;
|
||||
this.logger.verbose(`Cache key: ${cacheKey}`);
|
||||
|
||||
if (await this.cache.has(cacheKey)) {
|
||||
this.logger.verbose(`Cache hit for key: ${cacheKey}`);
|
||||
const conversationId = (await this.cache.get(cacheKey)) as number;
|
||||
this.logger.verbose(`Cached conversation ID: ${conversationId}`);
|
||||
let conversationExists: conversation | boolean;
|
||||
try {
|
||||
conversationExists = await client.conversations.get({
|
||||
accountId: this.provider.accountId,
|
||||
conversationId: conversationId,
|
||||
});
|
||||
this.logger.verbose(`Conversation exists: ${JSON.stringify(conversationExists)}`);
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting conversation: ${error}`);
|
||||
conversationExists = false;
|
||||
}
|
||||
if (!conversationExists) {
|
||||
this.logger.verbose('Conversation does not exist, re-calling createConversation');
|
||||
this.cache.delete(cacheKey);
|
||||
return await this.createConversation(instance, body);
|
||||
}
|
||||
@@ -566,30 +577,37 @@ export class ChatwootService {
|
||||
}
|
||||
|
||||
const isGroup = body.key.remoteJid.includes('@g.us');
|
||||
this.logger.verbose(`Is group: ${isGroup}`);
|
||||
|
||||
const chatId = isGroup ? body.key.remoteJid : body.key.remoteJid.split('@')[0];
|
||||
this.logger.verbose(`Chat ID: ${chatId}`);
|
||||
|
||||
let nameContact: string;
|
||||
|
||||
nameContact = !body.key.fromMe ? body.pushName : chatId;
|
||||
this.logger.verbose(`Name contact: ${nameContact}`);
|
||||
|
||||
const filterInbox = await this.getInbox(instance);
|
||||
|
||||
if (!filterInbox) {
|
||||
this.logger.warn('inbox not found');
|
||||
this.logger.warn(`Inbox not found for instance: ${JSON.stringify(instance)}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isGroup) {
|
||||
this.logger.verbose('Processing group conversation');
|
||||
const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId);
|
||||
this.logger.verbose(`Group metadata: ${JSON.stringify(group)}`);
|
||||
|
||||
nameContact = `${group.subject} (GROUP)`;
|
||||
|
||||
const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(
|
||||
body.key.participant.split('@')[0],
|
||||
);
|
||||
this.logger.verbose(`Participant profile picture URL: ${JSON.stringify(picture_url)}`);
|
||||
|
||||
const findParticipant = await this.findContact(instance, body.key.participant.split('@')[0]);
|
||||
this.logger.verbose(`Found participant: ${JSON.stringify(findParticipant)}`);
|
||||
|
||||
if (findParticipant) {
|
||||
if (!findParticipant.name || findParticipant.name === chatId) {
|
||||
@@ -612,8 +630,10 @@ export class ChatwootService {
|
||||
}
|
||||
|
||||
const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId);
|
||||
this.logger.verbose(`Contact profile picture URL: ${JSON.stringify(picture_url)}`);
|
||||
|
||||
let contact = await this.findContact(instance, chatId);
|
||||
this.logger.verbose(`Found contact: ${JSON.stringify(contact)}`);
|
||||
|
||||
if (contact) {
|
||||
if (!body.key.fromMe) {
|
||||
@@ -630,8 +650,10 @@ export class ChatwootService {
|
||||
)
|
||||
: false);
|
||||
|
||||
const contactNeedsUpdate = pictureNeedsUpdate || nameNeedsUpdate;
|
||||
if (contactNeedsUpdate) {
|
||||
this.logger.verbose(`Picture needs update: ${pictureNeedsUpdate}`);
|
||||
this.logger.verbose(`Name needs update: ${nameNeedsUpdate}`);
|
||||
|
||||
if (pictureNeedsUpdate || nameNeedsUpdate) {
|
||||
contact = await this.updateContact(instance, contact.id, {
|
||||
...(nameNeedsUpdate && { name: nameContact }),
|
||||
...(waProfilePictureFile === '' && { avatar: null }),
|
||||
@@ -653,38 +675,50 @@ export class ChatwootService {
|
||||
}
|
||||
|
||||
if (!contact) {
|
||||
this.logger.warn('contact not found');
|
||||
this.logger.warn('Contact not created or found');
|
||||
return null;
|
||||
}
|
||||
|
||||
const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id;
|
||||
this.logger.verbose(`Contact ID: ${contactId}`);
|
||||
|
||||
const contactConversations = (await client.contacts.listConversations({
|
||||
accountId: this.provider.accountId,
|
||||
id: contactId,
|
||||
})) as any;
|
||||
this.logger.verbose(`Contact conversations: ${JSON.stringify(contactConversations)}`);
|
||||
|
||||
if (contactConversations?.payload?.length) {
|
||||
if (!contactConversations || !contactConversations.payload) {
|
||||
this.logger.error('No conversations found or payload is undefined');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (contactConversations.payload.length) {
|
||||
let conversation: any;
|
||||
if (this.provider.reopenConversation) {
|
||||
conversation = contactConversations.payload.find((conversation) => conversation.inbox_id == filterInbox.id);
|
||||
this.logger.verbose(`Found conversation in reopenConversation mode: ${JSON.stringify(conversation)}`);
|
||||
|
||||
if (this.provider.conversationPending) {
|
||||
await client.conversations.toggleStatus({
|
||||
accountId: this.provider.accountId,
|
||||
conversationId: conversation.id,
|
||||
data: {
|
||||
status: 'pending',
|
||||
},
|
||||
});
|
||||
if (conversation) {
|
||||
await client.conversations.toggleStatus({
|
||||
accountId: this.provider.accountId,
|
||||
conversationId: conversation.id,
|
||||
data: {
|
||||
status: 'pending',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
conversation = contactConversations.payload.find(
|
||||
(conversation) => conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id,
|
||||
);
|
||||
this.logger.verbose(`Found conversation: ${JSON.stringify(conversation)}`);
|
||||
}
|
||||
|
||||
if (conversation) {
|
||||
this.logger.verbose(`Returning existing conversation ID: ${conversation.id}`);
|
||||
this.cache.set(cacheKey, conversation.id);
|
||||
return conversation.id;
|
||||
}
|
||||
@@ -705,14 +739,15 @@ export class ChatwootService {
|
||||
});
|
||||
|
||||
if (!conversation) {
|
||||
this.logger.warn('conversation not found');
|
||||
this.logger.warn('Conversation not created or found');
|
||||
return null;
|
||||
}
|
||||
|
||||
this.logger.verbose(`New conversation created with ID: ${conversation.id}`);
|
||||
this.cache.set(cacheKey, conversation.id);
|
||||
return conversation.id;
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
this.logger.error(`Error in createConversation: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import EventEmitter2 from 'eventemitter2';
|
||||
|
||||
const maxListeners = parseInt(process.env.EVENT_EMITTER_MAX_LISTENERS, 10) || 50;
|
||||
|
||||
export const eventEmitter = new EventEmitter2({
|
||||
delimiter: '.',
|
||||
newListener: false,
|
||||
ignoreErrors: false,
|
||||
maxListeners: 50,
|
||||
maxListeners: maxListeners,
|
||||
});
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Logger } from '@config/logger.config';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const logger = new Logger('Prisma');
|
||||
|
||||
export const prismaServer = (() => {
|
||||
logger.verbose('connecting');
|
||||
const db = new PrismaClient();
|
||||
|
||||
process.on('beforeExit', () => {
|
||||
logger.verbose('instance destroyed');
|
||||
db.$disconnect();
|
||||
});
|
||||
|
||||
return db;
|
||||
})();
|
||||
@@ -1,12 +1,10 @@
|
||||
import { prismaRepository } from '@api/server.module';
|
||||
import { CacheService } from '@api/services/cache.service';
|
||||
import { INSTANCE_DIR } from '@config/path.config';
|
||||
import { prismaServer } from '@libs/prisma.connect';
|
||||
import { AuthenticationState, BufferJSON, initAuthCreds, WAProto as proto } from 'baileys';
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
const prisma = prismaServer;
|
||||
|
||||
// const fixFileName = (file: string): string | undefined => {
|
||||
// if (!file) {
|
||||
// return undefined;
|
||||
@@ -18,7 +16,7 @@ const prisma = prismaServer;
|
||||
|
||||
export async function keyExists(sessionId: string): Promise<any> {
|
||||
try {
|
||||
const key = await prisma.session.findUnique({ where: { sessionId: sessionId } });
|
||||
const key = await prismaRepository.session.findUnique({ where: { sessionId: sessionId } });
|
||||
return !!key;
|
||||
} catch (error) {
|
||||
return false;
|
||||
@@ -29,13 +27,13 @@ export async function saveKey(sessionId: string, keyJson: any): Promise<any> {
|
||||
const exists = await keyExists(sessionId);
|
||||
try {
|
||||
if (!exists)
|
||||
return await prisma.session.create({
|
||||
return await prismaRepository.session.create({
|
||||
data: {
|
||||
sessionId: sessionId,
|
||||
creds: JSON.stringify(keyJson),
|
||||
},
|
||||
});
|
||||
await prisma.session.update({
|
||||
await prismaRepository.session.update({
|
||||
where: { sessionId: sessionId },
|
||||
data: { creds: JSON.stringify(keyJson) },
|
||||
});
|
||||
@@ -48,7 +46,7 @@ export async function getAuthKey(sessionId: string): Promise<any> {
|
||||
try {
|
||||
const register = await keyExists(sessionId);
|
||||
if (!register) return null;
|
||||
const auth = await prisma.session.findUnique({ where: { sessionId: sessionId } });
|
||||
const auth = await prismaRepository.session.findUnique({ where: { sessionId: sessionId } });
|
||||
return JSON.parse(auth?.creds);
|
||||
} catch (error) {
|
||||
return null;
|
||||
@@ -59,7 +57,7 @@ async function deleteAuthKey(sessionId: string): Promise<any> {
|
||||
try {
|
||||
const register = await keyExists(sessionId);
|
||||
if (!register) return;
|
||||
await prisma.session.delete({ where: { sessionId: sessionId } });
|
||||
await prismaRepository.session.delete({ where: { sessionId: sessionId } });
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user