diff --git a/Dockerfile b/Dockerfile index 605785eb..ac814973 100644 --- a/Dockerfile +++ b/Dockerfile @@ -155,8 +155,6 @@ ENV CACHE_REDIS_SAVE_INSTANCES=false ENV CACHE_LOCAL_ENABLED=false ENV CACHE_LOCAL_TTL=604800 -ENV AUTHENTICATION_TYPE=apikey - ENV AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976 ENV AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b164fd30..fa80872f 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -39,15 +39,16 @@ model Instance { connectionStatus InstanceConnectionStatus @default(open) ownerJid String? @db.VarChar(100) profilePicUrl String? @db.VarChar(500) + integration String? @db.VarChar(100) + number String? @db.VarChar(100) + token String? @unique @db.VarChar(255) createdAt DateTime? @default(now()) @db.Date updatedAt DateTime? @updatedAt @db.Date - Auth Auth? Chat Chat[] Contact Contact[] Message Message[] Webhook Webhook? Chatwoot Chatwoot? - Integration Integration? Label Label[] Proxy Proxy? Setting Setting? @@ -68,15 +69,6 @@ model Session { Instance Instance @relation(fields: [sessionId], references: [id], onDelete: Cascade) } -model Auth { - id Int @id @default(autoincrement()) - apikey String @unique - createdAt DateTime? @default(now()) @db.Date - updatedAt DateTime? @updatedAt @db.Date - Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade) - instanceId String @unique -} - model Chat { id Int @id @default(autoincrement()) remoteJid String @db.VarChar(100) @@ -171,17 +163,6 @@ model Chatwoot { instanceId String @unique } -model Integration { - id Int @id @default(autoincrement()) - integration String @db.VarChar(100) - number String? @db.VarChar(100) - token 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 Label { id Int @id @default(autoincrement()) labelId String? @unique @db.VarChar(100) diff --git a/src/api/controllers/instance.controller.ts b/src/api/controllers/instance.controller.ts index d5fc5c45..03614e88 100644 --- a/src/api/controllers/instance.controller.ts +++ b/src/api/controllers/instance.controller.ts @@ -19,7 +19,6 @@ import { AuthService } from '../services/auth.service'; import { CacheService } from '../services/cache.service'; import { BaileysStartupService } from '../services/channels/whatsapp.baileys.service'; import { BusinessStartupService } from '../services/channels/whatsapp.business.service'; -import { IntegrationService } from '../services/integration.service'; import { WAMonitoringService } from '../services/monitor.service'; import { SettingsService } from '../services/settings.service'; import { WebhookService } from '../services/webhook.service'; @@ -40,7 +39,6 @@ export class InstanceController { private readonly rabbitmqService: RabbitmqService, private readonly sqsService: SqsService, private readonly typebotService: TypebotService, - private readonly integrationService: IntegrationService, private readonly proxyService: ProxyController, private readonly cache: CacheService, private readonly chatwootCache: CacheService, @@ -125,10 +123,17 @@ export class InstanceController { const instanceId = v4(); - await this.waMonitor.saveInstance({ instanceId, integration, instanceName, token, number }); + const hash = await this.authService.generateHash(token); - instance.instanceName = instanceName; - instance.instanceId = instanceId; + await this.waMonitor.saveInstance({ instanceId, integration, instanceName, hash, number }); + + instance.setInstance({ + instanceName, + instanceId, + integration, + token: hash, + number, + }); instance.sendDataWebhook(Events.INSTANCE_CREATE, { instanceName, @@ -138,14 +143,6 @@ export class InstanceController { this.waMonitor.waInstances[instance.instanceName] = instance; this.waMonitor.delInstanceTime(instance.instanceName); - const hash = await this.authService.generateHash( - { - instanceName: instance.instanceName, - instanceId: instanceId, - }, - token, - ); - let getWebhookEvents: string[]; if (webhook) { @@ -412,11 +409,6 @@ export class InstanceController { accessTokenWaBusiness = this.configService.get('WA_BUSINESS').TOKEN_WEBHOOK; } - this.integrationService.create(instance, { - integration, - number, - token, - }); if (!chatwootAccountId || !chatwootToken || !chatwootUrl) { let getQrcode: wa.QrCode; @@ -659,17 +651,14 @@ export class InstanceController { let arrayReturn = false; if (env.KEY !== key) { - const instanceByKey = await this.prismaRepository.auth.findUnique({ + const instanceByKey = await this.prismaRepository.instance.findUnique({ where: { - apikey: key, - }, - include: { - Instance: true, + token: key, }, }); if (instanceByKey) { - name = instanceByKey.Instance.name; + name = instanceByKey.name; arrayReturn = true; } else { throw new UnauthorizedException(); diff --git a/src/api/dto/integration.dto.ts b/src/api/dto/integration.dto.ts deleted file mode 100644 index a4cb67a0..00000000 --- a/src/api/dto/integration.dto.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class IntegrationDto { - integration: string; - number: string; - token: string; -} diff --git a/src/api/guards/auth.guard.ts b/src/api/guards/auth.guard.ts index cf4f1938..a2d665d2 100644 --- a/src/api/guards/auth.guard.ts +++ b/src/api/guards/auth.guard.ts @@ -30,15 +30,14 @@ async function apikey(req: Request, _: Response, next: NextFunction) { if (param?.instanceName) { const instance = await prismaRepository.instance.findUnique({ where: { name: param.instanceName }, - include: { Auth: true }, }); - if (instance.Auth?.apikey === key) { + if (instance.token === key) { return next(); } } else { if (req.originalUrl.includes('/instance/fetchInstances') && db.ENABLED) { - const instanceByKey = await prismaRepository.auth.findFirst({ - where: { apikey: key }, + const instanceByKey = await prismaRepository.instance.findFirst({ + where: { token: key }, }); if (instanceByKey) { return next(); diff --git a/src/api/server.module.ts b/src/api/server.module.ts index f3d6ae9f..cb117883 100644 --- a/src/api/server.module.ts +++ b/src/api/server.module.ts @@ -24,7 +24,6 @@ import { ProviderFiles } from './provider/sessions'; import { PrismaRepository } from './repository/repository.service'; import { AuthService } from './services/auth.service'; import { CacheService } from './services/cache.service'; -import { IntegrationService } from './services/integration.service'; import { WAMonitoringService } from './services/monitor.service'; import { ProxyService } from './services/proxy.service'; import { SettingsService } from './services/settings.service'; @@ -73,8 +72,6 @@ export const rabbitmqController = new RabbitmqController(rabbitmqService); const sqsService = new SqsService(waMonitor); export const sqsController = new SqsController(sqsService); -const integrationService = new IntegrationService(waMonitor); - const chatwootService = new ChatwootService(waMonitor, configService, prismaRepository, chatwootCache); export const chatwootController = new ChatwootController(chatwootService, configService, prismaRepository); @@ -94,7 +91,6 @@ export const instanceController = new InstanceController( rabbitmqService, sqsService, typebotService, - integrationService, proxyController, cache, chatwootCache, diff --git a/src/api/services/auth.service.ts b/src/api/services/auth.service.ts index deb702ec..f2bce1f7 100644 --- a/src/api/services/auth.service.ts +++ b/src/api/services/auth.service.ts @@ -3,7 +3,6 @@ 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 { PrismaRepository } from '../repository/repository.service'; import { WAMonitoringService } from './monitor.service'; @@ -16,35 +15,16 @@ export class AuthService { private readonly logger = new Logger(AuthService.name); - private async apikey(instance: InstanceDto, token?: string) { + private async apikey(token?: string) { const apikey = token ? token : v4().toUpperCase(); - const db = this.configService.get('DATABASE'); - - if (db.ENABLED) { - try { - await this.prismaRepository.auth.create({ - data: { - apikey: apikey, - instanceId: instance.instanceId, - }, - }); - - 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) { const instances = await this.waMonitor.instanceInfo(); - const instance = instances.find((instance) => instance.instance.apikey === token); + const instance = instances.find((instance) => instance.instance.token === token); if (instance) { throw new BadRequestException('Token already exists'); @@ -53,7 +33,8 @@ export class AuthService { return true; } - public async generateHash(instance: InstanceDto, token?: string) { - return (await this.apikey(instance, token)) as { apikey: string }; + public async generateHash(token?: string) { + const hash = await this.apikey(token); + return hash; } } diff --git a/src/api/services/channel.service.ts b/src/api/services/channel.service.ts index d147dc8c..b69bf01a 100644 --- a/src/api/services/channel.service.ts +++ b/src/api/services/channel.service.ts @@ -23,7 +23,7 @@ import { import { Logger } from '../../config/logger.config'; import { ROOT_DIR } from '../../config/path.config'; import { NotFoundException } from '../../exceptions'; -import { IntegrationDto } from '../dto/integration.dto'; +import { InstanceDto } from '../dto/instance.dto'; import { ProxyDto } from '../dto/proxy.dto'; import { SettingsDto } from '../dto/settings.dto'; import { WebhookDto } from '../dto/webhook.dto'; @@ -61,7 +61,6 @@ export class ChannelStartupService { public readonly localSqs: wa.LocalSqs = {}; public readonly localTypebot: wa.LocalTypebot = {}; public readonly localProxy: wa.LocalProxy = {}; - public readonly localIntegration: wa.LocalIntegration = {}; public readonly localSettings: wa.LocalSettings = {}; public readonly storePath = join(ROOT_DIR, 'store'); @@ -74,14 +73,13 @@ export class ChannelStartupService { public typebotService = new TypebotService(waMonitor, this.configService, this.eventEmitter); - public set instanceName(name: string) { - this.logger.setInstance(name); + public setInstance(instance: InstanceDto) { + this.instance.name = instance.instanceName; + this.instance.id = instance.instanceId; + this.instance.integration = instance.integration; + this.instance.number = instance.number; + this.instance.token = instance.token; - if (!name) { - this.instance.name = v4(); - return; - } - this.instance.name = name; this.sendDataWebhook(Events.STATUS_INSTANCE, { instance: this.instance.name, status: 'created', @@ -99,6 +97,16 @@ export class ChannelStartupService { } } + public set instanceName(name: string) { + this.logger.setInstance(name); + + if (!name) { + this.instance.name = v4(); + return; + } + this.instance.name = name; + } + public get instanceName() { return this.instance.name; } @@ -115,70 +123,34 @@ export class ChannelStartupService { return this.instance.id; } + public set integration(integration: string) { + this.instance.integration = integration; + } + + public get integration() { + return this.instance.integration; + } + + public set number(number: string) { + this.instance.number = number; + } + + public get number() { + return this.instance.number; + } + + public set token(token: string) { + this.instance.token = token; + } + + public get token() { + return this.instance.token; + } + public get wuid() { return this.instance.wuid; } - public async loadIntegration() { - const data = await this.prismaRepository.integration.findUnique({ - where: { - instanceId: this.instanceId, - }, - }); - - this.localIntegration.integration = data?.integration; - - this.localIntegration.number = data?.number; - - this.localIntegration.token = data?.token; - } - - public async setIntegration(data: IntegrationDto) { - 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, - }, - }); - - Object.assign(this.localIntegration, data); - } - - public async findIntegration() { - let data; - - data = await this.prismaRepository.integration.findUnique({ - where: { - instanceId: this.instanceId, - }, - }); - - if (!data) { - await this.prismaRepository.integration.create({ - data: { - integration: 'WHATSAPP-BAILEYS', - number: '', - token: '', - instanceId: this.instanceId, - }, - }); - data = { integration: 'WHATSAPP-BAILEYS', number: '', token: '' }; - } - - return data; - } - public async loadSettings() { const data = await this.prismaRepository.setting.findUnique({ where: { @@ -650,12 +622,8 @@ export class ChannelStartupService { const now = localISOTime; const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; - const tokenStore = await this.prismaRepository.auth.findFirst({ - where: { - instanceId: this.instanceId, - }, - }); - const instanceApikey = tokenStore?.apikey || 'Apikey not found'; + + const instanceApikey = this.token || 'Apikey not found'; if (rabbitmqEnabled) { const amqp = getAMQP(); diff --git a/src/api/services/channels/whatsapp.baileys.service.ts b/src/api/services/channels/whatsapp.baileys.service.ts index 9683bea3..dd598034 100644 --- a/src/api/services/channels/whatsapp.baileys.service.ts +++ b/src/api/services/channels/whatsapp.baileys.service.ts @@ -26,7 +26,6 @@ import makeWASocket, { ParticipantAction, prepareWAMessageMedia, proto, - useMultiFileAuthState, UserFacingSocketConfig, WABrowserDescription, WAMediaUpload, @@ -462,19 +461,17 @@ export class BaileysStartupService extends ChannelStartupService { const provider = this.configService.get('PROVIDER'); if (provider?.ENABLED) { - return await this.authStateProvider.authStateProvider(this.instance.name); + return await this.authStateProvider.authStateProvider(this.instance.id); } if (cache?.REDIS.ENABLED && cache?.REDIS.SAVE_INSTANCES) { this.logger.info('Redis enabled'); - return await useMultiFileAuthStateRedisDb(this.instance.name, this.cache); + return await useMultiFileAuthStateRedisDb(this.instance.id, this.cache); } if (db.SAVE_DATA.INSTANCE && db.ENABLED) { - return await useMultiFileAuthStatePrisma(this.instanceId); + return await useMultiFileAuthStatePrisma(this.instance.id); } - - return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); } public async connectToWhatsapp(number?: string): Promise { diff --git a/src/api/services/channels/whatsapp.business.service.ts b/src/api/services/channels/whatsapp.business.service.ts index 72584b66..274a8a94 100644 --- a/src/api/services/channels/whatsapp.business.service.ts +++ b/src/api/services/channels/whatsapp.business.service.ts @@ -70,12 +70,10 @@ export class BusinessStartupService extends ChannelStartupService { private async post(message: any, params: string) { try { - const integration = await this.findIntegration(); - let urlServer = this.configService.get('WA_BUSINESS').URL; const version = this.configService.get('WA_BUSINESS').VERSION; - urlServer = `${urlServer}/${version}/${integration.number}/${params}`; - const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${integration.token}` }; + urlServer = `${urlServer}/${version}/${this.number}/${params}`; + const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` }; const result = await axios.post(urlServer, message, { headers }); return result.data; } catch (e) { @@ -150,13 +148,11 @@ export class BusinessStartupService extends ChannelStartupService { private async downloadMediaMessage(message: any) { try { - const integration = await this.findIntegration(); - const id = message[message.type].id; let urlServer = this.configService.get('WA_BUSINESS').URL; const version = this.configService.get('WA_BUSINESS').VERSION; urlServer = `${urlServer}/${version}/${id}`; - const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${integration.token}` }; + const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` }; let result = await axios.get(urlServer, { headers }); result = await axios.get(result.data.url, { headers, responseType: 'arraybuffer' }); return result.data; @@ -851,8 +847,6 @@ export class BusinessStartupService extends ChannelStartupService { } private async getIdMedia(mediaMessage: any) { - const integration = await this.findIntegration(); - const formData = new FormData(); const fileBuffer = await fs.readFile(mediaMessage.media); @@ -861,9 +855,9 @@ export class BusinessStartupService extends ChannelStartupService { formData.append('file', fileBlob); formData.append('typeFile', mediaMessage.mimetype); formData.append('messaging_product', 'whatsapp'); - const headers = { Authorization: `Bearer ${integration.token}` }; + const headers = { Authorization: `Bearer ${this.token}` }; const res = await axios.post( - process.env.API_URL + '/' + process.env.VERSION + '/' + integration.number + '/media', + process.env.API_URL + '/' + process.env.VERSION + '/' + this.number + '/media', formData, { headers }, ); diff --git a/src/api/services/integration.service.ts b/src/api/services/integration.service.ts deleted file mode 100644 index 0b1e4182..00000000 --- a/src/api/services/integration.service.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Integration } from '@prisma/client'; - -import { Logger } from '../../config/logger.config'; -import { InstanceDto } from '../dto/instance.dto'; -import { IntegrationDto } from '../dto/integration.dto'; -import { WAMonitoringService } from './monitor.service'; - -export class IntegrationService { - constructor(private readonly waMonitor: WAMonitoringService) {} - - private readonly logger = new Logger(IntegrationService.name); - - public create(instance: InstanceDto, data: IntegrationDto) { - this.waMonitor.waInstances[instance.instanceName].setIntegration(data); - - return { integration: { ...instance, integration: data } }; - } - - public async find(instance: InstanceDto): Promise { - try { - const result = await this.waMonitor.waInstances[instance.instanceName].findIntegration(); - - if (Object.keys(result).length === 0) { - this.create(instance, { integration: 'WHATSAPP-BAILEYS', number: '', token: '' }); - return null; - } - - return result; - } catch (error) { - return null; - } - } -} diff --git a/src/api/services/monitor.service.ts b/src/api/services/monitor.service.ts index f5136377..4136ca95 100644 --- a/src/api/services/monitor.service.ts +++ b/src/api/services/monitor.service.ts @@ -1,6 +1,6 @@ import { execSync } from 'child_process'; import EventEmitter2 from 'eventemitter2'; -import { existsSync, mkdirSync, opendirSync, readdirSync, rmSync, writeFileSync } from 'fs'; +import { opendirSync, readdirSync, rmSync } from 'fs'; import { join } from 'path'; import { @@ -16,6 +16,7 @@ import { import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config'; import { NotFoundException } from '../../exceptions'; +import { InstanceDto } from '../dto/instance.dto'; import { ProviderFiles } from '../provider/sessions'; import { PrismaRepository } from '../repository/repository.service'; import { Integration } from '../types/wa.types'; @@ -54,7 +55,7 @@ export class WAMonitoringService { setTimeout(async () => { if (this.waInstances[instance]?.connectionStatus?.state !== 'open') { if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') { - if ((await this.waInstances[instance].findIntegration()).integration === Integration.WHATSAPP_BAILEYS) { + if ((await this.waInstances[instance].integration) === Integration.WHATSAPP_BAILEYS) { await this.waInstances[instance]?.client?.logout('Log out instance: ' + instance); this.waInstances[instance]?.client?.ws?.close(); this.waInstances[instance]?.client?.end(undefined); @@ -94,16 +95,22 @@ export class WAMonitoringService { } } - const findIntegration = await this.waInstances[key].findIntegration(); + const findIntegration = { + integration: this.waInstances[key].integration, + token: this.waInstances[key].token, + number: this.waInstances[key].number, + }; let integration: any; - if (findIntegration) { + if (this.waInstances[key].integration === Integration.WHATSAPP_BUSINESS) { integration = { ...findIntegration, webhookWaBusiness: `${urlServer}/webhook/whatsapp/${encodeURIComponent(key)}`, }; } + const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; + if (value.connectionStatus.state === 'open') { const instanceData = { instance: { @@ -117,14 +124,10 @@ export class WAMonitoringService { }, }; - if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { + if (expose) { instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - instanceData.instance['apikey'] = ( - await this.prismaRepository.auth.findFirst({ - where: { instanceId: this.waInstances[key].instanceId }, - }) - )?.apikey; + instanceData.instance['token'] = this.waInstances[key].token; if (this.configService.get('CHATWOOT').ENABLED) instanceData.instance['chatwoot'] = chatwoot; @@ -141,14 +144,10 @@ export class WAMonitoringService { }, }; - if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { + if (expose) { instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - instanceData.instance['apikey'] = ( - await this.prismaRepository.auth.findFirst({ - where: { instanceId: this.waInstances[key].instanceId }, - }) - )?.apikey; + instanceData.instance['token'] = this.waInstances[key].token; if (this.configService.get('CHATWOOT').ENABLED) instanceData.instance['chatwoot'] = chatwoot; @@ -174,9 +173,7 @@ export class WAMonitoringService { throw new NotFoundException(`Instance "${instanceId}" not found`); } } else if (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); + instanceName = await this.prismaRepository.instance.findFirst({ where: { number } }).then((r) => r?.name); if (!instanceName) { throw new NotFoundException(`Instance "${number}" not found`); } @@ -214,33 +211,11 @@ export class WAMonitoringService { if (this.providerSession?.ENABLED) { await this.providerFiles.removeSession(instanceName); } - rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); } - public async cleaningStoreFiles(instanceName: string) { - if (!this.db.ENABLED) { - if (this.providerSession?.ENABLED) { - await this.providerFiles.removeSession(instanceName); - } - rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); + public async cleaningStoreData(instanceName: string) { + execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`); - execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`); - - execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`); - execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`); - execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'proxy', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'rabbitmq', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'typebot', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'websocket', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`); - execSync(`rm -rf ${join(STORE_DIR, 'labels', instanceName + '*')}`); - - return; - } const instance = await this.prismaRepository.instance.findFirst({ where: { name: instanceName }, }); @@ -254,8 +229,6 @@ export class WAMonitoringService { await this.prismaRepository.messageUpdate.deleteMany({ where: { instanceId: instance.id } }); await this.prismaRepository.message.deleteMany({ where: { instanceId: instance.id } }); - await this.prismaRepository.integration.deleteMany({ where: { instanceId: instance.id } }); - await this.prismaRepository.auth.deleteMany({ where: { instanceId: instance.id } }); await this.prismaRepository.webhook.deleteMany({ where: { instanceId: instance.id } }); await this.prismaRepository.chatwoot.deleteMany({ where: { instanceId: instance.id } }); await this.prismaRepository.proxy.deleteMany({ where: { instanceId: instance.id } }); @@ -274,12 +247,10 @@ export class WAMonitoringService { try { if (this.providerSession.ENABLED) { await this.loadInstancesFromProvider(); - } else if (this.redis.REDIS.ENABLED && this.redis.REDIS.SAVE_INSTANCES) { - await this.loadInstancesFromRedis(); } else if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { await this.loadInstancesFromDatabasePostgres(); - } else { - await this.loadInstancesFromFiles(); + } else if (this.redis.REDIS.ENABLED && this.redis.REDIS.SAVE_INSTANCES) { + await this.loadInstancesFromRedis(); } } catch (error) { this.logger.error(error); @@ -288,41 +259,27 @@ export class WAMonitoringService { public async saveInstance(data: any) { try { - const msgParsed = JSON.parse(JSON.stringify(data)); - if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) { + if (this.db.ENABLED) { await this.prismaRepository.instance.create({ data: { id: data.instanceId, name: data.instanceName, connectionStatus: 'close', - }, - }); - - await this.prismaRepository.integration.create({ - data: { - instanceId: data.instanceId, - integration: data.integration, number: data.number, - token: data.token, + integration: data.integration || Integration.WHATSAPP_BAILEYS, + token: data.hash, }, }); - } else { - const path = join(INSTANCE_DIR, data.instanceName); - if (!existsSync(path)) mkdirSync(path, { recursive: true }); - writeFileSync(path + '/integration.json', JSON.stringify(msgParsed)); } } catch (error) { this.logger.error(error); } } - private async setInstance(id: string, name: string) { - const integration = await this.prismaRepository.integration.findUnique({ - where: { instanceId: id }, - }); - + private async setInstance(instanceData: InstanceDto) { let instance: BaileysStartupService | BusinessStartupService; - if (integration && integration.integration === Integration.WHATSAPP_BUSINESS) { + + if (instanceData.integration && instanceData.integration === Integration.WHATSAPP_BUSINESS) { instance = new BusinessStartupService( this.configService, this.eventEmitter, @@ -333,8 +290,13 @@ export class WAMonitoringService { this.providerFiles, ); - instance.instanceName = name; - instance.instanceId = id; + instance.setInstance({ + instanceId: instanceData.instanceId, + instanceName: instanceData.instanceName, + integration: instanceData.integration, + token: instanceData.token, + number: instanceData.number, + }); } else { instance = new BaileysStartupService( this.configService, @@ -346,24 +308,45 @@ export class WAMonitoringService { this.providerFiles, ); - instance.instanceName = name; - instance.instanceId = id; - - if (!integration) { - await instance.setIntegration({ integration: Integration.WHATSAPP_BAILEYS, number: '', token: '' }); - } + instance.setInstance({ + instanceId: instanceData.instanceId, + instanceName: instanceData.instanceName, + integration: instanceData.integration, + token: instanceData.token, + number: instanceData.number, + }); } await instance.connectToWhatsapp(); - this.waInstances[name] = instance; + this.waInstances[instanceData.instanceName] = instance; } private async loadInstancesFromRedis() { const keys = await this.cache.keys(); if (keys?.length > 0) { - await Promise.all(keys.map((k) => this.setInstance(k.split(':')[1], k.split(':')[2]))); + await Promise.all( + keys.map(async (k) => { + const instanceData = await this.prismaRepository.instance.findUnique({ + where: { id: k.split(':')[1] }, + }); + + if (!instanceData) { + return; + } + + const instance = { + instanceId: k.split(':')[1], + instanceName: k.split(':')[2], + integration: instanceData.integration, + token: instanceData.token, + number: instanceData.number, + }; + + this.setInstance(instance); + }), + ); } } @@ -374,7 +357,17 @@ export class WAMonitoringService { return; } - await Promise.all(instances.map(async (instance) => this.setInstance(instance.id, instance.name))); + await Promise.all( + instances.map(async (instance) => { + this.setInstance({ + instanceId: instance.id, + instanceName: instance.name, + integration: instance.integration, + token: instance.token, + number: instance.number, + }); + }), + ); } private async loadInstancesFromProvider() { @@ -384,28 +377,18 @@ export class WAMonitoringService { return; } - await Promise.all(instances?.data?.map(async (instanceName: string) => this.setInstance('', instanceName))); - } - - private async loadInstancesFromFiles() { - const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); - const instanceDirs = []; - - for await (const dirent of dir) { - if (dirent.isDirectory()) { - instanceDirs.push(dirent.name); - } - } - await Promise.all( - instanceDirs.map(async (instanceName) => { - const files = readdirSync(join(INSTANCE_DIR, instanceName), { encoding: 'utf-8' }); + instances?.data?.map(async (instanceId: string) => { + const instance = await this.prismaRepository.instance.findUnique({ + where: { id: instanceId }, + }); - if (files.length === 0) { - rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true }); - } else { - await this.setInstance('', instanceName); - } + this.setInstance({ + instanceId: instance.id, + instanceName: instance.name, + integration: instance.integration, + token: instance.token, + }); }), ); } @@ -420,7 +403,7 @@ export class WAMonitoringService { try { this.cleaningUp(instanceName); - this.cleaningStoreFiles(instanceName); + this.cleaningStoreData(instanceName); } finally { this.logger.warn(`Instance "${instanceName}" - REMOVED`); } diff --git a/src/api/types/wa.types.ts b/src/api/types/wa.types.ts index b707cb40..6514c735 100644 --- a/src/api/types/wa.types.ts +++ b/src/api/types/wa.types.ts @@ -42,6 +42,7 @@ export declare namespace wa { base64?: string; code?: string; }; + export type Instance = { id?: string; qrcode?: QrCode; @@ -51,6 +52,9 @@ export declare namespace wa { wuid?: string; profileName?: string; profilePictureUrl?: string; + token?: string; + number?: string; + integration?: string; }; export type LocalWebHook = { @@ -130,12 +134,6 @@ export declare namespace wa { password?: string; }; - export type LocalIntegration = { - integration?: string; - number?: string; - token?: string; - }; - export type StateConnection = { instance?: string; state?: WAConnectionState | 'refused';