feat: prisma and remove mongodb

This commit is contained in:
Davidson Gomes
2024-06-06 14:47:58 -03:00
parent 35f97e08dd
commit 36ec67cef9
76 changed files with 1663 additions and 3894 deletions

View File

@@ -1,3 +1,5 @@
import { Contact, Message, MessageUpdate } from '@prisma/client';
import { Logger } from '../../config/logger.config';
import {
ArchiveChatDto,
@@ -16,9 +18,7 @@ import {
WhatsAppNumberDto,
} from '../dto/chat.dto';
import { InstanceDto } from '../dto/instance.dto';
import { ContactQuery } from '../repository/mongodb/contact.repository';
import { MessageQuery } from '../repository/mongodb/message.repository';
import { MessageUpQuery } from '../repository/mongodb/messageUp.repository';
import { Query } from '../repository/repository.service';
import { WAMonitoringService } from '../services/monitor.service';
const logger = new Logger('ChatController');
@@ -61,7 +61,7 @@ export class ChatController {
return await this.waMonitor.waInstances[instanceName].fetchProfile(instanceName, data.number);
}
public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) {
public async fetchContacts({ instanceName }: InstanceDto, query: Query<Contact>) {
logger.verbose('requested fetchContacts from ' + instanceName + ' instance');
return await this.waMonitor.waInstances[instanceName].fetchContacts(query);
}
@@ -71,12 +71,12 @@ export class ChatController {
return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data);
}
public async fetchMessages({ instanceName }: InstanceDto, query: MessageQuery) {
public async fetchMessages({ instanceName }: InstanceDto, query: Query<Message>) {
logger.verbose('requested fetchMessages from ' + instanceName + ' instance');
return await this.waMonitor.waInstances[instanceName].fetchMessages(query);
}
public async fetchStatusMessage({ instanceName }: InstanceDto, query: MessageUpQuery) {
public async fetchStatusMessage({ instanceName }: InstanceDto, query: Query<MessageUpdate>) {
logger.verbose('requested fetchStatusMessage from ' + instanceName + ' instance');
return await this.waMonitor.waInstances[instanceName].fetchStatusMessage(query);
}

View File

@@ -1,3 +1,4 @@
import { JsonValue } from '@prisma/client/runtime/library';
import { delay } from '@whiskeysockets/baileys';
import { isURL } from 'class-validator';
import EventEmitter2 from 'eventemitter2';
@@ -13,8 +14,7 @@ import { SqsService } from '../integrations/sqs/services/sqs.service';
import { TypebotService } from '../integrations/typebot/services/typebot.service';
import { WebsocketService } from '../integrations/websocket/services/websocket.service';
import { ProviderFiles } from '../provider/sessions';
import { MongodbRepository } from '../repository/mongodb/repository.manager';
import { PrismaRepository } from '../repository/prisma/repository.service';
import { PrismaRepository } from '../repository/repository.service';
import { AuthService } from '../services/auth.service';
import { CacheService } from '../services/cache.service';
import { BaileysStartupService } from '../services/channels/whatsapp.baileys.service';
@@ -30,7 +30,6 @@ export class InstanceController {
constructor(
private readonly waMonitor: WAMonitoringService,
private readonly configService: ConfigService,
private readonly mongodbRepository: MongodbRepository,
private readonly prismaRepository: PrismaRepository,
private readonly eventEmitter: EventEmitter2,
private readonly authService: AuthService,
@@ -54,45 +53,45 @@ export class InstanceController {
public async createInstance({
instanceName,
webhook,
webhook_by_events,
webhook_base64,
events,
webhookByEvents,
webhookBase64,
webhookEvents,
qrcode,
number,
mobile,
integration,
token,
chatwoot_account_id,
chatwoot_token,
chatwoot_url,
chatwoot_sign_msg,
chatwoot_reopen_conversation,
chatwoot_conversation_pending,
chatwoot_import_contacts,
chatwoot_name_inbox,
chatwoot_merge_brazil_contacts,
chatwoot_import_messages,
chatwoot_days_limit_import_messages,
reject_call,
msg_call,
groups_ignore,
always_online,
read_messages,
read_status,
sync_full_history,
websocket_enabled,
websocket_events,
rabbitmq_enabled,
rabbitmq_events,
sqs_enabled,
sqs_events,
typebot_url,
chatwootAccountId,
chatwootToken,
chatwootUrl,
chatwootSignMsg,
chatwootReopenConversation,
chatwootConversationPending,
chatwootImportContacts,
chatwootNameInbox,
chatwootMergeBrazilContacts,
chatwootImportMessages,
chatwootDaysLimitImportMessages,
rejectCall,
msgCall,
groupsIgnore,
alwaysOnline,
readMessages,
readStatus,
syncFullHistory,
websocketEnabled,
websocketEvents,
rabbitmqEnabled,
rabbitmqEvents,
sqsEnabled,
sqsEvents,
typebotUrl,
typebot,
typebot_expire,
typebot_keyword_finish,
typebot_delay_message,
typebot_unknown_message,
typebot_listening_from_me,
typebotExpire,
typebotKeywordFinish,
typebotDelayMessage,
typebotUnknownMessage,
typebotListeningFromMe,
proxy,
}: InstanceDto) {
try {
@@ -111,7 +110,6 @@ export class InstanceController {
instance = new BusinessStartupService(
this.configService,
this.eventEmitter,
this.mongodbRepository,
this.prismaRepository,
this.cache,
this.chatwootCache,
@@ -122,7 +120,6 @@ export class InstanceController {
instance = new BaileysStartupService(
this.configService,
this.eventEmitter,
this.mongodbRepository,
this.prismaRepository,
this.cache,
this.chatwootCache,
@@ -131,11 +128,12 @@ export class InstanceController {
);
}
await this.waMonitor.saveInstance({ integration, instanceName, token, number, mobile });
const instanceId = v4();
await this.waMonitor.saveInstance({ instanceId, integration, instanceName, token, number, mobile });
instance.instanceName = instanceName;
const instanceId = v4();
instance.instanceId = instanceId;
instance.sendDataWebhook(Events.INSTANCE_CREATE, {
instanceName,
@@ -158,7 +156,7 @@ export class InstanceController {
this.logger.verbose('hash: ' + hash + ' generated');
let webhookEvents: string[];
let getWebhookEvents: string[];
if (webhook) {
if (!isURL(webhook, { require_tld: false })) {
@@ -168,7 +166,7 @@ export class InstanceController {
this.logger.verbose('creating webhook');
try {
let newEvents: string[] = [];
if (events.length === 0) {
if (webhookEvents.length === 0) {
newEvents = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
@@ -196,29 +194,31 @@ export class InstanceController {
'TYPEBOT_CHANGE_STATUS',
];
} else {
newEvents = events;
newEvents = webhookEvents;
}
this.webhookService.create(instance, {
enabled: true,
url: webhook,
events: newEvents,
webhook_by_events,
webhook_base64,
webhookByEvents,
webhookBase64,
});
webhookEvents = (await this.webhookService.find(instance)).events;
const webhookEventsJson: JsonValue = (await this.webhookService.find(instance)).events;
getWebhookEvents = Array.isArray(webhookEventsJson) ? webhookEventsJson.map((event) => String(event)) : [];
} catch (error) {
this.logger.log(error);
}
}
let websocketEvents: string[];
let getWebsocketEvents: string[];
if (websocket_enabled) {
if (websocketEnabled) {
this.logger.verbose('creating websocket');
try {
let newEvents: string[] = [];
if (websocket_events.length === 0) {
if (websocketEvents.length === 0) {
newEvents = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
@@ -246,26 +246,31 @@ export class InstanceController {
'TYPEBOT_CHANGE_STATUS',
];
} else {
newEvents = websocket_events;
newEvents = websocketEvents;
}
this.websocketService.create(instance, {
enabled: true,
events: newEvents,
});
websocketEvents = (await this.websocketService.find(instance)).events;
const websocketEventsJson: JsonValue = (await this.websocketService.find(instance)).events;
// websocketEvents = (await this.websocketService.find(instance)).events;
getWebsocketEvents = Array.isArray(websocketEventsJson)
? websocketEventsJson.map((event) => String(event))
: [];
} catch (error) {
this.logger.log(error);
}
}
let rabbitmqEvents: string[];
let getRabbitmqEvents: string[];
if (rabbitmq_enabled) {
if (rabbitmqEnabled) {
this.logger.verbose('creating rabbitmq');
try {
let newEvents: string[] = [];
if (rabbitmq_events.length === 0) {
if (rabbitmqEvents.length === 0) {
newEvents = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
@@ -293,26 +298,30 @@ export class InstanceController {
'TYPEBOT_CHANGE_STATUS',
];
} else {
newEvents = rabbitmq_events;
newEvents = rabbitmqEvents;
}
this.rabbitmqService.create(instance, {
enabled: true,
events: newEvents,
});
rabbitmqEvents = (await this.rabbitmqService.find(instance)).events;
const rabbitmqEventsJson: JsonValue = (await this.rabbitmqService.find(instance)).events;
getRabbitmqEvents = Array.isArray(rabbitmqEventsJson) ? rabbitmqEventsJson.map((event) => String(event)) : [];
// rabbitmqEvents = (await this.rabbitmqService.find(instance)).events;
} catch (error) {
this.logger.log(error);
}
}
let sqsEvents: string[];
let getSqsEvents: string[];
if (sqs_enabled) {
if (sqsEnabled) {
this.logger.verbose('creating sqs');
try {
let newEvents: string[] = [];
if (sqs_events.length === 0) {
if (sqsEvents.length === 0) {
newEvents = [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
@@ -340,14 +349,18 @@ export class InstanceController {
'TYPEBOT_CHANGE_STATUS',
];
} else {
newEvents = sqs_events;
newEvents = sqsEvents;
}
this.sqsService.create(instance, {
enabled: true,
events: newEvents,
});
sqsEvents = (await this.sqsService.find(instance)).events;
const sqsEventsJson: JsonValue = (await this.sqsService.find(instance)).events;
getSqsEvents = Array.isArray(sqsEventsJson) ? sqsEventsJson.map((event) => String(event)) : [];
// sqsEvents = (await this.sqsService.find(instance)).events;
} catch (error) {
this.logger.log(error);
}
@@ -361,27 +374,31 @@ export class InstanceController {
await this.proxyService.createProxy(instance, {
enabled: true,
proxy,
host: proxy.host,
port: proxy.port,
protocol: proxy.protocol,
username: proxy.username,
password: proxy.password,
});
}
if (typebot_url) {
if (typebotUrl) {
try {
if (!isURL(typebot_url, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in typebot_url');
if (!isURL(typebotUrl, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in typebotUrl');
}
this.logger.verbose('creating typebot');
this.typebotService.create(instance, {
enabled: true,
url: typebot_url,
url: typebotUrl,
typebot: typebot,
expire: typebot_expire,
keyword_finish: typebot_keyword_finish,
delay_message: typebot_delay_message,
unknown_message: typebot_unknown_message,
listening_from_me: typebot_listening_from_me,
expire: typebotExpire,
keywordFinish: typebotKeywordFinish,
delayMessage: typebotDelayMessage,
unknownMessage: typebotUnknownMessage,
listeningFromMe: typebotListeningFromMe,
});
} catch (error) {
this.logger.log(error);
@@ -390,29 +407,29 @@ export class InstanceController {
this.logger.verbose('creating settings');
const settings: wa.LocalSettings = {
reject_call: reject_call || false,
msg_call: msg_call || '',
groups_ignore: groups_ignore || true,
always_online: always_online || false,
read_messages: read_messages || false,
read_status: read_status || false,
sync_full_history: sync_full_history ?? false,
rejectCall: rejectCall || false,
msgCall: msgCall || '',
groupsIgnore: groupsIgnore || true,
alwaysOnline: alwaysOnline || false,
readMessages: readMessages || false,
readStatus: readStatus || false,
syncFullHistory: syncFullHistory ?? false,
};
this.logger.verbose('settings: ' + JSON.stringify(settings));
this.settingsService.create(instance, settings);
let webhook_wa_business = null,
access_token_wa_business = '';
let webhookWaBusiness = null,
accessTokenWaBusiness = '';
if (integration === Integration.WHATSAPP_BUSINESS) {
if (!number) {
throw new BadRequestException('number is required');
}
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
webhook_wa_business = `${urlServer}/webhook/whatsapp/${encodeURIComponent(instance.instanceName)}`;
access_token_wa_business = this.configService.get<WaBusiness>('WA_BUSINESS').TOKEN_WEBHOOK;
webhookWaBusiness = `${urlServer}/webhook/whatsapp/${encodeURIComponent(instance.instanceName)}`;
accessTokenWaBusiness = this.configService.get<WaBusiness>('WA_BUSINESS').TOKEN_WEBHOOK;
}
this.integrationService.create(instance, {
@@ -420,7 +437,7 @@ export class InstanceController {
number,
token,
});
if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) {
if (!chatwootAccountId || !chatwootToken || !chatwootUrl) {
let getQrcode: wa.QrCode;
if (qrcode) {
@@ -435,38 +452,38 @@ export class InstanceController {
instanceName: instance.instanceName,
instanceId: instanceId,
integration: integration,
webhook_wa_business,
access_token_wa_business,
webhookWaBusiness,
accessTokenWaBusiness,
status: 'created',
},
hash,
webhook: {
webhook,
webhook_by_events,
webhook_base64,
events: webhookEvents,
webhookByEvents,
webhookBase64,
events: getWebhookEvents,
},
websocket: {
enabled: websocket_enabled,
events: websocketEvents,
enabled: websocketEnabled,
events: getWebsocketEvents,
},
rabbitmq: {
enabled: rabbitmq_enabled,
events: rabbitmqEvents,
enabled: rabbitmqEnabled,
events: getRabbitmqEvents,
},
sqs: {
enabled: sqs_enabled,
events: sqsEvents,
enabled: sqsEnabled,
events: getSqsEvents,
},
typebot: {
enabled: typebot_url ? true : false,
url: typebot_url,
enabled: typebotUrl ? true : false,
url: typebotUrl,
typebot,
expire: typebot_expire,
keyword_finish: typebot_keyword_finish,
delay_message: typebot_delay_message,
unknown_message: typebot_unknown_message,
listening_from_me: typebot_listening_from_me,
expire: typebotExpire,
keywordFinish: typebotKeywordFinish,
delayMessage: typebotDelayMessage,
unknownMessage: typebotUnknownMessage,
listeningFromMe: typebotListeningFromMe,
},
settings,
qrcode: getQrcode,
@@ -478,32 +495,32 @@ export class InstanceController {
return result;
}
if (!chatwoot_account_id) {
throw new BadRequestException('account_id is required');
if (!chatwootAccountId) {
throw new BadRequestException('accountId is required');
}
if (!chatwoot_token) {
if (!chatwootToken) {
throw new BadRequestException('token is required');
}
if (!chatwoot_url) {
if (!chatwootUrl) {
throw new BadRequestException('url is required');
}
if (!isURL(chatwoot_url, { require_tld: false })) {
if (!isURL(chatwootUrl, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in chatwoot');
}
if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) {
throw new BadRequestException('sign_msg is required');
if (chatwootSignMsg !== true && chatwootSignMsg !== false) {
throw new BadRequestException('signMsg is required');
}
if (chatwoot_reopen_conversation !== true && chatwoot_reopen_conversation !== false) {
throw new BadRequestException('reopen_conversation is required');
if (chatwootReopenConversation !== true && chatwootReopenConversation !== false) {
throw new BadRequestException('reopenConversation is required');
}
if (chatwoot_conversation_pending !== true && chatwoot_conversation_pending !== false) {
throw new BadRequestException('conversation_pending is required');
if (chatwootConversationPending !== true && chatwootConversationPending !== false) {
throw new BadRequestException('conversationPending is required');
}
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
@@ -511,19 +528,19 @@ export class InstanceController {
try {
this.chatwootService.create(instance, {
enabled: true,
account_id: chatwoot_account_id,
token: chatwoot_token,
url: chatwoot_url,
sign_msg: chatwoot_sign_msg || false,
name_inbox: chatwoot_name_inbox ?? instance.instanceName.split('-cwId-')[0],
accountId: chatwootAccountId,
token: chatwootToken,
url: chatwootUrl,
signMsg: chatwootSignMsg || false,
nameInbox: chatwootNameInbox ?? instance.instanceName.split('-cwId-')[0],
number,
reopen_conversation: chatwoot_reopen_conversation || false,
conversation_pending: chatwoot_conversation_pending || false,
import_contacts: chatwoot_import_contacts ?? true,
merge_brazil_contacts: chatwoot_merge_brazil_contacts ?? false,
import_messages: chatwoot_import_messages ?? true,
days_limit_import_messages: chatwoot_days_limit_import_messages ?? 60,
auto_create: true,
reopenConversation: chatwootReopenConversation || false,
conversationPending: chatwootConversationPending || false,
importContacts: chatwootImportContacts ?? true,
mergeBrazilContacts: chatwootMergeBrazilContacts ?? false,
importMessages: chatwootImportMessages ?? true,
daysLimitImportMessages: chatwootDaysLimitImportMessages ?? 60,
autoCreate: true,
});
} catch (error) {
this.logger.log(error);
@@ -534,55 +551,55 @@ export class InstanceController {
instanceName: instance.instanceName,
instanceId: instanceId,
integration: integration,
webhook_wa_business,
access_token_wa_business,
webhookWaBusiness,
accessTokenWaBusiness,
status: 'created',
},
hash,
webhook: {
webhook,
webhook_by_events,
webhook_base64,
events: webhookEvents,
webhookByEvents,
webhookBase64,
events: getWebhookEvents,
},
websocket: {
enabled: websocket_enabled,
events: websocketEvents,
enabled: websocketEnabled,
events: getWebsocketEvents,
},
rabbitmq: {
enabled: rabbitmq_enabled,
events: rabbitmqEvents,
enabled: rabbitmqEnabled,
events: getRabbitmqEvents,
},
sqs: {
enabled: sqs_enabled,
events: sqsEvents,
enabled: sqsEnabled,
events: getSqsEvents,
},
typebot: {
enabled: typebot_url ? true : false,
url: typebot_url,
enabled: typebotUrl ? true : false,
url: typebotUrl,
typebot,
expire: typebot_expire,
keyword_finish: typebot_keyword_finish,
delay_message: typebot_delay_message,
unknown_message: typebot_unknown_message,
listening_from_me: typebot_listening_from_me,
expire: typebotExpire,
keywordFinish: typebotKeywordFinish,
delayMessage: typebotDelayMessage,
unknownMessage: typebotUnknownMessage,
listeningFromMe: typebotListeningFromMe,
},
settings,
chatwoot: {
enabled: true,
account_id: chatwoot_account_id,
token: chatwoot_token,
url: chatwoot_url,
sign_msg: chatwoot_sign_msg || false,
reopen_conversation: chatwoot_reopen_conversation || false,
conversation_pending: chatwoot_conversation_pending || false,
merge_brazil_contacts: chatwoot_merge_brazil_contacts ?? false,
import_contacts: chatwoot_import_contacts ?? true,
import_messages: chatwoot_import_messages ?? true,
days_limit_import_messages: chatwoot_days_limit_import_messages || 60,
accountId: chatwootAccountId,
token: chatwootToken,
url: chatwootUrl,
signMsg: chatwootSignMsg || false,
reopenConversation: chatwootReopenConversation || false,
conversationPending: chatwootConversationPending || false,
mergeBrazilContacts: chatwootMergeBrazilContacts ?? false,
importContacts: chatwootImportContacts ?? true,
importMessages: chatwootImportMessages ?? true,
daysLimitImportMessages: chatwootDaysLimitImportMessages || 60,
number,
name_inbox: chatwoot_name_inbox ?? instance.instanceName,
webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,
nameInbox: chatwootNameInbox ?? instance.instanceName,
webhookUrl: `${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,
},
};
} catch (error) {
@@ -686,9 +703,17 @@ export class InstanceController {
let arrayReturn = false;
if (env.KEY !== key) {
const instanceByKey = await this.mongodbRepository.auth.findByKey(key);
const instanceByKey = await this.prismaRepository.auth.findUnique({
where: {
apikey: key,
},
include: {
Instance: true,
},
});
if (instanceByKey) {
name = instanceByKey._id;
name = instanceByKey.Instance.name;
arrayReturn = true;
} else {
throw new UnauthorizedException();
@@ -737,8 +762,9 @@ export class InstanceController {
throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected');
}
try {
this.waMonitor.waInstances[instanceName]?.removeRabbitmqQueues();
this.waMonitor.waInstances[instanceName]?.clearCacheChatwoot();
const waInstances = this.waMonitor.waInstances[instanceName];
waInstances?.removeRabbitmqQueues();
waInstances?.clearCacheChatwoot();
if (instance.state === 'connecting') {
this.logger.verbose('logging out instance: ' + instanceName);
@@ -749,9 +775,9 @@ export class InstanceController {
this.logger.verbose('deleting instance: ' + instanceName);
try {
this.waMonitor.waInstances[instanceName]?.sendDataWebhook(Events.INSTANCE_DELETE, {
waInstances?.sendDataWebhook(Events.INSTANCE_DELETE, {
instanceName,
instanceId: (await this.mongodbRepository.auth.find(instanceName))?.instanceId,
instanceId: waInstances.instanceId,
});
} catch (error) {
this.logger.error(error);

View File

@@ -22,11 +22,15 @@ export class ProxyController {
if (!data.enabled) {
logger.verbose('proxy disabled');
data.proxy = null;
data.host = '';
data.port = '';
data.protocol = '';
data.username = '';
data.password = '';
}
if (data.proxy) {
const testProxy = await this.testProxy(data.proxy);
if (data.host) {
const testProxy = await this.testProxy(data);
if (!testProxy) {
throw new BadRequestException('Invalid proxy');
}
@@ -46,7 +50,7 @@ export class ProxyController {
return this.proxyService.find(instance);
}
public async testProxy(proxy: ProxyDto['proxy']) {
public async testProxy(proxy: ProxyDto) {
logger.verbose('requested testProxy');
try {
const serverIp = await axios.get('https://icanhazip.com/');