diff --git a/.gitignore b/.gitignore index 7465bfe4..bbca3a39 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ lerna-debug.log* !/instances/.gitkeep /test/ /src/env.yml + +/temp/* diff --git a/package.json b/package.json index e99b05a9..5c9525a5 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "homepage": "https://github.com/DavidsonGomes/evolution-api#readme", "dependencies": { "@adiwajshing/keyed-db": "^0.2.4", - "@whiskeysockets/baileys": "^6.3.0", "@ffmpeg-installer/ffmpeg": "^1.1.0", "@hapi/boom": "^10.0.1", + "@whiskeysockets/baileys": "^6.3.0", "axios": "^1.3.5", "class-validator": "^0.13.2", "compression": "^1.7.4", diff --git a/src/config/logger.config.ts b/src/config/logger.config.ts index d028b931..26e4c38f 100644 --- a/src/config/logger.config.ts +++ b/src/config/logger.config.ts @@ -67,7 +67,6 @@ export class Logger { this.configService.get('LOG').LEVEL.forEach((level) => types.push(Type[level])); const typeValue = typeof value; - if (types.includes(type)) { if (configService.get('LOG').COLOR) { console.log( diff --git a/src/db/redis.client.ts b/src/db/redis.client.ts index c64a0072..f5725ae0 100644 --- a/src/db/redis.client.ts +++ b/src/db/redis.client.ts @@ -5,8 +5,11 @@ import { Redis } from '../config/env.config'; export class RedisCache { constructor() { + this.logger.verbose('instance created'); process.on('beforeExit', async () => { + this.logger.verbose('instance destroyed'); if (this.statusConnection) { + this.logger.verbose('instance disconnect'); await this.client.disconnect(); } }); @@ -17,11 +20,14 @@ export class RedisCache { private redisEnv: Redis; public set reference(reference: string) { + this.logger.verbose('set reference: ' + reference); this.instanceName = reference; } public async connect(redisEnv: Redis) { + this.logger.verbose('connecting'); this.client = createClient({ url: redisEnv.URI }); + this.logger.verbose('connected in ' + redisEnv.URI); await this.client.connect(); this.statusConnection = true; this.redisEnv = redisEnv; @@ -32,6 +38,7 @@ export class RedisCache { public async instanceKeys(): Promise { try { + this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*'); return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']); } catch (error) { this.logger.error(error); @@ -40,13 +47,16 @@ export class RedisCache { public async keyExists(key?: string) { if (key) { + this.logger.verbose('keyExists: ' + key); return !!(await this.instanceKeys()).find((i) => i === key); } + this.logger.verbose('keyExists: ' + this.instanceName); return !!(await this.instanceKeys()).find((i) => i === this.instanceName); } public async writeData(field: string, data: any) { try { + this.logger.verbose('writeData: ' + field); const json = JSON.stringify(data, BufferJSON.replacer); return await this.client.hSet( @@ -61,14 +71,19 @@ export class RedisCache { public async readData(field: string) { try { + this.logger.verbose('readData: ' + field); const data = await this.client.hGet( this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, ); if (data) { + this.logger.verbose('readData: ' + field + ' success'); return JSON.parse(data, BufferJSON.reviver); } + + this.logger.verbose('readData: ' + field + ' not found'); + return null; } catch (error) { this.logger.error(error); } @@ -76,6 +91,7 @@ export class RedisCache { public async removeData(field: string) { try { + this.logger.verbose('removeData: ' + field); return await this.client.hDel( this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, @@ -87,6 +103,7 @@ export class RedisCache { public async delAll(hash?: string) { try { + this.logger.verbose('instance delAll: ' + hash); return await this.client.del( hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName, ); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index b6024044..6d5c96ef 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -126,6 +126,7 @@ export class WAStartupService { private readonly repository: RepositoryBroker, private readonly cache: RedisCache, ) { + this.logger.verbose('WAStartupService initialized'); this.cleanStore(); this.instance.qrcode = { count: 0 }; } @@ -148,6 +149,7 @@ export class WAStartupService { return; } this.instance.name = name; + this.logger.verbose(`Instance '${this.instance.name}' initialized`); this.sendDataWebhook(Events.STATUS_INSTANCE, { instance: this.instance.name, status: 'created', @@ -163,9 +165,12 @@ export class WAStartupService { } public async getProfileName() { + this.logger.verbose('Getting profile name'); let profileName = this.client.user?.name ?? this.client.user?.verifiedName; if (!profileName) { + this.logger.verbose('Profile name not found, trying to get from database'); if (this.configService.get('DATABASE').ENABLED) { + this.logger.verbose('Database enabled, trying to get from database'); const collection = dbserver .getClient() .db( @@ -175,10 +180,12 @@ export class WAStartupService { .collection(this.instanceName); const data = await collection.findOne({ _id: 'creds' }); if (data) { + this.logger.verbose('Profile name found in database'); const creds = JSON.parse(JSON.stringify(data), BufferJSON.reviver); profileName = creds.me?.name || creds.me?.verifiedName; } } else if (existsSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'))) { + this.logger.verbose('Profile name found in file'); const creds = JSON.parse( readFileSync(join(INSTANCE_DIR, this.instanceName, 'creds.json'), { encoding: 'utf-8', @@ -187,20 +194,26 @@ export class WAStartupService { profileName = creds.me?.name || creds.me?.verifiedName; } } + + this.logger.verbose(`Profile name: ${profileName}`); return profileName; } public async getProfileStatus() { + this.logger.verbose('Getting profile status'); const status = await this.client.fetchStatus(this.instance.wuid); + this.logger.verbose(`Profile status: ${status.status}`); return status.status; } public get profilePictureUrl() { + this.logger.verbose('Getting profile picture url'); return this.instance.profilePictureUrl; } public get qrCode(): wa.QrCode { + this.logger.verbose('Getting qrcode'); return { code: this.instance.qrcode?.code, base64: this.instance.qrcode?.base64, @@ -208,20 +221,44 @@ export class WAStartupService { } private async loadWebhook() { + this.logger.verbose('Loading webhook'); const data = await this.repository.webhook.find(this.instanceName); this.localWebhook.url = data?.url; + this.logger.verbose(`Webhook url: ${this.localWebhook.url}`); + this.localWebhook.enabled = data?.enabled; + this.logger.verbose(`Webhook enabled: ${this.localWebhook.enabled}`); + 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.logger.verbose('Webhook loaded'); } public async setWebhook(data: WebhookRaw) { + this.logger.verbose('Setting webhook'); await this.repository.webhook.create(data, this.instanceName); + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); Object.assign(this.localWebhook, data); + this.logger.verbose('Webhook set'); } public async findWebhook() { - return await this.repository.webhook.find(this.instanceName); + this.logger.verbose('Finding webhook'); + const data = await this.repository.webhook.find(this.instanceName); + + if (!data) { + this.logger.verbose('Webhook not found'); + throw new NotFoundException('Webhook not found'); + } + + this.logger.verbose(`Webhook url: ${data.url}`); + this.logger.verbose(`Webhook events: ${data.events}`); + return data; } public async sendDataWebhook(event: Events, data: T, local = true) { @@ -474,6 +511,13 @@ export class WAStartupService { this.instance.wuid, )}/*.json`, ); + this.logger.verbose( + `Cleaned ${join( + this.storePath, + key.toLowerCase().replace('_', '-'), + this.instance.wuid, + )}/*.json`, + ); } } } catch (error) {} @@ -1189,12 +1233,13 @@ export class WAStartupService { private async convertToWebP(image: string) { try { let imagePath: string; - const outputPath = `${join(process.cwd(), 'temp', 'sticker.webp')}`; + const timestamp = new Date().getTime(); + const outputPath = `${join(process.cwd(), 'temp', `${timestamp}.webp`)}`; if (isBase64(image)) { const base64Data = image.replace(/^data:image\/(jpeg|png|gif);base64,/, ''); const imageBuffer = Buffer.from(base64Data, 'base64'); - imagePath = `${join(process.cwd(), 'temp', 'temp-sticker.png')}`; + imagePath = `${join(process.cwd(), 'temp', `temp-${timestamp}.png`)}`; await sharp(imageBuffer).toFile(imagePath); } else { const timestamp = new Date().getTime(); @@ -1202,7 +1247,7 @@ export class WAStartupService { const response = await axios.get(url, { responseType: 'arraybuffer' }); const imageBuffer = Buffer.from(response.data, 'binary'); - imagePath = `${join(process.cwd(), 'temp', 'temp-sticker.png')}`; + imagePath = `${join(process.cwd(), 'temp', `temp-${timestamp}.png`)}`; await sharp(imageBuffer).toFile(imagePath); }