mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-14 01:41:24 -06:00
feat: prisma and remove mongodb
This commit is contained in:
parent
35f97e08dd
commit
36ec67cef9
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,7 +1,17 @@
|
||||
# 1.8.1 (develop)
|
||||
# 2.0.0 (develop)
|
||||
|
||||
### Feature
|
||||
* New method of saving sessions to a file using worker, made in partnership with [codechat](https://github.com/code-chat-br/whatsapp-api)
|
||||
* Added prism orm, connection to postgres and mysql
|
||||
|
||||
### Fixed
|
||||
*
|
||||
|
||||
### Break changes
|
||||
* jwt authentication removed
|
||||
* Connection to mongodb removed
|
||||
* Standardized all request bodies to use camelCase
|
||||
* Change in webhook information from owner to instanceId
|
||||
|
||||
# 1.8.0 (2024-05-27 16:10)
|
||||
|
||||
|
@ -74,7 +74,6 @@
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"libphonenumber-js": "^1.10.39",
|
||||
"link-preview-js": "^3.0.4",
|
||||
"mongoose": "^6.10.5",
|
||||
"node-cache": "^5.1.2",
|
||||
"node-mime-types": "^1.1.0",
|
||||
"node-windows": "^1.0.0-beta.8",
|
||||
|
@ -34,9 +34,8 @@ enum TypebotSessionStatus {
|
||||
}
|
||||
|
||||
model Instance {
|
||||
id Int @id @default(autoincrement())
|
||||
id String @id @default(cuid())
|
||||
name String @unique @db.VarChar(255)
|
||||
description String? @db.VarChar(255)
|
||||
connectionStatus InstanceConnectionStatus @default(open)
|
||||
ownerJid String? @db.VarChar(100)
|
||||
profilePicUrl String? @db.VarChar(500)
|
||||
@ -60,33 +59,31 @@ model Instance {
|
||||
}
|
||||
|
||||
model Session {
|
||||
id Int @id @unique @default(autoincrement())
|
||||
sessionId String @unique @default(cuid())
|
||||
creds String? @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique @db.Integer
|
||||
|
||||
@@map("sessions")
|
||||
id Int @id @unique @default(autoincrement())
|
||||
sessionId String @unique
|
||||
creds String? @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
Instance Instance @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model Auth {
|
||||
id Int @id @default(autoincrement())
|
||||
apiKey String @unique
|
||||
apikey String @unique
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime? @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique @db.Integer
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Chat {
|
||||
id Int @id @default(autoincrement())
|
||||
lastMsgTimestamp DateTime? @db.Timestamp
|
||||
remoteJid String @db.VarChar(100)
|
||||
lastMsgTimestamp String? @db.VarChar(100)
|
||||
labels Json? @db.JsonB
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime? @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int
|
||||
instanceId String
|
||||
}
|
||||
|
||||
model Contact {
|
||||
@ -97,79 +94,77 @@ model Contact {
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime? @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int
|
||||
instanceId String
|
||||
}
|
||||
|
||||
model Message {
|
||||
id Int @id @default(autoincrement())
|
||||
keyId String @db.VarChar(100)
|
||||
keyRemoteJid String @db.VarChar(100)
|
||||
keyFromMe Boolean @db.Boolean
|
||||
keyParticipant String? @db.VarChar(100)
|
||||
key Json @db.JsonB
|
||||
pushName String? @db.VarChar(100)
|
||||
participant String? @db.VarChar(100)
|
||||
messageType String @db.VarChar(100)
|
||||
message Json @db.JsonB
|
||||
contextInfo Json? @db.JsonB
|
||||
source DeviceMessage
|
||||
messageTimestamp Int @db.Integer
|
||||
messageTimestamp String @db.VarChar(100)
|
||||
chatwootMessageId Int? @db.Integer
|
||||
chatwootInboxId Int? @db.Integer
|
||||
chatwootConversationId Int? @db.Integer
|
||||
chatwootContactInboxSourceId String? @db.VarChar(100)
|
||||
chatwotIsRead Boolean? @db.Boolean
|
||||
chatwootIsRead Boolean? @db.Boolean
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int
|
||||
instanceId String
|
||||
typebotSessionId Int?
|
||||
MessageUpdate MessageUpdate[]
|
||||
TypebotSession TypebotSession? @relation(fields: [typebotSessionId], references: [id])
|
||||
|
||||
@@index([keyId], name: "keyId")
|
||||
}
|
||||
|
||||
model MessageUpdate {
|
||||
id Int @id @default(autoincrement())
|
||||
keyId String @db.VarChar(100)
|
||||
remoteJid String @db.VarChar(100)
|
||||
fromMe Boolean @db.Boolean
|
||||
participant String? @db.VarChar(100)
|
||||
dateTime DateTime @db.Date
|
||||
pollUpdates Json? @db.JsonB
|
||||
status String @db.VarChar(30)
|
||||
Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
|
||||
messageId Int
|
||||
}
|
||||
|
||||
model Webhook {
|
||||
id Int @id @default(autoincrement())
|
||||
url String @db.VarChar(500)
|
||||
enabled Boolean? @default(true) @db.Boolean
|
||||
events Json? @db.JsonB
|
||||
webhook_by_events Boolean? @default(false) @db.Boolean
|
||||
webhook_base64 Boolean? @default(false) @db.Boolean
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
id Int @id @default(autoincrement())
|
||||
url String @db.VarChar(500)
|
||||
enabled Boolean? @default(true) @db.Boolean
|
||||
events Json? @db.JsonB
|
||||
webhookByEvents Boolean? @default(false) @db.Boolean
|
||||
webhookBase64 Boolean? @default(false) @db.Boolean
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Chatwoot {
|
||||
id Int @id @default(autoincrement())
|
||||
enabled Boolean? @default(true) @db.Boolean
|
||||
account_id String? @db.VarChar(100)
|
||||
token String? @db.VarChar(100)
|
||||
url String? @db.VarChar(500)
|
||||
name_inbox String? @db.VarChar(100)
|
||||
sign_msg Boolean? @default(false) @db.Boolean
|
||||
sign_delimiter String? @db.VarChar(100)
|
||||
number String? @db.VarChar(100)
|
||||
reopen_conversation Boolean? @default(false) @db.Boolean
|
||||
conversation_pending Boolean? @default(false) @db.Boolean
|
||||
merge_brazil_contacts Boolean? @default(false) @db.Boolean
|
||||
import_contacts Boolean? @default(false) @db.Boolean
|
||||
import_messages Boolean? @default(false) @db.Boolean
|
||||
days_limit_import_messages Int? @db.Integer
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
id Int @id @default(autoincrement())
|
||||
enabled Boolean? @default(true) @db.Boolean
|
||||
accountId String? @db.VarChar(100)
|
||||
token String? @db.VarChar(100)
|
||||
url String? @db.VarChar(500)
|
||||
nameInbox String? @db.VarChar(100)
|
||||
signMsg Boolean? @default(false) @db.Boolean
|
||||
signDelimiter String? @db.VarChar(100)
|
||||
number String? @db.VarChar(100)
|
||||
reopenConversation Boolean? @default(false) @db.Boolean
|
||||
conversationPending Boolean? @default(false) @db.Boolean
|
||||
mergeBrazilContacts Boolean? @default(false) @db.Boolean
|
||||
importContacts Boolean? @default(false) @db.Boolean
|
||||
importMessages Boolean? @default(false) @db.Boolean
|
||||
daysLimitImportMessages Int? @db.Integer
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Integration {
|
||||
@ -180,7 +175,7 @@ model Integration {
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Label {
|
||||
@ -192,20 +187,20 @@ model Label {
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int
|
||||
instanceId String
|
||||
}
|
||||
|
||||
model Proxy {
|
||||
id Int @id @default(autoincrement())
|
||||
enabled Boolean? @default(true) @db.Boolean
|
||||
proxyHost String? @db.VarChar(100)
|
||||
proxyPort Int? @db.Integer
|
||||
proxyUsername String? @db.VarChar(100)
|
||||
proxyPassword String? @db.VarChar(100)
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
id Int @id @default(autoincrement())
|
||||
enabled Boolean? @default(true) @db.Boolean
|
||||
host String? @db.VarChar(100)
|
||||
port String? @db.VarChar(100)
|
||||
username String? @db.VarChar(100)
|
||||
password String? @db.VarChar(100)
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Setting {
|
||||
@ -220,7 +215,7 @@ model Setting {
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Rabbitmq {
|
||||
@ -230,7 +225,7 @@ model Rabbitmq {
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Sqs {
|
||||
@ -240,7 +235,7 @@ model Sqs {
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Websocket {
|
||||
@ -250,7 +245,7 @@ model Websocket {
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
instanceId String @unique
|
||||
}
|
||||
|
||||
model Typebot {
|
||||
@ -266,7 +261,7 @@ model Typebot {
|
||||
createdAt DateTime? @default(now()) @db.Date
|
||||
updatedAt DateTime? @updatedAt @db.Date
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId Int @unique
|
||||
instanceId String @unique
|
||||
sessions TypebotSession[]
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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/');
|
||||
|
@ -11,41 +11,41 @@ export class InstanceDto {
|
||||
integration?: string;
|
||||
token?: string;
|
||||
webhook?: string;
|
||||
webhook_by_events?: boolean;
|
||||
webhook_base64?: boolean;
|
||||
events?: string[];
|
||||
reject_call?: boolean;
|
||||
msg_call?: string;
|
||||
groups_ignore?: boolean;
|
||||
always_online?: boolean;
|
||||
read_messages?: boolean;
|
||||
read_status?: boolean;
|
||||
sync_full_history?: boolean;
|
||||
chatwoot_account_id?: string;
|
||||
chatwoot_token?: string;
|
||||
chatwoot_url?: string;
|
||||
chatwoot_sign_msg?: boolean;
|
||||
chatwoot_reopen_conversation?: boolean;
|
||||
chatwoot_conversation_pending?: boolean;
|
||||
chatwoot_merge_brazil_contacts?: boolean;
|
||||
chatwoot_import_contacts?: boolean;
|
||||
chatwoot_import_messages?: boolean;
|
||||
chatwoot_days_limit_import_messages?: number;
|
||||
chatwoot_name_inbox?: string;
|
||||
websocket_enabled?: boolean;
|
||||
websocket_events?: string[];
|
||||
rabbitmq_enabled?: boolean;
|
||||
rabbitmq_events?: string[];
|
||||
sqs_enabled?: boolean;
|
||||
sqs_events?: string[];
|
||||
typebot_url?: string;
|
||||
webhookByEvents?: boolean;
|
||||
webhookBase64?: boolean;
|
||||
webhookEvents?: string[];
|
||||
rejectCall?: boolean;
|
||||
msgCall?: string;
|
||||
groupsIgnore?: boolean;
|
||||
alwaysOnline?: boolean;
|
||||
readMessages?: boolean;
|
||||
readStatus?: boolean;
|
||||
syncFullHistory?: boolean;
|
||||
chatwootAccountId?: string;
|
||||
chatwootToken?: string;
|
||||
chatwootUrl?: string;
|
||||
chatwootSignMsg?: boolean;
|
||||
chatwootReopenConversation?: boolean;
|
||||
chatwootConversationPending?: boolean;
|
||||
chatwootMergeBrazilContacts?: boolean;
|
||||
chatwootImportContacts?: boolean;
|
||||
chatwootImportMessages?: boolean;
|
||||
chatwootDaysLimitImportMessages?: number;
|
||||
chatwootNameInbox?: string;
|
||||
websocketEnabled?: boolean;
|
||||
websocketEvents?: string[];
|
||||
rabbitmqEnabled?: boolean;
|
||||
rabbitmqEvents?: string[];
|
||||
sqsEnabled?: boolean;
|
||||
sqsEvents?: string[];
|
||||
typebotUrl?: string;
|
||||
typebot?: string;
|
||||
typebot_expire?: number;
|
||||
typebot_keyword_finish?: string;
|
||||
typebot_delay_message?: number;
|
||||
typebot_unknown_message?: string;
|
||||
typebot_listening_from_me?: boolean;
|
||||
proxy?: ProxyDto['proxy'];
|
||||
typebotExpire?: number;
|
||||
typebotKeywordFinish?: string;
|
||||
typebotDelayMessage?: number;
|
||||
typebotUnknownMessage?: string;
|
||||
typebotListeningFromMe?: boolean;
|
||||
proxy?: ProxyDto;
|
||||
}
|
||||
|
||||
export class SetPresenceDto {
|
||||
|
@ -1,7 +1,7 @@
|
||||
export class LabelDto {
|
||||
id?: string;
|
||||
name: string;
|
||||
color: number;
|
||||
color: string;
|
||||
predefinedId?: string;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,8 @@
|
||||
class Proxy {
|
||||
export class ProxyDto {
|
||||
enabled: boolean;
|
||||
host: string;
|
||||
port: string;
|
||||
protocol: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
}
|
||||
|
||||
export class ProxyDto {
|
||||
enabled: boolean;
|
||||
proxy: Proxy;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
export class SettingsDto {
|
||||
reject_call?: boolean;
|
||||
msg_call?: string;
|
||||
groups_ignore?: boolean;
|
||||
always_online?: boolean;
|
||||
read_messages?: boolean;
|
||||
read_status?: boolean;
|
||||
sync_full_history?: boolean;
|
||||
rejectCall?: boolean;
|
||||
msgCall?: string;
|
||||
groupsIgnore?: boolean;
|
||||
alwaysOnline?: boolean;
|
||||
readMessages?: boolean;
|
||||
readStatus?: boolean;
|
||||
syncFullHistory?: boolean;
|
||||
}
|
||||
|
@ -2,6 +2,6 @@ export class WebhookDto {
|
||||
enabled?: boolean;
|
||||
url?: string;
|
||||
events?: string[];
|
||||
webhook_by_events?: boolean;
|
||||
webhook_base64?: boolean;
|
||||
webhookByEvents?: boolean;
|
||||
webhookBase64?: boolean;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { Auth, configService, Database } from '../../config/env.config';
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { ForbiddenException, UnauthorizedException } from '../../exceptions';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
import { mongodbRepository } from '../server.module';
|
||||
import { prismaRepository } from '../server.module';
|
||||
|
||||
const logger = new Logger('GUARD');
|
||||
|
||||
@ -28,13 +28,18 @@ async function apikey(req: Request, _: Response, next: NextFunction) {
|
||||
|
||||
try {
|
||||
if (param?.instanceName) {
|
||||
const instanceKey = await mongodbRepository.auth.find(param.instanceName);
|
||||
if (instanceKey?.apikey === key) {
|
||||
const instance = await prismaRepository.instance.findUnique({
|
||||
where: { name: param.instanceName },
|
||||
include: { Auth: true },
|
||||
});
|
||||
if (instance.Auth?.apikey === key) {
|
||||
return next();
|
||||
}
|
||||
} else {
|
||||
if (req.originalUrl.includes('/instance/fetchInstances') && db.ENABLED) {
|
||||
const instanceByKey = await mongodbRepository.auth.findByKey(key);
|
||||
const instanceByKey = await prismaRepository.auth.findFirst({
|
||||
where: { apikey: key },
|
||||
});
|
||||
if (instanceByKey) {
|
||||
return next();
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
InternalServerErrorException,
|
||||
NotFoundException,
|
||||
} from '../../exceptions';
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
import { prismaServer } from '../../libs/prisma.connect';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
import { cache, waMonitor } from '../server.module';
|
||||
|
||||
@ -28,11 +28,9 @@ async function getInstance(instanceName: string) {
|
||||
}
|
||||
|
||||
if (db.ENABLED) {
|
||||
const collection = mongodbServer
|
||||
.getClient()
|
||||
.db(db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||
.collection(instanceName);
|
||||
return exists || (await collection.find({}).toArray()).length > 0;
|
||||
const prisma = prismaServer;
|
||||
|
||||
return exists || (await prisma.instance.findMany({ where: { name: instanceName } })).length > 0;
|
||||
}
|
||||
|
||||
return exists || existsSync(join(INSTANCE_DIR, instanceName));
|
||||
|
@ -5,8 +5,7 @@ import { ConfigService, HttpServer } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { BadRequestException } from '../../../../exceptions';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { MongodbRepository } from '../../../repository/mongodb/repository.manager';
|
||||
import { PrismaRepository } from '../../../repository/prisma/repository.service';
|
||||
import { PrismaRepository } from '../../../repository/repository.service';
|
||||
import { waMonitor } from '../../../server.module';
|
||||
import { CacheService } from '../../../services/cache.service';
|
||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||
@ -18,7 +17,6 @@ export class ChatwootController {
|
||||
constructor(
|
||||
private readonly chatwootService: ChatwootService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly mongodbRepository: MongodbRepository,
|
||||
private readonly prismaRepository: PrismaRepository,
|
||||
) {}
|
||||
|
||||
@ -30,39 +28,39 @@ export class ChatwootController {
|
||||
throw new BadRequestException('url is not valid');
|
||||
}
|
||||
|
||||
if (!data.account_id) {
|
||||
throw new BadRequestException('account_id is required');
|
||||
if (!data.accountId) {
|
||||
throw new BadRequestException('accountId is required');
|
||||
}
|
||||
|
||||
if (!data.token) {
|
||||
throw new BadRequestException('token is required');
|
||||
}
|
||||
|
||||
if (data.sign_msg !== true && data.sign_msg !== false) {
|
||||
throw new BadRequestException('sign_msg is required');
|
||||
if (data.signMsg !== true && data.signMsg !== false) {
|
||||
throw new BadRequestException('signMsg is required');
|
||||
}
|
||||
if (data.sign_msg === false) data.sign_delimiter = null;
|
||||
if (data.signMsg === false) data.signDelimiter = null;
|
||||
}
|
||||
|
||||
if (!data.enabled) {
|
||||
logger.verbose('chatwoot disabled');
|
||||
data.account_id = '';
|
||||
data.accountId = '';
|
||||
data.token = '';
|
||||
data.url = '';
|
||||
data.sign_msg = false;
|
||||
data.sign_delimiter = null;
|
||||
data.reopen_conversation = false;
|
||||
data.conversation_pending = false;
|
||||
data.import_contacts = false;
|
||||
data.import_messages = false;
|
||||
data.merge_brazil_contacts = false;
|
||||
data.days_limit_import_messages = 0;
|
||||
data.auto_create = false;
|
||||
data.name_inbox = '';
|
||||
data.signMsg = false;
|
||||
data.signDelimiter = null;
|
||||
data.reopenConversation = false;
|
||||
data.conversationPending = false;
|
||||
data.importContacts = false;
|
||||
data.importMessages = false;
|
||||
data.mergeBrazilContacts = false;
|
||||
data.daysLimitImportMessages = 0;
|
||||
data.autoCreate = false;
|
||||
data.nameInbox = '';
|
||||
}
|
||||
|
||||
if (!data.name_inbox || data.name_inbox === '') {
|
||||
data.name_inbox = instance.instanceName;
|
||||
if (!data.nameInbox || data.nameInbox === '') {
|
||||
data.nameInbox = instance.instanceName;
|
||||
}
|
||||
|
||||
const result = await this.chatwootService.create(instance, data);
|
||||
@ -87,10 +85,10 @@ export class ChatwootController {
|
||||
return {
|
||||
enabled: false,
|
||||
url: '',
|
||||
account_id: '',
|
||||
accountId: '',
|
||||
token: '',
|
||||
sign_msg: false,
|
||||
name_inbox: '',
|
||||
signMsg: false,
|
||||
nameInbox: '',
|
||||
webhook_url: '',
|
||||
};
|
||||
}
|
||||
@ -107,13 +105,7 @@ export class ChatwootController {
|
||||
logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance');
|
||||
|
||||
const chatwootCache = new CacheService(new CacheEngine(this.configService, ChatwootService.name).getEngine());
|
||||
const chatwootService = new ChatwootService(
|
||||
waMonitor,
|
||||
this.configService,
|
||||
this.mongodbRepository,
|
||||
this.prismaRepository,
|
||||
chatwootCache,
|
||||
);
|
||||
const chatwootService = new ChatwootService(waMonitor, this.configService, this.prismaRepository, chatwootCache);
|
||||
|
||||
return chatwootService.receiveWebhook(instance, data);
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
export class ChatwootDto {
|
||||
enabled?: boolean;
|
||||
account_id?: string;
|
||||
accountId?: string;
|
||||
token?: string;
|
||||
url?: string;
|
||||
name_inbox?: string;
|
||||
sign_msg?: boolean;
|
||||
sign_delimiter?: string;
|
||||
nameInbox?: string;
|
||||
signMsg?: boolean;
|
||||
signDelimiter?: string;
|
||||
number?: string;
|
||||
reopen_conversation?: boolean;
|
||||
conversation_pending?: boolean;
|
||||
merge_brazil_contacts?: boolean;
|
||||
import_contacts?: boolean;
|
||||
import_messages?: boolean;
|
||||
days_limit_import_messages?: number;
|
||||
auto_create?: boolean;
|
||||
reopenConversation?: boolean;
|
||||
conversationPending?: boolean;
|
||||
mergeBrazilContacts?: boolean;
|
||||
importContacts?: boolean;
|
||||
importMessages?: boolean;
|
||||
daysLimitImportMessages?: number;
|
||||
autoCreate?: boolean;
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
export class ChatwootRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
account_id?: string;
|
||||
token?: string;
|
||||
url?: string;
|
||||
name_inbox?: string;
|
||||
sign_msg?: boolean;
|
||||
sign_delimiter?: string;
|
||||
number?: string;
|
||||
reopen_conversation?: boolean;
|
||||
conversation_pending?: boolean;
|
||||
merge_brazil_contacts?: boolean;
|
||||
import_contacts?: boolean;
|
||||
import_messages?: boolean;
|
||||
days_limit_import_messages?: number;
|
||||
}
|
||||
|
||||
const chatwootSchema = new Schema<ChatwootRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
account_id: { type: String, required: true },
|
||||
token: { type: String, required: true },
|
||||
url: { type: String, required: true },
|
||||
name_inbox: { type: String, required: true },
|
||||
sign_msg: { type: Boolean, required: true },
|
||||
sign_delimiter: { type: String, required: false },
|
||||
number: { type: String, required: true },
|
||||
reopen_conversation: { type: Boolean, required: true },
|
||||
conversation_pending: { type: Boolean, required: true },
|
||||
merge_brazil_contacts: { type: Boolean, required: true },
|
||||
import_contacts: { type: Boolean, required: true },
|
||||
import_messages: { type: Boolean, required: true },
|
||||
days_limit_import_messages: { type: Number, required: true },
|
||||
});
|
||||
|
||||
export const ChatwootModel = mongodbServer?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot');
|
||||
export type IChatwootModel = typeof ChatwootModel;
|
@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { ChatwootRaw, IChatwootModel } from '../../../models';
|
||||
|
||||
export class ChatwootRepository extends Repository {
|
||||
constructor(private readonly chatwootModel: IChatwootModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('ChatwootRepository');
|
||||
|
||||
public async create(data: ChatwootRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating chatwoot');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving chatwoot to db');
|
||||
const insert = await this.chatwootModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving chatwoot to store');
|
||||
|
||||
this.writeStore<ChatwootRaw>({
|
||||
path: join(this.storePath, 'chatwoot'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('chatwoot saved to store in path: ' + join(this.storePath, 'chatwoot') + '/' + instance);
|
||||
|
||||
this.logger.verbose('chatwoot created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<ChatwootRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding chatwoot');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding chatwoot in db');
|
||||
return await this.chatwootModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding chatwoot in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'chatwoot', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as ChatwootRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
@ -8,11 +8,12 @@ import ChatwootClient, {
|
||||
inbox,
|
||||
} from '@figuro/chatwoot-sdk';
|
||||
import { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request';
|
||||
import { proto } from '@whiskeysockets/baileys';
|
||||
import { Chatwoot as ChatwootModel, Contact as ContactModel, Message as MessageModel } from '@prisma/client';
|
||||
import axios from 'axios';
|
||||
import FormData from 'form-data';
|
||||
import { createReadStream, unlinkSync, writeFileSync } from 'fs';
|
||||
import Jimp from 'jimp';
|
||||
import Long from 'long';
|
||||
import mimeTypes from 'mime-types';
|
||||
import path from 'path';
|
||||
|
||||
@ -22,14 +23,20 @@ import i18next from '../../../../utils/i18n';
|
||||
import { ICache } from '../../../abstract/abstract.cache';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../../../dto/sendMessage.dto';
|
||||
import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../models';
|
||||
import { MongodbRepository } from '../../../repository/mongodb/repository.manager';
|
||||
import { PrismaRepository } from '../../../repository/prisma/repository.service';
|
||||
import { PrismaRepository } from '../../../repository/repository.service';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { Events } from '../../../types/wa.types';
|
||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||
import { chatwootImport } from '../utils/chatwoot-import-helper';
|
||||
|
||||
interface ChatwootMessage {
|
||||
messageId?: number;
|
||||
inboxId?: number;
|
||||
conversationId?: number;
|
||||
contactInboxSourceId?: string;
|
||||
isRead?: boolean;
|
||||
}
|
||||
|
||||
export class ChatwootService {
|
||||
private readonly logger = new Logger(ChatwootService.name);
|
||||
|
||||
@ -38,7 +45,6 @@ export class ChatwootService {
|
||||
constructor(
|
||||
private readonly waMonitor: WAMonitoringService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly mongodbRepository: MongodbRepository,
|
||||
private readonly prismaRepository: PrismaRepository,
|
||||
private readonly cache: ICache,
|
||||
) {}
|
||||
@ -46,7 +52,7 @@ export class ChatwootService {
|
||||
private async getProvider(instance: InstanceDto) {
|
||||
const cacheKey = `${instance.instanceName}:getProvider`;
|
||||
if (await this.cache.has(cacheKey)) {
|
||||
return (await this.cache.get(cacheKey)) as ChatwootRaw;
|
||||
return (await this.cache.get(cacheKey)) as ChatwootModel;
|
||||
}
|
||||
|
||||
this.logger.verbose('get provider to instance: ' + instance.instanceName);
|
||||
@ -110,12 +116,12 @@ export class ChatwootService {
|
||||
|
||||
this.logger.verbose('chatwoot created');
|
||||
|
||||
if (data.auto_create) {
|
||||
if (data.autoCreate) {
|
||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||
|
||||
await this.initInstanceChatwoot(
|
||||
instance,
|
||||
data.name_inbox ?? instance.instanceName.split('-cwId-')[0],
|
||||
data.nameInbox ?? instance.instanceName.split('-cwId-')[0],
|
||||
`${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,
|
||||
true,
|
||||
data.number,
|
||||
@ -1195,26 +1201,22 @@ export class ChatwootService {
|
||||
|
||||
this.logger.verbose('check if is a message deletion');
|
||||
if (body.event === 'message_updated' && body.content_attributes?.deleted) {
|
||||
const message = await this.mongodbRepository.message.find({
|
||||
const message = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
owner: instance.instanceName,
|
||||
chatwoot: {
|
||||
messageId: body.id,
|
||||
},
|
||||
chatwootMessageId: body.id,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
if (message.length && message[0].key?.id) {
|
||||
|
||||
if (message) {
|
||||
this.logger.verbose('deleting message in whatsapp. Message id: ' + message[0].key.id);
|
||||
await waInstance?.client.sendMessage(message[0].key.remoteJid, { delete: message[0].key });
|
||||
|
||||
this.logger.verbose('deleting message in repository. Message id: ' + message[0].key.id);
|
||||
this.mongodbRepository.message.delete({
|
||||
this.prismaRepository.message.deleteMany({
|
||||
where: {
|
||||
owner: instance.instanceName,
|
||||
chatwoot: {
|
||||
messageId: body.id,
|
||||
},
|
||||
instanceId: instance.instanceId,
|
||||
chatwootMessageId: body.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -1368,9 +1370,7 @@ export class ChatwootService {
|
||||
messageId: body.id,
|
||||
inboxId: body.inbox?.id,
|
||||
conversationId: body.conversation?.id,
|
||||
contactInbox: {
|
||||
sourceId: body.conversation?.contact_inbox?.source_id,
|
||||
},
|
||||
contactInboxSourceId: body.conversation?.contact_inbox?.source_id,
|
||||
},
|
||||
instance,
|
||||
);
|
||||
@ -1391,25 +1391,27 @@ export class ChatwootService {
|
||||
},
|
||||
};
|
||||
|
||||
let messageSent: MessageRaw | proto.WebMessageInfo;
|
||||
let messageSent: any;
|
||||
try {
|
||||
messageSent = await waInstance?.textMessage(data, true);
|
||||
if (!messageSent) {
|
||||
throw new Error('Message not sent');
|
||||
}
|
||||
|
||||
if (Long.isLong(messageSent?.messageTimestamp)) {
|
||||
messageSent.messageTimestamp = messageSent.messageTimestamp?.toNumber();
|
||||
}
|
||||
|
||||
this.updateChatwootMessageId(
|
||||
{
|
||||
...messageSent,
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
{
|
||||
messageId: body.id,
|
||||
inboxId: body.inbox?.id,
|
||||
conversationId: body.conversation?.id,
|
||||
contactInbox: {
|
||||
sourceId: body.conversation?.contact_inbox?.source_id,
|
||||
},
|
||||
contactInboxSourceId: body.conversation?.contact_inbox?.source_id,
|
||||
},
|
||||
instance,
|
||||
);
|
||||
@ -1424,32 +1426,72 @@ export class ChatwootService {
|
||||
|
||||
const chatwootRead = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_READ;
|
||||
if (chatwootRead) {
|
||||
const lastMessage = await this.mongodbRepository.message.find({
|
||||
const lastMessage = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
key: {
|
||||
fromMe: false,
|
||||
path: ['fromMe'],
|
||||
equals: false,
|
||||
},
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
if (lastMessage.length > 0 && !lastMessage[0].chatwoot?.isRead) {
|
||||
if (lastMessage && !lastMessage.chatwootIsRead) {
|
||||
const key = lastMessage.key as {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
|
||||
waInstance?.markMessageAsRead({
|
||||
read_messages: lastMessage.map((msg) => ({
|
||||
id: msg.key?.id,
|
||||
fromMe: msg.key?.fromMe,
|
||||
remoteJid: msg.key?.remoteJid,
|
||||
})),
|
||||
read_messages: [
|
||||
{
|
||||
id: key.id,
|
||||
fromMe: key.fromMe,
|
||||
remoteJid: key.remoteJid,
|
||||
},
|
||||
],
|
||||
});
|
||||
const updateMessage = lastMessage.map((msg) => ({
|
||||
key: msg.key,
|
||||
owner: msg.owner,
|
||||
chatwoot: {
|
||||
...msg.chatwoot,
|
||||
isRead: true,
|
||||
const updateMessage = {
|
||||
chatwootMessageId: lastMessage.chatwootMessageId,
|
||||
chatwootConversationId: lastMessage.chatwootConversationId,
|
||||
chatwootInboxId: lastMessage.chatwootInboxId,
|
||||
chatwootContactInboxSourceId: lastMessage.chatwootContactInboxSourceId,
|
||||
chatwootIsRead: true,
|
||||
};
|
||||
|
||||
await this.prismaRepository.message.updateMany({
|
||||
where: {
|
||||
instanceId: instance.instanceId,
|
||||
AND: [
|
||||
{
|
||||
key: {
|
||||
path: ['id'],
|
||||
equals: key.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: {
|
||||
path: ['remoteJid'],
|
||||
equals: key.remoteJid,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: {
|
||||
path: ['fromMe'],
|
||||
equals: key.fromMe,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: {
|
||||
path: ['participant'],
|
||||
equals: key.participant,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}));
|
||||
this.mongodbRepository.message.update(updateMessage, instance.instanceName, true);
|
||||
data: updateMessage,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1481,31 +1523,48 @@ export class ChatwootService {
|
||||
}
|
||||
}
|
||||
|
||||
private updateChatwootMessageId(
|
||||
message: MessageRaw,
|
||||
chatwootMessageIds: MessageRaw['chatwoot'],
|
||||
instance: InstanceDto,
|
||||
) {
|
||||
if (!chatwootMessageIds.messageId || !message?.key?.id) {
|
||||
private updateChatwootMessageId(message: MessageModel, chatwootMessageIds: ChatwootMessage, instance: InstanceDto) {
|
||||
const key = message.key as {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
|
||||
if (!chatwootMessageIds.messageId || !key?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
message.chatwoot = chatwootMessageIds;
|
||||
this.mongodbRepository.message.update([message], instance.instanceName, true);
|
||||
}
|
||||
|
||||
private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageRaw> {
|
||||
const messages = await this.mongodbRepository.message.find({
|
||||
this.prismaRepository.message.updateMany({
|
||||
where: {
|
||||
key: {
|
||||
id: keyId,
|
||||
path: ['id'],
|
||||
equals: key.id,
|
||||
},
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
data: {
|
||||
chatwootMessageId: chatwootMessageIds.messageId,
|
||||
chatwootConversationId: chatwootMessageIds.conversationId,
|
||||
chatwootInboxId: chatwootMessageIds.inboxId,
|
||||
chatwootContactInboxSourceId: chatwootMessageIds.contactInboxSourceId,
|
||||
chatwootIsRead: chatwootMessageIds.isRead,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageModel> {
|
||||
const messages = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
key: {
|
||||
path: ['id'],
|
||||
equals: keyId,
|
||||
},
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
|
||||
return messages.length ? messages[0] : null;
|
||||
return messages || null;
|
||||
}
|
||||
|
||||
private async getReplyToIds(
|
||||
@ -1519,8 +1578,8 @@ export class ChatwootService {
|
||||
inReplyToExternalId = msg.message?.extendedTextMessage?.contextInfo?.stanzaId;
|
||||
if (inReplyToExternalId) {
|
||||
const message = await this.getMessageByKeyId(instance, inReplyToExternalId);
|
||||
if (message?.chatwoot?.messageId) {
|
||||
inReplyTo = message.chatwoot.messageId;
|
||||
if (message?.chatwootMessageId) {
|
||||
inReplyTo = message.chatwootMessageId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1533,16 +1592,21 @@ export class ChatwootService {
|
||||
|
||||
private async getQuotedMessage(msg: any, instance: InstanceDto): Promise<Quoted> {
|
||||
if (msg?.content_attributes?.in_reply_to) {
|
||||
const message = await this.mongodbRepository.message.find({
|
||||
const message = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
chatwoot: {
|
||||
messageId: msg?.content_attributes?.in_reply_to,
|
||||
},
|
||||
owner: instance.instanceName,
|
||||
chatwootMessageId: msg?.content_attributes?.in_reply_to,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
if (message.length && message[0]?.key?.id) {
|
||||
|
||||
const key = message.key as {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
|
||||
if (message && key?.id) {
|
||||
return {
|
||||
key: message[0].key,
|
||||
message: message[0].message,
|
||||
@ -1588,7 +1652,12 @@ export class ChatwootService {
|
||||
|
||||
private getReactionMessage(msg: any) {
|
||||
interface ReactionMessage {
|
||||
key: MessageRaw['key'];
|
||||
key: {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
text: string;
|
||||
}
|
||||
const reactionMessage: ReactionMessage | undefined = msg?.reactionMessage;
|
||||
@ -2131,22 +2200,23 @@ export class ChatwootService {
|
||||
}
|
||||
|
||||
const message = await this.getMessageByKeyId(instance, body.key.id);
|
||||
if (message?.chatwoot?.messageId && message?.chatwoot?.conversationId) {
|
||||
if (message?.chatwootMessageId && message?.chatwootConversationId) {
|
||||
this.logger.verbose('deleting message in repository. Message id: ' + body.key.id);
|
||||
this.mongodbRepository.message.delete({
|
||||
this.prismaRepository.message.deleteMany({
|
||||
where: {
|
||||
key: {
|
||||
id: body.key.id,
|
||||
path: ['id'],
|
||||
equals: body.key.id,
|
||||
},
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose('deleting message in chatwoot. Message id: ' + body.key.id);
|
||||
return await client.messages.delete({
|
||||
accountId: this.provider.account_id,
|
||||
conversationId: message.chatwoot.conversationId,
|
||||
messageId: message.chatwoot.messageId,
|
||||
conversationId: message.chatwootConversationId,
|
||||
messageId: message.chatwootMessageId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -2157,18 +2227,25 @@ export class ChatwootService {
|
||||
body?.editedMessage?.conversation || body?.editedMessage?.extendedTextMessage?.text
|
||||
}\n\n_\`${i18next.t('cw.message.edited')}.\`_`;
|
||||
const message = await this.getMessageByKeyId(instance, body?.key?.id);
|
||||
const messageType = message.key?.fromMe ? 'outgoing' : 'incoming';
|
||||
const key = message.key as {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
|
||||
if (message && message.chatwoot?.conversationId) {
|
||||
const messageType = key?.fromMe ? 'outgoing' : 'incoming';
|
||||
|
||||
if (message && message.chatwootConversationId) {
|
||||
const send = await this.createMessage(
|
||||
instance,
|
||||
message.chatwoot.conversationId,
|
||||
message.chatwootConversationId,
|
||||
editedText,
|
||||
messageType,
|
||||
false,
|
||||
[],
|
||||
{
|
||||
message: { extendedTextMessage: { contextInfo: { stanzaId: message.key.id } } },
|
||||
message: { extendedTextMessage: { contextInfo: { stanzaId: key.id } } },
|
||||
},
|
||||
'WAID:' + body.key.id,
|
||||
);
|
||||
@ -2189,9 +2266,11 @@ export class ChatwootService {
|
||||
}
|
||||
|
||||
const message = await this.getMessageByKeyId(instance, body.key.id);
|
||||
const { conversationId, contactInbox } = message?.chatwoot || {};
|
||||
const conversationId = message?.chatwootConversationId;
|
||||
const contactInboxSourceId = message?.chatwootContactInboxSourceId;
|
||||
|
||||
if (conversationId) {
|
||||
let sourceId = contactInbox?.sourceId;
|
||||
let sourceId = contactInboxSourceId;
|
||||
const inbox = (await this.getInbox(instance)) as inbox & {
|
||||
inbox_identifier?: string;
|
||||
};
|
||||
@ -2317,7 +2396,7 @@ export class ChatwootService {
|
||||
/* We can't proccess messages exactly in batch because Chatwoot use message id to order
|
||||
messages in frontend and we are receiving the messages mixed between the batches.
|
||||
Because this, we need to put all batches together and order after */
|
||||
public addHistoryMessages(instance: InstanceDto, messagesRaw: MessageRaw[]) {
|
||||
public addHistoryMessages(instance: InstanceDto, messagesRaw: MessageModel[]) {
|
||||
if (!this.isImportHistoryAvailable()) {
|
||||
return;
|
||||
}
|
||||
@ -2325,7 +2404,7 @@ export class ChatwootService {
|
||||
chatwootImport.addHistoryMessages(instance, messagesRaw);
|
||||
}
|
||||
|
||||
public addHistoryContacts(instance: InstanceDto, contactsRaw: ContactRaw[]) {
|
||||
public addHistoryContacts(instance: InstanceDto, contactsRaw: ContactModel[]) {
|
||||
if (!this.isImportHistoryAvailable()) {
|
||||
return;
|
||||
}
|
||||
@ -2382,16 +2461,18 @@ export class ChatwootService {
|
||||
);
|
||||
|
||||
const contactsWithProfilePicture = (
|
||||
await this.mongodbRepository.contact.find({
|
||||
await this.prismaRepository.contact.findMany({
|
||||
where: {
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
id: {
|
||||
$in: recentContacts.map((contact) => contact.identifier),
|
||||
in: recentContacts.map((contact) => Number(contact.identifier)),
|
||||
},
|
||||
profilePicUrl: {
|
||||
not: null,
|
||||
},
|
||||
profilePictureUrl: { $ne: null },
|
||||
},
|
||||
} as any)
|
||||
).reduce((acc: Map<string, ContactRaw>, contact: ContactRaw) => acc.set(contact.id, contact), new Map());
|
||||
})
|
||||
).reduce((acc: Map<number, ContactModel>, contact: ContactModel) => acc.set(contact.id, contact), new Map());
|
||||
|
||||
recentContacts.forEach(async (contact) => {
|
||||
if (contactsWithProfilePicture.has(contact.identifier)) {
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { inbox } from '@figuro/chatwoot-sdk';
|
||||
import { Chatwoot as ChatwootModel, Contact, Message } from '@prisma/client';
|
||||
import { proto } from '@whiskeysockets/baileys';
|
||||
|
||||
import { InstanceDto } from '../../../../api/dto/instance.dto';
|
||||
import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../../api/models';
|
||||
import { Chatwoot, configService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||
import { postgresClient } from '../libs/postgres.client';
|
||||
import { ChatwootService } from '../services/chatwoot.service';
|
||||
|
||||
@ -29,8 +30,8 @@ type IWebMessageInfo = Omit<proto.IWebMessageInfo, 'key'> & Partial<Pick<proto.I
|
||||
class ChatwootImport {
|
||||
private logger = new Logger(ChatwootImport.name);
|
||||
private repositoryMessagesCache = new Map<string, Set<string>>();
|
||||
private historyMessages = new Map<string, MessageRaw[]>();
|
||||
private historyContacts = new Map<string, ContactRaw[]>();
|
||||
private historyMessages = new Map<string, Message[]>();
|
||||
private historyContacts = new Map<string, Contact[]>();
|
||||
|
||||
public getRepositoryMessagesCache(instance: InstanceDto) {
|
||||
return this.repositoryMessagesCache.has(instance.instanceName)
|
||||
@ -46,14 +47,14 @@ class ChatwootImport {
|
||||
this.repositoryMessagesCache.delete(instance.instanceName);
|
||||
}
|
||||
|
||||
public addHistoryMessages(instance: InstanceDto, messagesRaw: MessageRaw[]) {
|
||||
public addHistoryMessages(instance: InstanceDto, messagesRaw: Message[]) {
|
||||
const actualValue = this.historyMessages.has(instance.instanceName)
|
||||
? this.historyMessages.get(instance.instanceName)
|
||||
: [];
|
||||
this.historyMessages.set(instance.instanceName, actualValue.concat(messagesRaw));
|
||||
}
|
||||
|
||||
public addHistoryContacts(instance: InstanceDto, contactsRaw: ContactRaw[]) {
|
||||
public addHistoryContacts(instance: InstanceDto, contactsRaw: Contact[]) {
|
||||
const actualValue = this.historyContacts.has(instance.instanceName)
|
||||
? this.historyContacts.get(instance.instanceName)
|
||||
: [];
|
||||
@ -78,7 +79,7 @@ class ChatwootImport {
|
||||
return this.historyMessages.get(instance.instanceName)?.length ?? 0;
|
||||
}
|
||||
|
||||
public async importHistoryContacts(instance: InstanceDto, provider: ChatwootRaw) {
|
||||
public async importHistoryContacts(instance: InstanceDto, provider: ChatwootDto) {
|
||||
try {
|
||||
if (this.getHistoryMessagesLenght(instance) > 0) {
|
||||
return;
|
||||
@ -93,21 +94,21 @@ class ChatwootImport {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let contactsChunk: ContactRaw[] = this.sliceIntoChunks(contacts, 3000);
|
||||
let contactsChunk: Contact[] = this.sliceIntoChunks(contacts, 3000);
|
||||
while (contactsChunk.length > 0) {
|
||||
// inserting contacts in chatwoot db
|
||||
let sqlInsert = `INSERT INTO contacts
|
||||
(name, phone_number, account_id, identifier, created_at, updated_at) VALUES `;
|
||||
const bindInsert = [provider.account_id];
|
||||
const bindInsert = [provider.accountId];
|
||||
|
||||
for (const contact of contactsChunk) {
|
||||
bindInsert.push(contact.pushName);
|
||||
const bindName = `$${bindInsert.length}`;
|
||||
|
||||
bindInsert.push(`+${contact.id.split('@')[0]}`);
|
||||
bindInsert.push(`+${contact.remoteJid.split('@')[0]}`);
|
||||
const bindPhoneNumber = `$${bindInsert.length}`;
|
||||
|
||||
bindInsert.push(contact.id);
|
||||
bindInsert.push(contact.remoteJid);
|
||||
const bindIdentifier = `$${bindInsert.length}`;
|
||||
|
||||
sqlInsert += `(${bindName}, ${bindPhoneNumber}, $1, ${bindIdentifier}, NOW(), NOW()),`;
|
||||
@ -137,7 +138,7 @@ class ChatwootImport {
|
||||
instance: InstanceDto,
|
||||
chatwootService: ChatwootService,
|
||||
inbox: inbox,
|
||||
provider: ChatwootRaw,
|
||||
provider: ChatwootModel,
|
||||
) {
|
||||
try {
|
||||
const pgClient = postgresClient.getChatwootConnection();
|
||||
@ -156,8 +157,16 @@ class ChatwootImport {
|
||||
|
||||
// ordering messages by number and timestamp asc
|
||||
messagesOrdered.sort((a, b) => {
|
||||
const aKey = a.key as {
|
||||
remoteJid: string;
|
||||
};
|
||||
|
||||
const bKey = b.key as {
|
||||
remoteJid: string;
|
||||
};
|
||||
|
||||
return (
|
||||
parseInt(a.key.remoteJid) - parseInt(b.key.remoteJid) ||
|
||||
parseInt(aKey.remoteJid) - parseInt(bKey.remoteJid) ||
|
||||
(a.messageTimestamp as number) - (b.messageTimestamp as number)
|
||||
);
|
||||
});
|
||||
@ -165,7 +174,7 @@ class ChatwootImport {
|
||||
const allMessagesMappedByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesOrdered);
|
||||
// Map structure: +552199999999 => { first message timestamp from number, last message timestamp from number}
|
||||
const phoneNumbersWithTimestamp = new Map<string, firstLastTimestamp>();
|
||||
allMessagesMappedByPhoneNumber.forEach((messages: MessageRaw[], phoneNumber: string) => {
|
||||
allMessagesMappedByPhoneNumber.forEach((messages: Message[], phoneNumber: string) => {
|
||||
phoneNumbersWithTimestamp.set(phoneNumber, {
|
||||
first: messages[0]?.messageTimestamp as number,
|
||||
last: messages[messages.length - 1]?.messageTimestamp as number,
|
||||
@ -174,9 +183,9 @@ class ChatwootImport {
|
||||
|
||||
// processing messages in batch
|
||||
const batchSize = 4000;
|
||||
let messagesChunk: MessageRaw[] = this.sliceIntoChunks(messagesOrdered, batchSize);
|
||||
let messagesChunk: Message[] = this.sliceIntoChunks(messagesOrdered, batchSize);
|
||||
while (messagesChunk.length > 0) {
|
||||
// Map structure: +552199999999 => MessageRaw[]
|
||||
// Map structure: +552199999999 => Message[]
|
||||
const messagesByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesChunk);
|
||||
|
||||
if (messagesByPhoneNumber.size > 0) {
|
||||
@ -191,9 +200,9 @@ class ChatwootImport {
|
||||
let sqlInsertMsg = `INSERT INTO messages
|
||||
(content, account_id, inbox_id, conversation_id, message_type, private, content_type,
|
||||
sender_type, sender_id, created_at, updated_at) VALUES `;
|
||||
const bindInsertMsg = [provider.account_id, inbox.id];
|
||||
const bindInsertMsg = [provider.accountId, inbox.id];
|
||||
|
||||
messagesByPhoneNumber.forEach((messages: MessageRaw[], phoneNumber: string) => {
|
||||
messagesByPhoneNumber.forEach((messages: any[], phoneNumber: string) => {
|
||||
const fksChatwoot = fksByNumber.get(phoneNumber);
|
||||
|
||||
messages.forEach((message) => {
|
||||
@ -257,14 +266,14 @@ class ChatwootImport {
|
||||
}
|
||||
|
||||
public async selectOrCreateFksFromChatwoot(
|
||||
provider: ChatwootRaw,
|
||||
provider: ChatwootModel,
|
||||
inbox: inbox,
|
||||
phoneNumbersWithTimestamp: Map<string, firstLastTimestamp>,
|
||||
messagesByPhoneNumber: Map<string, MessageRaw[]>,
|
||||
messagesByPhoneNumber: Map<string, Message[]>,
|
||||
): Promise<Map<string, FksChatwoot>> {
|
||||
const pgClient = postgresClient.getChatwootConnection();
|
||||
|
||||
const bindValues = [provider.account_id, inbox.id];
|
||||
const bindValues = [provider.accountId, inbox.id];
|
||||
const phoneNumberBind = Array.from(messagesByPhoneNumber.keys())
|
||||
.map((phoneNumber) => {
|
||||
const phoneNumberTimestamp = phoneNumbersWithTimestamp.get(phoneNumber);
|
||||
@ -348,7 +357,7 @@ class ChatwootImport {
|
||||
return new Map(fksFromChatwoot.rows.map((item: FksChatwoot) => [item.phone_number, item]));
|
||||
}
|
||||
|
||||
public async getChatwootUser(provider: ChatwootRaw): Promise<ChatwootUser> {
|
||||
public async getChatwootUser(provider: ChatwootModel): Promise<ChatwootUser> {
|
||||
try {
|
||||
const pgClient = postgresClient.getChatwootConnection();
|
||||
|
||||
@ -362,10 +371,13 @@ class ChatwootImport {
|
||||
}
|
||||
}
|
||||
|
||||
public createMessagesMapByPhoneNumber(messages: MessageRaw[]): Map<string, MessageRaw[]> {
|
||||
return messages.reduce((acc: Map<string, MessageRaw[]>, message: MessageRaw) => {
|
||||
if (!this.isIgnorePhoneNumber(message?.key?.remoteJid)) {
|
||||
const phoneNumber = message?.key?.remoteJid?.split('@')[0];
|
||||
public createMessagesMapByPhoneNumber(messages: Message[]): Map<string, Message[]> {
|
||||
return messages.reduce((acc: Map<string, Message[]>, message: Message) => {
|
||||
const key = message?.key as {
|
||||
remoteJid: string;
|
||||
};
|
||||
if (!this.isIgnorePhoneNumber(key?.remoteJid)) {
|
||||
const phoneNumber = key?.remoteJid?.split('@')[0];
|
||||
if (phoneNumber) {
|
||||
const phoneNumberPlus = `+${phoneNumber}`;
|
||||
const messages = acc.has(phoneNumberPlus) ? acc.get(phoneNumberPlus) : [];
|
||||
@ -380,7 +392,7 @@ class ChatwootImport {
|
||||
|
||||
public async getContactsOrderByRecentConversations(
|
||||
inbox: inbox,
|
||||
provider: ChatwootRaw,
|
||||
provider: ChatwootModel,
|
||||
limit = 50,
|
||||
): Promise<{ id: number; phone_number: string; identifier: string }[]> {
|
||||
try {
|
||||
@ -394,7 +406,7 @@ class ChatwootImport {
|
||||
ORDER BY conversations.last_activity_at DESC
|
||||
LIMIT $3`;
|
||||
|
||||
return (await pgClient.query(sql, [provider.account_id, inbox.id, limit]))?.rows;
|
||||
return (await pgClient.query(sql, [provider.accountId, inbox.id, limit]))?.rows;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error on get recent conversations: ${error.toString()}`);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { JsonValue } from '@prisma/client/runtime/library';
|
||||
import * as amqp from 'amqplib/callback_api';
|
||||
|
||||
import { configService, Rabbitmq } from '../../../../config/env.config';
|
||||
@ -107,12 +108,14 @@ export const initQueues = (instanceName: string, events: string[]) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const removeQueues = (instanceName: string, events: string[]) => {
|
||||
if (!events || !events.length) return;
|
||||
export const removeQueues = (instanceName: string, events: JsonValue) => {
|
||||
const eventsArray = Array.isArray(events) ? events.map((event) => String(event)) : [];
|
||||
|
||||
if (!events || !eventsArray.length) return;
|
||||
|
||||
const channel = getAMQP();
|
||||
|
||||
const queues = events.map((event) => {
|
||||
const queues = eventsArray.map((event) => {
|
||||
return `${event.replace(/_/g, '.').toLowerCase()}`;
|
||||
});
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
export class RabbitmqRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
}
|
||||
|
||||
const rabbitmqSchema = new Schema<RabbitmqRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
events: { type: [String], required: true },
|
||||
});
|
||||
|
||||
export const RabbitmqModel = mongodbServer?.model(RabbitmqRaw.name, rabbitmqSchema, 'rabbitmq');
|
||||
export type IRabbitmqModel = typeof RabbitmqModel;
|
@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { IRabbitmqModel, RabbitmqRaw } from '../../../models';
|
||||
|
||||
export class RabbitmqRepository extends Repository {
|
||||
constructor(private readonly rabbitmqModel: IRabbitmqModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('RabbitmqRepository');
|
||||
|
||||
public async create(data: RabbitmqRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating rabbitmq');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving rabbitmq to db');
|
||||
const insert = await this.rabbitmqModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('rabbitmq saved to db: ' + insert.modifiedCount + ' rabbitmq');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving rabbitmq to store');
|
||||
|
||||
this.writeStore<RabbitmqRaw>({
|
||||
path: join(this.storePath, 'rabbitmq'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('rabbitmq saved to store in path: ' + join(this.storePath, 'rabbitmq') + '/' + instance);
|
||||
|
||||
this.logger.verbose('rabbitmq created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<RabbitmqRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding rabbitmq');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding rabbitmq in db');
|
||||
return await this.rabbitmqModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding rabbitmq in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'rabbitmq', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as RabbitmqRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { Rabbitmq } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { RabbitmqRaw } from '../../../models';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { RabbitmqDto } from '../dto/rabbitmq.dto';
|
||||
import { initQueues } from '../libs/amqp.server';
|
||||
@ -18,7 +19,7 @@ export class RabbitmqService {
|
||||
return { rabbitmq: { ...instance, rabbitmq: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<RabbitmqRaw> {
|
||||
public async find(instance: InstanceDto): Promise<Rabbitmq> {
|
||||
try {
|
||||
this.logger.verbose('find rabbitmq: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findRabbitmq();
|
||||
@ -29,7 +30,7 @@ export class RabbitmqService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, events: [] };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { SQS } from '@aws-sdk/client-sqs';
|
||||
import { JsonValue } from '@prisma/client/runtime/library';
|
||||
|
||||
import { configService, Sqs } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
@ -59,12 +60,13 @@ export const initQueues = (instanceName: string, events: string[]) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const removeQueues = (instanceName: string, events: string[]) => {
|
||||
if (!events || !events.length) return;
|
||||
export const removeQueues = (instanceName: string, events: JsonValue) => {
|
||||
const eventsArray = Array.isArray(events) ? events.map((event) => String(event)) : [];
|
||||
if (!events || !eventsArray.length) return;
|
||||
|
||||
const sqs = getSQS();
|
||||
|
||||
const queues = events.map((event) => {
|
||||
const queues = eventsArray.map((event) => {
|
||||
return `${event.replace(/_/g, '_').toLowerCase()}`;
|
||||
});
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
export class SqsRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
}
|
||||
|
||||
const sqsSchema = new Schema<SqsRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
events: { type: [String], required: true },
|
||||
});
|
||||
|
||||
export const SqsModel = mongodbServer?.model(SqsRaw.name, sqsSchema, 'sqs');
|
||||
export type ISqsModel = typeof SqsModel;
|
@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { ISqsModel, SqsRaw } from '../../../models';
|
||||
|
||||
export class SqsRepository extends Repository {
|
||||
constructor(private readonly sqsModel: ISqsModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('SqsRepository');
|
||||
|
||||
public async create(data: SqsRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating sqs');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving sqs to db');
|
||||
const insert = await this.sqsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('sqs saved to db: ' + insert.modifiedCount + ' sqs');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving sqs to store');
|
||||
|
||||
this.writeStore<SqsRaw>({
|
||||
path: join(this.storePath, 'sqs'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('sqs saved to store in path: ' + join(this.storePath, 'sqs') + '/' + instance);
|
||||
|
||||
this.logger.verbose('sqs created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<SqsRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding sqs');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding sqs in db');
|
||||
return await this.sqsModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding sqs in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'sqs', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as SqsRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { Sqs } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { SqsRaw } from '../../../models';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { SqsDto } from '../dto/sqs.dto';
|
||||
import { initQueues } from '../libs/sqs.server';
|
||||
@ -18,7 +19,7 @@ export class SqsService {
|
||||
return { sqs: { ...instance, sqs: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<SqsRaw> {
|
||||
public async find(instance: InstanceDto): Promise<Sqs> {
|
||||
try {
|
||||
this.logger.verbose('find sqs: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findSqs();
|
||||
@ -29,7 +30,7 @@ export class SqsService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, events: [] };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { TypebotSession } from '@prisma/client';
|
||||
|
||||
export class Session {
|
||||
remoteJid?: string;
|
||||
sessionId?: string;
|
||||
@ -19,9 +21,9 @@ export class TypebotDto {
|
||||
url: string;
|
||||
typebot?: string;
|
||||
expire?: number;
|
||||
keyword_finish?: string;
|
||||
delay_message?: number;
|
||||
unknown_message?: string;
|
||||
listening_from_me?: boolean;
|
||||
sessions?: Session[];
|
||||
keywordFinish?: string;
|
||||
delayMessage?: number;
|
||||
unknownMessage?: string;
|
||||
listeningFromMe?: boolean;
|
||||
sessions?: TypebotSession[];
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
class Session {
|
||||
remoteJid?: string;
|
||||
sessionId?: string;
|
||||
status?: string;
|
||||
createdAt?: number;
|
||||
updateAt?: number;
|
||||
prefilledVariables?: {
|
||||
remoteJid?: string;
|
||||
pushName?: string;
|
||||
additionalData?: { [key: string]: any };
|
||||
};
|
||||
}
|
||||
|
||||
export class TypebotRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
url: string;
|
||||
typebot?: string;
|
||||
expire?: number;
|
||||
keyword_finish?: string;
|
||||
delay_message?: number;
|
||||
unknown_message?: string;
|
||||
listening_from_me?: boolean;
|
||||
sessions?: Session[];
|
||||
}
|
||||
|
||||
const typebotSchema = new Schema<TypebotRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
url: { type: String, required: true },
|
||||
typebot: { type: String, required: true },
|
||||
expire: { type: Number, required: true },
|
||||
keyword_finish: { type: String, required: true },
|
||||
delay_message: { type: Number, required: true },
|
||||
unknown_message: { type: String, required: true },
|
||||
listening_from_me: { type: Boolean, required: true },
|
||||
sessions: [
|
||||
{
|
||||
remoteJid: { type: String, required: true },
|
||||
sessionId: { type: String, required: true },
|
||||
status: { type: String, required: true },
|
||||
createdAt: { type: Number, required: true },
|
||||
updateAt: { type: Number, required: true },
|
||||
prefilledVariables: {
|
||||
remoteJid: { type: String, required: false },
|
||||
pushName: { type: String, required: false },
|
||||
additionalData: { type: Schema.Types.Mixed, required: false },
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const TypebotModel = mongodbServer?.model(TypebotRaw.name, typebotSchema, 'typebot');
|
||||
export type ITypebotModel = typeof TypebotModel;
|
@ -1,68 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { ITypebotModel, TypebotRaw } from '../../../models';
|
||||
|
||||
export class TypebotRepository extends Repository {
|
||||
constructor(private readonly typebotModel: ITypebotModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('TypebotRepository');
|
||||
|
||||
public async create(data: TypebotRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating typebot');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving typebot to db');
|
||||
const insert = await this.typebotModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('typebot saved to db: ' + insert.modifiedCount + ' typebot');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving typebot to store');
|
||||
|
||||
this.writeStore<TypebotRaw>({
|
||||
path: join(this.storePath, 'typebot'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('typebot saved to store in path: ' + join(this.storePath, 'typebot') + '/' + instance);
|
||||
|
||||
this.logger.verbose('typebot created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<TypebotRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding typebot');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding typebot in db');
|
||||
return await this.typebotModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding typebot in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'typebot', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as TypebotRaw;
|
||||
} catch (error) {
|
||||
return {
|
||||
enabled: false,
|
||||
url: '',
|
||||
typebot: '',
|
||||
expire: 0,
|
||||
sessions: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
import { Message } from '@prisma/client';
|
||||
import axios from 'axios';
|
||||
import EventEmitter2 from 'eventemitter2';
|
||||
|
||||
import { ConfigService, Typebot } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { MessageRaw } from '../../../models';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { Events } from '../../../types/wa.types';
|
||||
import { Session, TypebotDto } from '../dto/typebot.dto';
|
||||
import { TypebotDto } from '../dto/typebot.dto';
|
||||
|
||||
export class TypebotService {
|
||||
constructor(
|
||||
@ -64,10 +64,10 @@ export class TypebotService {
|
||||
url: findData.url,
|
||||
typebot: findData.typebot,
|
||||
expire: findData.expire,
|
||||
keyword_finish: findData.keyword_finish,
|
||||
delay_message: findData.delay_message,
|
||||
unknown_message: findData.unknown_message,
|
||||
listening_from_me: findData.listening_from_me,
|
||||
keywordFinish: findData.keywordFinish,
|
||||
delayMessage: findData.delayMessage,
|
||||
unknownMessage: findData.unknownMessage,
|
||||
listeningFromMe: findData.listeningFromMe,
|
||||
sessions: findData.sessions,
|
||||
};
|
||||
|
||||
@ -82,19 +82,19 @@ export class TypebotService {
|
||||
}
|
||||
});
|
||||
} else if (status === 'paused') {
|
||||
const session: Session = {
|
||||
remoteJid: remoteJid,
|
||||
sessionId: Math.floor(Math.random() * 10000000000).toString(),
|
||||
status: status,
|
||||
createdAt: Date.now(),
|
||||
updateAt: Date.now(),
|
||||
prefilledVariables: {
|
||||
remoteJid: remoteJid,
|
||||
pushName: '',
|
||||
additionalData: {},
|
||||
},
|
||||
};
|
||||
findData.sessions.push(session);
|
||||
// const session: Session = {
|
||||
// remoteJid: remoteJid,
|
||||
// sessionId: Math.floor(Math.random() * 10000000000).toString(),
|
||||
// status: status,
|
||||
// createdAt: Date.now(),
|
||||
// updateAt: Date.now(),
|
||||
// prefilledVariables: {
|
||||
// remoteJid: remoteJid,
|
||||
// pushName: '',
|
||||
// additionalData: {},
|
||||
// },
|
||||
// };
|
||||
// findData.sessions.push(session);
|
||||
}
|
||||
|
||||
const typebotData = {
|
||||
@ -102,10 +102,10 @@ export class TypebotService {
|
||||
url: findData.url,
|
||||
typebot: findData.typebot,
|
||||
expire: findData.expire,
|
||||
keyword_finish: findData.keyword_finish,
|
||||
delay_message: findData.delay_message,
|
||||
unknown_message: findData.unknown_message,
|
||||
listening_from_me: findData.listening_from_me,
|
||||
keywordFinish: findData.keywordFinish,
|
||||
delayMessage: findData.delayMessage,
|
||||
unknownMessage: findData.unknownMessage,
|
||||
listeningFromMe: findData.listeningFromMe,
|
||||
sessions: findData.sessions,
|
||||
};
|
||||
|
||||
@ -124,7 +124,8 @@ export class TypebotService {
|
||||
|
||||
public async clearSessions(instance: InstanceDto, remoteJid: string) {
|
||||
const findTypebot = await this.find(instance);
|
||||
const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
const sessions = [];
|
||||
// const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
|
||||
const sessionWithRemoteJid = sessions.filter((session) => session.remoteJid === remoteJid);
|
||||
|
||||
@ -138,10 +139,10 @@ export class TypebotService {
|
||||
url: findTypebot.url,
|
||||
typebot: findTypebot.typebot,
|
||||
expire: findTypebot.expire,
|
||||
keyword_finish: findTypebot.keyword_finish,
|
||||
delay_message: findTypebot.delay_message,
|
||||
unknown_message: findTypebot.unknown_message,
|
||||
listening_from_me: findTypebot.listening_from_me,
|
||||
keywordFinish: findTypebot.keywordFinish,
|
||||
delayMessage: findTypebot.delayMessage,
|
||||
unknownMessage: findTypebot.unknownMessage,
|
||||
listeningFromMe: findTypebot.listeningFromMe,
|
||||
sessions,
|
||||
};
|
||||
|
||||
@ -163,10 +164,10 @@ export class TypebotService {
|
||||
const variables = data.variables;
|
||||
const findTypebot = await this.find(instance);
|
||||
const expire = findTypebot.expire;
|
||||
const keyword_finish = findTypebot.keyword_finish;
|
||||
const delay_message = findTypebot.delay_message;
|
||||
const unknown_message = findTypebot.unknown_message;
|
||||
const listening_from_me = findTypebot.listening_from_me;
|
||||
const keywordFinish = findTypebot.keywordFinish;
|
||||
const delayMessage = findTypebot.delayMessage;
|
||||
const unknownMessage = findTypebot.unknownMessage;
|
||||
const listeningFromMe = findTypebot.listeningFromMe;
|
||||
|
||||
const prefilledVariables = {
|
||||
remoteJid: remoteJid,
|
||||
@ -188,10 +189,10 @@ export class TypebotService {
|
||||
typebot: typebot,
|
||||
remoteJid: remoteJid,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
prefilledVariables: prefilledVariables,
|
||||
});
|
||||
@ -467,10 +468,10 @@ export class TypebotService {
|
||||
url: data.url,
|
||||
typebot: data.typebot,
|
||||
expire: data.expire,
|
||||
keyword_finish: data.keyword_finish,
|
||||
delay_message: data.delay_message,
|
||||
unknown_message: data.unknown_message,
|
||||
listening_from_me: data.listening_from_me,
|
||||
keywordFinish: data.keywordFinish,
|
||||
delayMessage: data.delayMessage,
|
||||
unknownMessage: data.unknownMessage,
|
||||
listeningFromMe: data.listeningFromMe,
|
||||
sessions: data.sessions,
|
||||
};
|
||||
|
||||
@ -585,7 +586,7 @@ export class TypebotService {
|
||||
await instance.textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
@ -598,7 +599,7 @@ export class TypebotService {
|
||||
await instance.mediaMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
mediaMessage: {
|
||||
@ -612,7 +613,7 @@ export class TypebotService {
|
||||
await instance.mediaMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
mediaMessage: {
|
||||
@ -626,7 +627,7 @@ export class TypebotService {
|
||||
await instance.audioWhatsapp({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'recording',
|
||||
encoding: true,
|
||||
},
|
||||
@ -658,7 +659,7 @@ export class TypebotService {
|
||||
await instance.textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
@ -675,16 +676,17 @@ export class TypebotService {
|
||||
}
|
||||
}
|
||||
|
||||
public async sendTypebot(instance: InstanceDto, remoteJid: string, msg: MessageRaw) {
|
||||
public async sendTypebot(instance: InstanceDto, remoteJid: string, msg: Message) {
|
||||
const findTypebot = await this.find(instance);
|
||||
const url = findTypebot.url;
|
||||
const typebot = findTypebot.typebot;
|
||||
const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
// const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
const sessions = [];
|
||||
const expire = findTypebot.expire;
|
||||
const keyword_finish = findTypebot.keyword_finish;
|
||||
const delay_message = findTypebot.delay_message;
|
||||
const unknown_message = findTypebot.unknown_message;
|
||||
const listening_from_me = findTypebot.listening_from_me;
|
||||
const keywordFinish = findTypebot.keywordFinish;
|
||||
const delayMessage = findTypebot.delayMessage;
|
||||
const unknownMessage = findTypebot.unknownMessage;
|
||||
const listeningFromMe = findTypebot.listeningFromMe;
|
||||
const messageType = this.getTypeMessage(msg.message).messageType;
|
||||
|
||||
const session = sessions.find((session) => session.remoteJid === remoteJid);
|
||||
@ -705,10 +707,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
remoteJid: remoteJid,
|
||||
pushName: msg.pushName,
|
||||
@ -720,22 +722,22 @@ export class TypebotService {
|
||||
const content = this.getConversationMessage(msg.message);
|
||||
|
||||
if (!content) {
|
||||
if (unknown_message) {
|
||||
if (unknownMessage) {
|
||||
this.waMonitor.waInstances[instance.instanceName].textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: delay_message || 1000,
|
||||
delay: delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
text: unknown_message,
|
||||
text: unknownMessage,
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyword_finish && content.toLowerCase() === keyword_finish.toLowerCase()) {
|
||||
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
|
||||
const newSessions = await this.clearSessions(instance, remoteJid);
|
||||
|
||||
const typebotData = {
|
||||
@ -743,10 +745,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
};
|
||||
|
||||
@ -801,10 +803,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: sessions,
|
||||
remoteJid: remoteJid,
|
||||
pushName: msg.pushName,
|
||||
@ -819,22 +821,22 @@ export class TypebotService {
|
||||
const content = this.getConversationMessage(msg.message);
|
||||
|
||||
if (!content) {
|
||||
if (unknown_message) {
|
||||
if (unknownMessage) {
|
||||
this.waMonitor.waInstances[instance.instanceName].textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: delay_message || 1000,
|
||||
delay: delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
text: unknown_message,
|
||||
text: unknownMessage,
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyword_finish && content.toLowerCase() === keyword_finish.toLowerCase()) {
|
||||
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
|
||||
const newSessions = await this.clearSessions(instance, remoteJid);
|
||||
|
||||
const typebotData = {
|
||||
@ -842,10 +844,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
};
|
||||
|
||||
@ -899,10 +901,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions,
|
||||
};
|
||||
|
||||
@ -911,22 +913,22 @@ export class TypebotService {
|
||||
const content = this.getConversationMessage(msg.message);
|
||||
|
||||
if (!content) {
|
||||
if (unknown_message) {
|
||||
if (unknownMessage) {
|
||||
this.waMonitor.waInstances[instance.instanceName].textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: delay_message || 1000,
|
||||
delay: delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
text: unknown_message,
|
||||
text: unknownMessage,
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyword_finish && content.toLowerCase() === keyword_finish.toLowerCase()) {
|
||||
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
|
||||
const newSessions = await this.clearSessions(instance, remoteJid);
|
||||
|
||||
const typebotData = {
|
||||
@ -934,10 +936,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
};
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
export class WebsocketRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
}
|
||||
|
||||
const websocketSchema = new Schema<WebsocketRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
events: { type: [String], required: true },
|
||||
});
|
||||
|
||||
export const WebsocketModel = mongodbServer?.model(WebsocketRaw.name, websocketSchema, 'websocket');
|
||||
export type IWebsocketModel = typeof WebsocketModel;
|
@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { IWebsocketModel, WebsocketRaw } from '../../../models';
|
||||
|
||||
export class WebsocketRepository extends Repository {
|
||||
constructor(private readonly websocketModel: IWebsocketModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('WebsocketRepository');
|
||||
|
||||
public async create(data: WebsocketRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating websocket');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving websocket to db');
|
||||
const insert = await this.websocketModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('websocket saved to db: ' + insert.modifiedCount + ' websocket');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving websocket to store');
|
||||
|
||||
this.writeStore<WebsocketRaw>({
|
||||
path: join(this.storePath, 'websocket'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('websocket saved to store in path: ' + join(this.storePath, 'websocket') + '/' + instance);
|
||||
|
||||
this.logger.verbose('websocket created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<WebsocketRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding websocket');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding websocket in db');
|
||||
return await this.websocketModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding websocket in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'websocket', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as WebsocketRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { Websocket } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { WebsocketRaw } from '../../../models';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { WebsocketDto } from '../dto/websocket.dto';
|
||||
|
||||
@ -16,7 +17,7 @@ export class WebsocketService {
|
||||
return { websocket: { ...instance, websocket: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<WebsocketRaw> {
|
||||
public async find(instance: InstanceDto): Promise<Websocket> {
|
||||
try {
|
||||
this.logger.verbose('find websocket: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findWebsocket();
|
||||
@ -27,7 +28,7 @@ export class WebsocketService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, events: [] };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
|
||||
export class AuthRaw {
|
||||
_id?: string;
|
||||
apikey?: string;
|
||||
instanceId?: string;
|
||||
}
|
||||
|
||||
const authSchema = new Schema<AuthRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
apikey: { type: String, minlength: 1 },
|
||||
instanceId: { type: String, minlength: 1 },
|
||||
});
|
||||
|
||||
export const AuthModel = mongodbServer?.model(AuthRaw.name, authSchema, 'authentication');
|
||||
export type IAuthModel = typeof AuthModel;
|
@ -1,26 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
|
||||
export class ChatRaw {
|
||||
_id?: string;
|
||||
id?: string;
|
||||
owner: string;
|
||||
lastMsgTimestamp?: number;
|
||||
labels?: string[];
|
||||
}
|
||||
|
||||
type ChatRawBoolean<T> = {
|
||||
[P in keyof T]?: 0 | 1;
|
||||
};
|
||||
export type ChatRawSelect = ChatRawBoolean<ChatRaw>;
|
||||
|
||||
const chatSchema = new Schema<ChatRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
id: { type: String, required: true, minlength: 1 },
|
||||
owner: { type: String, required: true, minlength: 1 },
|
||||
labels: { type: [String], default: [] },
|
||||
});
|
||||
|
||||
export const ChatModel = mongodbServer?.model(ChatRaw.name, chatSchema, 'chats');
|
||||
export type IChatModel = typeof ChatModel;
|
@ -1,27 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
|
||||
export class ContactRaw {
|
||||
_id?: string;
|
||||
pushName?: string;
|
||||
id?: string;
|
||||
profilePictureUrl?: string;
|
||||
owner: string;
|
||||
}
|
||||
|
||||
type ContactRawBoolean<T> = {
|
||||
[P in keyof T]?: 0 | 1;
|
||||
};
|
||||
export type ContactRawSelect = ContactRawBoolean<ContactRaw>;
|
||||
|
||||
const contactSchema = new Schema<ContactRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
pushName: { type: String, minlength: 1 },
|
||||
id: { type: String, required: true, minlength: 1 },
|
||||
profilePictureUrl: { type: String, minlength: 1 },
|
||||
owner: { type: String, required: true, minlength: 1 },
|
||||
});
|
||||
|
||||
export const ContactModel = mongodbServer?.model(ContactRaw.name, contactSchema, 'contacts');
|
||||
export type IContactModel = typeof ContactModel;
|
@ -1,14 +0,0 @@
|
||||
export * from '../integrations/chatwoot/models/chatwoot.model';
|
||||
export * from '../integrations/rabbitmq/models/rabbitmq.model';
|
||||
export * from '../integrations/sqs/models/sqs.model';
|
||||
export * from '../integrations/typebot/models/typebot.model';
|
||||
export * from '../integrations/websocket/models/websocket.model';
|
||||
export * from './auth.model';
|
||||
export * from './chat.model';
|
||||
export * from './contact.model';
|
||||
export * from './integration.model';
|
||||
export * from './label.model';
|
||||
export * from './message.model';
|
||||
export * from './proxy.model';
|
||||
export * from './settings.model';
|
||||
export * from './webhook.model';
|
@ -1,20 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
|
||||
export class IntegrationRaw {
|
||||
_id?: string;
|
||||
integration?: string;
|
||||
number?: string;
|
||||
token?: string;
|
||||
}
|
||||
|
||||
const integrationSchema = new Schema<IntegrationRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
integration: { type: String, required: true },
|
||||
number: { type: String, required: true },
|
||||
token: { type: String, required: true },
|
||||
});
|
||||
|
||||
export const IntegrationModel = mongodbServer?.model(IntegrationRaw.name, integrationSchema, 'integration');
|
||||
export type IntegrationModel = typeof IntegrationModel;
|
@ -1,29 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
|
||||
export class LabelRaw {
|
||||
_id?: string;
|
||||
id?: string;
|
||||
owner: string;
|
||||
name: string;
|
||||
color: number;
|
||||
predefinedId?: string;
|
||||
}
|
||||
|
||||
type LabelRawBoolean<T> = {
|
||||
[P in keyof T]?: 0 | 1;
|
||||
};
|
||||
export type LabelRawSelect = LabelRawBoolean<LabelRaw>;
|
||||
|
||||
const labelSchema = new Schema<LabelRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
id: { type: String, required: true, minlength: 1 },
|
||||
owner: { type: String, required: true, minlength: 1 },
|
||||
name: { type: String, required: true, minlength: 1 },
|
||||
color: { type: Number, required: true, min: 0, max: 19 },
|
||||
predefinedId: { type: String },
|
||||
});
|
||||
|
||||
export const LabelModel = mongodbServer?.model(LabelRaw.name, labelSchema, 'labels');
|
||||
export type ILabelModel = typeof LabelModel;
|
@ -1,102 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
import { wa } from '../types/wa.types';
|
||||
|
||||
class Key {
|
||||
id?: string;
|
||||
remoteJid?: string;
|
||||
fromMe?: boolean;
|
||||
participant?: string;
|
||||
}
|
||||
|
||||
class ChatwootMessage {
|
||||
messageId?: number;
|
||||
inboxId?: number;
|
||||
conversationId?: number;
|
||||
contactInbox?: { sourceId: string };
|
||||
isRead?: boolean;
|
||||
}
|
||||
|
||||
export class MessageRaw {
|
||||
_id?: string;
|
||||
key?: Key;
|
||||
pushName?: string;
|
||||
participant?: string;
|
||||
message?: object;
|
||||
messageType?: string;
|
||||
messageTimestamp?: number | Long.Long;
|
||||
owner: string;
|
||||
source?: 'android' | 'web' | 'ios' | 'unknown' | 'desktop';
|
||||
source_id?: string;
|
||||
source_reply_id?: string;
|
||||
chatwoot?: ChatwootMessage;
|
||||
contextInfo?: any;
|
||||
status?: wa.StatusMessage | any;
|
||||
}
|
||||
|
||||
type MessageRawBoolean<T> = {
|
||||
[P in keyof T]?: 0 | 1;
|
||||
};
|
||||
export type MessageRawSelect = Omit<Omit<MessageRawBoolean<MessageRaw>, 'key'>, 'chatwoot'> & {
|
||||
key?: MessageRawBoolean<Key>;
|
||||
chatwoot?: MessageRawBoolean<ChatwootMessage>;
|
||||
};
|
||||
|
||||
const messageSchema = new Schema<MessageRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
key: {
|
||||
id: { type: String, required: true, minlength: 1 },
|
||||
remoteJid: { type: String, required: true, minlength: 1 },
|
||||
fromMe: { type: Boolean, required: true },
|
||||
participant: { type: String, minlength: 1 },
|
||||
},
|
||||
pushName: { type: String },
|
||||
participant: { type: String },
|
||||
messageType: { type: String },
|
||||
message: { type: Object },
|
||||
source: { type: String, minlength: 3, enum: ['android', 'web', 'ios', 'unknown', 'desktop'] },
|
||||
messageTimestamp: { type: Number, required: true },
|
||||
owner: { type: String, required: true, minlength: 1 },
|
||||
chatwoot: {
|
||||
messageId: { type: Number },
|
||||
inboxId: { type: Number },
|
||||
conversationId: { type: Number },
|
||||
contactInbox: { type: Object },
|
||||
isRead: { type: Boolean },
|
||||
},
|
||||
});
|
||||
|
||||
messageSchema.index({ 'chatwoot.messageId': 1, owner: 1 });
|
||||
messageSchema.index({ 'key.id': 1 });
|
||||
messageSchema.index({ 'key.id': 1, owner: 1 });
|
||||
messageSchema.index({ owner: 1 });
|
||||
|
||||
export const MessageModel = mongodbServer?.model(MessageRaw.name, messageSchema, 'messages');
|
||||
export type IMessageModel = typeof MessageModel;
|
||||
|
||||
export class MessageUpdateRaw {
|
||||
_id?: string;
|
||||
remoteJid?: string;
|
||||
id?: string;
|
||||
fromMe?: boolean;
|
||||
participant?: string;
|
||||
datetime?: number;
|
||||
status?: wa.StatusMessage;
|
||||
owner: string;
|
||||
pollUpdates?: any;
|
||||
}
|
||||
|
||||
const messageUpdateSchema = new Schema<MessageUpdateRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
remoteJid: { type: String, required: true, min: 1 },
|
||||
id: { type: String, required: true, min: 1 },
|
||||
fromMe: { type: Boolean, required: true },
|
||||
participant: { type: String, min: 1 },
|
||||
datetime: { type: Number, required: true, min: 1 },
|
||||
status: { type: String, required: true },
|
||||
owner: { type: String, required: true, min: 1 },
|
||||
});
|
||||
|
||||
export const MessageUpModel = mongodbServer?.model(MessageUpdateRaw.name, messageUpdateSchema, 'messageUpdate');
|
||||
export type IMessageUpModel = typeof MessageUpModel;
|
@ -1,32 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
|
||||
class Proxy {
|
||||
host?: string;
|
||||
port?: string;
|
||||
protocol?: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
}
|
||||
|
||||
export class ProxyRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
proxy?: Proxy;
|
||||
}
|
||||
|
||||
const proxySchema = new Schema<ProxyRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
proxy: {
|
||||
host: { type: String, required: true },
|
||||
port: { type: String, required: true },
|
||||
protocol: { type: String, required: true },
|
||||
username: { type: String, required: false },
|
||||
password: { type: String, required: false },
|
||||
},
|
||||
});
|
||||
|
||||
export const ProxyModel = mongodbServer?.model(ProxyRaw.name, proxySchema, 'proxy');
|
||||
export type IProxyModel = typeof ProxyModel;
|
@ -1,28 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
|
||||
export class SettingsRaw {
|
||||
_id?: string;
|
||||
reject_call?: boolean;
|
||||
msg_call?: string;
|
||||
groups_ignore?: boolean;
|
||||
always_online?: boolean;
|
||||
read_messages?: boolean;
|
||||
read_status?: boolean;
|
||||
sync_full_history?: boolean;
|
||||
}
|
||||
|
||||
const settingsSchema = new Schema<SettingsRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
reject_call: { type: Boolean, required: true },
|
||||
msg_call: { type: String, required: true },
|
||||
groups_ignore: { type: Boolean, required: true },
|
||||
always_online: { type: Boolean, required: true },
|
||||
read_messages: { type: Boolean, required: true },
|
||||
read_status: { type: Boolean, required: true },
|
||||
sync_full_history: { type: Boolean, required: true },
|
||||
});
|
||||
|
||||
export const SettingsModel = mongodbServer?.model(SettingsRaw.name, settingsSchema, 'settings');
|
||||
export type ISettingsModel = typeof SettingsModel;
|
@ -1,24 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
|
||||
export class WebhookRaw {
|
||||
_id?: string;
|
||||
url?: string;
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
webhook_by_events?: boolean;
|
||||
webhook_base64?: boolean;
|
||||
}
|
||||
|
||||
const webhookSchema = new Schema<WebhookRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
url: { type: String, required: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
events: { type: [String], required: true },
|
||||
webhook_by_events: { type: Boolean, required: true },
|
||||
webhook_base64: { type: Boolean, required: true },
|
||||
});
|
||||
|
||||
export const WebhookModel = mongodbServer?.model(WebhookRaw.name, webhookSchema, 'webhook');
|
||||
export type IWebhookModel = typeof WebhookModel;
|
@ -1,149 +0,0 @@
|
||||
import { opendirSync, readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { Auth, ConfigService } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { AUTH_DIR } from '../../../config/path.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { AuthRaw, IAuthModel, IntegrationModel } from '../../models';
|
||||
|
||||
export class AuthRepository extends Repository {
|
||||
constructor(
|
||||
private readonly authModel: IAuthModel,
|
||||
private readonly integrationModel: IntegrationModel,
|
||||
readonly configService: ConfigService,
|
||||
) {
|
||||
super(configService);
|
||||
this.auth = configService.get<Auth>('AUTHENTICATION');
|
||||
}
|
||||
|
||||
private readonly auth: Auth;
|
||||
private readonly logger = new Logger('AuthRepository');
|
||||
|
||||
public async create(data: AuthRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating auth');
|
||||
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving auth to db');
|
||||
const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving auth to store');
|
||||
|
||||
this.writeStore<AuthRaw>({
|
||||
path: join(AUTH_DIR, 'apikey'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, 'apikey') + '/' + instance);
|
||||
|
||||
this.logger.verbose('auth created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return { error } as any;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<AuthRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding auth');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding auth in db');
|
||||
return await this.authModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding auth in store');
|
||||
|
||||
return JSON.parse(
|
||||
readFileSync(join(AUTH_DIR, 'apikey', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as AuthRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
public async findByKey(key: string): Promise<AuthRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding auth');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding auth in db');
|
||||
return await this.authModel.findOne({ apikey: key });
|
||||
}
|
||||
|
||||
return {};
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
public async list(): Promise<AuthRaw[]> {
|
||||
try {
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('listing auth in db');
|
||||
return await this.authModel.find();
|
||||
}
|
||||
|
||||
this.logger.verbose('listing auth in store');
|
||||
|
||||
const auths: AuthRaw[] = [];
|
||||
const openDir = opendirSync(join(AUTH_DIR, 'apikey'), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
for await (const dirent of openDir) {
|
||||
if (dirent.isFile()) {
|
||||
auths.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(AUTH_DIR, 'apikey', dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return auths;
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public async findInstanceNameById(instanceId: string): Promise<string | null> {
|
||||
try {
|
||||
this.logger.verbose('finding auth by instanceId');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding auth in db');
|
||||
const response = await this.authModel.findOne({ instanceId });
|
||||
|
||||
return response._id;
|
||||
}
|
||||
|
||||
this.logger.verbose('finding auth in store is not supported');
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async findInstanceNameByNumber(number: string): Promise<string | null> {
|
||||
try {
|
||||
this.logger.verbose('finding auth by number');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding auth in db');
|
||||
const instance = await this.integrationModel.findOne({ number });
|
||||
|
||||
const response = await this.authModel.findOne({ _id: instance._id });
|
||||
|
||||
return response._id;
|
||||
}
|
||||
|
||||
this.logger.verbose('finding auth in store is not supported');
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
import { opendirSync, readFileSync, rmSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { ChatRaw, ChatRawSelect, IChatModel } from '../../models';
|
||||
|
||||
export class ChatQuery {
|
||||
select?: ChatRawSelect;
|
||||
where: ChatRaw;
|
||||
}
|
||||
|
||||
export class ChatRepository extends Repository {
|
||||
constructor(private readonly chatModel: IChatModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('ChatRepository');
|
||||
|
||||
public async insert(data: ChatRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||
this.logger.verbose('inserting chats');
|
||||
if (data.length === 0) {
|
||||
this.logger.verbose('no chats to insert');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.logger.verbose('saving chats to store');
|
||||
if (this.dbSettings.ENABLED && saveDb) {
|
||||
this.logger.verbose('saving chats to db');
|
||||
const insert = await this.chatModel.insertMany([...data]);
|
||||
|
||||
this.logger.verbose('chats saved to db: ' + insert.length + ' chats');
|
||||
return { insertCount: insert.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving chats to store');
|
||||
|
||||
const store = this.configService.get<StoreConf>('STORE');
|
||||
|
||||
if (store.CHATS) {
|
||||
this.logger.verbose('saving chats to store');
|
||||
data.forEach((chat) => {
|
||||
this.writeStore<ChatRaw>({
|
||||
path: join(this.storePath, 'chats', instanceName),
|
||||
fileName: chat.id,
|
||||
data: chat,
|
||||
});
|
||||
this.logger.verbose(
|
||||
'chats saved to store in path: ' + join(this.storePath, 'chats', instanceName) + '/' + chat.id,
|
||||
);
|
||||
});
|
||||
|
||||
this.logger.verbose('chats saved to store');
|
||||
return { insertCount: data.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('chats not saved to store');
|
||||
return { insertCount: 0 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
} finally {
|
||||
data = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(query: ChatQuery): Promise<ChatRaw[]> {
|
||||
try {
|
||||
this.logger.verbose('finding chats');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding chats in db');
|
||||
return await this.chatModel.find({ owner: query.where.owner }).select(query.select ?? {});
|
||||
}
|
||||
|
||||
this.logger.verbose('finding chats in store');
|
||||
|
||||
const chats: ChatRaw[] = [];
|
||||
const openDir = opendirSync(join(this.storePath, 'chats', query.where.owner));
|
||||
for await (const dirent of openDir) {
|
||||
if (dirent.isFile()) {
|
||||
chats.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'chats', query.where.owner, dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.verbose('chats found in store: ' + chats.length + ' chats');
|
||||
return chats;
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public async delete(query: ChatQuery) {
|
||||
try {
|
||||
this.logger.verbose('deleting chats');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('deleting chats in db');
|
||||
return await this.chatModel.deleteOne({ ...query.where });
|
||||
}
|
||||
|
||||
this.logger.verbose('deleting chats in store');
|
||||
rmSync(join(this.storePath, 'chats', query.where.owner, query.where.id + '.josn'), {
|
||||
force: true,
|
||||
recursive: true,
|
||||
});
|
||||
|
||||
return { deleted: { chatId: query.where.id } };
|
||||
} catch (error) {
|
||||
return { error: error?.toString() };
|
||||
}
|
||||
}
|
||||
|
||||
public async update(data: ChatRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('updating chats');
|
||||
|
||||
if (data.length === 0) {
|
||||
this.logger.verbose('no chats to update');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.dbSettings.ENABLED && saveDb) {
|
||||
this.logger.verbose('updating chats in db');
|
||||
|
||||
const chats = data.map((chat) => {
|
||||
return {
|
||||
updateOne: {
|
||||
filter: { id: chat.id },
|
||||
update: { ...chat },
|
||||
upsert: true,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const { nModified } = await this.chatModel.bulkWrite(chats);
|
||||
|
||||
this.logger.verbose('chats updated in db: ' + nModified + ' chats');
|
||||
return { insertCount: nModified };
|
||||
}
|
||||
|
||||
this.logger.verbose('updating chats in store');
|
||||
|
||||
const store = this.configService.get<StoreConf>('STORE');
|
||||
|
||||
if (store.CONTACTS) {
|
||||
this.logger.verbose('updating chats in store');
|
||||
data.forEach((chat) => {
|
||||
this.writeStore({
|
||||
path: join(this.storePath, 'chats', instanceName),
|
||||
fileName: chat.id,
|
||||
data: chat,
|
||||
});
|
||||
this.logger.verbose(
|
||||
'chats updated in store in path: ' + join(this.storePath, 'chats', instanceName) + '/' + chat.id,
|
||||
);
|
||||
});
|
||||
|
||||
this.logger.verbose('chats updated in store: ' + data.length + ' chats');
|
||||
|
||||
return { insertCount: data.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('chats not updated');
|
||||
return { insertCount: 0 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
} finally {
|
||||
data = undefined;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,227 +0,0 @@
|
||||
import { opendirSync, readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { ContactRaw, ContactRawSelect, IContactModel } from '../../models';
|
||||
|
||||
export class ContactQuery {
|
||||
select?: ContactRawSelect;
|
||||
where: ContactRaw;
|
||||
}
|
||||
|
||||
export class ContactQueryMany {
|
||||
owner: ContactRaw['owner'];
|
||||
ids: ContactRaw['id'][];
|
||||
}
|
||||
|
||||
export class ContactRepository extends Repository {
|
||||
constructor(private readonly contactModel: IContactModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('ContactRepository');
|
||||
|
||||
public async insert(data: ContactRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||
this.logger.verbose('inserting contacts');
|
||||
|
||||
if (data.length === 0) {
|
||||
this.logger.verbose('no contacts to insert');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.dbSettings.ENABLED && saveDb) {
|
||||
this.logger.verbose('saving contacts to db');
|
||||
|
||||
const insert = await this.contactModel.insertMany([...data]);
|
||||
|
||||
this.logger.verbose('contacts saved to db: ' + insert.length + ' contacts');
|
||||
return { insertCount: insert.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving contacts to store');
|
||||
|
||||
const store = this.configService.get<StoreConf>('STORE');
|
||||
|
||||
if (store.CONTACTS) {
|
||||
this.logger.verbose('saving contacts to store');
|
||||
data.forEach((contact) => {
|
||||
this.writeStore({
|
||||
path: join(this.storePath, 'contacts', instanceName),
|
||||
fileName: contact.id,
|
||||
data: contact,
|
||||
});
|
||||
this.logger.verbose(
|
||||
'contacts saved to store in path: ' + join(this.storePath, 'contacts', instanceName) + '/' + contact.id,
|
||||
);
|
||||
});
|
||||
|
||||
this.logger.verbose('contacts saved to store: ' + data.length + ' contacts');
|
||||
return { insertCount: data.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('contacts not saved');
|
||||
return { insertCount: 0 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
} finally {
|
||||
data = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public async update(data: ContactRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('updating contacts');
|
||||
|
||||
if (data.length === 0) {
|
||||
this.logger.verbose('no contacts to update');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.dbSettings.ENABLED && saveDb) {
|
||||
this.logger.verbose('updating contacts in db');
|
||||
|
||||
const contacts = data.map((contact) => {
|
||||
return {
|
||||
updateOne: {
|
||||
filter: { id: contact.id },
|
||||
update: { ...contact },
|
||||
upsert: true,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const { nModified } = await this.contactModel.bulkWrite(contacts);
|
||||
|
||||
this.logger.verbose('contacts updated in db: ' + nModified + ' contacts');
|
||||
return { insertCount: nModified };
|
||||
}
|
||||
|
||||
this.logger.verbose('updating contacts in store');
|
||||
|
||||
const store = this.configService.get<StoreConf>('STORE');
|
||||
|
||||
if (store.CONTACTS) {
|
||||
this.logger.verbose('updating contacts in store');
|
||||
data.forEach((contact) => {
|
||||
this.writeStore({
|
||||
path: join(this.storePath, 'contacts', instanceName),
|
||||
fileName: contact.id,
|
||||
data: contact,
|
||||
});
|
||||
this.logger.verbose(
|
||||
'contacts updated in store in path: ' + join(this.storePath, 'contacts', instanceName) + '/' + contact.id,
|
||||
);
|
||||
});
|
||||
|
||||
this.logger.verbose('contacts updated in store: ' + data.length + ' contacts');
|
||||
|
||||
return { insertCount: data.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('contacts not updated');
|
||||
return { insertCount: 0 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
} finally {
|
||||
data = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(query: ContactQuery): Promise<ContactRaw[]> {
|
||||
try {
|
||||
this.logger.verbose('finding contacts');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding contacts in db');
|
||||
return await this.contactModel.find({ ...query.where }).select(query.select ?? {});
|
||||
}
|
||||
|
||||
this.logger.verbose('finding contacts in store');
|
||||
const contacts: ContactRaw[] = [];
|
||||
if (query?.where?.id) {
|
||||
this.logger.verbose('finding contacts in store by id');
|
||||
contacts.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'contacts', query.where.owner, query.where.id + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
this.logger.verbose('finding contacts in store by owner');
|
||||
|
||||
const openDir = opendirSync(join(this.storePath, 'contacts', query.where.owner), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
for await (const dirent of openDir) {
|
||||
if (dirent.isFile()) {
|
||||
contacts.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'contacts', query.where.owner, dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.verbose('contacts found in store: ' + contacts.length + ' contacts');
|
||||
return contacts;
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public async findManyById(query: ContactQueryMany): Promise<ContactRaw[]> {
|
||||
try {
|
||||
this.logger.verbose('finding contacts');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding contacts in db');
|
||||
return await this.contactModel.find({
|
||||
owner: query.owner,
|
||||
id: { $in: query.ids },
|
||||
});
|
||||
}
|
||||
|
||||
this.logger.verbose('finding contacts in store');
|
||||
const contacts: ContactRaw[] = [];
|
||||
if (query.ids.length > 0) {
|
||||
this.logger.verbose('finding contacts in store by id');
|
||||
query.ids.forEach((id) => {
|
||||
contacts.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'contacts', query.owner, id + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
this.logger.verbose('finding contacts in store by owner');
|
||||
|
||||
const openDir = opendirSync(join(this.storePath, 'contacts', query.owner), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
for await (const dirent of openDir) {
|
||||
if (dirent.isFile()) {
|
||||
contacts.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'contacts', query.owner, dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.verbose('contacts found in store: ' + contacts.length + ' contacts');
|
||||
return contacts;
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
import { opendirSync, readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { Auth, ConfigService } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { AUTH_DIR } from '../../../config/path.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { AuthRaw, IAuthModel, IntegrationModel } from '../../models';
|
||||
|
||||
export class AuthRepository extends Repository {
|
||||
constructor(
|
||||
private readonly authModel: IAuthModel,
|
||||
private readonly integrationModel: IntegrationModel,
|
||||
readonly configService: ConfigService,
|
||||
) {
|
||||
super(configService);
|
||||
this.auth = configService.get<Auth>('AUTHENTICATION');
|
||||
}
|
||||
|
||||
private readonly auth: Auth;
|
||||
private readonly logger = new Logger('AuthRepository');
|
||||
|
||||
public async create(data: AuthRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating auth');
|
||||
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving auth to db');
|
||||
const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving auth to store');
|
||||
|
||||
this.writeStore<AuthRaw>({
|
||||
path: join(AUTH_DIR, 'apikey'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, 'apikey') + '/' + instance);
|
||||
|
||||
this.logger.verbose('auth created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return { error } as any;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<AuthRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding auth');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding auth in db');
|
||||
return await this.authModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding auth in store');
|
||||
|
||||
return JSON.parse(
|
||||
readFileSync(join(AUTH_DIR, 'apikey', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as AuthRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
public async findByKey(key: string): Promise<AuthRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding auth');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding auth in db');
|
||||
return await this.authModel.findOne({ apikey: key });
|
||||
}
|
||||
|
||||
return {};
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
public async list(): Promise<AuthRaw[]> {
|
||||
try {
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('listing auth in db');
|
||||
return await this.authModel.find();
|
||||
}
|
||||
|
||||
this.logger.verbose('listing auth in store');
|
||||
|
||||
const auths: AuthRaw[] = [];
|
||||
const openDir = opendirSync(join(AUTH_DIR, 'apikey'), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
for await (const dirent of openDir) {
|
||||
if (dirent.isFile()) {
|
||||
auths.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(AUTH_DIR, 'apikey', dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return auths;
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public async findInstanceNameById(instanceId: string): Promise<string | null> {
|
||||
try {
|
||||
this.logger.verbose('finding auth by instanceId');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding auth in db');
|
||||
const response = await this.authModel.findOne({ instanceId });
|
||||
|
||||
return response._id;
|
||||
}
|
||||
|
||||
this.logger.verbose('finding auth in store is not supported');
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async findInstanceNameByNumber(number: string): Promise<string | null> {
|
||||
try {
|
||||
this.logger.verbose('finding auth by number');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding auth in db');
|
||||
const instance = await this.integrationModel.findOne({ number });
|
||||
|
||||
const response = await this.authModel.findOne({ _id: instance._id });
|
||||
|
||||
return response._id;
|
||||
}
|
||||
|
||||
this.logger.verbose('finding auth in store is not supported');
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { IntegrationModel, IntegrationRaw } from '../../models';
|
||||
|
||||
export class IntegrationRepository extends Repository {
|
||||
constructor(private readonly integrationModel: IntegrationModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('IntegrationRepository');
|
||||
|
||||
public async create(data: IntegrationRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating integration');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving integration to db');
|
||||
const insert = await this.integrationModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('integration saved to db: ' + insert.modifiedCount + ' integration');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving integration to store');
|
||||
|
||||
this.writeStore<IntegrationRaw>({
|
||||
path: join(this.storePath, 'integration'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose(
|
||||
'integration saved to store in path: ' + join(this.storePath, 'integration') + '/' + instance,
|
||||
);
|
||||
|
||||
this.logger.verbose('integration created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<IntegrationRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding integration');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding integration in db');
|
||||
return await this.integrationModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding integration in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'integration', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as IntegrationRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
import { opendirSync, readFileSync, rmSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { ILabelModel, LabelRaw, LabelRawSelect } from '../../models';
|
||||
|
||||
export class LabelQuery {
|
||||
select?: LabelRawSelect;
|
||||
where: Partial<LabelRaw>;
|
||||
}
|
||||
|
||||
export class LabelRepository extends Repository {
|
||||
constructor(private readonly labelModel: ILabelModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('LabelRepository');
|
||||
|
||||
public async insert(data: LabelRaw, instanceName: string, saveDb = false): Promise<IInsert> {
|
||||
this.logger.verbose('inserting labels');
|
||||
|
||||
try {
|
||||
if (this.dbSettings.ENABLED && saveDb) {
|
||||
this.logger.verbose('saving labels to db');
|
||||
const insert = await this.labelModel.findOneAndUpdate({ id: data.id }, data, { upsert: true });
|
||||
|
||||
this.logger.verbose(`label ${data.name} saved to db`);
|
||||
return { insertCount: Number(!!insert._id) };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving label to store');
|
||||
|
||||
const store = this.configService.get<StoreConf>('STORE');
|
||||
|
||||
if (store.LABELS) {
|
||||
this.logger.verbose('saving label to store');
|
||||
this.writeStore<LabelRaw>({
|
||||
path: join(this.storePath, 'labels', instanceName),
|
||||
fileName: data.id,
|
||||
data,
|
||||
});
|
||||
this.logger.verbose(
|
||||
'labels saved to store in path: ' + join(this.storePath, 'labels', instanceName) + '/' + data.id,
|
||||
);
|
||||
|
||||
this.logger.verbose(`label ${data.name} saved to store`);
|
||||
return { insertCount: 1 };
|
||||
}
|
||||
|
||||
this.logger.verbose('labels not saved to store');
|
||||
return { insertCount: 0 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
} finally {
|
||||
data = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(query: LabelQuery): Promise<LabelRaw[]> {
|
||||
try {
|
||||
this.logger.verbose('finding labels');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding labels in db');
|
||||
return await this.labelModel.find({ owner: query.where.owner }).select(query.select ?? {});
|
||||
}
|
||||
|
||||
this.logger.verbose('finding labels in store');
|
||||
|
||||
const labels: LabelRaw[] = [];
|
||||
const openDir = opendirSync(join(this.storePath, 'labels', query.where.owner));
|
||||
for await (const dirent of openDir) {
|
||||
if (dirent.isFile()) {
|
||||
labels.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'labels', query.where.owner, dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.verbose('labels found in store: ' + labels.length + ' labels');
|
||||
return labels;
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public async delete(query: LabelQuery) {
|
||||
try {
|
||||
this.logger.verbose('deleting labels');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('deleting labels in db');
|
||||
return await this.labelModel.deleteOne({ ...query.where });
|
||||
}
|
||||
|
||||
this.logger.verbose('deleting labels in store');
|
||||
rmSync(join(this.storePath, 'labels', query.where.owner, query.where.id + '.josn'), {
|
||||
force: true,
|
||||
recursive: true,
|
||||
});
|
||||
|
||||
return { deleted: { labelId: query.where.id } };
|
||||
} catch (error) {
|
||||
return { error: error?.toString() };
|
||||
}
|
||||
}
|
||||
}
|
@ -1,240 +0,0 @@
|
||||
import { opendirSync, readFileSync, rmSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { IMessageModel, MessageRaw, MessageRawSelect } from '../../models';
|
||||
|
||||
export class MessageQuery {
|
||||
select?: MessageRawSelect;
|
||||
where: MessageRaw;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export class MessageRepository extends Repository {
|
||||
constructor(private readonly messageModel: IMessageModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('MessageRepository');
|
||||
|
||||
public buildQuery(query: MessageQuery): MessageQuery {
|
||||
for (const [o, p] of Object.entries(query?.where || {})) {
|
||||
if (typeof p === 'object' && p !== null && !Array.isArray(p)) {
|
||||
for (const [k, v] of Object.entries(p)) {
|
||||
query.where[`${o}.${k}`] = v;
|
||||
}
|
||||
delete query.where[o];
|
||||
}
|
||||
}
|
||||
|
||||
for (const [o, p] of Object.entries(query?.select || {})) {
|
||||
if (typeof p === 'object' && p !== null && !Array.isArray(p)) {
|
||||
for (const [k, v] of Object.entries(p)) {
|
||||
query.select[`${o}.${k}`] = v;
|
||||
}
|
||||
delete query.select[o];
|
||||
}
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
public async insert(data: MessageRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||
this.logger.verbose('inserting messages');
|
||||
|
||||
if (!Array.isArray(data) || data.length === 0) {
|
||||
this.logger.verbose('no messages to insert');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.dbSettings.ENABLED && saveDb) {
|
||||
this.logger.verbose('saving messages to db');
|
||||
const cleanedData = data.map((obj) => {
|
||||
const cleanedObj = { ...obj };
|
||||
if ('extendedTextMessage' in obj.message) {
|
||||
const extendedTextMessage = obj.message.extendedTextMessage as {
|
||||
contextInfo?: {
|
||||
mentionedJid?: any;
|
||||
};
|
||||
};
|
||||
|
||||
if (typeof extendedTextMessage === 'object' && extendedTextMessage !== null) {
|
||||
if ('contextInfo' in extendedTextMessage) {
|
||||
delete extendedTextMessage.contextInfo?.mentionedJid;
|
||||
extendedTextMessage.contextInfo = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
return cleanedObj;
|
||||
});
|
||||
|
||||
const insert = await this.messageModel.insertMany([...cleanedData]);
|
||||
|
||||
this.logger.verbose('messages saved to db: ' + insert.length + ' messages');
|
||||
return { insertCount: insert.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving messages to store');
|
||||
|
||||
const store = this.configService.get<StoreConf>('STORE');
|
||||
|
||||
if (store.MESSAGES) {
|
||||
this.logger.verbose('saving messages to store');
|
||||
|
||||
data.forEach((message) => {
|
||||
this.writeStore({
|
||||
path: join(this.storePath, 'messages', instanceName),
|
||||
fileName: message.key.id,
|
||||
data: message,
|
||||
});
|
||||
this.logger.verbose(
|
||||
'messages saved to store in path: ' + join(this.storePath, 'messages', instanceName) + '/' + message.key.id,
|
||||
);
|
||||
});
|
||||
|
||||
this.logger.verbose('messages saved to store: ' + data.length + ' messages');
|
||||
return { insertCount: data.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('messages not saved to store');
|
||||
return { insertCount: 0 };
|
||||
} catch (error) {
|
||||
console.log('ERROR: ', error);
|
||||
return error;
|
||||
} finally {
|
||||
data = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(query: MessageQuery) {
|
||||
try {
|
||||
this.logger.verbose('finding messages');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding messages in db');
|
||||
query = this.buildQuery(query);
|
||||
|
||||
return await this.messageModel
|
||||
.find({ ...query.where })
|
||||
.select(query.select || {})
|
||||
.sort({ messageTimestamp: -1 })
|
||||
.limit(query?.limit ?? 0);
|
||||
}
|
||||
|
||||
this.logger.verbose('finding messages in store');
|
||||
const messages: MessageRaw[] = [];
|
||||
if (query?.where?.key?.id) {
|
||||
this.logger.verbose('finding messages in store by id');
|
||||
messages.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'messages', query.where.owner, query.where.key.id + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
this.logger.verbose('finding messages in store by owner');
|
||||
const openDir = opendirSync(join(this.storePath, 'messages', query.where.owner), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
|
||||
for await (const dirent of openDir) {
|
||||
if (dirent.isFile()) {
|
||||
messages.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'messages', query.where.owner, dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.verbose('messages found in store: ' + messages.length + ' messages');
|
||||
return messages
|
||||
.sort((x, y) => {
|
||||
return (y.messageTimestamp as number) - (x.messageTimestamp as number);
|
||||
})
|
||||
.splice(0, query?.limit ?? messages.length);
|
||||
} catch (error) {
|
||||
this.logger.error(`error on message find: ${error.toString()}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public async update(data: MessageRaw[], instanceName: string, saveDb?: boolean): Promise<IInsert> {
|
||||
try {
|
||||
if (this.dbSettings.ENABLED && saveDb) {
|
||||
this.logger.verbose('updating messages in db');
|
||||
|
||||
const messages = data.map((message) => {
|
||||
return {
|
||||
updateOne: {
|
||||
filter: { 'key.id': message.key.id },
|
||||
update: { ...message },
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const { nModified } = await this.messageModel.bulkWrite(messages);
|
||||
|
||||
this.logger.verbose('messages updated in db: ' + nModified + ' messages');
|
||||
return { insertCount: nModified };
|
||||
}
|
||||
|
||||
this.logger.verbose('updating messages in store');
|
||||
|
||||
const store = this.configService.get<StoreConf>('STORE');
|
||||
|
||||
if (store.MESSAGES) {
|
||||
this.logger.verbose('updating messages in store');
|
||||
data.forEach((message) => {
|
||||
this.writeStore({
|
||||
path: join(this.storePath, 'messages', instanceName),
|
||||
fileName: message.key.id,
|
||||
data: message,
|
||||
});
|
||||
this.logger.verbose(
|
||||
'messages updated in store in path: ' +
|
||||
join(this.storePath, 'messages', instanceName) +
|
||||
'/' +
|
||||
message.key.id,
|
||||
);
|
||||
});
|
||||
|
||||
this.logger.verbose('messages updated in store: ' + data.length + ' messages');
|
||||
return { insertCount: data.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('messages not updated');
|
||||
return { insertCount: 0 };
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async delete(query: MessageQuery) {
|
||||
try {
|
||||
this.logger.verbose('deleting message');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('deleting message in db');
|
||||
query = this.buildQuery(query);
|
||||
|
||||
return await this.messageModel.deleteOne({ ...query.where });
|
||||
}
|
||||
|
||||
this.logger.verbose('deleting message in store');
|
||||
rmSync(join(this.storePath, 'messages', query.where.owner, query.where.key.id + '.json'), {
|
||||
force: true,
|
||||
recursive: true,
|
||||
});
|
||||
|
||||
return { deleted: { messageId: query.where.key.id } };
|
||||
} catch (error) {
|
||||
return { error: error?.toString() };
|
||||
}
|
||||
}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
import { opendirSync, readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService, StoreConf } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { IMessageUpModel, MessageUpdateRaw } from '../../models';
|
||||
|
||||
export class MessageUpQuery {
|
||||
where: MessageUpdateRaw;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export class MessageUpRepository extends Repository {
|
||||
constructor(private readonly messageUpModel: IMessageUpModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('MessageUpRepository');
|
||||
|
||||
public async insert(data: MessageUpdateRaw[], instanceName: string, saveDb?: boolean): Promise<IInsert> {
|
||||
this.logger.verbose('inserting message up');
|
||||
|
||||
if (data.length === 0) {
|
||||
this.logger.verbose('no message up to insert');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.dbSettings.ENABLED && saveDb) {
|
||||
this.logger.verbose('saving message up to db');
|
||||
const insert = await this.messageUpModel.insertMany([...data]);
|
||||
|
||||
this.logger.verbose('message up saved to db: ' + insert.length + ' message up');
|
||||
return { insertCount: insert.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving message up to store');
|
||||
|
||||
const store = this.configService.get<StoreConf>('STORE');
|
||||
|
||||
if (store.MESSAGE_UP) {
|
||||
this.logger.verbose('saving message up to store');
|
||||
data.forEach((update) => {
|
||||
this.writeStore<MessageUpdateRaw>({
|
||||
path: join(this.storePath, 'message-up', instanceName),
|
||||
fileName: update.id,
|
||||
data: update,
|
||||
});
|
||||
this.logger.verbose(
|
||||
'message up saved to store in path: ' + join(this.storePath, 'message-up', instanceName) + '/' + update.id,
|
||||
);
|
||||
});
|
||||
|
||||
this.logger.verbose('message up saved to store: ' + data.length + ' message up');
|
||||
return { insertCount: data.length };
|
||||
}
|
||||
|
||||
this.logger.verbose('message up not saved to store');
|
||||
return { insertCount: 0 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(query: MessageUpQuery) {
|
||||
try {
|
||||
this.logger.verbose('finding message up');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding message up in db');
|
||||
return await this.messageUpModel
|
||||
.find({ ...query.where })
|
||||
.sort({ datetime: -1 })
|
||||
.limit(query?.limit ?? 0);
|
||||
}
|
||||
|
||||
this.logger.verbose('finding message up in store');
|
||||
|
||||
const messageUpdate: MessageUpdateRaw[] = [];
|
||||
if (query?.where?.id) {
|
||||
this.logger.verbose('finding message up in store by id');
|
||||
|
||||
messageUpdate.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'message-up', query.where.owner, query.where.id + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
this.logger.verbose('finding message up in store by owner');
|
||||
|
||||
const openDir = opendirSync(join(this.storePath, 'message-up', query.where.owner), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
|
||||
for await (const dirent of openDir) {
|
||||
if (dirent.isFile()) {
|
||||
messageUpdate.push(
|
||||
JSON.parse(
|
||||
readFileSync(join(this.storePath, 'message-up', query.where.owner, dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.verbose('message up found in store: ' + messageUpdate.length + ' message up');
|
||||
return messageUpdate
|
||||
.sort((x, y) => {
|
||||
return y.datetime - x.datetime;
|
||||
})
|
||||
.splice(0, query?.limit ?? messageUpdate.length);
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { IProxyModel, ProxyRaw } from '../../models';
|
||||
|
||||
export class ProxyRepository extends Repository {
|
||||
constructor(private readonly proxyModel: IProxyModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('ProxyRepository');
|
||||
|
||||
public async create(data: ProxyRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating proxy');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving proxy to db');
|
||||
const insert = await this.proxyModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('proxy saved to db: ' + insert.modifiedCount + ' proxy');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving proxy to store');
|
||||
|
||||
this.writeStore<ProxyRaw>({
|
||||
path: join(this.storePath, 'proxy'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('proxy saved to store in path: ' + join(this.storePath, 'proxy') + '/' + instance);
|
||||
|
||||
this.logger.verbose('proxy created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<ProxyRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding proxy');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding proxy in db');
|
||||
return await this.proxyModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding proxy in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'proxy', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as ProxyRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import fs from 'fs';
|
||||
import { MongoClient } from 'mongodb';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService, Database } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { ChatwootRepository } from '../../integrations/chatwoot/repository/chatwoot.repository';
|
||||
import { RabbitmqRepository } from '../../integrations/rabbitmq/repository/rabbitmq.repository';
|
||||
import { SqsRepository } from '../../integrations/sqs/repository/sqs.repository';
|
||||
import { TypebotRepository } from '../../integrations/typebot/repository/typebot.repository';
|
||||
import { WebsocketRepository } from '../../integrations/websocket/repository/websocket.repository';
|
||||
import { AuthRepository } from './auth.repository';
|
||||
import { ChatRepository } from './chat.repository';
|
||||
import { ContactRepository } from './contact.repository';
|
||||
import { IntegrationRepository } from './integration.repository';
|
||||
import { LabelRepository } from './label.repository';
|
||||
import { MessageRepository } from './message.repository';
|
||||
import { MessageUpRepository } from './messageUp.repository';
|
||||
import { ProxyRepository } from './proxy.repository';
|
||||
import { SettingsRepository } from './settings.repository';
|
||||
import { WebhookRepository } from './webhook.repository';
|
||||
export class MongodbRepository {
|
||||
constructor(
|
||||
public readonly message: MessageRepository,
|
||||
public readonly chat: ChatRepository,
|
||||
public readonly contact: ContactRepository,
|
||||
public readonly messageUpdate: MessageUpRepository,
|
||||
public readonly webhook: WebhookRepository,
|
||||
public readonly chatwoot: ChatwootRepository,
|
||||
public readonly settings: SettingsRepository,
|
||||
public readonly websocket: WebsocketRepository,
|
||||
public readonly rabbitmq: RabbitmqRepository,
|
||||
public readonly sqs: SqsRepository,
|
||||
public readonly typebot: TypebotRepository,
|
||||
public readonly proxy: ProxyRepository,
|
||||
public readonly integration: IntegrationRepository,
|
||||
public readonly auth: AuthRepository,
|
||||
public readonly labels: LabelRepository,
|
||||
private configService: ConfigService,
|
||||
mongodbServer?: MongoClient,
|
||||
prismaServer?: PrismaClient,
|
||||
) {
|
||||
this.mongodbClient = mongodbServer;
|
||||
this.prismaClient = prismaServer;
|
||||
this.__init_repo_without_db__();
|
||||
}
|
||||
|
||||
private mongodbClient?: MongoClient;
|
||||
private prismaClient?: PrismaClient;
|
||||
private readonly logger = new Logger('RepositoryBroker');
|
||||
|
||||
public get mongodbServer() {
|
||||
return this.mongodbClient;
|
||||
}
|
||||
|
||||
public get prismaServer() {
|
||||
return this.prismaClient;
|
||||
}
|
||||
|
||||
private __init_repo_without_db__() {
|
||||
this.logger.verbose('initializing repository without db');
|
||||
if (!this.configService.get<Database>('DATABASE').ENABLED) {
|
||||
const storePath = join(process.cwd(), 'store');
|
||||
|
||||
this.logger.verbose('creating store path: ' + storePath);
|
||||
try {
|
||||
const authDir = join(storePath, 'auth', 'apikey');
|
||||
const chatsDir = join(storePath, 'chats');
|
||||
const contactsDir = join(storePath, 'contacts');
|
||||
const messagesDir = join(storePath, 'messages');
|
||||
const messageUpDir = join(storePath, 'message-up');
|
||||
const webhookDir = join(storePath, 'webhook');
|
||||
const chatwootDir = join(storePath, 'chatwoot');
|
||||
const settingsDir = join(storePath, 'settings');
|
||||
const websocketDir = join(storePath, 'websocket');
|
||||
const rabbitmqDir = join(storePath, 'rabbitmq');
|
||||
const sqsDir = join(storePath, 'sqs');
|
||||
const typebotDir = join(storePath, 'typebot');
|
||||
const proxyDir = join(storePath, 'proxy');
|
||||
const integrationDir = join(storePath, 'integration');
|
||||
const tempDir = join(storePath, 'temp');
|
||||
|
||||
if (!fs.existsSync(authDir)) {
|
||||
this.logger.verbose('creating auth dir: ' + authDir);
|
||||
fs.mkdirSync(authDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(chatsDir)) {
|
||||
this.logger.verbose('creating chats dir: ' + chatsDir);
|
||||
fs.mkdirSync(chatsDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(contactsDir)) {
|
||||
this.logger.verbose('creating contacts dir: ' + contactsDir);
|
||||
fs.mkdirSync(contactsDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(messagesDir)) {
|
||||
this.logger.verbose('creating messages dir: ' + messagesDir);
|
||||
fs.mkdirSync(messagesDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(messageUpDir)) {
|
||||
this.logger.verbose('creating message-up dir: ' + messageUpDir);
|
||||
fs.mkdirSync(messageUpDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(webhookDir)) {
|
||||
this.logger.verbose('creating webhook dir: ' + webhookDir);
|
||||
fs.mkdirSync(webhookDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(chatwootDir)) {
|
||||
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
||||
fs.mkdirSync(chatwootDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(settingsDir)) {
|
||||
this.logger.verbose('creating settings dir: ' + settingsDir);
|
||||
fs.mkdirSync(settingsDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(websocketDir)) {
|
||||
this.logger.verbose('creating websocket dir: ' + websocketDir);
|
||||
fs.mkdirSync(websocketDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(rabbitmqDir)) {
|
||||
this.logger.verbose('creating rabbitmq dir: ' + rabbitmqDir);
|
||||
fs.mkdirSync(rabbitmqDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(sqsDir)) {
|
||||
this.logger.verbose('creating sqs dir: ' + sqsDir);
|
||||
fs.mkdirSync(sqsDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(typebotDir)) {
|
||||
this.logger.verbose('creating typebot dir: ' + typebotDir);
|
||||
fs.mkdirSync(typebotDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(proxyDir)) {
|
||||
this.logger.verbose('creating proxy dir: ' + proxyDir);
|
||||
fs.mkdirSync(proxyDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(integrationDir)) {
|
||||
this.logger.verbose('creating integration dir: ' + integrationDir);
|
||||
fs.mkdirSync(integrationDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(tempDir)) {
|
||||
this.logger.verbose('creating temp dir: ' + tempDir);
|
||||
fs.mkdirSync(tempDir, { recursive: true });
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
const storePath = join(process.cwd(), 'store');
|
||||
|
||||
this.logger.verbose('creating store path: ' + storePath);
|
||||
|
||||
const tempDir = join(storePath, 'temp');
|
||||
const chatwootDir = join(storePath, 'chatwoot');
|
||||
|
||||
if (!fs.existsSync(chatwootDir)) {
|
||||
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
||||
fs.mkdirSync(chatwootDir, { recursive: true });
|
||||
}
|
||||
if (!fs.existsSync(tempDir)) {
|
||||
this.logger.verbose('creating temp dir: ' + tempDir);
|
||||
fs.mkdirSync(tempDir, { recursive: true });
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { ISettingsModel, SettingsRaw } from '../../models';
|
||||
|
||||
export class SettingsRepository extends Repository {
|
||||
constructor(private readonly settingsModel: ISettingsModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('SettingsRepository');
|
||||
|
||||
public async create(data: SettingsRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating settings');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving settings to db');
|
||||
const insert = await this.settingsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('settings saved to db: ' + insert.modifiedCount + ' settings');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving settings to store');
|
||||
|
||||
this.writeStore<SettingsRaw>({
|
||||
path: join(this.storePath, 'settings'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('settings saved to store in path: ' + join(this.storePath, 'settings') + '/' + instance);
|
||||
|
||||
this.logger.verbose('settings created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<SettingsRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding settings');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding settings in db');
|
||||
return await this.settingsModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding settings in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'settings', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as SettingsRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../abstract/abstract.repository';
|
||||
import { IWebhookModel, WebhookRaw } from '../../models';
|
||||
|
||||
export class WebhookRepository extends Repository {
|
||||
constructor(private readonly webhookModel: IWebhookModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('WebhookRepository');
|
||||
|
||||
public async create(data: WebhookRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating webhook');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving webhook to db');
|
||||
const insert = await this.webhookModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('webhook saved to db: ' + insert.modifiedCount + ' webhook');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving webhook to store');
|
||||
|
||||
this.writeStore<WebhookRaw>({
|
||||
path: join(this.storePath, 'webhook'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('webhook saved to store in path: ' + join(this.storePath, 'webhook') + '/' + instance);
|
||||
|
||||
this.logger.verbose('webhook created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<WebhookRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding webhook');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding webhook in db');
|
||||
return await this.webhookModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding webhook in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'webhook', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as WebhookRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
import { ConfigService } from '../../../config/env.config';
|
||||
import { Logger } from '../../../config/logger.config';
|
||||
import { ConfigService } from '../../config/env.config';
|
||||
import { Logger } from '../../config/logger.config';
|
||||
|
||||
export class Query<T> {
|
||||
where?: T;
|
@ -1,3 +1,4 @@
|
||||
import { Contact, Message, MessageUpdate } from '@prisma/client';
|
||||
import { RequestHandler, Router } from 'express';
|
||||
|
||||
import { Logger } from '../../config/logger.config';
|
||||
@ -37,9 +38,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 { chatController } from '../server.module';
|
||||
import { HttpStatus } from './index.router';
|
||||
|
||||
@ -176,10 +175,10 @@ export class ChatRouter extends RouterBroker {
|
||||
logger.verbose('request query: ');
|
||||
logger.verbose(req.query);
|
||||
|
||||
const response = await this.dataValidate<ContactQuery>({
|
||||
const response = await this.dataValidate<Query<Contact>>({
|
||||
request: req,
|
||||
schema: contactValidateSchema,
|
||||
ClassRef: ContactQuery,
|
||||
ClassRef: Query<Contact>,
|
||||
execute: (instance, data) => chatController.fetchContacts(instance, data),
|
||||
});
|
||||
|
||||
@ -210,10 +209,10 @@ export class ChatRouter extends RouterBroker {
|
||||
logger.verbose('request query: ');
|
||||
logger.verbose(req.query);
|
||||
|
||||
const response = await this.dataValidate<MessageQuery>({
|
||||
const response = await this.dataValidate<Query<Message>>({
|
||||
request: req,
|
||||
schema: messageValidateSchema,
|
||||
ClassRef: MessageQuery,
|
||||
ClassRef: Query<Message>,
|
||||
execute: (instance, data) => chatController.fetchMessages(instance, data),
|
||||
});
|
||||
|
||||
@ -227,10 +226,10 @@ export class ChatRouter extends RouterBroker {
|
||||
logger.verbose('request query: ');
|
||||
logger.verbose(req.query);
|
||||
|
||||
const response = await this.dataValidate<MessageUpQuery>({
|
||||
const response = await this.dataValidate<Query<MessageUpdate>>({
|
||||
request: req,
|
||||
schema: messageUpSchema,
|
||||
ClassRef: MessageUpQuery,
|
||||
ClassRef: Query<MessageUpdate>,
|
||||
execute: (instance, data) => chatController.fetchStatusMessage(instance, data),
|
||||
});
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { RequestHandler, Router } from 'express';
|
||||
|
||||
import { ConfigService, Database } from '../../config/env.config';
|
||||
import { ConfigService } from '../../config/env.config';
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { mongodbServer } from '../../libs/mongodb.connect';
|
||||
import { instanceNameSchema, presenceOnlySchema } from '../../validate/validate.schema';
|
||||
import { RouterBroker } from '../abstract/abstract.router';
|
||||
import { InstanceDto, SetPresenceDto } from '../dto/instance.dto';
|
||||
@ -162,28 +161,6 @@ export class InstanceRouter extends RouterBroker {
|
||||
|
||||
return res.status(HttpStatus.OK).json(response);
|
||||
});
|
||||
|
||||
this.router.delete('/deleteDatabase', async (req, res) => {
|
||||
logger.verbose('request received in deleteDatabase');
|
||||
logger.verbose('request body: ');
|
||||
logger.verbose(req.body);
|
||||
|
||||
logger.verbose('request query: ');
|
||||
logger.verbose(req.query);
|
||||
const db = this.configService.get<Database>('DATABASE');
|
||||
if (db.ENABLED) {
|
||||
try {
|
||||
await mongodbServer.dropDatabase();
|
||||
return res
|
||||
.status(HttpStatus.CREATED)
|
||||
.json({ status: 'SUCCESS', error: false, response: { message: 'database deleted' } });
|
||||
} catch (error) {
|
||||
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: 'Database is not enabled' });
|
||||
});
|
||||
}
|
||||
|
||||
public readonly router = Router();
|
||||
|
@ -2,8 +2,6 @@ import { CacheEngine } from '../cache/cacheengine';
|
||||
import { configService } from '../config/env.config';
|
||||
import { eventEmitter } from '../config/event.config';
|
||||
import { Logger } from '../config/logger.config';
|
||||
import { mongodbServer } from '../libs/mongodb.connect';
|
||||
import { prismaServer } from '../libs/prisma.connect';
|
||||
import { ChatController } from './controllers/chat.controller';
|
||||
import { GroupController } from './controllers/group.controller';
|
||||
import { InstanceController } from './controllers/instance.controller';
|
||||
@ -13,50 +11,17 @@ import { SendMessageController } from './controllers/sendMessage.controller';
|
||||
import { SettingsController } from './controllers/settings.controller';
|
||||
import { WebhookController } from './controllers/webhook.controller';
|
||||
import { ChatwootController } from './integrations/chatwoot/controllers/chatwoot.controller';
|
||||
import { ChatwootRepository } from './integrations/chatwoot/repository/chatwoot.repository';
|
||||
import { ChatwootService } from './integrations/chatwoot/services/chatwoot.service';
|
||||
import { RabbitmqController } from './integrations/rabbitmq/controllers/rabbitmq.controller';
|
||||
import { RabbitmqRepository } from './integrations/rabbitmq/repository/rabbitmq.repository';
|
||||
import { RabbitmqService } from './integrations/rabbitmq/services/rabbitmq.service';
|
||||
import { SqsController } from './integrations/sqs/controllers/sqs.controller';
|
||||
import { SqsRepository } from './integrations/sqs/repository/sqs.repository';
|
||||
import { SqsService } from './integrations/sqs/services/sqs.service';
|
||||
import { TypebotController } from './integrations/typebot/controllers/typebot.controller';
|
||||
import { TypebotRepository } from './integrations/typebot/repository/typebot.repository';
|
||||
import { TypebotService } from './integrations/typebot/services/typebot.service';
|
||||
import { WebsocketController } from './integrations/websocket/controllers/websocket.controller';
|
||||
import { WebsocketRepository } from './integrations/websocket/repository/websocket.repository';
|
||||
import { WebsocketService } from './integrations/websocket/services/websocket.service';
|
||||
import {
|
||||
AuthModel,
|
||||
ChatModel,
|
||||
ChatwootModel,
|
||||
ContactModel,
|
||||
IntegrationModel,
|
||||
MessageModel,
|
||||
MessageUpModel,
|
||||
ProxyModel,
|
||||
RabbitmqModel,
|
||||
SettingsModel,
|
||||
SqsModel,
|
||||
TypebotModel,
|
||||
WebhookModel,
|
||||
WebsocketModel,
|
||||
} from './models';
|
||||
import { LabelModel } from './models/label.model';
|
||||
import { ProviderFiles } from './provider/sessions';
|
||||
import { AuthRepository } from './repository/mongodb/auth.repository';
|
||||
import { ChatRepository } from './repository/mongodb/chat.repository';
|
||||
import { ContactRepository } from './repository/mongodb/contact.repository';
|
||||
import { IntegrationRepository } from './repository/mongodb/integration.repository';
|
||||
import { LabelRepository } from './repository/mongodb/label.repository';
|
||||
import { MessageRepository } from './repository/mongodb/message.repository';
|
||||
import { MessageUpRepository } from './repository/mongodb/messageUp.repository';
|
||||
import { ProxyRepository } from './repository/mongodb/proxy.repository';
|
||||
import { MongodbRepository } from './repository/mongodb/repository.manager';
|
||||
import { SettingsRepository } from './repository/mongodb/settings.repository';
|
||||
import { WebhookRepository } from './repository/mongodb/webhook.repository';
|
||||
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 { IntegrationService } from './services/integration.service';
|
||||
@ -67,62 +32,24 @@ import { WebhookService } from './services/webhook.service';
|
||||
|
||||
const logger = new Logger('WA MODULE');
|
||||
|
||||
const messageRepository = new MessageRepository(MessageModel, configService);
|
||||
const chatRepository = new ChatRepository(ChatModel, configService);
|
||||
const contactRepository = new ContactRepository(ContactModel, configService);
|
||||
const messageUpdateRepository = new MessageUpRepository(MessageUpModel, configService);
|
||||
const typebotRepository = new TypebotRepository(TypebotModel, configService);
|
||||
const webhookRepository = new WebhookRepository(WebhookModel, configService);
|
||||
const websocketRepository = new WebsocketRepository(WebsocketModel, configService);
|
||||
const proxyRepository = new ProxyRepository(ProxyModel, configService);
|
||||
const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService);
|
||||
const sqsRepository = new SqsRepository(SqsModel, configService);
|
||||
const integrationRepository = new IntegrationRepository(IntegrationModel, configService);
|
||||
const chatwootRepository = new ChatwootRepository(ChatwootModel, configService);
|
||||
const settingsRepository = new SettingsRepository(SettingsModel, configService);
|
||||
const authRepository = new AuthRepository(AuthModel, IntegrationModel, configService);
|
||||
const labelRepository = new LabelRepository(LabelModel, configService);
|
||||
|
||||
export const mongodbRepository = new MongodbRepository(
|
||||
messageRepository,
|
||||
chatRepository,
|
||||
contactRepository,
|
||||
messageUpdateRepository,
|
||||
webhookRepository,
|
||||
chatwootRepository,
|
||||
settingsRepository,
|
||||
websocketRepository,
|
||||
rabbitmqRepository,
|
||||
sqsRepository,
|
||||
typebotRepository,
|
||||
proxyRepository,
|
||||
integrationRepository,
|
||||
authRepository,
|
||||
labelRepository,
|
||||
configService,
|
||||
mongodbServer.getClient(),
|
||||
prismaServer,
|
||||
);
|
||||
|
||||
export const prismaRepository = new PrismaRepository(configService);
|
||||
|
||||
export const cache = new CacheService(new CacheEngine(configService, 'instance').getEngine());
|
||||
const chatwootCache = new CacheService(new CacheEngine(configService, ChatwootService.name).getEngine());
|
||||
const baileysCache = new CacheService(new CacheEngine(configService, 'baileys').getEngine());
|
||||
|
||||
const providerFiles = new ProviderFiles(configService);
|
||||
export const prismaRepository = new PrismaRepository(configService);
|
||||
|
||||
export const waMonitor = new WAMonitoringService(
|
||||
eventEmitter,
|
||||
configService,
|
||||
mongodbRepository,
|
||||
prismaRepository,
|
||||
providerFiles,
|
||||
cache,
|
||||
chatwootCache,
|
||||
baileysCache,
|
||||
providerFiles,
|
||||
);
|
||||
|
||||
const authService = new AuthService(waMonitor, mongodbRepository, prismaRepository);
|
||||
const authService = new AuthService(waMonitor, configService, prismaRepository);
|
||||
|
||||
const typebotService = new TypebotService(waMonitor, configService, eventEmitter);
|
||||
export const typebotController = new TypebotController(typebotService);
|
||||
@ -144,19 +71,8 @@ export const sqsController = new SqsController(sqsService);
|
||||
|
||||
const integrationService = new IntegrationService(waMonitor);
|
||||
|
||||
const chatwootService = new ChatwootService(
|
||||
waMonitor,
|
||||
configService,
|
||||
mongodbRepository,
|
||||
prismaRepository,
|
||||
chatwootCache,
|
||||
);
|
||||
export const chatwootController = new ChatwootController(
|
||||
chatwootService,
|
||||
configService,
|
||||
mongodbRepository,
|
||||
prismaRepository,
|
||||
);
|
||||
const chatwootService = new ChatwootService(waMonitor, configService, prismaRepository, chatwootCache);
|
||||
export const chatwootController = new ChatwootController(chatwootService, configService, prismaRepository);
|
||||
|
||||
const settingsService = new SettingsService(waMonitor);
|
||||
export const settingsController = new SettingsController(settingsService);
|
||||
@ -164,7 +80,6 @@ export const settingsController = new SettingsController(settingsService);
|
||||
export const instanceController = new InstanceController(
|
||||
waMonitor,
|
||||
configService,
|
||||
mongodbRepository,
|
||||
prismaRepository,
|
||||
eventEmitter,
|
||||
authService,
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { ConfigService } from '../../config/env.config';
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { BadRequestException } from '../../exceptions';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
import { MongodbRepository } from '../repository/mongodb/repository.manager';
|
||||
import { PrismaRepository } from '../repository/prisma/repository.service';
|
||||
import { PrismaRepository } from '../repository/repository.service';
|
||||
import { WAMonitoringService } from './monitor.service';
|
||||
|
||||
export class AuthService {
|
||||
constructor(
|
||||
private readonly waMonitor: WAMonitoringService,
|
||||
private readonly mongodbRepository: MongodbRepository,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly prismaRepository: PrismaRepository,
|
||||
) {}
|
||||
|
||||
@ -21,22 +21,28 @@ export class AuthService {
|
||||
|
||||
this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey);
|
||||
|
||||
const auth = await this.mongodbRepository.auth.create(
|
||||
{ apikey, instanceId: instance.instanceId },
|
||||
instance.instanceName,
|
||||
);
|
||||
const db = this.configService.get('DATABASE');
|
||||
|
||||
this.logger.verbose('APIKEY saved in database');
|
||||
if (db.ENABLED) {
|
||||
try {
|
||||
await this.prismaRepository.auth.create({
|
||||
data: {
|
||||
apikey: apikey,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (auth['error']) {
|
||||
this.logger.error({
|
||||
localError: AuthService.name + '.apikey',
|
||||
error: auth['error'],
|
||||
});
|
||||
throw new BadRequestException('Authentication error', auth['error']?.toString());
|
||||
this.logger.verbose('APIKEY saved in database');
|
||||
|
||||
return { apikey };
|
||||
} catch (error) {
|
||||
this.logger.error({
|
||||
localError: AuthService.name + '.apikey',
|
||||
error: error,
|
||||
});
|
||||
throw new BadRequestException('Authentication error', error?.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return { apikey };
|
||||
}
|
||||
|
||||
public async checkDuplicateToken(token: string) {
|
||||
|
@ -21,20 +21,21 @@ import {
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { ROOT_DIR } from '../../config/path.config';
|
||||
import { NotFoundException } from '../../exceptions';
|
||||
import { ChatwootRaw } from '../integrations/chatwoot/models/chatwoot.model';
|
||||
import { IntegrationDto } from '../dto/integration.dto';
|
||||
import { ProxyDto } from '../dto/proxy.dto';
|
||||
import { SettingsDto } from '../dto/settings.dto';
|
||||
import { WebhookDto } from '../dto/webhook.dto';
|
||||
import { ChatwootDto } from '../integrations/chatwoot/dto/chatwoot.dto';
|
||||
import { ChatwootService } from '../integrations/chatwoot/services/chatwoot.service';
|
||||
import { RabbitmqDto } from '../integrations/rabbitmq/dto/rabbitmq.dto';
|
||||
import { getAMQP, removeQueues } from '../integrations/rabbitmq/libs/amqp.server';
|
||||
import { SqsDto } from '../integrations/sqs/dto/sqs.dto';
|
||||
import { getSQS, removeQueues as removeQueuesSQS } from '../integrations/sqs/libs/sqs.server';
|
||||
import { TypebotDto } from '../integrations/typebot/dto/typebot.dto';
|
||||
import { TypebotService } from '../integrations/typebot/services/typebot.service';
|
||||
import { WebsocketDto } from '../integrations/websocket/dto/websocket.dto';
|
||||
import { getIO } from '../integrations/websocket/libs/socket.server';
|
||||
import { WebsocketRaw } from '../integrations/websocket/models/websocket.model';
|
||||
import { IntegrationRaw, ProxyRaw, RabbitmqRaw, SettingsRaw, SqsRaw, TypebotRaw } from '../models';
|
||||
import { WebhookRaw } from '../models/webhook.model';
|
||||
import { ContactQuery } from '../repository/mongodb/contact.repository';
|
||||
import { MessageQuery } from '../repository/mongodb/message.repository';
|
||||
import { MessageUpQuery } from '../repository/mongodb/messageUp.repository';
|
||||
import { MongodbRepository } from '../repository/mongodb/repository.manager';
|
||||
import { PrismaRepository } from '../repository/prisma/repository.service';
|
||||
import { PrismaRepository } from '../repository/repository.service';
|
||||
import { waMonitor } from '../server.module';
|
||||
import { Events, wa } from '../types/wa.types';
|
||||
import { CacheService } from './cache.service';
|
||||
@ -43,7 +44,6 @@ export class ChannelStartupService {
|
||||
constructor(
|
||||
public readonly configService: ConfigService,
|
||||
public readonly eventEmitter: EventEmitter2,
|
||||
public readonly mongodbRepository: MongodbRepository,
|
||||
public readonly prismaRepository: PrismaRepository,
|
||||
public readonly chatwootCache: CacheService,
|
||||
) {
|
||||
@ -68,7 +68,6 @@ export class ChannelStartupService {
|
||||
public chatwootService = new ChatwootService(
|
||||
waMonitor,
|
||||
this.configService,
|
||||
this.mongodbRepository,
|
||||
this.prismaRepository,
|
||||
this.chatwootCache,
|
||||
);
|
||||
@ -109,6 +108,21 @@ export class ChannelStartupService {
|
||||
return this.instance.name;
|
||||
}
|
||||
|
||||
public set instanceId(id: string) {
|
||||
if (!id) {
|
||||
this.logger.verbose('Instance id not found, generating random id with uuid');
|
||||
this.instance.id = v4();
|
||||
return;
|
||||
}
|
||||
this.logger.verbose(`Setting instanceId: ${id}`);
|
||||
this.instance.id = id;
|
||||
}
|
||||
|
||||
public get instanceId() {
|
||||
this.logger.verbose('Getting instanceId');
|
||||
return this.instance.id;
|
||||
}
|
||||
|
||||
public get wuid() {
|
||||
this.logger.verbose('Getting remoteJid of instance');
|
||||
return this.instance.wuid;
|
||||
@ -116,7 +130,12 @@ export class ChannelStartupService {
|
||||
|
||||
public async loadIntegration() {
|
||||
this.logger.verbose('Loading webhook');
|
||||
const data = await this.mongodbRepository.integration.find(this.instanceName);
|
||||
const data = await this.prismaRepository.integration.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.localIntegration.integration = data?.integration;
|
||||
this.logger.verbose(`Integration: ${this.localIntegration.integration}`);
|
||||
|
||||
@ -129,9 +148,26 @@ export class ChannelStartupService {
|
||||
this.logger.verbose('Integration loaded');
|
||||
}
|
||||
|
||||
public async setIntegration(data: IntegrationRaw) {
|
||||
public async setIntegration(data: IntegrationDto) {
|
||||
this.logger.verbose('Setting integration');
|
||||
await this.mongodbRepository.integration.create(data, this.instanceName);
|
||||
console.log('setIntegration');
|
||||
await this.prismaRepository.integration.upsert({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
update: {
|
||||
integration: data.integration,
|
||||
number: data.number,
|
||||
token: data.token,
|
||||
},
|
||||
create: {
|
||||
integration: data.integration,
|
||||
number: data.number,
|
||||
token: data.token,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Integration: ${data.integration}`);
|
||||
this.logger.verbose(`Integration number: ${data.number}`);
|
||||
this.logger.verbose(`Integration token: ${data.token}`);
|
||||
@ -141,15 +177,23 @@ export class ChannelStartupService {
|
||||
|
||||
public async findIntegration() {
|
||||
this.logger.verbose('Finding integration');
|
||||
let data: any;
|
||||
let data;
|
||||
|
||||
data = await this.mongodbRepository.integration.find(this.instanceName);
|
||||
data = await this.prismaRepository.integration.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.mongodbRepository.integration.create(
|
||||
{ integration: 'WHATSAPP-BAILEYS', number: '', token: '' },
|
||||
this.instanceName,
|
||||
);
|
||||
await this.prismaRepository.integration.create({
|
||||
data: {
|
||||
integration: 'WHATSAPP-BAILEYS',
|
||||
number: '',
|
||||
token: '',
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
data = { integration: 'WHATSAPP-BAILEYS', number: '', token: '' };
|
||||
}
|
||||
|
||||
@ -157,84 +201,106 @@ export class ChannelStartupService {
|
||||
this.logger.verbose(`Integration number: ${data.number}`);
|
||||
this.logger.verbose(`Integration token: ${data.token}`);
|
||||
|
||||
return {
|
||||
integration: data.integration,
|
||||
number: data.number,
|
||||
token: data.token,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
public async loadSettings() {
|
||||
this.logger.verbose('Loading settings');
|
||||
const data = await this.mongodbRepository.settings.find(this.instanceName);
|
||||
this.localSettings.reject_call = data?.reject_call;
|
||||
this.logger.verbose(`Settings reject_call: ${this.localSettings.reject_call}`);
|
||||
const data = await this.prismaRepository.setting.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.localSettings.msg_call = data?.msg_call;
|
||||
this.logger.verbose(`Settings msg_call: ${this.localSettings.msg_call}`);
|
||||
this.localSettings.rejectCall = data?.rejectCall;
|
||||
this.logger.verbose(`Settings rejectCall: ${this.localSettings.rejectCall}`);
|
||||
|
||||
this.localSettings.groups_ignore = data?.groups_ignore;
|
||||
this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`);
|
||||
this.localSettings.msgCall = data?.msgCall;
|
||||
this.logger.verbose(`Settings msgCall: ${this.localSettings.msgCall}`);
|
||||
|
||||
this.localSettings.always_online = data?.always_online;
|
||||
this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`);
|
||||
this.localSettings.groupsIgnore = data?.groupsIgnore;
|
||||
this.logger.verbose(`Settings groupsIgnore: ${this.localSettings.groupsIgnore}`);
|
||||
|
||||
this.localSettings.read_messages = data?.read_messages;
|
||||
this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`);
|
||||
this.localSettings.alwaysOnline = data?.alwaysOnline;
|
||||
this.logger.verbose(`Settings alwaysOnline: ${this.localSettings.alwaysOnline}`);
|
||||
|
||||
this.localSettings.read_status = data?.read_status;
|
||||
this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`);
|
||||
this.localSettings.readMessages = data?.readMessages;
|
||||
this.logger.verbose(`Settings readMessages: ${this.localSettings.readMessages}`);
|
||||
|
||||
this.localSettings.sync_full_history = data?.sync_full_history;
|
||||
this.logger.verbose(`Settings sync_full_history: ${this.localSettings.sync_full_history}`);
|
||||
this.localSettings.readStatus = data?.readStatus;
|
||||
this.logger.verbose(`Settings readStatus: ${this.localSettings.readStatus}`);
|
||||
|
||||
this.localSettings.syncFullHistory = data?.syncFullHistory;
|
||||
this.logger.verbose(`Settings syncFullHistory: ${this.localSettings.syncFullHistory}`);
|
||||
|
||||
this.logger.verbose('Settings loaded');
|
||||
}
|
||||
|
||||
public async setSettings(data: SettingsRaw) {
|
||||
public async setSettings(data: SettingsDto) {
|
||||
this.logger.verbose('Setting settings');
|
||||
await this.mongodbRepository.settings.create(data, this.instanceName);
|
||||
this.logger.verbose(`Settings reject_call: ${data.reject_call}`);
|
||||
this.logger.verbose(`Settings msg_call: ${data.msg_call}`);
|
||||
this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`);
|
||||
this.logger.verbose(`Settings always_online: ${data.always_online}`);
|
||||
this.logger.verbose(`Settings read_messages: ${data.read_messages}`);
|
||||
this.logger.verbose(`Settings read_status: ${data.read_status}`);
|
||||
this.logger.verbose(`Settings sync_full_history: ${data.sync_full_history}`);
|
||||
await this.prismaRepository.setting.create({
|
||||
data: {
|
||||
rejectCall: data.rejectCall,
|
||||
msgCall: data.msgCall,
|
||||
groupsIgnore: data.groupsIgnore,
|
||||
alwaysOnline: data.alwaysOnline,
|
||||
readMessages: data.readMessages,
|
||||
readStatus: data.readStatus,
|
||||
syncFullHistory: data.syncFullHistory,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Settings rejectCall: ${data.rejectCall}`);
|
||||
this.logger.verbose(`Settings msgCall: ${data.msgCall}`);
|
||||
this.logger.verbose(`Settings groupsIgnore: ${data.groupsIgnore}`);
|
||||
this.logger.verbose(`Settings alwaysOnline: ${data.alwaysOnline}`);
|
||||
this.logger.verbose(`Settings readMessages: ${data.readMessages}`);
|
||||
this.logger.verbose(`Settings readStatus: ${data.readStatus}`);
|
||||
this.logger.verbose(`Settings syncFullHistory: ${data.syncFullHistory}`);
|
||||
Object.assign(this.localSettings, data);
|
||||
this.logger.verbose('Settings set');
|
||||
}
|
||||
|
||||
public async findSettings() {
|
||||
this.logger.verbose('Finding settings');
|
||||
const data = await this.mongodbRepository.settings.find(this.instanceName);
|
||||
const data = await this.prismaRepository.setting.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.logger.verbose('Settings not found');
|
||||
return null;
|
||||
}
|
||||
|
||||
this.logger.verbose(`Settings url: ${data.reject_call}`);
|
||||
this.logger.verbose(`Settings msg_call: ${data.msg_call}`);
|
||||
this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`);
|
||||
this.logger.verbose(`Settings always_online: ${data.always_online}`);
|
||||
this.logger.verbose(`Settings read_messages: ${data.read_messages}`);
|
||||
this.logger.verbose(`Settings read_status: ${data.read_status}`);
|
||||
this.logger.verbose(`Settings sync_full_history: ${data.sync_full_history}`);
|
||||
this.logger.verbose(`Settings url: ${data.rejectCall}`);
|
||||
this.logger.verbose(`Settings msgCall: ${data.msgCall}`);
|
||||
this.logger.verbose(`Settings groupsIgnore: ${data.groupsIgnore}`);
|
||||
this.logger.verbose(`Settings alwaysOnline: ${data.alwaysOnline}`);
|
||||
this.logger.verbose(`Settings readMessages: ${data.readMessages}`);
|
||||
this.logger.verbose(`Settings readStatus: ${data.readStatus}`);
|
||||
this.logger.verbose(`Settings syncFullHistory: ${data.syncFullHistory}`);
|
||||
return {
|
||||
reject_call: data.reject_call,
|
||||
msg_call: data.msg_call,
|
||||
groups_ignore: data.groups_ignore,
|
||||
always_online: data.always_online,
|
||||
read_messages: data.read_messages,
|
||||
read_status: data.read_status,
|
||||
sync_full_history: data.sync_full_history,
|
||||
rejectCall: data.rejectCall,
|
||||
msgCall: data.msgCall,
|
||||
groupsIgnore: data.groupsIgnore,
|
||||
alwaysOnline: data.alwaysOnline,
|
||||
readMessages: data.readMessages,
|
||||
readStatus: data.readStatus,
|
||||
syncFullHistory: data.syncFullHistory,
|
||||
};
|
||||
}
|
||||
|
||||
public async loadWebhook() {
|
||||
this.logger.verbose('Loading webhook');
|
||||
const data = await this.mongodbRepository.webhook.find(this.instanceName);
|
||||
const data = await this.prismaRepository.webhook.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.localWebhook.url = data?.url;
|
||||
this.logger.verbose(`Webhook url: ${this.localWebhook.url}`);
|
||||
|
||||
@ -244,18 +310,28 @@ export class ChannelStartupService {
|
||||
this.localWebhook.events = data?.events;
|
||||
this.logger.verbose(`Webhook events: ${this.localWebhook.events}`);
|
||||
|
||||
this.localWebhook.webhook_by_events = data?.webhook_by_events;
|
||||
this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`);
|
||||
this.localWebhook.webhookByEvents = data?.webhookByEvents;
|
||||
this.logger.verbose(`Webhook by events: ${this.localWebhook.webhookByEvents}`);
|
||||
|
||||
this.localWebhook.webhook_base64 = data?.webhook_base64;
|
||||
this.logger.verbose(`Webhook by webhook_base64: ${this.localWebhook.webhook_base64}`);
|
||||
this.localWebhook.webhookBase64 = data?.webhookBase64;
|
||||
this.logger.verbose(`Webhook by webhookBase64: ${this.localWebhook.webhookBase64}`);
|
||||
|
||||
this.logger.verbose('Webhook loaded');
|
||||
}
|
||||
|
||||
public async setWebhook(data: WebhookRaw) {
|
||||
public async setWebhook(data: WebhookDto) {
|
||||
this.logger.verbose('Setting webhook');
|
||||
await this.mongodbRepository.webhook.create(data, this.instanceName);
|
||||
await this.prismaRepository.webhook.create({
|
||||
data: {
|
||||
url: data.url,
|
||||
enabled: data.enabled,
|
||||
events: data.events,
|
||||
webhookByEvents: data.webhookByEvents,
|
||||
webhookBase64: data.webhookBase64,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Webhook url: ${data.url}`);
|
||||
this.logger.verbose(`Webhook events: ${data.events}`);
|
||||
Object.assign(this.localWebhook, data);
|
||||
@ -264,7 +340,11 @@ export class ChannelStartupService {
|
||||
|
||||
public async findWebhook() {
|
||||
this.logger.verbose('Finding webhook');
|
||||
const data = await this.mongodbRepository.webhook.find(this.instanceName);
|
||||
const data = await this.prismaRepository.webhook.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.logger.verbose('Webhook not found');
|
||||
@ -274,23 +354,22 @@ export class ChannelStartupService {
|
||||
this.logger.verbose(`Webhook url: ${data.url}`);
|
||||
this.logger.verbose(`Webhook events: ${data.events}`);
|
||||
|
||||
return {
|
||||
enabled: data.enabled,
|
||||
url: data.url,
|
||||
events: data.events,
|
||||
webhook_by_events: data.webhook_by_events,
|
||||
webhook_base64: data.webhook_base64,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
public async loadChatwoot() {
|
||||
this.logger.verbose('Loading chatwoot');
|
||||
const data = await this.mongodbRepository.chatwoot.find(this.instanceName);
|
||||
const data = await this.prismaRepository.chatwoot.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.localChatwoot.enabled = data?.enabled;
|
||||
this.logger.verbose(`Chatwoot enabled: ${this.localChatwoot.enabled}`);
|
||||
|
||||
this.localChatwoot.account_id = data?.account_id;
|
||||
this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.account_id}`);
|
||||
this.localChatwoot.accountId = data?.accountId;
|
||||
this.logger.verbose(`Chatwoot account id: ${this.localChatwoot.accountId}`);
|
||||
|
||||
this.localChatwoot.token = data?.token;
|
||||
this.logger.verbose(`Chatwoot token: ${this.localChatwoot.token}`);
|
||||
@ -298,53 +377,74 @@ export class ChannelStartupService {
|
||||
this.localChatwoot.url = data?.url;
|
||||
this.logger.verbose(`Chatwoot url: ${this.localChatwoot.url}`);
|
||||
|
||||
this.localChatwoot.name_inbox = data?.name_inbox;
|
||||
this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.name_inbox}`);
|
||||
this.localChatwoot.nameInbox = data?.nameInbox;
|
||||
this.logger.verbose(`Chatwoot inbox name: ${this.localChatwoot.nameInbox}`);
|
||||
|
||||
this.localChatwoot.sign_msg = data?.sign_msg;
|
||||
this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.sign_msg}`);
|
||||
this.localChatwoot.signMsg = data?.signMsg;
|
||||
this.logger.verbose(`Chatwoot sign msg: ${this.localChatwoot.signMsg}`);
|
||||
|
||||
this.localChatwoot.signDelimiter = data?.signDelimiter;
|
||||
this.logger.verbose(`Chatwoot sign delimiter: ${this.localChatwoot.signDelimiter}`);
|
||||
|
||||
this.localChatwoot.number = data?.number;
|
||||
this.logger.verbose(`Chatwoot number: ${this.localChatwoot.number}`);
|
||||
|
||||
this.localChatwoot.reopen_conversation = data?.reopen_conversation;
|
||||
this.logger.verbose(`Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`);
|
||||
this.localChatwoot.reopenConversation = data?.reopenConversation;
|
||||
this.logger.verbose(`Chatwoot reopen conversation: ${this.localChatwoot.reopenConversation}`);
|
||||
|
||||
this.localChatwoot.conversation_pending = data?.conversation_pending;
|
||||
this.logger.verbose(`Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`);
|
||||
this.localChatwoot.conversationPending = data?.conversationPending;
|
||||
this.logger.verbose(`Chatwoot conversation pending: ${this.localChatwoot.conversationPending}`);
|
||||
|
||||
this.localChatwoot.merge_brazil_contacts = data?.merge_brazil_contacts;
|
||||
this.logger.verbose(`Chatwoot merge brazil contacts: ${this.localChatwoot.merge_brazil_contacts}`);
|
||||
this.localChatwoot.mergeBrazilContacts = data?.mergeBrazilContacts;
|
||||
this.logger.verbose(`Chatwoot merge brazil contacts: ${this.localChatwoot.mergeBrazilContacts}`);
|
||||
|
||||
this.localChatwoot.import_contacts = data?.import_contacts;
|
||||
this.logger.verbose(`Chatwoot import contacts: ${this.localChatwoot.import_contacts}`);
|
||||
this.localChatwoot.importContacts = data?.importContacts;
|
||||
this.logger.verbose(`Chatwoot import contacts: ${this.localChatwoot.importContacts}`);
|
||||
|
||||
this.localChatwoot.import_messages = data?.import_messages;
|
||||
this.logger.verbose(`Chatwoot import messages: ${this.localChatwoot.import_messages}`);
|
||||
this.localChatwoot.importMessages = data?.importMessages;
|
||||
this.logger.verbose(`Chatwoot import messages: ${this.localChatwoot.importMessages}`);
|
||||
|
||||
this.localChatwoot.days_limit_import_messages = data?.days_limit_import_messages;
|
||||
this.logger.verbose(`Chatwoot days limit import messages: ${this.localChatwoot.days_limit_import_messages}`);
|
||||
this.localChatwoot.daysLimitImportMessages = data?.daysLimitImportMessages;
|
||||
this.logger.verbose(`Chatwoot days limit import messages: ${this.localChatwoot.daysLimitImportMessages}`);
|
||||
|
||||
this.logger.verbose('Chatwoot loaded');
|
||||
}
|
||||
|
||||
public async setChatwoot(data: ChatwootRaw) {
|
||||
public async setChatwoot(data: ChatwootDto) {
|
||||
this.logger.verbose('Setting chatwoot');
|
||||
await this.mongodbRepository.chatwoot.create(data, this.instanceName);
|
||||
this.logger.verbose(`Chatwoot account id: ${data.account_id}`);
|
||||
await this.prismaRepository.chatwoot.create({
|
||||
data: {
|
||||
enabled: data.enabled,
|
||||
accountId: data.accountId,
|
||||
token: data.token,
|
||||
url: data.url,
|
||||
nameInbox: data.nameInbox,
|
||||
signMsg: data.signMsg,
|
||||
number: data.number,
|
||||
reopenConversation: data.reopenConversation,
|
||||
conversationPending: data.conversationPending,
|
||||
mergeBrazilContacts: data.mergeBrazilContacts,
|
||||
importContacts: data.importContacts,
|
||||
importMessages: data.importMessages,
|
||||
daysLimitImportMessages: data.daysLimitImportMessages,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Chatwoot account id: ${data.accountId}`);
|
||||
this.logger.verbose(`Chatwoot token: ${data.token}`);
|
||||
this.logger.verbose(`Chatwoot url: ${data.url}`);
|
||||
this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`);
|
||||
this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`);
|
||||
this.logger.verbose(`Chatwoot sign delimiter: ${data.sign_delimiter}`);
|
||||
this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`);
|
||||
this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`);
|
||||
this.logger.verbose(`Chatwoot merge brazil contacts: ${data.merge_brazil_contacts}`);
|
||||
this.logger.verbose(`Chatwoot import contacts: ${data.import_contacts}`);
|
||||
this.logger.verbose(`Chatwoot import messages: ${data.import_messages}`);
|
||||
this.logger.verbose(`Chatwoot days limit import messages: ${data.days_limit_import_messages}`);
|
||||
this.logger.verbose(`Chatwoot inbox name: ${data.nameInbox}`);
|
||||
this.logger.verbose(`Chatwoot sign msg: ${data.signMsg}`);
|
||||
this.logger.verbose(`Chatwoot sign delimiter: ${data.signDelimiter}`);
|
||||
this.logger.verbose(`Chatwoot reopen conversation: ${data.reopenConversation}`);
|
||||
this.logger.verbose(`Chatwoot conversation pending: ${data.conversationPending}`);
|
||||
this.logger.verbose(`Chatwoot merge brazil contacts: ${data.mergeBrazilContacts}`);
|
||||
this.logger.verbose(`Chatwoot import contacts: ${data.importContacts}`);
|
||||
this.logger.verbose(`Chatwoot import messages: ${data.importMessages}`);
|
||||
this.logger.verbose(`Chatwoot days limit import messages: ${data.daysLimitImportMessages}`);
|
||||
|
||||
Object.assign(this.localChatwoot, { ...data, sign_delimiter: data.sign_msg ? data.sign_delimiter : null });
|
||||
Object.assign(this.localChatwoot, { ...data, signDelimiter: data.signMsg ? data.signDelimiter : null });
|
||||
|
||||
this.clearCacheChatwoot();
|
||||
|
||||
@ -353,40 +453,44 @@ export class ChannelStartupService {
|
||||
|
||||
public async findChatwoot() {
|
||||
this.logger.verbose('Finding chatwoot');
|
||||
const data = await this.mongodbRepository.chatwoot.find(this.instanceName);
|
||||
const data = await this.prismaRepository.chatwoot.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.logger.verbose('Chatwoot not found');
|
||||
return null;
|
||||
}
|
||||
|
||||
this.logger.verbose(`Chatwoot account id: ${data.account_id}`);
|
||||
this.logger.verbose(`Chatwoot account id: ${data.accountId}`);
|
||||
this.logger.verbose(`Chatwoot token: ${data.token}`);
|
||||
this.logger.verbose(`Chatwoot url: ${data.url}`);
|
||||
this.logger.verbose(`Chatwoot inbox name: ${data.name_inbox}`);
|
||||
this.logger.verbose(`Chatwoot sign msg: ${data.sign_msg}`);
|
||||
this.logger.verbose(`Chatwoot sign delimiter: ${data.sign_delimiter}`);
|
||||
this.logger.verbose(`Chatwoot reopen conversation: ${data.reopen_conversation}`);
|
||||
this.logger.verbose(`Chatwoot conversation pending: ${data.conversation_pending}`);
|
||||
this.logger.verbose(`Chatwoot merge brazilian contacts: ${data.merge_brazil_contacts}`);
|
||||
this.logger.verbose(`Chatwoot import contacts: ${data.import_contacts}`);
|
||||
this.logger.verbose(`Chatwoot import messages: ${data.import_messages}`);
|
||||
this.logger.verbose(`Chatwoot days limit import messages: ${data.days_limit_import_messages}`);
|
||||
this.logger.verbose(`Chatwoot inbox name: ${data.nameInbox}`);
|
||||
this.logger.verbose(`Chatwoot sign msg: ${data.signMsg}`);
|
||||
this.logger.verbose(`Chatwoot sign delimiter: ${data.signDelimiter}`);
|
||||
this.logger.verbose(`Chatwoot reopen conversation: ${data.reopenConversation}`);
|
||||
this.logger.verbose(`Chatwoot conversation pending: ${data.conversationPending}`);
|
||||
this.logger.verbose(`Chatwoot merge brazilian contacts: ${data.mergeBrazilContacts}`);
|
||||
this.logger.verbose(`Chatwoot import contacts: ${data.importContacts}`);
|
||||
this.logger.verbose(`Chatwoot import messages: ${data.importMessages}`);
|
||||
this.logger.verbose(`Chatwoot days limit import messages: ${data.daysLimitImportMessages}`);
|
||||
|
||||
return {
|
||||
enabled: data.enabled,
|
||||
account_id: data.account_id,
|
||||
accountId: data.accountId,
|
||||
token: data.token,
|
||||
url: data.url,
|
||||
name_inbox: data.name_inbox,
|
||||
sign_msg: data.sign_msg,
|
||||
sign_delimiter: data.sign_delimiter || null,
|
||||
reopen_conversation: data.reopen_conversation,
|
||||
conversation_pending: data.conversation_pending,
|
||||
merge_brazil_contacts: data.merge_brazil_contacts,
|
||||
import_contacts: data.import_contacts,
|
||||
import_messages: data.import_messages,
|
||||
days_limit_import_messages: data.days_limit_import_messages,
|
||||
nameInbox: data.nameInbox,
|
||||
signMsg: data.signMsg,
|
||||
signDelimiter: data.signDelimiter || null,
|
||||
reopenConversation: data.reopenConversation,
|
||||
conversationPending: data.conversationPending,
|
||||
mergeBrazilContacts: data.mergeBrazilContacts,
|
||||
importContacts: data.importContacts,
|
||||
importMessages: data.importMessages,
|
||||
daysLimitImportMessages: data.daysLimitImportMessages,
|
||||
};
|
||||
}
|
||||
|
||||
@ -400,7 +504,11 @@ export class ChannelStartupService {
|
||||
|
||||
public async loadWebsocket() {
|
||||
this.logger.verbose('Loading websocket');
|
||||
const data = await this.mongodbRepository.websocket.find(this.instanceName);
|
||||
const data = await this.prismaRepository.websocket.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.localWebsocket.enabled = data?.enabled;
|
||||
this.logger.verbose(`Websocket enabled: ${this.localWebsocket.enabled}`);
|
||||
@ -411,9 +519,16 @@ export class ChannelStartupService {
|
||||
this.logger.verbose('Websocket loaded');
|
||||
}
|
||||
|
||||
public async setWebsocket(data: WebsocketRaw) {
|
||||
public async setWebsocket(data: WebsocketDto) {
|
||||
this.logger.verbose('Setting websocket');
|
||||
await this.mongodbRepository.websocket.create(data, this.instanceName);
|
||||
await this.prismaRepository.websocket.create({
|
||||
data: {
|
||||
enabled: data.enabled,
|
||||
events: data.events,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Websocket events: ${data.events}`);
|
||||
Object.assign(this.localWebsocket, data);
|
||||
this.logger.verbose('Websocket set');
|
||||
@ -421,7 +536,11 @@ export class ChannelStartupService {
|
||||
|
||||
public async findWebsocket() {
|
||||
this.logger.verbose('Finding websocket');
|
||||
const data = await this.mongodbRepository.websocket.find(this.instanceName);
|
||||
const data = await this.prismaRepository.websocket.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.logger.verbose('Websocket not found');
|
||||
@ -429,15 +548,16 @@ export class ChannelStartupService {
|
||||
}
|
||||
|
||||
this.logger.verbose(`Websocket events: ${data.events}`);
|
||||
return {
|
||||
enabled: data.enabled,
|
||||
events: data.events,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
public async loadRabbitmq() {
|
||||
this.logger.verbose('Loading rabbitmq');
|
||||
const data = await this.mongodbRepository.rabbitmq.find(this.instanceName);
|
||||
const data = await this.prismaRepository.rabbitmq.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.localRabbitmq.enabled = data?.enabled;
|
||||
this.logger.verbose(`Rabbitmq enabled: ${this.localRabbitmq.enabled}`);
|
||||
@ -448,9 +568,16 @@ export class ChannelStartupService {
|
||||
this.logger.verbose('Rabbitmq loaded');
|
||||
}
|
||||
|
||||
public async setRabbitmq(data: RabbitmqRaw) {
|
||||
public async setRabbitmq(data: RabbitmqDto) {
|
||||
this.logger.verbose('Setting rabbitmq');
|
||||
await this.mongodbRepository.rabbitmq.create(data, this.instanceName);
|
||||
await this.prismaRepository.rabbitmq.create({
|
||||
data: {
|
||||
enabled: data.enabled,
|
||||
events: data.events,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Rabbitmq events: ${data.events}`);
|
||||
Object.assign(this.localRabbitmq, data);
|
||||
this.logger.verbose('Rabbitmq set');
|
||||
@ -458,7 +585,11 @@ export class ChannelStartupService {
|
||||
|
||||
public async findRabbitmq() {
|
||||
this.logger.verbose('Finding rabbitmq');
|
||||
const data = await this.mongodbRepository.rabbitmq.find(this.instanceName);
|
||||
const data = await this.prismaRepository.rabbitmq.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.logger.verbose('Rabbitmq not found');
|
||||
@ -466,10 +597,7 @@ export class ChannelStartupService {
|
||||
}
|
||||
|
||||
this.logger.verbose(`Rabbitmq events: ${data.events}`);
|
||||
return {
|
||||
enabled: data.enabled,
|
||||
events: data.events,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
public async removeRabbitmqQueues() {
|
||||
@ -482,7 +610,11 @@ export class ChannelStartupService {
|
||||
|
||||
public async loadSqs() {
|
||||
this.logger.verbose('Loading sqs');
|
||||
const data = await this.mongodbRepository.sqs.find(this.instanceName);
|
||||
const data = await this.prismaRepository.sqs.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.localSqs.enabled = data?.enabled;
|
||||
this.logger.verbose(`Sqs enabled: ${this.localSqs.enabled}`);
|
||||
@ -493,9 +625,16 @@ export class ChannelStartupService {
|
||||
this.logger.verbose('Sqs loaded');
|
||||
}
|
||||
|
||||
public async setSqs(data: SqsRaw) {
|
||||
public async setSqs(data: SqsDto) {
|
||||
this.logger.verbose('Setting sqs');
|
||||
await this.mongodbRepository.sqs.create(data, this.instanceName);
|
||||
await this.prismaRepository.sqs.create({
|
||||
data: {
|
||||
enabled: data.enabled,
|
||||
events: data.events,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Sqs events: ${data.events}`);
|
||||
Object.assign(this.localSqs, data);
|
||||
this.logger.verbose('Sqs set');
|
||||
@ -503,7 +642,11 @@ export class ChannelStartupService {
|
||||
|
||||
public async findSqs() {
|
||||
this.logger.verbose('Finding sqs');
|
||||
const data = await this.mongodbRepository.sqs.find(this.instanceName);
|
||||
const data = await this.prismaRepository.sqs.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.logger.verbose('Sqs not found');
|
||||
@ -511,10 +654,7 @@ export class ChannelStartupService {
|
||||
}
|
||||
|
||||
this.logger.verbose(`Sqs events: ${data.events}`);
|
||||
return {
|
||||
enabled: data.enabled,
|
||||
events: data.events,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
public async removeSqsQueues() {
|
||||
@ -527,7 +667,14 @@ export class ChannelStartupService {
|
||||
|
||||
public async loadTypebot() {
|
||||
this.logger.verbose('Loading typebot');
|
||||
const data = await this.mongodbRepository.typebot.find(this.instanceName);
|
||||
const data = await this.prismaRepository.typebot.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
include: {
|
||||
sessions: true,
|
||||
},
|
||||
});
|
||||
|
||||
this.localTypebot.enabled = data?.enabled;
|
||||
this.logger.verbose(`Typebot enabled: ${this.localTypebot.enabled}`);
|
||||
@ -541,39 +688,66 @@ export class ChannelStartupService {
|
||||
this.localTypebot.expire = data?.expire;
|
||||
this.logger.verbose(`Typebot expire: ${this.localTypebot.expire}`);
|
||||
|
||||
this.localTypebot.keyword_finish = data?.keyword_finish;
|
||||
this.logger.verbose(`Typebot keyword_finish: ${this.localTypebot.keyword_finish}`);
|
||||
this.localTypebot.keywordFinish = data?.keywordFinish;
|
||||
this.logger.verbose(`Typebot keywordFinish: ${this.localTypebot.keywordFinish}`);
|
||||
|
||||
this.localTypebot.delay_message = data?.delay_message;
|
||||
this.logger.verbose(`Typebot delay_message: ${this.localTypebot.delay_message}`);
|
||||
this.localTypebot.delayMessage = data?.delayMessage;
|
||||
this.logger.verbose(`Typebot delayMessage: ${this.localTypebot.delayMessage}`);
|
||||
|
||||
this.localTypebot.unknown_message = data?.unknown_message;
|
||||
this.logger.verbose(`Typebot unknown_message: ${this.localTypebot.unknown_message}`);
|
||||
this.localTypebot.unknownMessage = data?.unknownMessage;
|
||||
this.logger.verbose(`Typebot unknownMessage: ${this.localTypebot.unknownMessage}`);
|
||||
|
||||
this.localTypebot.listening_from_me = data?.listening_from_me;
|
||||
this.logger.verbose(`Typebot listening_from_me: ${this.localTypebot.listening_from_me}`);
|
||||
this.localTypebot.listeningFromMe = data?.listeningFromMe;
|
||||
this.logger.verbose(`Typebot listeningFromMe: ${this.localTypebot.listeningFromMe}`);
|
||||
|
||||
this.localTypebot.sessions = data?.sessions;
|
||||
|
||||
this.logger.verbose('Typebot loaded');
|
||||
}
|
||||
|
||||
public async setTypebot(data: TypebotRaw) {
|
||||
public async setTypebot(data: TypebotDto) {
|
||||
this.logger.verbose('Setting typebot');
|
||||
await this.mongodbRepository.typebot.create(data, this.instanceName);
|
||||
|
||||
const typebot = await this.prismaRepository.typebot.create({
|
||||
data: {
|
||||
enabled: data.enabled,
|
||||
url: data.url,
|
||||
typebot: data.typebot,
|
||||
expire: data.expire,
|
||||
keywordFinish: data.keywordFinish,
|
||||
delayMessage: data.delayMessage,
|
||||
unknownMessage: data.unknownMessage,
|
||||
listeningFromMe: data.listeningFromMe,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
await this.prismaRepository.typebotSession.deleteMany({
|
||||
where: {
|
||||
typebotId: typebot.id,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Typebot typebot: ${data.typebot}`);
|
||||
this.logger.verbose(`Typebot expire: ${data.expire}`);
|
||||
this.logger.verbose(`Typebot keyword_finish: ${data.keyword_finish}`);
|
||||
this.logger.verbose(`Typebot delay_message: ${data.delay_message}`);
|
||||
this.logger.verbose(`Typebot unknown_message: ${data.unknown_message}`);
|
||||
this.logger.verbose(`Typebot listening_from_me: ${data.listening_from_me}`);
|
||||
this.logger.verbose(`Typebot keywordFinish: ${data.keywordFinish}`);
|
||||
this.logger.verbose(`Typebot delayMessage: ${data.delayMessage}`);
|
||||
this.logger.verbose(`Typebot unknownMessage: ${data.unknownMessage}`);
|
||||
this.logger.verbose(`Typebot listeningFromMe: ${data.listeningFromMe}`);
|
||||
Object.assign(this.localTypebot, data);
|
||||
this.logger.verbose('Typebot set');
|
||||
}
|
||||
|
||||
public async findTypebot() {
|
||||
this.logger.verbose('Finding typebot');
|
||||
const data = await this.mongodbRepository.typebot.find(this.instanceName);
|
||||
const data = await this.prismaRepository.typebot.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
include: {
|
||||
sessions: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.logger.verbose('Typebot not found');
|
||||
@ -585,48 +759,69 @@ export class ChannelStartupService {
|
||||
url: data.url,
|
||||
typebot: data.typebot,
|
||||
expire: data.expire,
|
||||
keyword_finish: data.keyword_finish,
|
||||
delay_message: data.delay_message,
|
||||
unknown_message: data.unknown_message,
|
||||
listening_from_me: data.listening_from_me,
|
||||
keywordFinish: data.keywordFinish,
|
||||
delayMessage: data.delayMessage,
|
||||
unknownMessage: data.unknownMessage,
|
||||
listeningFromMe: data.listeningFromMe,
|
||||
sessions: data.sessions,
|
||||
};
|
||||
}
|
||||
|
||||
public async loadProxy() {
|
||||
this.logger.verbose('Loading proxy');
|
||||
const data = await this.mongodbRepository.proxy.find(this.instanceName);
|
||||
const data = await this.prismaRepository.proxy.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.localProxy.enabled = data?.enabled;
|
||||
this.logger.verbose(`Proxy enabled: ${this.localProxy.enabled}`);
|
||||
|
||||
this.localProxy.proxy = data?.proxy;
|
||||
this.localProxy.proxy = {
|
||||
host: data?.host,
|
||||
port: `${data?.port}`,
|
||||
username: data?.username,
|
||||
password: data?.password,
|
||||
};
|
||||
|
||||
this.logger.verbose(`Proxy proxy: ${this.localProxy.proxy?.host}`);
|
||||
|
||||
this.logger.verbose('Proxy loaded');
|
||||
}
|
||||
|
||||
public async setProxy(data: ProxyRaw) {
|
||||
public async setProxy(data: ProxyDto) {
|
||||
this.logger.verbose('Setting proxy');
|
||||
await this.mongodbRepository.proxy.create(data, this.instanceName);
|
||||
this.logger.verbose(`Proxy proxy: ${data.proxy}`);
|
||||
await this.prismaRepository.proxy.create({
|
||||
data: {
|
||||
enabled: data.enabled,
|
||||
host: data.host,
|
||||
port: data.port,
|
||||
username: data.username,
|
||||
password: data.password,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose(`Proxy proxy: ${data.host}`);
|
||||
Object.assign(this.localProxy, data);
|
||||
this.logger.verbose('Proxy set');
|
||||
}
|
||||
|
||||
public async findProxy() {
|
||||
this.logger.verbose('Finding proxy');
|
||||
const data = await this.mongodbRepository.proxy.find(this.instanceName);
|
||||
const data = await this.prismaRepository.proxy.findUnique({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
this.logger.verbose('Proxy not found');
|
||||
throw new NotFoundException('Proxy not found');
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: data.enabled,
|
||||
proxy: data.proxy,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
public async sendDataWebhook<T = any>(event: Events, data: T, local = true) {
|
||||
@ -646,7 +841,11 @@ export class ChannelStartupService {
|
||||
const now = localISOTime;
|
||||
|
||||
const expose = this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES;
|
||||
const tokenStore = await this.mongodbRepository.auth.find(this.instanceName);
|
||||
const tokenStore = await this.prismaRepository.auth.findFirst({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
});
|
||||
const instanceApikey = tokenStore?.apikey || 'Apikey not found';
|
||||
|
||||
if (rabbitmqEnabled) {
|
||||
@ -930,7 +1129,7 @@ export class ChannelStartupService {
|
||||
this.logger.verbose('Sending data to webhook local');
|
||||
let baseURL: string;
|
||||
|
||||
if (this.localWebhook.webhook_by_events) {
|
||||
if (this.localWebhook.webhookByEvents) {
|
||||
baseURL = `${this.localWebhook.url}/${transformedWe}`;
|
||||
} else {
|
||||
baseURL = this.localWebhook.url;
|
||||
@ -1167,61 +1366,63 @@ export class ChannelStartupService {
|
||||
return `${number}@s.whatsapp.net`;
|
||||
}
|
||||
|
||||
public async fetchContacts(query: ContactQuery) {
|
||||
public async fetchContacts(query: any) {
|
||||
this.logger.verbose('Fetching contacts');
|
||||
if (query?.where) {
|
||||
query.where.owner = this.instance.name;
|
||||
if (query.where?.id) {
|
||||
query.where.id = this.createJid(query.where.id);
|
||||
query.where.remoteJid = this.instance.name;
|
||||
if (query.where?.remoteJid) {
|
||||
query.where.remoteJid = this.createJid(query.where.remoteJid);
|
||||
}
|
||||
} else {
|
||||
query = {
|
||||
where: {
|
||||
owner: this.instance.name,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
};
|
||||
}
|
||||
return await this.mongodbRepository.contact.find(query);
|
||||
return await this.prismaRepository.contact.findMany({
|
||||
where: query.where,
|
||||
});
|
||||
}
|
||||
|
||||
public async fetchMessages(query: MessageQuery) {
|
||||
public async fetchMessages(query: any) {
|
||||
this.logger.verbose('Fetching messages');
|
||||
if (query?.where) {
|
||||
if (query.where?.key?.remoteJid) {
|
||||
query.where.key.remoteJid = this.createJid(query.where.key.remoteJid);
|
||||
}
|
||||
query.where.owner = this.instance.name;
|
||||
query.where.instanceId = this.instanceId;
|
||||
} else {
|
||||
query = {
|
||||
where: {
|
||||
owner: this.instance.name,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
limit: query?.limit,
|
||||
};
|
||||
}
|
||||
return await this.mongodbRepository.message.find(query);
|
||||
return await this.prismaRepository.message.findMany(query);
|
||||
}
|
||||
|
||||
public async fetchStatusMessage(query: MessageUpQuery) {
|
||||
public async fetchStatusMessage(query: any) {
|
||||
this.logger.verbose('Fetching status messages');
|
||||
if (query?.where) {
|
||||
if (query.where?.remoteJid) {
|
||||
query.where.remoteJid = this.createJid(query.where.remoteJid);
|
||||
}
|
||||
query.where.owner = this.instance.name;
|
||||
query.where.instanceId = this.instanceId;
|
||||
} else {
|
||||
query = {
|
||||
where: {
|
||||
owner: this.instance.name,
|
||||
instanceId: this.instanceId,
|
||||
},
|
||||
limit: query?.limit,
|
||||
};
|
||||
}
|
||||
return await this.mongodbRepository.messageUpdate.find(query);
|
||||
return await this.prismaRepository.messageUpdate.findMany(query);
|
||||
}
|
||||
|
||||
public async fetchChats() {
|
||||
this.logger.verbose('Fetching chats');
|
||||
return await this.mongodbRepository.chat.find({ where: { owner: this.instance.name } });
|
||||
return await this.prismaRepository.chat.findMany({ where: { instanceId: this.instanceId } });
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,10 +22,8 @@ import {
|
||||
SendTemplateDto,
|
||||
SendTextDto,
|
||||
} from '../../dto/sendMessage.dto';
|
||||
import { ContactRaw, MessageRaw, MessageUpdateRaw, SettingsRaw } from '../../models';
|
||||
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 { Events, wa } from '../../types/wa.types';
|
||||
import { CacheService } from './../cache.service';
|
||||
import { ChannelStartupService } from './../channel.service';
|
||||
@ -34,14 +32,13 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
constructor(
|
||||
public readonly configService: ConfigService,
|
||||
public readonly eventEmitter: EventEmitter2,
|
||||
public readonly mongodbRepository: MongodbRepository,
|
||||
public readonly prismaRepository: PrismaRepository,
|
||||
public readonly cache: CacheService,
|
||||
public readonly chatwootCache: CacheService,
|
||||
public readonly baileysCache: CacheService,
|
||||
private readonly providerFiles: ProviderFiles,
|
||||
) {
|
||||
super(configService, eventEmitter, mongodbRepository, prismaRepository, chatwootCache);
|
||||
super(configService, eventEmitter, prismaRepository, chatwootCache);
|
||||
this.logger.verbose('BusinessStartupService initialized');
|
||||
this.cleanStore();
|
||||
}
|
||||
@ -318,9 +315,9 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
return messageType;
|
||||
}
|
||||
|
||||
protected async messageHandle(received: any, database: Database, settings: SettingsRaw) {
|
||||
protected async messageHandle(received: any, database: Database, settings: any) {
|
||||
try {
|
||||
let messageRaw: MessageRaw;
|
||||
let messageRaw: any;
|
||||
let pushName: any;
|
||||
|
||||
if (received.contacts) pushName = received.contacts[0].profile.name;
|
||||
@ -398,11 +395,11 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
};
|
||||
}
|
||||
|
||||
if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') {
|
||||
if (this.localSettings.readMessages && received.key.id !== 'status@broadcast') {
|
||||
// await this.client.readMessages([received.key]);
|
||||
}
|
||||
|
||||
if (this.localSettings.read_status && received.key.id === 'status@broadcast') {
|
||||
if (this.localSettings.readStatus && received.key.id === 'status@broadcast') {
|
||||
// await this.client.readMessages([received.key]);
|
||||
}
|
||||
|
||||
@ -433,7 +430,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
);
|
||||
|
||||
if (this.localTypebot.enabled || typebotSessionRemoteJid) {
|
||||
if (!(this.localTypebot.listening_from_me === false && key.fromMe === true)) {
|
||||
if (!(this.localTypebot.listeningFromMe === false && key.fromMe === true)) {
|
||||
if (messageRaw.messageType !== 'reactionMessage')
|
||||
await this.typebotService.sendTypebot(
|
||||
{ instanceName: this.instance.name },
|
||||
@ -444,32 +441,34 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
}
|
||||
|
||||
this.logger.verbose('Inserting message in database');
|
||||
await this.mongodbRepository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE);
|
||||
|
||||
this.logger.verbose('Verifying contact from message');
|
||||
const contact = await this.mongodbRepository.contact.find({
|
||||
where: { owner: this.instance.name, id: key.remoteJid },
|
||||
await this.prismaRepository.message.create({
|
||||
data: messageRaw,
|
||||
});
|
||||
|
||||
const contactRaw: ContactRaw = {
|
||||
id: received.contacts[0].profile.phone,
|
||||
this.logger.verbose('Verifying contact from message');
|
||||
const contact = await this.prismaRepository.contact.findFirst({
|
||||
where: { instanceId: this.instanceId, remoteJid: key.remoteJid },
|
||||
});
|
||||
|
||||
const contactRaw: any = {
|
||||
remoteJid: received.contacts[0].profile.phone,
|
||||
pushName,
|
||||
//profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl,
|
||||
owner: this.instance.name,
|
||||
// profilePicUrl: '',
|
||||
instanceId: this.instanceId,
|
||||
};
|
||||
|
||||
if (contactRaw.id === 'status@broadcast') {
|
||||
if (contactRaw.remoteJid === 'status@broadcast') {
|
||||
this.logger.verbose('Contact is status@broadcast');
|
||||
return;
|
||||
}
|
||||
|
||||
if (contact?.length) {
|
||||
if (contact) {
|
||||
this.logger.verbose('Contact found in database');
|
||||
const contactRaw: ContactRaw = {
|
||||
id: received.contacts[0].profile.phone,
|
||||
const contactRaw: any = {
|
||||
remoteJid: received.contacts[0].profile.phone,
|
||||
pushName,
|
||||
//profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl,
|
||||
owner: this.instance.name,
|
||||
// profilePicUrl: '',
|
||||
instanceId: this.instanceId,
|
||||
};
|
||||
|
||||
this.logger.verbose('Sending data to webhook in event CONTACTS_UPDATE');
|
||||
@ -484,7 +483,10 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
}
|
||||
|
||||
this.logger.verbose('Updating contact in database');
|
||||
await this.mongodbRepository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||
await this.prismaRepository.contact.updateMany({
|
||||
where: { remoteJid: contact.remoteJid },
|
||||
data: contactRaw,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -494,7 +496,9 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw);
|
||||
|
||||
this.logger.verbose('Inserting contact in database');
|
||||
this.mongodbRepository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS);
|
||||
this.prismaRepository.contact.create({
|
||||
data: contactRaw,
|
||||
});
|
||||
}
|
||||
this.logger.verbose('Event received: messages.update');
|
||||
if (received.statuses) {
|
||||
@ -513,27 +517,38 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
|
||||
if (item.status === 'read' && !key.fromMe) return;
|
||||
|
||||
const findMessage = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
instanceId: this.instanceId,
|
||||
key: {
|
||||
path: ['id'],
|
||||
equals: key.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (item.message === null && item.status === undefined) {
|
||||
this.logger.verbose('Message deleted');
|
||||
|
||||
this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE');
|
||||
this.sendDataWebhook(Events.MESSAGES_DELETE, key);
|
||||
|
||||
const message: MessageUpdateRaw = {
|
||||
...key,
|
||||
const message: any = {
|
||||
messageId: findMessage.id,
|
||||
keyId: key.id,
|
||||
remoteJid: key.remoteJid,
|
||||
fromMe: key.fromMe,
|
||||
participant: key?.remoteJid,
|
||||
status: 'DELETED',
|
||||
datetime: Date.now(),
|
||||
owner: this.instance.name,
|
||||
dateTime: Date.now(),
|
||||
};
|
||||
|
||||
this.logger.verbose(message);
|
||||
|
||||
this.logger.verbose('Inserting message in database');
|
||||
await this.mongodbRepository.messageUpdate.insert(
|
||||
[message],
|
||||
this.instance.name,
|
||||
database.SAVE_DATA.MESSAGE_UPDATE,
|
||||
);
|
||||
await this.prismaRepository.messageUpdate.create({
|
||||
data: message,
|
||||
});
|
||||
|
||||
if (this.localChatwoot.enabled) {
|
||||
this.chatwootService.eventWhatsapp(
|
||||
@ -546,11 +561,14 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
return;
|
||||
}
|
||||
|
||||
const message: MessageUpdateRaw = {
|
||||
...key,
|
||||
const message: any = {
|
||||
messageId: findMessage.id,
|
||||
keyId: key.id,
|
||||
remoteJid: key.remoteJid,
|
||||
fromMe: key.fromMe,
|
||||
participant: key?.remoteJid,
|
||||
status: item.status.toUpperCase(),
|
||||
datetime: Date.now(),
|
||||
owner: this.instance.name,
|
||||
dateTime: Date.now(),
|
||||
};
|
||||
|
||||
this.logger.verbose(message);
|
||||
@ -559,11 +577,9 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
this.sendDataWebhook(Events.MESSAGES_UPDATE, message);
|
||||
|
||||
this.logger.verbose('Inserting message in database');
|
||||
this.mongodbRepository.messageUpdate.insert(
|
||||
[message],
|
||||
this.instance.name,
|
||||
database.SAVE_DATA.MESSAGE_UPDATE,
|
||||
);
|
||||
await this.prismaRepository.messageUpdate.create({
|
||||
data: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -848,13 +864,13 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
|
||||
console.log(content);
|
||||
|
||||
const messageRaw: MessageRaw = {
|
||||
const messageRaw: any = {
|
||||
key: { fromMe: true, id: messageSent?.messages[0]?.id, remoteJid: this.createJid(number) },
|
||||
//pushName: messageSent.pushName,
|
||||
message: this.convertMessageToRaw(message, content),
|
||||
messageType: this.renderMessageType(content.type),
|
||||
messageTimestamp: (messageSent?.messages[0]?.timestamp as number) || Math.round(new Date().getTime() / 1000),
|
||||
owner: this.instance.name,
|
||||
instanceId: this.instanceId,
|
||||
//ource: getDevice(messageSent.key.id),
|
||||
};
|
||||
|
||||
@ -868,11 +884,9 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
}
|
||||
|
||||
this.logger.verbose('Inserting message in database');
|
||||
await this.mongodbRepository.message.insert(
|
||||
[messageRaw],
|
||||
this.instance.name,
|
||||
this.configService.get<Database>('DATABASE').SAVE_DATA.NEW_MESSAGE,
|
||||
);
|
||||
await this.prismaRepository.message.create({
|
||||
data: messageRaw,
|
||||
});
|
||||
|
||||
return messageRaw;
|
||||
} catch (error) {
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Integration } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
import { IntegrationDto } from '../dto/integration.dto';
|
||||
import { IntegrationRaw } from '../models';
|
||||
import { WAMonitoringService } from './monitor.service';
|
||||
|
||||
export class IntegrationService {
|
||||
@ -16,19 +17,19 @@ export class IntegrationService {
|
||||
return { integration: { ...instance, integration: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<IntegrationRaw> {
|
||||
public async find(instance: InstanceDto): Promise<Integration> {
|
||||
try {
|
||||
this.logger.verbose('find integration: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findIntegration();
|
||||
|
||||
if (Object.keys(result).length === 0) {
|
||||
this.create(instance, { integration: 'WHATSAPP-BAILEYS', number: '', token: '' });
|
||||
return { integration: 'WHATSAPP-BAILEYS', number: '', token: '' };
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { integration: '', number: '', token: '' };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { execSync } from 'child_process';
|
||||
import EventEmitter2 from 'eventemitter2';
|
||||
import { existsSync, mkdirSync, opendirSync, readdirSync, rmSync, writeFileSync } from 'fs';
|
||||
import { Db } from 'mongodb';
|
||||
import { Collection } from 'mongoose';
|
||||
import { join } from 'path';
|
||||
|
||||
import {
|
||||
@ -17,21 +15,8 @@ import {
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config';
|
||||
import { NotFoundException } from '../../exceptions';
|
||||
import {
|
||||
AuthModel,
|
||||
ChatwootModel,
|
||||
ContactModel,
|
||||
LabelModel,
|
||||
ProxyModel,
|
||||
RabbitmqModel,
|
||||
SettingsModel,
|
||||
TypebotModel,
|
||||
WebhookModel,
|
||||
WebsocketModel,
|
||||
} from '../models';
|
||||
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 { Integration } from '../types/wa.types';
|
||||
import { CacheService } from './cache.service';
|
||||
import { BaileysStartupService } from './channels/whatsapp.baileys.service';
|
||||
@ -41,12 +26,11 @@ export class WAMonitoringService {
|
||||
constructor(
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly monogodbRepository: MongodbRepository,
|
||||
private readonly primaRepository: PrismaRepository,
|
||||
private readonly prismaRepository: PrismaRepository,
|
||||
private readonly providerFiles: ProviderFiles,
|
||||
private readonly cache: CacheService,
|
||||
private readonly chatwootCache: CacheService,
|
||||
private readonly baileysCache: CacheService,
|
||||
private readonly providerFiles: ProviderFiles,
|
||||
) {
|
||||
this.logger.verbose('instance created');
|
||||
|
||||
@ -55,17 +39,11 @@ export class WAMonitoringService {
|
||||
|
||||
Object.assign(this.db, configService.get<Database>('DATABASE'));
|
||||
Object.assign(this.redis, configService.get<CacheConf>('CACHE'));
|
||||
|
||||
this.dbInstance = this.db.ENABLED
|
||||
? this.monogodbRepository.mongodbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||
: undefined;
|
||||
}
|
||||
|
||||
private readonly db: Partial<Database> = {};
|
||||
private readonly redis: Partial<CacheConf> = {};
|
||||
|
||||
private dbInstance: Db;
|
||||
|
||||
private readonly logger = new Logger(WAMonitoringService.name);
|
||||
public readonly waInstances: Record<string, BaileysStartupService | BusinessStartupService> = {};
|
||||
|
||||
@ -126,7 +104,7 @@ export class WAMonitoringService {
|
||||
if (findIntegration) {
|
||||
integration = {
|
||||
...findIntegration,
|
||||
webhook_wa_business: `${urlServer}/webhook/whatsapp/${encodeURIComponent(key)}`,
|
||||
webhookWaBusiness: `${urlServer}/webhook/whatsapp/${encodeURIComponent(key)}`,
|
||||
};
|
||||
}
|
||||
|
||||
@ -136,7 +114,7 @@ export class WAMonitoringService {
|
||||
const instanceData = {
|
||||
instance: {
|
||||
instanceName: key,
|
||||
instanceId: (await this.monogodbRepository.auth.find(key))?.instanceId,
|
||||
instanceId: this.waInstances[key].instanceId,
|
||||
owner: value.wuid,
|
||||
profileName: (await value.getProfileName()) || 'not loaded',
|
||||
profilePictureUrl: value.profilePictureUrl,
|
||||
@ -148,7 +126,11 @@ export class WAMonitoringService {
|
||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||
|
||||
instanceData.instance['apikey'] = (await this.monogodbRepository.auth.find(key))?.apikey;
|
||||
instanceData.instance['apikey'] = (
|
||||
await this.prismaRepository.auth.findFirst({
|
||||
where: { instanceId: this.waInstances[key].instanceId },
|
||||
})
|
||||
)?.apikey;
|
||||
|
||||
instanceData.instance['chatwoot'] = chatwoot;
|
||||
|
||||
@ -162,7 +144,7 @@ export class WAMonitoringService {
|
||||
const instanceData = {
|
||||
instance: {
|
||||
instanceName: key,
|
||||
instanceId: (await this.monogodbRepository.auth.find(key))?.instanceId,
|
||||
instanceId: this.waInstances[key].instanceId,
|
||||
status: value.connectionStatus.state,
|
||||
},
|
||||
};
|
||||
@ -170,7 +152,11 @@ export class WAMonitoringService {
|
||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||
|
||||
instanceData.instance['apikey'] = (await this.monogodbRepository.auth.find(key))?.apikey;
|
||||
instanceData.instance['apikey'] = (
|
||||
await this.prismaRepository.auth.findFirst({
|
||||
where: { instanceId: this.waInstances[key].instanceId },
|
||||
})
|
||||
)?.apikey;
|
||||
|
||||
instanceData.instance['chatwoot'] = chatwoot;
|
||||
|
||||
@ -194,12 +180,14 @@ export class WAMonitoringService {
|
||||
this.logger.verbose('get instance info');
|
||||
let instanceName: string;
|
||||
if (instanceId) {
|
||||
instanceName = await this.monogodbRepository.auth.findInstanceNameById(instanceId);
|
||||
instanceName = await this.prismaRepository.instance.findFirst({ where: { id: instanceId } }).then((r) => r?.name);
|
||||
if (!instanceName) {
|
||||
throw new NotFoundException(`Instance "${instanceId}" not found`);
|
||||
}
|
||||
} else if (number) {
|
||||
instanceName = await this.monogodbRepository.auth.findInstanceNameByNumber(number);
|
||||
const id = await this.prismaRepository.integration.findFirst({ where: { number } }).then((r) => r?.instanceId);
|
||||
|
||||
instanceName = await this.prismaRepository.instance.findFirst({ where: { id } }).then((r) => r?.name);
|
||||
if (!instanceName) {
|
||||
throw new NotFoundException(`Instance "${number}" not found`);
|
||||
}
|
||||
@ -216,50 +204,12 @@ export class WAMonitoringService {
|
||||
return this.instanceInfo(instanceName);
|
||||
}
|
||||
|
||||
private delInstanceFiles() {
|
||||
this.logger.verbose('cron to delete instance files started');
|
||||
setInterval(async () => {
|
||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||
const collections = await this.dbInstance.collections();
|
||||
collections.forEach(async (collection) => {
|
||||
const name = collection.namespace.replace(/^[\w-]+./, '');
|
||||
await this.dbInstance.collection(name).deleteMany({
|
||||
$or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }],
|
||||
});
|
||||
this.logger.verbose('instance files deleted: ' + name);
|
||||
});
|
||||
} else if (!this.redis.REDIS.ENABLED && !this.redis.REDIS.SAVE_INSTANCES) {
|
||||
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
||||
for await (const dirent of dir) {
|
||||
if (dirent.isDirectory()) {
|
||||
const files = readdirSync(join(INSTANCE_DIR, dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
files.forEach(async (file) => {
|
||||
if (file.match(/^app.state.*/) || file.match(/^session-.*/)) {
|
||||
rmSync(join(INSTANCE_DIR, dirent.name, file), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.logger.verbose('instance files deleted: ' + dirent.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 3600 * 1000 * 2);
|
||||
}
|
||||
|
||||
public async cleaningUp(instanceName: string) {
|
||||
this.logger.verbose('cleaning up instance: ' + instanceName);
|
||||
|
||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||
this.logger.verbose('cleaning up instance in database: ' + instanceName);
|
||||
await this.monogodbRepository.mongodbServer.connect();
|
||||
const collections: any[] = await this.dbInstance.collections();
|
||||
if (collections.length > 0) {
|
||||
await this.dbInstance.dropCollection(instanceName);
|
||||
}
|
||||
// TODO: deleta instancia
|
||||
return;
|
||||
}
|
||||
|
||||
@ -304,20 +254,7 @@ export class WAMonitoringService {
|
||||
|
||||
this.logger.verbose('cleaning store database instance: ' + instanceName);
|
||||
|
||||
if (this.db.PROVIDER === 'mongodb') {
|
||||
await AuthModel.deleteMany({ _id: instanceName });
|
||||
await WebhookModel.deleteMany({ _id: instanceName });
|
||||
await ChatwootModel.deleteMany({ _id: instanceName });
|
||||
await ProxyModel.deleteMany({ _id: instanceName });
|
||||
await RabbitmqModel.deleteMany({ _id: instanceName });
|
||||
await TypebotModel.deleteMany({ _id: instanceName });
|
||||
await WebsocketModel.deleteMany({ _id: instanceName });
|
||||
await SettingsModel.deleteMany({ _id: instanceName });
|
||||
await LabelModel.deleteMany({ owner: instanceName });
|
||||
await ContactModel.deleteMany({ owner: instanceName });
|
||||
|
||||
return;
|
||||
}
|
||||
// TODO: deleta dados da instancia
|
||||
}
|
||||
|
||||
public async loadInstance() {
|
||||
@ -329,8 +266,7 @@ export class WAMonitoringService {
|
||||
} else if (this.redis.REDIS.ENABLED && this.redis.REDIS.SAVE_INSTANCES) {
|
||||
await this.loadInstancesFromRedis();
|
||||
} else if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||
if (this.db.PROVIDER === 'mongodb') await this.loadInstancesFromDatabaseMongoDB();
|
||||
else if (this.db.PROVIDER === 'postgresql') await this.loadInstancesFromDatabasePostgres();
|
||||
await this.loadInstancesFromDatabasePostgres();
|
||||
} else {
|
||||
await this.loadInstancesFromFiles();
|
||||
}
|
||||
@ -345,9 +281,22 @@ export class WAMonitoringService {
|
||||
try {
|
||||
const msgParsed = JSON.parse(JSON.stringify(data));
|
||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||
await this.monogodbRepository.mongodbServer.connect();
|
||||
await this.dbInstance.collection(data.instanceName).replaceOne({ _id: 'integration' }, msgParsed, {
|
||||
upsert: true,
|
||||
await this.prismaRepository.instance.create({
|
||||
data: {
|
||||
id: data.instanceId,
|
||||
name: data.instanceName,
|
||||
connectionStatus: 'close',
|
||||
},
|
||||
});
|
||||
|
||||
console.log('saveInstance');
|
||||
await this.prismaRepository.integration.create({
|
||||
data: {
|
||||
instanceId: data.instanceId,
|
||||
integration: data.integration,
|
||||
number: data.number,
|
||||
token: data.token,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const path = join(INSTANCE_DIR, data.instanceName);
|
||||
@ -359,16 +308,18 @@ export class WAMonitoringService {
|
||||
}
|
||||
}
|
||||
|
||||
private async setInstance(name: string) {
|
||||
const integration = await this.monogodbRepository.integration.find(name);
|
||||
private async setInstance(id: string, name: string) {
|
||||
console.log('setInstance', name);
|
||||
const integration = await this.prismaRepository.integration.findUnique({
|
||||
where: { instanceId: id },
|
||||
});
|
||||
|
||||
let instance: BaileysStartupService | BusinessStartupService;
|
||||
if (integration && integration.integration === Integration.WHATSAPP_BUSINESS) {
|
||||
instance = new BusinessStartupService(
|
||||
this.configService,
|
||||
this.eventEmitter,
|
||||
this.monogodbRepository,
|
||||
this.primaRepository,
|
||||
this.prismaRepository,
|
||||
this.cache,
|
||||
this.chatwootCache,
|
||||
this.baileysCache,
|
||||
@ -376,12 +327,12 @@ export class WAMonitoringService {
|
||||
);
|
||||
|
||||
instance.instanceName = name;
|
||||
instance.instanceId = id;
|
||||
} else {
|
||||
instance = new BaileysStartupService(
|
||||
this.configService,
|
||||
this.eventEmitter,
|
||||
this.monogodbRepository,
|
||||
this.primaRepository,
|
||||
this.prismaRepository,
|
||||
this.cache,
|
||||
this.chatwootCache,
|
||||
this.baileysCache,
|
||||
@ -389,9 +340,10 @@ export class WAMonitoringService {
|
||||
);
|
||||
|
||||
instance.instanceName = name;
|
||||
instance.instanceId = id;
|
||||
|
||||
if (!integration) {
|
||||
await instance.setIntegration({ integration: Integration.WHATSAPP_BAILEYS });
|
||||
await instance.setIntegration({ integration: Integration.WHATSAPP_BAILEYS, number: '', token: '' });
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,45 +355,34 @@ export class WAMonitoringService {
|
||||
}
|
||||
|
||||
private async loadInstancesFromRedis() {
|
||||
console.log('loadInstancesFromRedis');
|
||||
this.logger.verbose('Redis enabled');
|
||||
const keys = await this.cache.keys();
|
||||
|
||||
if (keys?.length > 0) {
|
||||
this.logger.verbose('Reading instance keys and setting instances');
|
||||
await Promise.all(keys.map((k) => this.setInstance(k.split(':')[2])));
|
||||
await Promise.all(keys.map((k) => this.setInstance(k.split(':')[1], k.split(':')[2])));
|
||||
} else {
|
||||
this.logger.verbose('No instance keys found');
|
||||
}
|
||||
}
|
||||
|
||||
private async loadInstancesFromDatabaseMongoDB() {
|
||||
this.logger.verbose('Database enabled');
|
||||
await this.monogodbRepository.mongodbServer.connect();
|
||||
const collections: any[] = await this.dbInstance.collections();
|
||||
await this.deleteTempInstances(collections);
|
||||
if (collections.length > 0) {
|
||||
this.logger.verbose('Reading collections and setting instances');
|
||||
await Promise.all(collections.map((coll) => this.setInstance(coll.namespace.replace(/^[\w-]+\./, ''))));
|
||||
} else {
|
||||
this.logger.verbose('No collections found');
|
||||
}
|
||||
}
|
||||
|
||||
private async loadInstancesFromDatabasePostgres() {
|
||||
console.log('loadInstancesFromDatabasePostgres');
|
||||
this.logger.verbose('Database enabled');
|
||||
await this.primaRepository.onModuleInit();
|
||||
|
||||
const instances = await this.primaRepository.instance.findMany();
|
||||
const instances = await this.prismaRepository.instance.findMany();
|
||||
|
||||
console.log('instances', instances);
|
||||
if (instances.length === 0) {
|
||||
this.logger.verbose('No instances found');
|
||||
return;
|
||||
}
|
||||
|
||||
await Promise.all(instances.map(async (instance) => this.setInstance(instance.name)));
|
||||
await Promise.all(instances.map(async (instance) => this.setInstance(instance.id, instance.name)));
|
||||
}
|
||||
|
||||
private async loadInstancesFromProvider() {
|
||||
console.log('loadInstancesFromProvider');
|
||||
this.logger.verbose('Provider in files enabled');
|
||||
const [instances] = await this.providerFiles.allInstances();
|
||||
|
||||
@ -450,10 +391,11 @@ export class WAMonitoringService {
|
||||
return;
|
||||
}
|
||||
|
||||
await Promise.all(instances?.data?.map(async (instanceName: string) => this.setInstance(instanceName)));
|
||||
await Promise.all(instances?.data?.map(async (instanceName: string) => this.setInstance('', instanceName)));
|
||||
}
|
||||
|
||||
private async loadInstancesFromFiles() {
|
||||
console.log('loadInstancesFromFiles');
|
||||
this.logger.verbose('Store in files enabled');
|
||||
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
||||
const instanceDirs = [];
|
||||
@ -474,7 +416,7 @@ export class WAMonitoringService {
|
||||
if (files.length === 0) {
|
||||
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
||||
} else {
|
||||
await this.setInstance(instanceName);
|
||||
await this.setInstance('', instanceName);
|
||||
}
|
||||
}),
|
||||
);
|
||||
@ -534,25 +476,42 @@ export class WAMonitoringService {
|
||||
});
|
||||
}
|
||||
|
||||
private async deleteTempInstances(collections: Collection<Document>[]) {
|
||||
private delInstanceFiles() {
|
||||
this.logger.verbose('cron to delete instance files started');
|
||||
setInterval(async () => {
|
||||
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
||||
for await (const dirent of dir) {
|
||||
if (dirent.isDirectory()) {
|
||||
const files = readdirSync(join(INSTANCE_DIR, dirent.name), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
files.forEach(async (file) => {
|
||||
if (file.match(/^app.state.*/) || file.match(/^session-.*/)) {
|
||||
rmSync(join(INSTANCE_DIR, dirent.name, file), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.logger.verbose('instance files deleted: ' + dirent.name);
|
||||
}
|
||||
}
|
||||
}, 3600 * 1000 * 2);
|
||||
}
|
||||
|
||||
private async deleteTempInstances() {
|
||||
const shouldDelete = this.configService.get<boolean>('DEL_TEMP_INSTANCES');
|
||||
if (!shouldDelete) {
|
||||
this.logger.verbose('Temp instances deletion is disabled');
|
||||
return;
|
||||
}
|
||||
this.logger.verbose('Cleaning up temp instances');
|
||||
const auths = await this.monogodbRepository.auth.list();
|
||||
if (auths.length === 0) {
|
||||
this.logger.verbose('No temp instances found');
|
||||
return;
|
||||
}
|
||||
const instancesClosed = await this.prismaRepository.instance.findMany({ where: { connectionStatus: 'close' } });
|
||||
|
||||
let tempInstances = 0;
|
||||
auths.forEach((auth) => {
|
||||
if (collections.find((coll) => coll.namespace.replace(/^[\w-]+\./, '') === auth._id)) {
|
||||
return;
|
||||
}
|
||||
instancesClosed.forEach((instance) => {
|
||||
tempInstances++;
|
||||
this.eventEmitter.emit('remove.instance', auth._id, 'inner');
|
||||
this.eventEmitter.emit('remove.instance', instance.id, 'inner');
|
||||
});
|
||||
this.logger.verbose('Temp instances removed: ' + tempInstances);
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Proxy } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
import { ProxyDto } from '../dto/proxy.dto';
|
||||
import { ProxyRaw } from '../models';
|
||||
import { WAMonitoringService } from './monitor.service';
|
||||
|
||||
export class ProxyService {
|
||||
@ -16,7 +17,7 @@ export class ProxyService {
|
||||
return { proxy: { ...instance, proxy: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<ProxyRaw> {
|
||||
public async find(instance: InstanceDto): Promise<Proxy> {
|
||||
try {
|
||||
this.logger.verbose('find proxy: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findProxy();
|
||||
@ -27,7 +28,7 @@ export class ProxyService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, proxy: null };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ export class SettingsService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { reject_call: false, msg_call: '', groups_ignore: true };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { Webhook } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
import { WebhookDto } from '../dto/webhook.dto';
|
||||
@ -15,7 +17,7 @@ export class WebhookService {
|
||||
return { webhook: { ...instance, webhook: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<WebhookDto> {
|
||||
public async find(instance: InstanceDto): Promise<Webhook> {
|
||||
try {
|
||||
this.logger.verbose('find webhook: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findWebhook();
|
||||
@ -26,7 +28,7 @@ export class WebhookService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, url: '', events: [], webhook_by_events: false, webhook_base64: false };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-namespace */
|
||||
import { TypebotSession } from '@prisma/client';
|
||||
import { JsonValue } from '@prisma/client/runtime/library';
|
||||
import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys';
|
||||
|
||||
export enum Events {
|
||||
@ -41,6 +43,7 @@ export declare namespace wa {
|
||||
code?: string;
|
||||
};
|
||||
export type Instance = {
|
||||
id?: string;
|
||||
qrcode?: QrCode;
|
||||
pairingCode?: string;
|
||||
authState?: { state: AuthenticationState; saveCreds: () => void };
|
||||
@ -53,50 +56,51 @@ export declare namespace wa {
|
||||
export type LocalWebHook = {
|
||||
enabled?: boolean;
|
||||
url?: string;
|
||||
events?: string[];
|
||||
webhook_by_events?: boolean;
|
||||
webhook_base64?: boolean;
|
||||
events?: JsonValue;
|
||||
webhookByEvents?: boolean;
|
||||
webhookBase64?: boolean;
|
||||
};
|
||||
|
||||
export type LocalChatwoot = {
|
||||
enabled?: boolean;
|
||||
account_id?: string;
|
||||
accountId?: string;
|
||||
token?: string;
|
||||
url?: string;
|
||||
name_inbox?: string;
|
||||
sign_msg?: boolean;
|
||||
nameInbox?: string;
|
||||
signMsg?: boolean;
|
||||
signDelimiter?: string;
|
||||
number?: string;
|
||||
reopen_conversation?: boolean;
|
||||
conversation_pending?: boolean;
|
||||
merge_brazil_contacts?: boolean;
|
||||
import_contacts?: boolean;
|
||||
import_messages?: boolean;
|
||||
days_limit_import_messages?: number;
|
||||
reopenConversation?: boolean;
|
||||
conversationPending?: boolean;
|
||||
mergeBrazilContacts?: boolean;
|
||||
importContacts?: boolean;
|
||||
importMessages?: boolean;
|
||||
daysLimitImportMessages?: number;
|
||||
};
|
||||
|
||||
export type LocalSettings = {
|
||||
reject_call?: boolean;
|
||||
msg_call?: string;
|
||||
groups_ignore?: boolean;
|
||||
always_online?: boolean;
|
||||
read_messages?: boolean;
|
||||
read_status?: boolean;
|
||||
sync_full_history?: boolean;
|
||||
rejectCall?: boolean;
|
||||
msgCall?: string;
|
||||
groupsIgnore?: boolean;
|
||||
alwaysOnline?: boolean;
|
||||
readMessages?: boolean;
|
||||
readStatus?: boolean;
|
||||
syncFullHistory?: boolean;
|
||||
};
|
||||
|
||||
export type LocalWebsocket = {
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
events?: JsonValue;
|
||||
};
|
||||
|
||||
export type LocalRabbitmq = {
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
events?: JsonValue;
|
||||
};
|
||||
|
||||
export type LocalSqs = {
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
events?: JsonValue;
|
||||
};
|
||||
|
||||
type Session = {
|
||||
@ -110,11 +114,11 @@ export declare namespace wa {
|
||||
url?: string;
|
||||
typebot?: string;
|
||||
expire?: number;
|
||||
keyword_finish?: string;
|
||||
delay_message?: number;
|
||||
unknown_message?: string;
|
||||
listening_from_me?: boolean;
|
||||
sessions?: Session[];
|
||||
keywordFinish?: string;
|
||||
delayMessage?: number;
|
||||
unknownMessage?: string;
|
||||
listeningFromMe?: boolean;
|
||||
sessions?: TypebotSession[];
|
||||
};
|
||||
|
||||
type Proxy = {
|
||||
|
@ -301,7 +301,7 @@ export class ConfigService {
|
||||
DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME || 'evolution',
|
||||
},
|
||||
ENABLED: process.env?.DATABASE_ENABLED === 'true',
|
||||
PROVIDER: process.env.DATABASE_PROVIDER || 'mongodb',
|
||||
PROVIDER: process.env.DATABASE_PROVIDER || 'postgresql',
|
||||
SAVE_DATA: {
|
||||
INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true',
|
||||
NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true',
|
||||
|
@ -1,25 +0,0 @@
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
import { configService, Database } from '../config/env.config';
|
||||
import { Logger } from '../config/logger.config';
|
||||
|
||||
const logger = new Logger('MongoDB');
|
||||
|
||||
const db = configService.get<Database>('DATABASE');
|
||||
export const mongodbServer = (() => {
|
||||
if (db.ENABLED && db.PROVIDER === 'mongodb') {
|
||||
logger.verbose('connecting');
|
||||
const dbs = mongoose.createConnection(db.CONNECTION.URI, {
|
||||
dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api',
|
||||
});
|
||||
logger.verbose('connected in ' + db.CONNECTION.URI);
|
||||
logger.info('ON - dbName: ' + dbs['$dbName']);
|
||||
|
||||
process.on('beforeExit', () => {
|
||||
logger.verbose('instance destroyed');
|
||||
mongodbServer.destroy(true, (error) => logger.error(error));
|
||||
});
|
||||
|
||||
return dbs;
|
||||
}
|
||||
})();
|
@ -3,11 +3,12 @@ import { PrismaClient } from '@prisma/client';
|
||||
import { configService, Database } from '../config/env.config';
|
||||
import { Logger } from '../config/logger.config';
|
||||
|
||||
const logger = new Logger('MongoDB');
|
||||
const logger = new Logger('Prisma');
|
||||
|
||||
const db = configService.get<Database>('DATABASE');
|
||||
|
||||
export const prismaServer = (() => {
|
||||
if (db.ENABLED && db.PROVIDER !== 'mongodb') {
|
||||
if (db.ENABLED) {
|
||||
logger.verbose('connecting');
|
||||
const db = new PrismaClient();
|
||||
|
||||
|
@ -10,6 +10,7 @@ import { initAMQP, initGlobalQueues } from './api/integrations/rabbitmq/libs/amq
|
||||
import { initSQS } from './api/integrations/sqs/libs/sqs.server';
|
||||
import { initIO } from './api/integrations/websocket/libs/socket.server';
|
||||
import { ProviderFiles } from './api/provider/sessions';
|
||||
import { PrismaRepository } from './api/repository/repository.service';
|
||||
import { HttpStatus, router } from './api/routes/index.router';
|
||||
import { waMonitor } from './api/server.module';
|
||||
import { Auth, configService, Cors, HttpServer, Rabbitmq, Sqs, Webhook } from './config/env.config';
|
||||
@ -29,6 +30,8 @@ async function bootstrap() {
|
||||
const providerFiles = new ProviderFiles(configService);
|
||||
await providerFiles.onModuleInit();
|
||||
logger.info('Provider:Files - ON');
|
||||
const prismaRepository = new PrismaRepository(configService);
|
||||
await prismaRepository.onModuleInit();
|
||||
|
||||
app.use(
|
||||
cors({
|
||||
|
@ -1,107 +0,0 @@
|
||||
import {
|
||||
AuthenticationCreds,
|
||||
AuthenticationState,
|
||||
BufferJSON,
|
||||
initAuthCreds,
|
||||
proto,
|
||||
SignalDataTypeMap,
|
||||
} from '@whiskeysockets/baileys';
|
||||
|
||||
import { configService, Database } from '../config/env.config';
|
||||
import { Logger } from '../config/logger.config';
|
||||
import { mongodbServer } from '../libs/mongodb.connect';
|
||||
|
||||
export async function useMultiFileAuthStateMongoDb(
|
||||
coll: string,
|
||||
): Promise<{ state: AuthenticationState; saveCreds: () => Promise<void> }> {
|
||||
const logger = new Logger(useMultiFileAuthStateMongoDb.name);
|
||||
|
||||
const client = mongodbServer.getClient();
|
||||
|
||||
const collection = client
|
||||
.db(configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||
.collection(coll);
|
||||
|
||||
const writeData = async (data: any, key: string): Promise<any> => {
|
||||
try {
|
||||
await client.connect();
|
||||
let msgParsed = JSON.parse(JSON.stringify(data, BufferJSON.replacer));
|
||||
if (Array.isArray(msgParsed)) {
|
||||
msgParsed = {
|
||||
_id: key,
|
||||
content_array: msgParsed,
|
||||
};
|
||||
}
|
||||
return await collection.replaceOne({ _id: key }, msgParsed, {
|
||||
upsert: true,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const readData = async (key: string): Promise<any> => {
|
||||
try {
|
||||
await client.connect();
|
||||
let data = (await collection.findOne({ _id: key })) as any;
|
||||
if (data?.content_array) {
|
||||
data = data.content_array;
|
||||
}
|
||||
const creds = JSON.stringify(data);
|
||||
return JSON.parse(creds, BufferJSON.reviver);
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const removeData = async (key: string) => {
|
||||
try {
|
||||
await client.connect();
|
||||
return await collection.deleteOne({ _id: key });
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds();
|
||||
|
||||
return {
|
||||
state: {
|
||||
creds,
|
||||
keys: {
|
||||
get: async (type, ids: string[]) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const data: { [_: string]: SignalDataTypeMap[type] } = {};
|
||||
await Promise.all(
|
||||
ids.map(async (id) => {
|
||||
let value = await readData(`${type}-${id}`);
|
||||
if (type === 'app-state-sync-key' && value) {
|
||||
value = proto.Message.AppStateSyncKeyData.fromObject(value);
|
||||
}
|
||||
|
||||
data[id] = value;
|
||||
}),
|
||||
);
|
||||
|
||||
return data;
|
||||
},
|
||||
set: async (data: any) => {
|
||||
const tasks: Promise<void>[] = [];
|
||||
for (const category in data) {
|
||||
for (const id in data[category]) {
|
||||
const value = data[category][id];
|
||||
const key = `${category}-${id}`;
|
||||
tasks.push(value ? writeData(value, key) : removeData(key));
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(tasks);
|
||||
},
|
||||
},
|
||||
},
|
||||
saveCreds: async () => {
|
||||
return await writeData(creds, 'creds');
|
||||
},
|
||||
};
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { BufferJSON, initAuthCreds, WAProto as proto } from '@whiskeysockets/baileys';
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
import { INSTANCE_DIR } from '../config/path.config';
|
||||
import { prismaServer } from '../libs/prisma.connect';
|
||||
|
||||
const prisma = prismaServer;
|
||||
|
||||
const fixFileName = (file) => {
|
||||
if (!file) {
|
||||
@ -28,8 +30,16 @@ export async function saveKey(sessionId, keyJson) {
|
||||
const jaExiste = await keyExists(sessionId);
|
||||
try {
|
||||
if (!jaExiste)
|
||||
return await prisma.session.create({ data: { sessionId: sessionId, creds: JSON.stringify(keyJson) } as any });
|
||||
await prisma.session.update({ where: { sessionId: sessionId }, data: { creds: JSON.stringify(keyJson) } });
|
||||
return await prisma.session.create({
|
||||
data: {
|
||||
sessionId: sessionId,
|
||||
creds: JSON.stringify(keyJson),
|
||||
},
|
||||
});
|
||||
await prisma.session.update({
|
||||
where: { sessionId: sessionId },
|
||||
data: { creds: JSON.stringify(keyJson) },
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(`${error}`);
|
||||
return null;
|
||||
@ -68,7 +78,7 @@ async function fileExists(file) {
|
||||
}
|
||||
|
||||
export default async function useMultiFileAuthStatePrisma(sessionId) {
|
||||
const localFolder = path.join(process.cwd(), 'sessions', sessionId);
|
||||
const localFolder = path.join(INSTANCE_DIR, sessionId);
|
||||
const localFile = (key) => path.join(localFolder, fixFileName(key) + '.json');
|
||||
await fs.mkdir(localFolder, { recursive: true });
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user