diff --git a/.eslintrc.js b/.eslintrc.js index d3545e60..f805da92 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,10 +3,14 @@ module.exports = { parserOptions: { sourceType: 'CommonJS', }, - plugins: ['@typescript-eslint/eslint-plugin'], + plugins: [ + '@typescript-eslint', + 'simple-import-sort', + 'import' + ], extends: [ + 'eslint:recommended', 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', 'plugin:prettier/recommended' ], globals: { @@ -26,7 +30,11 @@ module.exports = { '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': 'error', + 'import/first': 'error', + 'import/no-duplicates': 'error', + 'simple-import-sort/imports': 'error', + 'simple-import-sort/exports': 'error', '@typescript-eslint/ban-types': [ 'error', { diff --git a/.gitignore b/.gitignore index 69d60b7a..2364b077 100644 --- a/.gitignore +++ b/.gitignore @@ -22,12 +22,13 @@ docker-compose.yaml /yarn.lock /package-lock.json -# IDE - VSCode +# IDEs .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json +.nova/* # Prisma /prisma/migrations @@ -40,3 +41,6 @@ docker-compose.yaml /store /temp/* + +.DS_Store +*.DS_Store \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js index 067abea5..f55f3f06 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -2,8 +2,11 @@ module.exports = { semi: true, trailingComma: 'all', singleQuote: true, - printWidth: 90, + printWidth: 120, + arrowParens: 'always', tabWidth: 2, - bracketSameLine: true, - bracketSpacing: true + useTabs: false, + bracketSameLine: false, + bracketSpacing: true, + parser: 'typescript' } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index cf5498ca..ed0b7517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# 1.4.6 (homolog) + +### Fixed + +* Fixed bug of creating new inbox by chatwoot +* When conversation reopens is pending when conversation pending is true +* Added docker-compose file with dockerhub image + # 1.4.5 (2023-07-26 09:32) ### Fixed diff --git a/docker-compose.yaml.example.dockerhub b/docker-compose.yaml.example.dockerhub new file mode 100644 index 00000000..6136997d --- /dev/null +++ b/docker-compose.yaml.example.dockerhub @@ -0,0 +1,28 @@ +version: '3.3' + +services: + api: + container_name: evolution_api + image: davidsongomes/evolution-api:latest + restart: always + ports: + - 8080:8080 + volumes: + - evolution_instances:/evolution/instances + - evolution_store:/evolution/store + networks: + - evolution-net + env_file: + - ./Docker/.env + command: ['node', './dist/src/main.js'] + expose: + - 8080 + +volumes: + evolution_instances: + evolution_store: + +networks: + evolution-net: + external: true + \ No newline at end of file diff --git a/package.json b/package.json index 0ef463d7..f717738c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.5", + "version": "1.4.6", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { @@ -8,7 +8,8 @@ "start": "ts-node --files --transpile-only ./src/main.ts", "start:prod": "bash start.sh", "dev:server": "clear && tsnd --files --transpile-only --respawn --ignore-watch node_modules ./src/main.ts", - "test": "clear && tsnd --files --transpile-only --respawn --ignore-watch node_modules ./test/all.test.ts" + "test": "clear && tsnd --files --transpile-only --respawn --ignore-watch node_modules ./test/all.test.ts", + "lint": "eslint --fix --ext .ts src" }, "repository": { "type": "git", @@ -80,16 +81,19 @@ "@types/express": "^4.17.17", "@types/js-yaml": "^4.0.5", "@types/jsonwebtoken": "^8.5.9", + "@types/mime-types": "^2.1.1", "@types/node": "^18.15.11", "@types/qrcode": "^1.5.0", "@types/qrcode-terminal": "^0.12.0", "@types/uuid": "^8.3.4", - "@typescript-eslint/eslint-plugin": "^5.57.1", - "@typescript-eslint/parser": "^5.57.1", - "eslint": "^8.38.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "eslint": "^8.45.0", "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.5", "eslint-plugin-prettier": "^4.2.1", - "prettier": "^2.8.7", + "eslint-plugin-simple-import-sort": "^10.0.0", + "prettier": "^2.8.8", "ts-node-dev": "^2.0.0", "typescript": "^4.9.5" } diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 78c90ec9..b90141ff 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -1,7 +1,7 @@ +import { isBooleanString } from 'class-validator'; import { readFileSync } from 'fs'; import { load } from 'js-yaml'; import { join } from 'path'; -import { isBooleanString } from 'class-validator'; export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string }; @@ -14,15 +14,7 @@ export type Cors = { export type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; -export type LogLevel = - | 'ERROR' - | 'WARN' - | 'DEBUG' - | 'INFO' - | 'LOG' - | 'VERBOSE' - | 'DARK' - | 'WEBHOOKS'; +export type LogLevel = 'ERROR' | 'WARN' | 'DEBUG' | 'INFO' | 'LOG' | 'VERBOSE' | 'DARK' | 'WEBHOOKS'; export type Log = { LEVEL: LogLevel[]; @@ -156,9 +148,7 @@ export class ConfigService { } private envYaml(): Env { - return load( - readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' }), - ) as Env; + return load(readFileSync(join(process.cwd(), 'src', 'env.yml'), { encoding: 'utf-8' })) as Env; } private envProcess(): Env { @@ -244,8 +234,7 @@ export class ConfigService { CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true', GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true', GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', - GROUP_PARTICIPANTS_UPDATE: - process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', + GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', }, @@ -262,8 +251,7 @@ export class ConfigService { API_KEY: { KEY: process.env.AUTHENTICATION_API_KEY, }, - EXPOSE_IN_FETCH_INSTANCES: - process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', + EXPOSE_IN_FETCH_INSTANCES: process.env?.AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES === 'true', JWT: { EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN) ? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN) diff --git a/src/config/logger.config.ts b/src/config/logger.config.ts index 26e4c38f..a5ca6a23 100644 --- a/src/config/logger.config.ts +++ b/src/config/logger.config.ts @@ -1,6 +1,7 @@ -import { configService, Log } from './env.config'; import dayjs from 'dayjs'; +import { configService, Log } from './env.config'; + const formatDateLog = (timestamp: number) => dayjs(timestamp) .toDate() diff --git a/src/db/db.connect.ts b/src/db/db.connect.ts index 59530b48..b11610c7 100644 --- a/src/db/db.connect.ts +++ b/src/db/db.connect.ts @@ -1,4 +1,5 @@ import mongoose from 'mongoose'; + import { configService, Database } from '../config/env.config'; import { Logger } from '../config/logger.config'; diff --git a/src/db/redis.client.ts b/src/db/redis.client.ts index 50e7efcb..dffeb949 100644 --- a/src/db/redis.client.ts +++ b/src/db/redis.client.ts @@ -1,7 +1,8 @@ import { createClient, RedisClientType } from '@redis/client'; -import { Logger } from '../config/logger.config'; import { BufferJSON } from '@whiskeysockets/baileys'; + import { Redis } from '../config/env.config'; +import { Logger } from '../config/logger.config'; export class RedisCache { constructor() { @@ -59,11 +60,7 @@ export class RedisCache { this.logger.verbose('writeData: ' + field); const json = JSON.stringify(data, BufferJSON.replacer); - return await this.client.hSet( - this.redisEnv.PREFIX_KEY + ':' + this.instanceName, - field, - json, - ); + return await this.client.hSet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, json); } catch (error) { this.logger.error(error); } @@ -72,10 +69,7 @@ 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, - ); + const data = await this.client.hGet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field); if (data) { this.logger.verbose('readData: ' + field + ' success'); @@ -92,10 +86,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, - ); + return await this.client.hDel(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field); } catch (error) { this.logger.error(error); } @@ -104,9 +95,7 @@ export class RedisCache { public async delAll(hash?: string) { try { this.logger.verbose('instance delAll: ' + hash); - const result = await this.client.del( - hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName, - ); + const result = await this.client.del(hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName); return result; } catch (error) { diff --git a/src/main.ts b/src/main.ts index ac66e7b5..b0d2e03e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,18 @@ +import 'express-async-errors'; + +// import * as Sentry from '@sentry/node'; import compression from 'compression'; -import { configService, Cors, HttpServer } from './config/env.config'; import cors from 'cors'; import express, { json, NextFunction, Request, Response, urlencoded } from 'express'; import { join } from 'path'; + +import { configService, Cors, HttpServer } from './config/env.config'; import { onUnexpectedError } from './config/error.config'; import { Logger } from './config/logger.config'; import { ROOT_DIR } from './config/path.config'; -import { waMonitor } from './whatsapp/whatsapp.module'; -import { HttpStatus, router } from './whatsapp/routers/index.router'; -import 'express-async-errors'; import { ServerUP } from './utils/server-up'; -import * as Sentry from '@sentry/node'; +import { HttpStatus, router } from './whatsapp/routers/index.router'; +import { waMonitor } from './whatsapp/whatsapp.module'; function initWA() { waMonitor.loadInstance(); @@ -73,7 +75,7 @@ function bootstrap() { // }); app.use( - (err: Error, req: Request, res: Response, next: NextFunction) => { + (err: Error, req: Request, res: Response) => { if (err) { return res.status(err['status'] || 500).json(err); } @@ -96,9 +98,7 @@ function bootstrap() { ServerUP.app = app; const server = ServerUP[httpServer.TYPE]; - server.listen(httpServer.PORT, () => - logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT), - ); + server.listen(httpServer.PORT, () => logger.log(httpServer.TYPE.toUpperCase() + ' - ON: ' + httpServer.PORT)); initWA(); diff --git a/src/utils/server-up.ts b/src/utils/server-up.ts index 9868efc0..e06caea7 100644 --- a/src/utils/server-up.ts +++ b/src/utils/server-up.ts @@ -1,8 +1,9 @@ import { Express } from 'express'; import { readFileSync } from 'fs'; -import { configService, SslConf } from '../config/env.config'; -import * as https from 'https'; import * as http from 'http'; +import * as https from 'https'; + +import { configService, SslConf } from '../config/env.config'; export class ServerUP { static #app: Express; diff --git a/src/utils/use-multi-file-auth-state-db.ts b/src/utils/use-multi-file-auth-state-db.ts index d0c518da..8b0d76e4 100644 --- a/src/utils/use-multi-file-auth-state-db.ts +++ b/src/utils/use-multi-file-auth-state-db.ts @@ -6,6 +6,7 @@ import { proto, SignalDataTypeMap, } from '@whiskeysockets/baileys'; + import { configService, Database } from '../config/env.config'; import { Logger } from '../config/logger.config'; import { dbserver } from '../db/db.connect'; @@ -24,12 +25,12 @@ export async function useMultiFileAuthStateDb( const writeData = async (data: any, key: string): Promise => { try { await client.connect(); - return await collection.replaceOne( - { _id: key }, - JSON.parse(JSON.stringify(data, BufferJSON.replacer)), - { upsert: true }, - ); - } catch {} + return await collection.replaceOne({ _id: key }, JSON.parse(JSON.stringify(data, BufferJSON.replacer)), { + upsert: true, + }); + } catch (error) { + logger.error(error); + } }; const readData = async (key: string): Promise => { @@ -38,14 +39,18 @@ export async function useMultiFileAuthStateDb( const data = await collection.findOne({ _id: key }); const creds = JSON.stringify(data); return JSON.parse(creds, BufferJSON.reviver); - } catch {} + } catch (error) { + logger.error(error); + } }; const removeData = async (key: string) => { try { await client.connect(); return await collection.deleteOne({ _id: key }); - } catch {} + } catch (error) { + logger.error(error); + } }; const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); diff --git a/src/utils/use-multi-file-auth-state-redis-db.ts b/src/utils/use-multi-file-auth-state-redis-db.ts index c5450ddc..57439ced 100644 --- a/src/utils/use-multi-file-auth-state-redis-db.ts +++ b/src/utils/use-multi-file-auth-state-redis-db.ts @@ -5,9 +5,9 @@ import { proto, SignalDataTypeMap, } from '@whiskeysockets/baileys'; -import { RedisCache } from '../db/redis.client'; + import { Logger } from '../config/logger.config'; -import { Redis } from '../config/env.config'; +import { RedisCache } from '../db/redis.client'; export async function useMultiFileAuthStateRedisDb(cache: RedisCache): Promise<{ state: AuthenticationState; diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index d7e2ac1e..8c1a4667 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -877,23 +877,8 @@ export const chatwootSchema: JSONSchema7 = { reopen_conversation: { type: 'boolean', enum: [true, false] }, conversation_pending: { type: 'boolean', enum: [true, false] }, }, - required: [ - 'enabled', - 'account_id', - 'token', - 'url', - 'sign_msg', - 'reopen_conversation', - 'conversation_pending', - ], - ...isNotEmpty( - 'account_id', - 'token', - 'url', - 'sign_msg', - 'reopen_conversation', - 'conversation_pending', - ), + required: ['enabled', 'account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'], + ...isNotEmpty('account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'), }; export const settingsSchema: JSONSchema7 = { @@ -907,18 +892,6 @@ export const settingsSchema: JSONSchema7 = { read_messages: { type: 'boolean', enum: [true, false] }, read_status: { type: 'boolean', enum: [true, false] }, }, - required: [ - 'reject_call', - 'groups_ignore', - 'always_online', - 'read_messages', - 'read_status', - ], - ...isNotEmpty( - 'reject_call', - 'groups_ignore', - 'always_online', - 'read_messages', - 'read_status', - ), + required: ['reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'], + ...isNotEmpty('reject_call', 'groups_ignore', 'always_online', 'read_messages', 'read_status'), }; diff --git a/src/whatsapp/abstract/abstract.repository.ts b/src/whatsapp/abstract/abstract.repository.ts index a7215383..a5b7a841 100644 --- a/src/whatsapp/abstract/abstract.repository.ts +++ b/src/whatsapp/abstract/abstract.repository.ts @@ -1,5 +1,6 @@ import { existsSync, mkdirSync, writeFileSync } from 'fs'; import { join } from 'path'; + import { ConfigService, Database } from '../../config/env.config'; import { ROOT_DIR } from '../../config/path.config'; @@ -34,11 +35,9 @@ export abstract class Repository implements IRepository { mkdirSync(create.path, { recursive: true }); } try { - writeFileSync( - join(create.path, create.fileName + '.json'), - JSON.stringify({ ...create.data }), - { encoding: 'utf-8' }, - ); + writeFileSync(join(create.path, create.fileName + '.json'), JSON.stringify({ ...create.data }), { + encoding: 'utf-8', + }); return { message: 'create - success' }; } finally { @@ -46,19 +45,23 @@ export abstract class Repository implements IRepository { } }; - public insert(data: any, instanceName: string, saveDb = false): Promise { + // eslint-disable-next-line + public insert(data: any, instanceName: string, saveDb = false): Promise { throw new Error('Method not implemented.'); } - public update(data: any, instanceName: string, saveDb = false): Promise { + // eslint-disable-next-line + public update(data: any, instanceName: string, saveDb = false): Promise { throw new Error('Method not implemented.'); } - public find(query: any): Promise { + // eslint-disable-next-line + public find(query: any): Promise { throw new Error('Method not implemented.'); } - delete(query: any, force?: boolean): Promise { + // eslint-disable-next-line + delete(query: any, force?: boolean): Promise { throw new Error('Method not implemented.'); } } diff --git a/src/whatsapp/abstract/abstract.router.ts b/src/whatsapp/abstract/abstract.router.ts index c44c6880..d18cf36d 100644 --- a/src/whatsapp/abstract/abstract.router.ts +++ b/src/whatsapp/abstract/abstract.router.ts @@ -1,11 +1,13 @@ -import { InstanceDto } from '../dto/instance.dto'; -import { JSONSchema7 } from 'json-schema'; -import { Request } from 'express'; -import { validate } from 'jsonschema'; -import { BadRequestException } from '../../exceptions'; import 'express-async-errors'; + +import { Request } from 'express'; +import { JSONSchema7 } from 'json-schema'; +import { validate } from 'jsonschema'; + import { Logger } from '../../config/logger.config'; +import { BadRequestException } from '../../exceptions'; import { GetParticipant, GroupInvite, GroupJid } from '../dto/group.dto'; +import { InstanceDto } from '../dto/instance.dto'; type DataValidate = { request: Request; @@ -98,6 +100,7 @@ export abstract class RouterBroker { public async groupValidate(args: DataValidate) { const { request, ClassRef, schema, execute } = args; + const instance = request.params as unknown as InstanceDto; const body = request.body; @@ -188,9 +191,7 @@ export abstract class RouterBroker { const getParticipants = request.query as unknown as GetParticipant; if (!getParticipants?.getParticipants) { - throw new BadRequestException( - 'The getParticipants needs to be informed in the query', - ); + throw new BadRequestException('The getParticipants needs to be informed in the query'); } const instance = request.params as unknown as InstanceDto; diff --git a/src/whatsapp/controllers/chat.controller.ts b/src/whatsapp/controllers/chat.controller.ts index 454ddabf..0299841c 100644 --- a/src/whatsapp/controllers/chat.controller.ts +++ b/src/whatsapp/controllers/chat.controller.ts @@ -1,7 +1,8 @@ -import { proto } from '@whiskeysockets/baileys'; +import { Logger } from '../../config/logger.config'; import { ArchiveChatDto, DeleteMessage, + getBase64FromMediaMessageDto, NumberDto, PrivacySettingDto, ProfileNameDto, @@ -9,14 +10,12 @@ import { ProfileStatusDto, ReadMessageDto, WhatsAppNumberDto, - getBase64FromMediaMessageDto, } from '../dto/chat.dto'; import { InstanceDto } from '../dto/instance.dto'; import { ContactQuery } from '../repository/contact.repository'; import { MessageQuery } from '../repository/message.repository'; import { MessageUpQuery } from '../repository/messageUp.repository'; import { WAMonitoringService } from '../services/monitor.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('ChatController'); @@ -50,10 +49,7 @@ export class ChatController { public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) { logger.verbose('requested fetchProfile from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchProfile( - instanceName, - data.number, - ); + return await this.waMonitor.waInstances[instanceName].fetchProfile(instanceName, data.number); } public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) { @@ -61,13 +57,8 @@ export class ChatController { return await this.waMonitor.waInstances[instanceName].fetchContacts(query); } - public async getBase64FromMediaMessage( - { instanceName }: InstanceDto, - data: getBase64FromMediaMessageDto, - ) { - logger.verbose( - 'requested getBase64FromMediaMessage from ' + instanceName + ' instance', - ); + public async getBase64FromMediaMessage({ instanceName }: InstanceDto, data: getBase64FromMediaMessageDto) { + logger.verbose('requested getBase64FromMediaMessage from ' + instanceName + ' instance'); return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data); } @@ -91,22 +82,14 @@ export class ChatController { return await this.waMonitor.waInstances[instanceName].fetchPrivacySettings(); } - public async updatePrivacySettings( - { instanceName }: InstanceDto, - data: PrivacySettingDto, - ) { + public async updatePrivacySettings({ instanceName }: InstanceDto, data: PrivacySettingDto) { logger.verbose('requested updatePrivacySettings from ' + instanceName + ' instance'); return await this.waMonitor.waInstances[instanceName].updatePrivacySettings(data); } - public async fetchBusinessProfile( - { instanceName }: InstanceDto, - data: ProfilePictureDto, - ) { + public async fetchBusinessProfile({ instanceName }: InstanceDto, data: ProfilePictureDto) { logger.verbose('requested fetchBusinessProfile from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].fetchBusinessProfile( - data.number, - ); + return await this.waMonitor.waInstances[instanceName].fetchBusinessProfile(data.number); } public async updateProfileName({ instanceName }: InstanceDto, data: ProfileNameDto) { @@ -114,30 +97,17 @@ export class ChatController { return await this.waMonitor.waInstances[instanceName].updateProfileName(data.name); } - public async updateProfileStatus( - { instanceName }: InstanceDto, - data: ProfileStatusDto, - ) { + public async updateProfileStatus({ instanceName }: InstanceDto, data: ProfileStatusDto) { logger.verbose('requested updateProfileStatus from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updateProfileStatus( - data.status, - ); + return await this.waMonitor.waInstances[instanceName].updateProfileStatus(data.status); } - public async updateProfilePicture( - { instanceName }: InstanceDto, - data: ProfilePictureDto, - ) { + public async updateProfilePicture({ instanceName }: InstanceDto, data: ProfilePictureDto) { logger.verbose('requested updateProfilePicture from ' + instanceName + ' instance'); - return await this.waMonitor.waInstances[instanceName].updateProfilePicture( - data.picture, - ); + return await this.waMonitor.waInstances[instanceName].updateProfilePicture(data.picture); } - public async removeProfilePicture( - { instanceName }: InstanceDto, - data: ProfilePictureDto, - ) { + public async removeProfilePicture({ instanceName }: InstanceDto) { logger.verbose('requested removeProfilePicture from ' + instanceName + ' instance'); return await this.waMonitor.waInstances[instanceName].removeProfilePicture(); } diff --git a/src/whatsapp/controllers/chatwoot.controller.ts b/src/whatsapp/controllers/chatwoot.controller.ts index ad92e607..ab291c43 100644 --- a/src/whatsapp/controllers/chatwoot.controller.ts +++ b/src/whatsapp/controllers/chatwoot.controller.ts @@ -1,24 +1,20 @@ import { isURL } from 'class-validator'; -import { BadRequestException } from '../../exceptions'; -import { InstanceDto } from '../dto/instance.dto'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { ChatwootService } from '../services/chatwoot.service'; -import { Logger } from '../../config/logger.config'; -import { waMonitor } from '../whatsapp.module'; + import { ConfigService, HttpServer } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { BadRequestException } from '../../exceptions'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { ChatwootService } from '../services/chatwoot.service'; +import { waMonitor } from '../whatsapp.module'; const logger = new Logger('ChatwootController'); export class ChatwootController { - constructor( - private readonly chatwootService: ChatwootService, - private readonly configService: ConfigService, - ) {} + constructor(private readonly chatwootService: ChatwootService, private readonly configService: ConfigService) {} public async createChatwoot(instance: InstanceDto, data: ChatwootDto) { - logger.verbose( - 'requested createChatwoot from ' + instance.instanceName + ' instance', - ); + logger.verbose('requested createChatwoot from ' + instance.instanceName + ' instance'); if (data.enabled) { if (!isURL(data.url, { require_tld: false })) { @@ -89,9 +85,7 @@ export class ChatwootController { } public async receiveWebhook(instance: InstanceDto, data: any) { - logger.verbose( - 'requested receiveWebhook from ' + instance.instanceName + ' instance', - ); + logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance'); const chatwootService = new ChatwootService(waMonitor, this.configService); return chatwootService.receiveWebhook(instance, data); diff --git a/src/whatsapp/controllers/group.controller.ts b/src/whatsapp/controllers/group.controller.ts index f4d381ce..0cf093ca 100644 --- a/src/whatsapp/controllers/group.controller.ts +++ b/src/whatsapp/controllers/group.controller.ts @@ -1,3 +1,4 @@ +import { Logger } from '../../config/logger.config'; import { CreateGroupDto, GetParticipant, @@ -13,7 +14,6 @@ import { } from '../dto/group.dto'; import { InstanceDto } from '../dto/instance.dto'; import { WAMonitoringService } from '../services/monitor.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('ChatController'); @@ -26,33 +26,18 @@ export class GroupController { } public async updateGroupPicture(instance: InstanceDto, update: GroupPictureDto) { - logger.verbose( - 'requested updateGroupPicture from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture( - update, - ); + logger.verbose('requested updateGroupPicture from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture(update); } public async updateGroupSubject(instance: InstanceDto, update: GroupSubjectDto) { - logger.verbose( - 'requested updateGroupSubject from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject( - update, - ); + logger.verbose('requested updateGroupSubject from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject(update); } - public async updateGroupDescription( - instance: InstanceDto, - update: GroupDescriptionDto, - ) { - logger.verbose( - 'requested updateGroupDescription from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription( - update, - ); + public async updateGroupDescription(instance: InstanceDto, update: GroupDescriptionDto) { + logger.verbose('requested updateGroupDescription from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription(update); } public async findGroupInfo(instance: InstanceDto, groupJid: GroupJid) { @@ -61,12 +46,8 @@ export class GroupController { } public async fetchAllGroups(instance: InstanceDto, getPaticipants: GetParticipant) { - logger.verbose( - 'requested fetchAllGroups from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups( - getPaticipants, - ); + logger.verbose('requested fetchAllGroups from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups(getPaticipants); } public async inviteCode(instance: InstanceDto, groupJid: GroupJid) { @@ -85,49 +66,28 @@ export class GroupController { } public async revokeInviteCode(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose( - 'requested revokeInviteCode from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode( - groupJid, - ); + logger.verbose('requested revokeInviteCode from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode(groupJid); } public async findParticipants(instance: InstanceDto, groupJid: GroupJid) { - logger.verbose( - 'requested findParticipants from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].findParticipants( - groupJid, - ); + logger.verbose('requested findParticipants from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].findParticipants(groupJid); } - public async updateGParticipate( - instance: InstanceDto, - update: GroupUpdateParticipantDto, - ) { - logger.verbose( - 'requested updateGParticipate from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant( - update, - ); + public async updateGParticipate(instance: InstanceDto, update: GroupUpdateParticipantDto) { + logger.verbose('requested updateGParticipate from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant(update); } public async updateGSetting(instance: InstanceDto, update: GroupUpdateSettingDto) { - logger.verbose( - 'requested updateGSetting from ' + instance.instanceName + ' instance', - ); + logger.verbose('requested updateGSetting from ' + instance.instanceName + ' instance'); return await this.waMonitor.waInstances[instance.instanceName].updateGSetting(update); } public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) { - logger.verbose( - 'requested toggleEphemeral from ' + instance.instanceName + ' instance', - ); - return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral( - update, - ); + logger.verbose('requested toggleEphemeral from ' + instance.instanceName + ' instance'); + return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral(update); } public async leaveGroup(instance: InstanceDto, groupJid: GroupJid) { diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index d9c351f7..e45644fe 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -1,19 +1,20 @@ import { delay } from '@whiskeysockets/baileys'; +import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; -import { Auth, ConfigService, HttpServer } from '../../config/env.config'; + +import { ConfigService, HttpServer } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { RedisCache } from '../../db/redis.client'; import { BadRequestException, InternalServerErrorException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; import { AuthService, OldToken } from '../services/auth.service'; -import { WAMonitoringService } from '../services/monitor.service'; -import { WAStartupService } from '../services/whatsapp.service'; -import { WebhookService } from '../services/webhook.service'; import { ChatwootService } from '../services/chatwoot.service'; -import { Logger } from '../../config/logger.config'; -import { wa } from '../types/wa.types'; -import { RedisCache } from '../../db/redis.client'; -import { isURL } from 'class-validator'; +import { WAMonitoringService } from '../services/monitor.service'; import { SettingsService } from '../services/settings.service'; +import { WebhookService } from '../services/webhook.service'; +import { WAStartupService } from '../services/whatsapp.service'; +import { wa } from '../types/wa.types'; export class InstanceController { constructor( @@ -55,21 +56,14 @@ export class InstanceController { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) { - throw new BadRequestException( - 'The instance name must be lowercase and without special characters', - ); + throw new BadRequestException('The instance name must be lowercase and without special characters'); } this.logger.verbose('checking duplicate token'); await this.authService.checkDuplicateToken(token); this.logger.verbose('creating instance'); - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); + const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); instance.instanceName = instanceName .toLowerCase() .replace(/[^a-z0-9]/g, '') @@ -175,17 +169,11 @@ export class InstanceController { throw new BadRequestException('sign_msg is required'); } - if ( - chatwoot_reopen_conversation !== true && - chatwoot_reopen_conversation !== false - ) { + if (chatwoot_reopen_conversation !== true && chatwoot_reopen_conversation !== false) { throw new BadRequestException('reopen_conversation is required'); } - if ( - chatwoot_conversation_pending !== true && - chatwoot_conversation_pending !== false - ) { + if (chatwoot_conversation_pending !== true && chatwoot_conversation_pending !== false) { throw new BadRequestException('conversation_pending is required'); } @@ -246,9 +234,7 @@ export class InstanceController { public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) { try { - this.logger.verbose( - 'requested connectToWhatsapp from ' + instanceName + ' instance', - ); + this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance'); const instance = this.waMonitor.waInstances[instanceName]; const state = instance?.connectionStatus?.state; @@ -321,16 +307,12 @@ export class InstanceController { const { instance } = await this.connectionState({ instanceName }); if (instance.state === 'close') { - throw new BadRequestException( - 'The "' + instanceName + '" instance is not connected', - ); + throw new BadRequestException('The "' + instanceName + '" instance is not connected'); } try { this.logger.verbose('logging out instance: ' + instanceName); - await this.waMonitor.waInstances[instanceName]?.client?.logout( - 'Log out instance: ' + instanceName, - ); + await this.waMonitor.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName); this.logger.verbose('close connection instance: ' + instanceName); this.waMonitor.waInstances[instanceName]?.client?.ws?.close(); @@ -346,9 +328,7 @@ export class InstanceController { const { instance } = await this.connectionState({ instanceName }); if (instance.state === 'open') { - throw new BadRequestException( - 'The "' + instanceName + '" instance needs to be disconnected', - ); + throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected'); } try { if (instance.state === 'connecting') { diff --git a/src/whatsapp/controllers/sendMessage.controller.ts b/src/whatsapp/controllers/sendMessage.controller.ts index fb942a9c..20e38ae5 100644 --- a/src/whatsapp/controllers/sendMessage.controller.ts +++ b/src/whatsapp/controllers/sendMessage.controller.ts @@ -1,4 +1,6 @@ import { isBase64, isURL } from 'class-validator'; + +import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { @@ -16,8 +18,6 @@ import { } from '../dto/sendMessage.dto'; import { WAMonitoringService } from '../services/monitor.service'; -import { Logger } from '../../config/logger.config'; - const logger = new Logger('MessageRouter'); export class SendMessageController { @@ -39,12 +39,7 @@ export class SendMessageController { throw new BadRequestException('For base64 the file name must be informed.'); } - logger.verbose( - 'isURL: ' + - isURL(data?.mediaMessage?.media) + - ', isBase64: ' + - isBase64(data?.mediaMessage?.media), - ); + logger.verbose('isURL: ' + isURL(data?.mediaMessage?.media) + ', isBase64: ' + isBase64(data?.mediaMessage?.media)); if (isURL(data?.mediaMessage?.media) || isBase64(data?.mediaMessage?.media)) { return await this.waMonitor.waInstances[instanceName].mediaMessage(data); } @@ -55,10 +50,7 @@ export class SendMessageController { logger.verbose('requested sendSticker from ' + instanceName + ' instance'); logger.verbose( - 'isURL: ' + - isURL(data?.stickerMessage?.image) + - ', isBase64: ' + - isBase64(data?.stickerMessage?.image), + 'isURL: ' + isURL(data?.stickerMessage?.image) + ', isBase64: ' + isBase64(data?.stickerMessage?.image), ); if (isURL(data.stickerMessage.image) || isBase64(data.stickerMessage.image)) { return await this.waMonitor.waInstances[instanceName].mediaSticker(data); @@ -69,12 +61,7 @@ export class SendMessageController { public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto) { logger.verbose('requested sendWhatsAppAudio from ' + instanceName + ' instance'); - logger.verbose( - 'isURL: ' + - isURL(data?.audioMessage?.audio) + - ', isBase64: ' + - isBase64(data?.audioMessage?.audio), - ); + logger.verbose('isURL: ' + isURL(data?.audioMessage?.audio) + ', isBase64: ' + isBase64(data?.audioMessage?.audio)); if (isURL(data.audioMessage.audio) || isBase64(data.audioMessage.audio)) { return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data); } @@ -83,10 +70,7 @@ export class SendMessageController { public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) { logger.verbose('requested sendButtons from ' + instanceName + ' instance'); - if ( - isBase64(data.buttonMessage.mediaMessage?.media) && - !data.buttonMessage.mediaMessage?.fileName - ) { + if (isBase64(data.buttonMessage.mediaMessage?.media) && !data.buttonMessage.mediaMessage?.fileName) { throw new BadRequestException('For bse64 the file name must be informed.'); } return await this.waMonitor.waInstances[instanceName].buttonMessage(data); @@ -109,7 +93,7 @@ export class SendMessageController { public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) { logger.verbose('requested sendReaction from ' + instanceName + ' instance'); - if (!data.reactionMessage.reaction.match(/[^\(\)\w\sΓ -ΓΊ"-\+]+/)) { + if (!data.reactionMessage.reaction.match(/[^()\w\sΓ -ΓΊ"-+]+/)) { throw new BadRequestException('"reaction" must be an emoji'); } return await this.waMonitor.waInstances[instanceName].reactionMessage(data); diff --git a/src/whatsapp/controllers/settings.controller.ts b/src/whatsapp/controllers/settings.controller.ts index f538abe6..32713b1f 100644 --- a/src/whatsapp/controllers/settings.controller.ts +++ b/src/whatsapp/controllers/settings.controller.ts @@ -1,9 +1,10 @@ -import { isURL } from 'class-validator'; -import { BadRequestException } from '../../exceptions'; +// import { isURL } from 'class-validator'; + +import { Logger } from '../../config/logger.config'; +// import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; import { SettingsService } from '../services/settings.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('SettingsController'); @@ -11,9 +12,8 @@ export class SettingsController { constructor(private readonly settingsService: SettingsService) {} public async createSettings(instance: InstanceDto, data: SettingsDto) { - logger.verbose( - 'requested createSettings from ' + instance.instanceName + ' instance', - ); + + logger.verbose('requested createSettings from ' + instance.instanceName + ' instance'); return this.settingsService.create(instance, data); } diff --git a/src/whatsapp/controllers/views.controller.ts b/src/whatsapp/controllers/views.controller.ts index 3f54ef39..5f4060ac 100644 --- a/src/whatsapp/controllers/views.controller.ts +++ b/src/whatsapp/controllers/views.controller.ts @@ -1,4 +1,5 @@ import { Request, Response } from 'express'; + import { Auth, ConfigService } from '../../config/env.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; @@ -6,10 +7,7 @@ import { HttpStatus } from '../routers/index.router'; import { WAMonitoringService } from '../services/monitor.service'; export class ViewsController { - constructor( - private readonly waMonit: WAMonitoringService, - private readonly configService: ConfigService, - ) {} + constructor(private readonly waMonit: WAMonitoringService, private readonly configService: ConfigService) {} public async qrcode(request: Request, response: Response) { try { diff --git a/src/whatsapp/controllers/webhook.controller.ts b/src/whatsapp/controllers/webhook.controller.ts index b5747b2e..281147db 100644 --- a/src/whatsapp/controllers/webhook.controller.ts +++ b/src/whatsapp/controllers/webhook.controller.ts @@ -1,9 +1,10 @@ import { isURL } from 'class-validator'; + +import { Logger } from '../../config/logger.config'; import { BadRequestException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { WebhookDto } from '../dto/webhook.dto'; import { WebhookService } from '../services/webhook.service'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('WebhookController'); diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 4681ef76..f2f9b1cc 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -1,16 +1,7 @@ -import { - WAPrivacyOnlineValue, - WAPrivacyValue, - WAReadReceiptsValue, - proto, -} from '@whiskeysockets/baileys'; +import { proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys'; export class OnWhatsAppDto { - constructor( - public readonly jid: string, - public readonly exists: boolean, - public readonly name?: string, - ) {} + constructor(public readonly jid: string, public readonly exists: boolean, public readonly name?: string) {} } export class getBase64FromMediaMessageDto { diff --git a/src/whatsapp/guards/auth.guard.ts b/src/whatsapp/guards/auth.guard.ts index 8607cab4..72148885 100644 --- a/src/whatsapp/guards/auth.guard.ts +++ b/src/whatsapp/guards/auth.guard.ts @@ -1,12 +1,13 @@ import { isJWT } from 'class-validator'; import { NextFunction, Request, Response } from 'express'; import jwt from 'jsonwebtoken'; + +import { name } from '../../../package.json'; import { Auth, configService } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; -import { name } from '../../../package.json'; +import { ForbiddenException, UnauthorizedException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { JwtPayload } from '../services/auth.service'; -import { ForbiddenException, UnauthorizedException } from '../../exceptions'; import { repository } from '../whatsapp.module'; const logger = new Logger('GUARD'); @@ -22,15 +23,8 @@ async function jwtGuard(req: Request, res: Response, next: NextFunction) { return next(); } - if ( - (req.originalUrl.includes('/instance/create') || - req.originalUrl.includes('/instance/fetchInstances')) && - !key - ) { - throw new ForbiddenException( - 'Missing global api key', - 'The global api key must be set', - ); + if ((req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && !key) { + throw new ForbiddenException('Missing global api key', 'The global api key must be set'); } const jwtOpts = configService.get('AUTHENTICATION').JWT; @@ -69,15 +63,8 @@ async function apikey(req: Request, res: Response, next: NextFunction) { return next(); } - if ( - (req.originalUrl.includes('/instance/create') || - req.originalUrl.includes('/instance/fetchInstances')) && - !key - ) { - throw new ForbiddenException( - 'Missing global api key', - 'The global api key must be set', - ); + if ((req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && !key) { + throw new ForbiddenException('Missing global api key', 'The global api key must be set'); } try { @@ -86,7 +73,9 @@ async function apikey(req: Request, res: Response, next: NextFunction) { if (instanceKey.apikey === key) { return next(); } - } catch (error) {} + } catch (error) { + logger.error(error); + } throw new UnauthorizedException(); } diff --git a/src/whatsapp/guards/instance.guard.ts b/src/whatsapp/guards/instance.guard.ts index 1e79ff1d..69d20414 100644 --- a/src/whatsapp/guards/instance.guard.ts +++ b/src/whatsapp/guards/instance.guard.ts @@ -1,16 +1,13 @@ import { NextFunction, Request, Response } from 'express'; import { existsSync } from 'fs'; import { join } from 'path'; + +import { configService, Database, Redis } from '../../config/env.config'; import { INSTANCE_DIR } from '../../config/path.config'; import { dbserver } from '../../db/db.connect'; -import { - BadRequestException, - ForbiddenException, - NotFoundException, -} from '../../exceptions'; +import { BadRequestException, ForbiddenException, NotFoundException } from '../../exceptions'; import { InstanceDto } from '../dto/instance.dto'; import { cache, waMonitor } from '../whatsapp.module'; -import { Database, Redis, configService } from '../../config/env.config'; async function getInstance(instanceName: string) { const db = configService.get('DATABASE'); @@ -35,10 +32,7 @@ async function getInstance(instanceName: string) { } export async function instanceExistsGuard(req: Request, _: Response, next: NextFunction) { - if ( - req.originalUrl.includes('/instance/create') || - req.originalUrl.includes('/instance/fetchInstances') - ) { + if (req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) { return next(); } @@ -58,9 +52,7 @@ export async function instanceLoggedGuard(req: Request, _: Response, next: NextF if (req.originalUrl.includes('/instance/create')) { const instance = req.body as InstanceDto; if (await getInstance(instance.instanceName)) { - throw new ForbiddenException( - `This name "${instance.instanceName}" is already in use.`, - ); + throw new ForbiddenException(`This name "${instance.instanceName}" is already in use.`); } if (waMonitor.waInstances[instance.instanceName]) { diff --git a/src/whatsapp/models/auth.model.ts b/src/whatsapp/models/auth.model.ts index b5da800d..5c5b6a41 100644 --- a/src/whatsapp/models/auth.model.ts +++ b/src/whatsapp/models/auth.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class AuthRaw { diff --git a/src/whatsapp/models/chat.model.ts b/src/whatsapp/models/chat.model.ts index ebf7f217..20153603 100644 --- a/src/whatsapp/models/chat.model.ts +++ b/src/whatsapp/models/chat.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class ChatRaw { diff --git a/src/whatsapp/models/chatwoot.model.ts b/src/whatsapp/models/chatwoot.model.ts index bac226e9..d72f6e74 100644 --- a/src/whatsapp/models/chatwoot.model.ts +++ b/src/whatsapp/models/chatwoot.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class ChatwootRaw { @@ -25,9 +26,5 @@ const chatwootSchema = new Schema({ number: { type: String, required: true }, }); -export const ChatwootModel = dbserver?.model( - ChatwootRaw.name, - chatwootSchema, - 'chatwoot', -); +export const ChatwootModel = dbserver?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot'); export type IChatwootModel = typeof ChatwootModel; diff --git a/src/whatsapp/models/contact.model.ts b/src/whatsapp/models/contact.model.ts index c15411fa..d9b51e1e 100644 --- a/src/whatsapp/models/contact.model.ts +++ b/src/whatsapp/models/contact.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class ContactRaw { diff --git a/src/whatsapp/models/index.ts b/src/whatsapp/models/index.ts index e6c6d8b4..ee472de6 100644 --- a/src/whatsapp/models/index.ts +++ b/src/whatsapp/models/index.ts @@ -1,7 +1,7 @@ +export * from './auth.model'; export * from './chat.model'; +export * from './chatwoot.model'; export * from './contact.model'; export * from './message.model'; -export * from './auth.model'; -export * from './webhook.model'; -export * from './chatwoot.model'; export * from './settings.model'; +export * from './webhook.model'; diff --git a/src/whatsapp/models/message.model.ts b/src/whatsapp/models/message.model.ts index 4a684e53..764b04d9 100644 --- a/src/whatsapp/models/message.model.ts +++ b/src/whatsapp/models/message.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; import { wa } from '../types/wa.types'; @@ -64,9 +65,5 @@ const messageUpdateSchema = new Schema({ owner: { type: String, required: true, min: 1 }, }); -export const MessageUpModel = dbserver?.model( - MessageUpdateRaw.name, - messageUpdateSchema, - 'messageUpdate', -); +export const MessageUpModel = dbserver?.model(MessageUpdateRaw.name, messageUpdateSchema, 'messageUpdate'); export type IMessageUpModel = typeof MessageUpModel; diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index b6d2488d..c928be42 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class SettingsRaw { @@ -21,9 +22,5 @@ const settingsSchema = new Schema({ read_status: { type: Boolean, required: true }, }); -export const SettingsModel = dbserver?.model( - SettingsRaw.name, - settingsSchema, - 'settings', -); +export const SettingsModel = dbserver?.model(SettingsRaw.name, settingsSchema, 'settings'); export type ISettingsModel = typeof SettingsModel; diff --git a/src/whatsapp/models/webhook.model.ts b/src/whatsapp/models/webhook.model.ts index 62ee38f4..fa91326c 100644 --- a/src/whatsapp/models/webhook.model.ts +++ b/src/whatsapp/models/webhook.model.ts @@ -1,4 +1,5 @@ import { Schema } from 'mongoose'; + import { dbserver } from '../../db/db.connect'; export class WebhookRaw { diff --git a/src/whatsapp/repository/auth.repository.ts b/src/whatsapp/repository/auth.repository.ts index 0d7e177f..4da8980b 100644 --- a/src/whatsapp/repository/auth.repository.ts +++ b/src/whatsapp/repository/auth.repository.ts @@ -1,16 +1,14 @@ -import { join } from 'path'; -import { Auth, ConfigService, Database } from '../../config/env.config'; -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { IAuthModel, AuthRaw } from '../models'; import { readFileSync } from 'fs'; -import { AUTH_DIR } from '../../config/path.config'; +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 } from '../models'; export class AuthRepository extends Repository { - constructor( - private readonly authModel: IAuthModel, - readonly configService: ConfigService, - ) { + constructor(private readonly authModel: IAuthModel, readonly configService: ConfigService) { super(configService); this.auth = configService.get('AUTHENTICATION'); } @@ -23,11 +21,7 @@ export class AuthRepository extends Repository { 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 }, - ); + 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 }; @@ -40,9 +34,7 @@ export class AuthRepository extends Repository { fileName: instance, data, }); - this.logger.verbose( - 'auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance, - ); + this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance); this.logger.verbose('auth created'); return { insertCount: 1 }; diff --git a/src/whatsapp/repository/chat.repository.ts b/src/whatsapp/repository/chat.repository.ts index 0f05760c..68d653a4 100644 --- a/src/whatsapp/repository/chat.repository.ts +++ b/src/whatsapp/repository/chat.repository.ts @@ -1,29 +1,23 @@ -import { join } from 'path'; -import { ConfigService, StoreConf } from '../../config/env.config'; -import { IInsert, Repository } from '../abstract/abstract.repository'; import { opendirSync, readFileSync, rmSync } from 'fs'; -import { ChatRaw, IChatModel } from '../models'; +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, IChatModel } from '../models'; export class ChatQuery { where: ChatRaw; } export class ChatRepository extends Repository { - constructor( - private readonly chatModel: IChatModel, - private readonly configService: ConfigService, - ) { + 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 { + public async insert(data: ChatRaw[], instanceName: string, saveDb = false): Promise { this.logger.verbose('inserting chats'); if (data.length === 0) { this.logger.verbose('no chats to insert'); @@ -53,10 +47,7 @@ export class ChatRepository extends Repository { data: chat, }); this.logger.verbose( - 'chats saved to store in path: ' + - join(this.storePath, 'chats', instanceName) + - '/' + - chat.id, + 'chats saved to store in path: ' + join(this.storePath, 'chats', instanceName) + '/' + chat.id, ); }); @@ -89,10 +80,9 @@ export class ChatRepository extends Repository { if (dirent.isFile()) { chats.push( JSON.parse( - readFileSync( - join(this.storePath, 'chats', query.where.owner, dirent.name), - { encoding: 'utf-8' }, - ), + readFileSync(join(this.storePath, 'chats', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), ), ); } diff --git a/src/whatsapp/repository/chatwoot.repository.ts b/src/whatsapp/repository/chatwoot.repository.ts index 3d24022a..47398d68 100644 --- a/src/whatsapp/repository/chatwoot.repository.ts +++ b/src/whatsapp/repository/chatwoot.repository.ts @@ -1,15 +1,13 @@ -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { ConfigService } from '../../config/env.config'; -import { join } from 'path'; import { readFileSync } from 'fs'; -import { IChatwootModel, ChatwootRaw } from '../models'; +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, - ) { + constructor(private readonly chatwootModel: IChatwootModel, private readonly configService: ConfigService) { super(configService); } @@ -20,15 +18,9 @@ export class ChatwootRepository extends Repository { 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 }, - ); + const insert = await this.chatwootModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); - this.logger.verbose( - 'chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot', - ); + this.logger.verbose('chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot'); return { insertCount: insert.modifiedCount }; } @@ -40,12 +32,7 @@ export class ChatwootRepository extends Repository { data, }); - this.logger.verbose( - 'chatwoot saved to store in path: ' + - join(this.storePath, 'chatwoot') + - '/' + - instance, - ); + this.logger.verbose('chatwoot saved to store in path: ' + join(this.storePath, 'chatwoot') + '/' + instance); this.logger.verbose('chatwoot created'); return { insertCount: 1 }; diff --git a/src/whatsapp/repository/contact.repository.ts b/src/whatsapp/repository/contact.repository.ts index 648b5bf4..03851607 100644 --- a/src/whatsapp/repository/contact.repository.ts +++ b/src/whatsapp/repository/contact.repository.ts @@ -1,29 +1,23 @@ import { opendirSync, readFileSync } from 'fs'; import { join } from 'path'; + import { ConfigService, StoreConf } from '../../config/env.config'; -import { ContactRaw, IContactModel } from '../models'; -import { IInsert, Repository } from '../abstract/abstract.repository'; import { Logger } from '../../config/logger.config'; +import { IInsert, Repository } from '../abstract/abstract.repository'; +import { ContactRaw, IContactModel } from '../models'; export class ContactQuery { where: ContactRaw; } export class ContactRepository extends Repository { - constructor( - private readonly contactModel: IContactModel, - private readonly configService: ConfigService, - ) { + 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 { + public async insert(data: ContactRaw[], instanceName: string, saveDb = false): Promise { this.logger.verbose('inserting contacts'); if (data.length === 0) { @@ -54,10 +48,7 @@ export class ContactRepository extends Repository { data: contact, }); this.logger.verbose( - 'contacts saved to store in path: ' + - join(this.storePath, 'contacts', instanceName) + - '/' + - contact.id, + 'contacts saved to store in path: ' + join(this.storePath, 'contacts', instanceName) + '/' + contact.id, ); }); @@ -74,11 +65,7 @@ export class ContactRepository extends Repository { } } - public async update( - data: ContactRaw[], - instanceName: string, - saveDb = false, - ): Promise { + public async update(data: ContactRaw[], instanceName: string, saveDb = false): Promise { try { this.logger.verbose('updating contacts'); @@ -119,10 +106,7 @@ export class ContactRepository extends Repository { data: contact, }); this.logger.verbose( - 'contacts updated in store in path: ' + - join(this.storePath, 'contacts', instanceName) + - '/' + - contact.id, + 'contacts updated in store in path: ' + join(this.storePath, 'contacts', instanceName) + '/' + contact.id, ); }); @@ -154,15 +138,9 @@ export class ContactRepository extends Repository { 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' }, - ), + readFileSync(join(this.storePath, 'contacts', query.where.owner, query.where.id + '.json'), { + encoding: 'utf-8', + }), ), ); } else { @@ -175,10 +153,9 @@ export class ContactRepository extends Repository { if (dirent.isFile()) { contacts.push( JSON.parse( - readFileSync( - join(this.storePath, 'contacts', query.where.owner, dirent.name), - { encoding: 'utf-8' }, - ), + readFileSync(join(this.storePath, 'contacts', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), ), ); } diff --git a/src/whatsapp/repository/message.repository.ts b/src/whatsapp/repository/message.repository.ts index dbfe01fc..ed362815 100644 --- a/src/whatsapp/repository/message.repository.ts +++ b/src/whatsapp/repository/message.repository.ts @@ -1,9 +1,10 @@ -import { ConfigService, StoreConf } from '../../config/env.config'; -import { join } from 'path'; -import { IMessageModel, MessageRaw } from '../models'; -import { IInsert, Repository } from '../abstract/abstract.repository'; 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 { IMessageModel, MessageRaw } from '../models'; export class MessageQuery { where: MessageRaw; @@ -11,20 +12,13 @@ export class MessageQuery { } export class MessageRepository extends Repository { - constructor( - private readonly messageModel: IMessageModel, - private readonly configService: ConfigService, - ) { + constructor(private readonly messageModel: IMessageModel, private readonly configService: ConfigService) { super(configService); } private readonly logger = new Logger('MessageRepository'); - public async insert( - data: MessageRaw[], - instanceName: string, - saveDb = false, - ): Promise { + public async insert(data: MessageRaw[], instanceName: string, saveDb = false): Promise { this.logger.verbose('inserting messages'); if (!Array.isArray(data) || data.length === 0) { @@ -74,10 +68,7 @@ export class MessageRepository extends Repository { data: message, }); this.logger.verbose( - 'messages saved to store in path: ' + - join(this.storePath, 'messages', instanceName) + - '/' + - message.key.id, + 'messages saved to store in path: ' + join(this.storePath, 'messages', instanceName) + '/' + message.key.id, ); }); @@ -119,15 +110,9 @@ export class MessageRepository extends Repository { 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' }, - ), + readFileSync(join(this.storePath, 'messages', query.where.owner, query.where.key.id + '.json'), { + encoding: 'utf-8', + }), ), ); } else { @@ -140,10 +125,9 @@ export class MessageRepository extends Repository { if (dirent.isFile()) { messages.push( JSON.parse( - readFileSync( - join(this.storePath, 'messages', query.where.owner, dirent.name), - { encoding: 'utf-8' }, - ), + readFileSync(join(this.storePath, 'messages', query.where.owner, dirent.name), { + encoding: 'utf-8', + }), ), ); } diff --git a/src/whatsapp/repository/messageUp.repository.ts b/src/whatsapp/repository/messageUp.repository.ts index 6a9f9cc4..b97bf59b 100644 --- a/src/whatsapp/repository/messageUp.repository.ts +++ b/src/whatsapp/repository/messageUp.repository.ts @@ -1,9 +1,10 @@ -import { ConfigService, StoreConf } from '../../config/env.config'; -import { IMessageUpModel, MessageUpdateRaw } from '../models'; -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { join } from 'path'; 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; @@ -11,20 +12,13 @@ export class MessageUpQuery { } export class MessageUpRepository extends Repository { - constructor( - private readonly messageUpModel: IMessageUpModel, - private readonly configService: ConfigService, - ) { + 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 { + public async insert(data: MessageUpdateRaw[], instanceName: string, saveDb?: boolean): Promise { this.logger.verbose('inserting message up'); if (data.length === 0) { @@ -54,10 +48,7 @@ export class MessageUpRepository extends Repository { data: update, }); this.logger.verbose( - 'message up saved to store in path: ' + - join(this.storePath, 'message-up', instanceName) + - '/' + - update.id, + 'message up saved to store in path: ' + join(this.storePath, 'message-up', instanceName) + '/' + update.id, ); }); @@ -91,42 +82,32 @@ export class MessageUpRepository extends Repository { messageUpdate.push( JSON.parse( - readFileSync( - join( - this.storePath, - 'message-up', - query.where.owner, - query.where.id + '.json', - ), - { encoding: 'utf-8' }, - ), + 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' }, - ); + 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' }, - ), + 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', - ); + this.logger.verbose('message up found in store: ' + messageUpdate.length + ' message up'); return messageUpdate .sort((x, y) => { return y.datetime - x.datetime; diff --git a/src/whatsapp/repository/repository.manager.ts b/src/whatsapp/repository/repository.manager.ts index d506cc46..ae02849f 100644 --- a/src/whatsapp/repository/repository.manager.ts +++ b/src/whatsapp/repository/repository.manager.ts @@ -1,17 +1,17 @@ -import { MessageRepository } from './message.repository'; -import { ChatRepository } from './chat.repository'; -import { ContactRepository } from './contact.repository'; -import { MessageUpRepository } from './messageUp.repository'; -import { MongoClient } from 'mongodb'; -import { WebhookRepository } from './webhook.repository'; -import { ChatwootRepository } from './chatwoot.repository'; -import { SettingsRepository } from './settings.repository'; - -import { AuthRepository } from './auth.repository'; -import { Auth, ConfigService, Database } from '../../config/env.config'; -import { join } from 'path'; import fs from 'fs'; +import { MongoClient } from 'mongodb'; +import { join } from 'path'; + +import { Auth, ConfigService, Database } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; +import { AuthRepository } from './auth.repository'; +import { ChatRepository } from './chat.repository'; +import { ChatwootRepository } from './chatwoot.repository'; +import { ContactRepository } from './contact.repository'; +import { MessageRepository } from './message.repository'; +import { MessageUpRepository } from './messageUp.repository'; +import { SettingsRepository } from './settings.repository'; +import { WebhookRepository } from './webhook.repository'; export class RepositoryBroker { constructor( public readonly message: MessageRepository, @@ -43,11 +43,7 @@ export class RepositoryBroker { this.logger.verbose('creating store path: ' + storePath); try { - const authDir = join( - storePath, - 'auth', - this.configService.get('AUTHENTICATION').TYPE, - ); + const authDir = join(storePath, 'auth', this.configService.get('AUTHENTICATION').TYPE); const chatsDir = join(storePath, 'chats'); const contactsDir = join(storePath, 'contacts'); const messagesDir = join(storePath, 'messages'); @@ -97,22 +93,23 @@ export class RepositoryBroker { this.logger.error(error); } } else { - 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 }); - } 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); } diff --git a/src/whatsapp/repository/settings.repository.ts b/src/whatsapp/repository/settings.repository.ts index d253643d..4d09d79f 100644 --- a/src/whatsapp/repository/settings.repository.ts +++ b/src/whatsapp/repository/settings.repository.ts @@ -1,15 +1,13 @@ -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { ConfigService } from '../../config/env.config'; -import { join } from 'path'; import { readFileSync } from 'fs'; -import { ISettingsModel, SettingsRaw } from '../models'; +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, - ) { + constructor(private readonly settingsModel: ISettingsModel, private readonly configService: ConfigService) { super(configService); } @@ -20,15 +18,9 @@ export class SettingsRepository extends Repository { 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 }, - ); + const insert = await this.settingsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true }); - this.logger.verbose( - 'settings saved to db: ' + insert.modifiedCount + ' settings', - ); + this.logger.verbose('settings saved to db: ' + insert.modifiedCount + ' settings'); return { insertCount: insert.modifiedCount }; } @@ -40,12 +32,7 @@ export class SettingsRepository extends Repository { data, }); - this.logger.verbose( - 'settings saved to store in path: ' + - join(this.storePath, 'settings') + - '/' + - instance, - ); + this.logger.verbose('settings saved to store in path: ' + join(this.storePath, 'settings') + '/' + instance); this.logger.verbose('settings created'); return { insertCount: 1 }; diff --git a/src/whatsapp/repository/webhook.repository.ts b/src/whatsapp/repository/webhook.repository.ts index d9b34af1..10074516 100644 --- a/src/whatsapp/repository/webhook.repository.ts +++ b/src/whatsapp/repository/webhook.repository.ts @@ -1,15 +1,13 @@ -import { IInsert, Repository } from '../abstract/abstract.repository'; -import { ConfigService } from '../../config/env.config'; -import { join } from 'path'; import { readFileSync } from 'fs'; -import { IWebhookModel, WebhookRaw } from '../models'; +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, - ) { + constructor(private readonly webhookModel: IWebhookModel, private readonly configService: ConfigService) { super(configService); } @@ -20,11 +18,7 @@ export class WebhookRepository extends Repository { 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 }, - ); + 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 }; @@ -38,12 +32,7 @@ export class WebhookRepository extends Repository { data, }); - this.logger.verbose( - 'webhook saved to store in path: ' + - join(this.storePath, 'webhook') + - '/' + - instance, - ); + this.logger.verbose('webhook saved to store in path: ' + join(this.storePath, 'webhook') + '/' + instance); this.logger.verbose('webhook created'); return { insertCount: 1 }; diff --git a/src/whatsapp/routers/chat.router.ts b/src/whatsapp/routers/chat.router.ts index 49e64117..285c29a0 100644 --- a/src/whatsapp/routers/chat.router.ts +++ b/src/whatsapp/routers/chat.router.ts @@ -1,4 +1,6 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { archiveChatSchema, contactValidateSchema, @@ -13,9 +15,11 @@ import { readMessageSchema, whatsappNumberSchema, } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; import { ArchiveChatDto, DeleteMessage, + getBase64FromMediaMessageDto, NumberDto, PrivacySettingDto, ProfileNameDto, @@ -23,17 +27,13 @@ import { ProfileStatusDto, ReadMessageDto, WhatsAppNumberDto, - getBase64FromMediaMessageDto, } from '../dto/chat.dto'; +import { InstanceDto } from '../dto/instance.dto'; import { ContactQuery } from '../repository/contact.repository'; import { MessageQuery } from '../repository/message.repository'; -import { chatController } from '../whatsapp.module'; -import { RouterBroker } from '../abstract/abstract.router'; -import { HttpStatus } from './index.router'; import { MessageUpQuery } from '../repository/messageUp.repository'; -import { proto } from '@whiskeysockets/baileys'; -import { InstanceDto } from '../dto/instance.dto'; -import { Logger } from '../../config/logger.config'; +import { chatController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; const logger = new Logger('ChatRouter'); @@ -92,27 +92,23 @@ export class ChatRouter extends RouterBroker { return res.status(HttpStatus.CREATED).json(response); }) - .delete( - this.routerPath('deleteMessageForEveryone'), - ...guards, - async (req, res) => { - logger.verbose('request received in deleteMessageForEveryone'); - logger.verbose('request body: '); - logger.verbose(req.body); + .delete(this.routerPath('deleteMessageForEveryone'), ...guards, async (req, res) => { + logger.verbose('request received in deleteMessageForEveryone'); + logger.verbose('request body: '); + logger.verbose(req.body); - logger.verbose('request query: '); - logger.verbose(req.query); + logger.verbose('request query: '); + logger.verbose(req.query); - const response = await this.dataValidate({ - request: req, - schema: deleteMessageSchema, - ClassRef: DeleteMessage, - execute: (instance, data) => chatController.deleteMessage(instance, data), - }); + const response = await this.dataValidate({ + request: req, + schema: deleteMessageSchema, + ClassRef: DeleteMessage, + execute: (instance, data) => chatController.deleteMessage(instance, data), + }); - return res.status(HttpStatus.CREATED).json(response); - }, - ) + return res.status(HttpStatus.CREATED).json(response); + }) .post(this.routerPath('fetchProfilePictureUrl'), ...guards, async (req, res) => { logger.verbose('request received in fetchProfilePictureUrl'); logger.verbose('request body: '); @@ -176,8 +172,7 @@ export class ChatRouter extends RouterBroker { request: req, schema: null, ClassRef: getBase64FromMediaMessageDto, - execute: (instance, data) => - chatController.getBase64FromMediaMessage(instance, data), + execute: (instance, data) => chatController.getBase64FromMediaMessage(instance, data), }); return res.status(HttpStatus.CREATED).json(response); @@ -263,8 +258,7 @@ export class ChatRouter extends RouterBroker { request: req, schema: privacySettingsSchema, ClassRef: PrivacySettingDto, - execute: (instance, data) => - chatController.updatePrivacySettings(instance, data), + execute: (instance, data) => chatController.updatePrivacySettings(instance, data), }); return res.status(HttpStatus.CREATED).json(response); @@ -281,8 +275,7 @@ export class ChatRouter extends RouterBroker { request: req, schema: profilePictureSchema, ClassRef: ProfilePictureDto, - execute: (instance, data) => - chatController.fetchBusinessProfile(instance, data), + execute: (instance, data) => chatController.fetchBusinessProfile(instance, data), }); return res.status(HttpStatus.OK).json(response); @@ -333,8 +326,7 @@ export class ChatRouter extends RouterBroker { request: req, schema: profilePictureSchema, ClassRef: ProfilePictureDto, - execute: (instance, data) => - chatController.updateProfilePicture(instance, data), + execute: (instance, data) => chatController.updateProfilePicture(instance, data), }); return res.status(HttpStatus.OK).json(response); @@ -351,8 +343,7 @@ export class ChatRouter extends RouterBroker { request: req, schema: profilePictureSchema, ClassRef: ProfilePictureDto, - execute: (instance, data) => - chatController.removeProfilePicture(instance, data), + execute: (instance) => chatController.removeProfilePicture(instance), }); return res.status(HttpStatus.OK).json(response); diff --git a/src/whatsapp/routers/chatwoot.router.ts b/src/whatsapp/routers/chatwoot.router.ts index 3d87f137..eb779587 100644 --- a/src/whatsapp/routers/chatwoot.router.ts +++ b/src/whatsapp/routers/chatwoot.router.ts @@ -1,12 +1,13 @@ import { RequestHandler, Router } from 'express'; -import { instanceNameSchema, chatwootSchema } from '../../validate/validate.schema'; -import { RouterBroker } from '../abstract/abstract.router'; -import { InstanceDto } from '../dto/instance.dto'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { chatwootController } from '../whatsapp.module'; -import { ChatwootService } from '../services/chatwoot.service'; -import { HttpStatus } from './index.router'; + import { Logger } from '../../config/logger.config'; +import { chatwootSchema, instanceNameSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { InstanceDto } from '../dto/instance.dto'; +// import { ChatwootService } from '../services/chatwoot.service'; +import { chatwootController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; const logger = new Logger('ChatwootRouter'); diff --git a/src/whatsapp/routers/group.router.ts b/src/whatsapp/routers/group.router.ts index 4c1b3023..f59e82a4 100644 --- a/src/whatsapp/routers/group.router.ts +++ b/src/whatsapp/routers/group.router.ts @@ -1,34 +1,35 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { createGroupSchema, + getParticipantsSchema, + groupInviteSchema, groupJidSchema, - updateParticipantsSchema, - updateSettingsSchema, + groupSendInviteSchema, toggleEphemeralSchema, + updateGroupDescriptionSchema, updateGroupPictureSchema, updateGroupSubjectSchema, - updateGroupDescriptionSchema, - groupInviteSchema, - groupSendInviteSchema, - getParticipantsSchema, + updateParticipantsSchema, + updateSettingsSchema, } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { CreateGroupDto, + GetParticipant, + GroupDescriptionDto, GroupInvite, GroupJid, GroupPictureDto, + GroupSendInvite, GroupSubjectDto, - GroupDescriptionDto, + GroupToggleEphemeralDto, GroupUpdateParticipantDto, GroupUpdateSettingDto, - GroupToggleEphemeralDto, - GroupSendInvite, - GetParticipant, } from '../dto/group.dto'; import { groupController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('GroupRouter'); @@ -96,8 +97,7 @@ export class GroupRouter extends RouterBroker { request: req, schema: updateGroupDescriptionSchema, ClassRef: GroupDescriptionDto, - execute: (instance, data) => - groupController.updateGroupDescription(instance, data), + execute: (instance, data) => groupController.updateGroupDescription(instance, data), }); res.status(HttpStatus.CREATED).json(response); diff --git a/src/whatsapp/routers/index.router.ts b/src/whatsapp/routers/index.router.ts index 4cf7befb..db082799 100644 --- a/src/whatsapp/routers/index.router.ts +++ b/src/whatsapp/routers/index.router.ts @@ -1,16 +1,17 @@ import { Router } from 'express'; +import fs from 'fs'; + import { Auth, configService } from '../../config/env.config'; -import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard'; import { authGuard } from '../guards/auth.guard'; +import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard'; import { ChatRouter } from './chat.router'; +import { ChatwootRouter } from './chatwoot.router'; import { GroupRouter } from './group.router'; import { InstanceRouter } from './instance.router'; import { MessageRouter } from './sendMessage.router'; +import { SettingsRouter } from './settings.router'; import { ViewsRouter } from './view.router'; import { WebhookRouter } from './webhook.router'; -import { ChatwootRouter } from './chatwoot.router'; -import fs from 'fs'; -import { SettingsRouter } from './settings.router'; enum HttpStatus { OK = 200, @@ -36,11 +37,7 @@ router version: packageJson.version, }); }) - .use( - '/instance', - new InstanceRouter(configService, ...guards).router, - new ViewsRouter(instanceExistsGuard).router, - ) + .use('/instance', new InstanceRouter(configService, ...guards).router, new ViewsRouter(instanceExistsGuard).router) .use('/message', new MessageRouter(...guards).router) .use('/chat', new ChatRouter(...guards).router) .use('/group', new GroupRouter(...guards).router) @@ -48,4 +45,4 @@ router .use('/chatwoot', new ChatwootRouter(...guards).router) .use('/settings', new SettingsRouter(...guards).router); -export { router, HttpStatus }; +export { HttpStatus, router }; diff --git a/src/whatsapp/routers/instance.router.ts b/src/whatsapp/routers/instance.router.ts index 850ffebd..ae6d4066 100644 --- a/src/whatsapp/routers/instance.router.ts +++ b/src/whatsapp/routers/instance.router.ts @@ -1,13 +1,14 @@ import { RequestHandler, Router } from 'express'; -import { instanceNameSchema, oldTokenSchema } from '../../validate/validate.schema'; -import { InstanceDto } from '../dto/instance.dto'; -import { instanceController } from '../whatsapp.module'; -import { RouterBroker } from '../abstract/abstract.router'; -import { HttpStatus } from './index.router'; -import { OldToken } from '../services/auth.service'; + import { Auth, ConfigService, Database } from '../../config/env.config'; -import { dbserver } from '../../db/db.connect'; import { Logger } from '../../config/logger.config'; +import { dbserver } from '../../db/db.connect'; +import { instanceNameSchema, oldTokenSchema } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; +import { InstanceDto } from '../dto/instance.dto'; +import { OldToken } from '../services/auth.service'; +import { instanceController } from '../whatsapp.module'; +import { HttpStatus } from './index.router'; const logger = new Logger('InstanceRouter'); @@ -160,19 +161,13 @@ export class InstanceRouter extends RouterBroker { if (db.ENABLED) { try { await dbserver.dropDatabase(); - return res - .status(HttpStatus.CREATED) - .json({ error: false, message: 'Database deleted' }); + return res.status(HttpStatus.CREATED).json({ error: false, 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: error.message }); } } - return res - .status(HttpStatus.INTERNAL_SERVER_ERROR) - .json({ error: true, message: 'Database is not enabled' }); + return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: 'Database is not enabled' }); }); } diff --git a/src/whatsapp/routers/sendMessage.router.ts b/src/whatsapp/routers/sendMessage.router.ts index f6f9c3eb..d87db44d 100644 --- a/src/whatsapp/routers/sendMessage.router.ts +++ b/src/whatsapp/routers/sendMessage.router.ts @@ -1,4 +1,6 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { audioMessageSchema, buttonMessageSchema, @@ -12,6 +14,7 @@ import { stickerMessageSchema, textMessageSchema, } from '../../validate/validate.schema'; +import { RouterBroker } from '../abstract/abstract.router'; import { SendAudioDto, SendButtonDto, @@ -26,9 +29,7 @@ import { SendTextDto, } from '../dto/sendMessage.dto'; import { sendMessageController } from '../whatsapp.module'; -import { RouterBroker } from '../abstract/abstract.router'; import { HttpStatus } from './index.router'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('MessageRouter'); @@ -79,8 +80,7 @@ export class MessageRouter extends RouterBroker { request: req, schema: audioMessageSchema, ClassRef: SendMediaDto, - execute: (instance, data) => - sendMessageController.sendWhatsAppAudio(instance, data), + execute: (instance, data) => sendMessageController.sendWhatsAppAudio(instance, data), }); return res.status(HttpStatus.CREATED).json(response); diff --git a/src/whatsapp/routers/settings.router.ts b/src/whatsapp/routers/settings.router.ts index 3ec3df83..6bd4d549 100644 --- a/src/whatsapp/routers/settings.router.ts +++ b/src/whatsapp/routers/settings.router.ts @@ -1,12 +1,13 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { instanceNameSchema, settingsSchema } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; +// import { SettingsService } from '../services/settings.service'; import { settingsController } from '../whatsapp.module'; -import { SettingsService } from '../services/settings.service'; import { HttpStatus } from './index.router'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('SettingsRouter'); diff --git a/src/whatsapp/routers/view.router.ts b/src/whatsapp/routers/view.router.ts index b5ddc008..c5e18129 100644 --- a/src/whatsapp/routers/view.router.ts +++ b/src/whatsapp/routers/view.router.ts @@ -1,4 +1,5 @@ import { RequestHandler, Router } from 'express'; + import { RouterBroker } from '../abstract/abstract.router'; import { viewsController } from '../whatsapp.module'; diff --git a/src/whatsapp/routers/webhook.router.ts b/src/whatsapp/routers/webhook.router.ts index c520d9d5..835d6014 100644 --- a/src/whatsapp/routers/webhook.router.ts +++ b/src/whatsapp/routers/webhook.router.ts @@ -1,11 +1,12 @@ import { RequestHandler, Router } from 'express'; + +import { Logger } from '../../config/logger.config'; import { instanceNameSchema, webhookSchema } from '../../validate/validate.schema'; import { RouterBroker } from '../abstract/abstract.router'; import { InstanceDto } from '../dto/instance.dto'; import { WebhookDto } from '../dto/webhook.dto'; import { webhookController } from '../whatsapp.module'; import { HttpStatus } from './index.router'; -import { Logger } from '../../config/logger.config'; const logger = new Logger('WebhookRouter'); diff --git a/src/whatsapp/services/auth.service.ts b/src/whatsapp/services/auth.service.ts index 88a84905..915a07b7 100644 --- a/src/whatsapp/services/auth.service.ts +++ b/src/whatsapp/services/auth.service.ts @@ -1,14 +1,15 @@ -import { Auth, ConfigService, Webhook } from '../../config/env.config'; -import { InstanceDto } from '../dto/instance.dto'; -import { name as apiName } from '../../../package.json'; -import { verify, sign } from 'jsonwebtoken'; -import { Logger } from '../../config/logger.config'; -import { v4 } from 'uuid'; -import { isJWT } from 'class-validator'; -import { BadRequestException } from '../../exceptions'; import axios from 'axios'; -import { WAMonitoringService } from './monitor.service'; +import { isJWT } from 'class-validator'; +import { sign, verify } from 'jsonwebtoken'; +import { v4 } from 'uuid'; + +import { name as apiName } from '../../../package.json'; +import { Auth, ConfigService, Webhook } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { BadRequestException } from '../../exceptions'; +import { InstanceDto } from '../dto/instance.dto'; import { RepositoryBroker } from '../repository/repository.manager'; +import { WAMonitoringService } from './monitor.service'; export type JwtPayload = { instanceName: string; @@ -63,9 +64,7 @@ export class AuthService { private async apikey(instance: InstanceDto, token?: string) { const apikey = token ? token : v4().toUpperCase(); - this.logger.verbose( - token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey, - ); + this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey); const auth = await this.repository.auth.create({ apikey }, instance.instanceName); @@ -101,13 +100,9 @@ export class AuthService { public async generateHash(instance: InstanceDto, token?: string) { const options = this.configService.get('AUTHENTICATION'); - this.logger.verbose( - 'generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName, - ); + this.logger.verbose('generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName); - return (await this[options.TYPE](instance, token)) as - | { jwt: string } - | { apikey: string }; + return (await this[options.TYPE](instance, token)) as { jwt: string } | { apikey: string }; } public async refreshToken({ oldToken }: OldToken) { @@ -150,10 +145,7 @@ export class AuthService { try { this.logger.verbose('checking webhook'); const webhook = await this.repository.webhook.find(decode.instanceName); - if ( - webhook?.enabled && - this.configService.get('WEBHOOK').EVENTS.NEW_JWT_TOKEN - ) { + if (webhook?.enabled && this.configService.get('WEBHOOK').EVENTS.NEW_JWT_TOKEN) { this.logger.verbose('sending webhook'); const httpService = axios.create({ baseURL: webhook.url }); diff --git a/src/whatsapp/services/chatwoot.service.ts b/src/whatsapp/services/chatwoot.service.ts index 2d470c37..0f2f46c8 100644 --- a/src/whatsapp/services/chatwoot.service.ts +++ b/src/whatsapp/services/chatwoot.service.ts @@ -1,19 +1,17 @@ -import { InstanceDto } from '../dto/instance.dto'; -import path from 'path'; -import { ChatwootDto } from '../dto/chatwoot.dto'; -import { WAMonitoringService } from './monitor.service'; -import { Logger } from '../../config/logger.config'; import ChatwootClient from '@figuro/chatwoot-sdk'; -import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; import axios from 'axios'; import FormData from 'form-data'; -import { SendTextDto } from '../dto/sendMessage.dto'; +import { createReadStream, readFileSync, unlinkSync, writeFileSync } from 'fs'; import mimeTypes from 'mime-types'; -import { SendAudioDto } from '../dto/sendMessage.dto'; -import { SendMediaDto } from '../dto/sendMessage.dto'; -import { ROOT_DIR } from '../../config/path.config'; +import path from 'path'; + import { ConfigService, HttpServer } from '../../config/env.config'; -import { type } from 'os'; +import { Logger } from '../../config/logger.config'; +import { ROOT_DIR } from '../../config/path.config'; +import { ChatwootDto } from '../dto/chatwoot.dto'; +import { InstanceDto } from '../dto/instance.dto'; +import { SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto'; +import { WAMonitoringService } from './monitor.service'; export class ChatwootService { private messageCacheFile: string; @@ -23,10 +21,7 @@ export class ChatwootService { private provider: any; - constructor( - private readonly waMonitor: WAMonitoringService, - private readonly configService: ConfigService, - ) { + constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) { this.messageCache = new Set(); } @@ -57,9 +52,7 @@ export class ChatwootService { private async getProvider(instance: InstanceDto) { this.logger.verbose('get provider to instance: ' + instance.instanceName); try { - const provider = await this.waMonitor.waInstances[ - instance.instanceName - ].findChatwoot(); + const provider = await this.waMonitor.waInstances[instance.instanceName].findChatwoot(); if (!provider) { this.logger.warn('provider not found'); @@ -172,9 +165,7 @@ export class ChatwootService { }); this.logger.verbose('check duplicate inbox'); - const checkDuplicate = findInbox.payload - .map((inbox) => inbox.name) - .includes(inboxName); + const checkDuplicate = findInbox.payload.map((inbox) => inbox.name).includes(inboxName); let inboxId: number; @@ -214,13 +205,7 @@ export class ChatwootService { this.logger.verbose('find contact in chatwoot and create if not exists'); const contact = (await this.findContact(instance, '123456')) || - ((await this.createContact( - instance, - '123456', - inboxId, - false, - 'EvolutionAPI', - )) as any); + ((await this.createContact(instance, '123456', inboxId, false, 'EvolutionAPI')) as any); if (!contact) { this.logger.warn('contact not found'); @@ -425,23 +410,18 @@ export class ChatwootService { if (isGroup) { this.logger.verbose('get group name'); - const group = await this.waMonitor.waInstances[ - instance.instanceName - ].client.groupMetadata(chatId); + const group = await this.waMonitor.waInstances[instance.instanceName].client.groupMetadata(chatId); nameContact = `${group.subject} (GROUP)`; this.logger.verbose('find or create participant in chatwoot'); - const picture_url = await this.waMonitor.waInstances[ - instance.instanceName - ].profilePicture(body.key.participant.split('@')[0]); - - const findParticipant = await this.findContact( - instance, + const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture( body.key.participant.split('@')[0], ); + const findParticipant = await this.findContact(instance, body.key.participant.split('@')[0]); + if (findParticipant) { if (!findParticipant.name || findParticipant.name === chatId) { await this.updateContact(instance, findParticipant.id, { @@ -463,9 +443,7 @@ export class ChatwootService { this.logger.verbose('find or create contact in chatwoot'); - const picture_url = await this.waMonitor.waInstances[ - instance.instanceName - ].profilePicture(chatId); + const picture_url = await this.waMonitor.waInstances[instance.instanceName].profilePicture(chatId); const findContact = await this.findContact(instance, chatId); @@ -510,8 +488,7 @@ export class ChatwootService { return null; } - const contactId = - contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; + const contactId = contact?.payload?.id || contact?.payload?.contact?.id || contact?.id; if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) { this.logger.verbose('update contact name in chatwoot'); @@ -529,14 +506,20 @@ export class ChatwootService { if (contactConversations) { let conversation: any; if (this.provider.reopen_conversation) { - conversation = contactConversations.payload.find( - (conversation) => conversation.inbox_id == filterInbox.id, - ); + conversation = contactConversations.payload.find((conversation) => conversation.inbox_id == filterInbox.id); + + if (this.provider.conversation_pending) { + await client.conversations.toggleStatus({ + accountId: this.provider.account_id, + conversationId: conversation.id, + data: { + status: 'pending', + }, + }); + } } else { conversation = contactConversations.payload.find( - (conversation) => - conversation.status !== 'resolved' && - conversation.inbox_id == filterInbox.id, + (conversation) => conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id, ); } this.logger.verbose('return conversation if exists'); @@ -595,9 +578,7 @@ export class ChatwootService { } this.logger.verbose('find inbox by name'); - const findByName = inbox.payload.find( - (inbox) => inbox.name === instance.instanceName, - ); + const findByName = inbox.payload.find((inbox) => inbox.name === instance.instanceName); if (!findByName) { this.logger.warn('inbox not found'); @@ -699,8 +680,7 @@ export class ChatwootService { this.logger.verbose('find conversation by contact id'); const conversation = findConversation.data.payload.find( - (conversation) => - conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', ); if (!conversation) { @@ -820,8 +800,7 @@ export class ChatwootService { this.logger.verbose('find conversation by contact id'); const conversation = findConversation.data.payload.find( - (conversation) => - conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', + (conversation) => conversation?.meta?.sender?.id === contact.id && conversation.status === 'open', ); if (!conversation) { @@ -871,12 +850,7 @@ export class ChatwootService { } } - public async sendAttachment( - waInstance: any, - number: string, - media: any, - caption?: string, - ) { + public async sendAttachment(waInstance: any, number: string, media: any, caption?: string) { this.logger.verbose('send attachment to instance: ' + waInstance.instanceName); try { @@ -957,9 +931,7 @@ export class ChatwootService { public async receiveWebhook(instance: InstanceDto, body: any) { try { - this.logger.verbose( - 'receive webhook to chatwoot instance: ' + instance.instanceName, - ); + this.logger.verbose('receive webhook to chatwoot instance: ' + instance.instanceName); const client = await this.clientCw(instance); if (!client) { @@ -972,8 +944,7 @@ export class ChatwootService { this.logger.verbose('check if is group'); const chatId = - body.conversation.meta.sender?.phone_number?.replace('+', '') || - body.conversation.meta.sender?.identifier; + body.conversation.meta.sender?.phone_number?.replace('+', '') || body.conversation.meta.sender?.identifier; const messageReceived = body.content; const senderName = body?.sender?.name; const waInstance = this.waMonitor.waInstances[instance.instanceName]; @@ -993,11 +964,7 @@ export class ChatwootService { await waInstance.connectToWhatsapp(number); } else { this.logger.verbose('whatsapp already connected'); - await this.createBotMessage( - instance, - `🚨 ${body.inbox.name} instance is connected.`, - 'incoming', - ); + await this.createBotMessage(instance, `🚨 ${body.inbox.name} instance is connected.`, 'incoming'); } } @@ -1008,20 +975,12 @@ export class ChatwootService { if (!state) { this.logger.verbose('state not found'); - await this.createBotMessage( - instance, - `⚠️ ${body.inbox.name} instance not found.`, - 'incoming', - ); + await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance not found.`, 'incoming'); } if (state) { this.logger.verbose('state: ' + state + ' found'); - await this.createBotMessage( - instance, - `⚠️ ${body.inbox.name} instance status: *${state}*`, - 'incoming', - ); + await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance status: *${state}*`, 'incoming'); } } @@ -1049,6 +1008,8 @@ export class ChatwootService { chatwoot_token: this.provider.token, chatwoot_url: this.provider.url, chatwoot_sign_msg: this.provider.sign_msg, + chatwoot_reopen_conversation: this.provider.reopen_conversation, + chatwoot_conversation_pending: this.provider.conversation_pending, }; if (command.split(':')[2]) { @@ -1070,19 +1031,10 @@ export class ChatwootService { } } - if ( - body.message_type === 'outgoing' && - body?.conversation?.messages?.length && - chatId !== '123456' - ) { + if (body.message_type === 'outgoing' && body?.conversation?.messages?.length && chatId !== '123456') { this.logger.verbose('check if is group'); - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); this.logger.verbose('cache file path: ' + this.messageCacheFile); this.messageCache = this.loadMessageCache(); @@ -1103,9 +1055,7 @@ export class ChatwootService { if (senderName === null || senderName === undefined) { formatText = messageReceived; } else { - formatText = this.provider.sign_msg - ? `*${senderName}:*\n\n${messageReceived}` - : messageReceived; + formatText = this.provider.sign_msg ? `*${senderName}:*\n\n${messageReceived}` : messageReceived; } for (const message of body.conversation.messages) { @@ -1119,12 +1069,7 @@ export class ChatwootService { formatText = null; } - await this.sendAttachment( - waInstance, - chatId, - attachment.data_url, - formatText, - ); + await this.sendAttachment(waInstance, chatId, attachment.data_url, formatText); } } else { this.logger.verbose('message is text'); @@ -1203,8 +1148,7 @@ export class ChatwootService { messageContextInfo: msg.messageContextInfo?.stanzaId, stickerMessage: undefined, documentMessage: msg.documentMessage?.caption, - documentWithCaptionMessage: - msg.documentWithCaptionMessage?.message?.documentMessage?.caption, + documentWithCaptionMessage: msg.documentWithCaptionMessage?.message?.documentMessage?.caption, audioMessage: msg.audioMessage?.caption, contactMessage: msg.contactMessage?.vcard, contactsArrayMessage: msg.contactsArrayMessage, @@ -1405,24 +1349,14 @@ export class ChatwootService { } this.logger.verbose('send data to chatwoot'); - const send = await this.sendData( - getConversion, - fileName, - messageType, - content, - ); + const send = await this.sendData(getConversion, fileName, messageType, content); if (!send) { this.logger.warn('message not sent'); return; } - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); this.messageCache = this.loadMessageCache(); @@ -1436,24 +1370,14 @@ export class ChatwootService { this.logger.verbose('message is not group'); this.logger.verbose('send data to chatwoot'); - const send = await this.sendData( - getConversion, - fileName, - messageType, - bodyMessage, - ); + const send = await this.sendData(getConversion, fileName, messageType, bodyMessage); if (!send) { this.logger.warn('message not sent'); return; } - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); this.messageCache = this.loadMessageCache(); @@ -1482,24 +1406,14 @@ export class ChatwootService { } this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage( - instance, - getConversion, - content, - messageType, - ); + const send = await this.createMessage(instance, getConversion, content, messageType); if (!send) { this.logger.warn('message not sent'); return; } - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); this.messageCache = this.loadMessageCache(); @@ -1513,24 +1427,14 @@ export class ChatwootService { this.logger.verbose('message is not group'); this.logger.verbose('send data to chatwoot'); - const send = await this.createMessage( - instance, - getConversion, - bodyMessage, - messageType, - ); + const send = await this.createMessage(instance, getConversion, bodyMessage, messageType); if (!send) { this.logger.warn('message not sent'); return; } - this.messageCacheFile = path.join( - ROOT_DIR, - 'store', - 'chatwoot', - `${instance.instanceName}_cache.txt`, - ); + this.messageCacheFile = path.join(ROOT_DIR, 'store', 'chatwoot', `${instance.instanceName}_cache.txt`); this.messageCache = this.loadMessageCache(); @@ -1580,16 +1484,9 @@ export class ChatwootService { return await this.createBotMessage(instance, erroQRcode, 'incoming'); } else { this.logger.verbose('qrcode success'); - const fileData = Buffer.from( - body?.qrcode.base64.replace('data:image/png;base64,', ''), - 'base64', - ); + const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64'); - const fileName = `${path.join( - waInstance?.storePath, - 'temp', - `${`${instance}.png`}`, - )}`; + const fileName = `${path.join(waInstance?.storePath, 'temp', `${`${instance}.png`}`)}`; this.logger.verbose('temp file name: ' + fileName); @@ -1597,22 +1494,17 @@ export class ChatwootService { writeFileSync(fileName, fileData, 'utf8'); this.logger.verbose('send qrcode to chatwoot'); - await this.createBotQr( - instance, - 'QRCode successfully generated!', - 'incoming', - fileName, - ); + await this.createBotQr(instance, 'QRCode successfully generated!', 'incoming', fileName); let msgQrCode = `⚑️ QRCode successfully generated!\n\nScan this QR code within the next 40 seconds.`; if (body?.qrcode?.pairingCode) { msgQrCode = msgQrCode + - `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring( - 0, + `\n\n*Pairing Code:* ${body.qrcode.pairingCode.substring(0, 4)}-${body.qrcode.pairingCode.substring( 4, - )}-${body.qrcode.pairingCode.substring(4, 8)}`; + 8, + )}`; } this.logger.verbose('send message to chatwoot'); @@ -1649,6 +1541,7 @@ export class ChatwootService { requestData['number'] = number; } + // eslint-disable-next-line const config = { method: 'post', maxBodyLength: Infinity, diff --git a/src/whatsapp/services/monitor.service.ts b/src/whatsapp/services/monitor.service.ts index 7ffa81e1..50f671d9 100644 --- a/src/whatsapp/services/monitor.service.ts +++ b/src/whatsapp/services/monitor.service.ts @@ -1,24 +1,15 @@ -import { opendirSync, readdirSync, rmSync } from 'fs'; -import { WAStartupService } from './whatsapp.service'; -import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config'; -import EventEmitter2 from 'eventemitter2'; -import { join } from 'path'; -import { Logger } from '../../config/logger.config'; -import { - Auth, - ConfigService, - Database, - DelInstance, - HttpServer, - Redis, -} from '../../config/env.config'; -import { RepositoryBroker } from '../repository/repository.manager'; -import { NotFoundException } from '../../exceptions'; -import { Db } from 'mongodb'; -import { RedisCache } from '../../db/redis.client'; import { execSync } from 'child_process'; +import EventEmitter2 from 'eventemitter2'; +import { opendirSync, readdirSync, rmSync } from 'fs'; +import { Db } from 'mongodb'; +import { join } from 'path'; + +import { Auth, ConfigService, Database, DelInstance, HttpServer, Redis } from '../../config/env.config'; +import { Logger } from '../../config/logger.config'; +import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config'; import { dbserver } from '../../db/db.connect'; -import mongoose from 'mongoose'; +import { RedisCache } from '../../db/redis.client'; +import { NotFoundException } from '../../exceptions'; import { AuthModel, ChatwootModel, @@ -28,6 +19,8 @@ import { SettingsModel, WebhookModel, } from '../models'; +import { RepositoryBroker } from '../repository/repository.manager'; +import { WAStartupService } from './whatsapp.service'; export class WAMonitoringService { constructor( @@ -63,16 +56,12 @@ export class WAMonitoringService { public delInstanceTime(instance: string) { const time = this.configService.get('DEL_INSTANCE'); if (typeof time === 'number' && time > 0) { - this.logger.verbose( - `Instance "${instance}" don't have connection, will be removed in ${time} minutes`, - ); + this.logger.verbose(`Instance "${instance}" don't have connection, will be removed in ${time} minutes`); setTimeout(async () => { if (this.waInstances[instance]?.connectionStatus?.state !== 'open') { if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') { - await this.waInstances[instance]?.client?.logout( - 'Log out instance: ' + instance, - ); + await this.waInstances[instance]?.client?.logout('Log out instance: ' + instance); this.waInstances[instance]?.client?.ws?.close(); this.waInstances[instance]?.client?.end(undefined); delete this.waInstances[instance]; @@ -124,21 +113,16 @@ export class WAMonitoringService { }; if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { - instanceData.instance['serverUrl'] = - this.configService.get('SERVER').URL; + instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - instanceData.instance['apikey'] = ( - await this.repository.auth.find(key) - ).apikey; + instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; instanceData.instance['chatwoot'] = chatwoot; } instances.push(instanceData); } else { - this.logger.verbose( - 'instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state, - ); + this.logger.verbose('instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state); const instanceData = { instance: { @@ -148,12 +132,9 @@ export class WAMonitoringService { }; if (this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) { - instanceData.instance['serverUrl'] = - this.configService.get('SERVER').URL; + instanceData.instance['serverUrl'] = this.configService.get('SERVER').URL; - instanceData.instance['apikey'] = ( - await this.repository.auth.find(key) - ).apikey; + instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey; instanceData.instance['chatwoot'] = chatwoot; } @@ -176,14 +157,11 @@ export class WAMonitoringService { collections.forEach(async (collection) => { const name = collection.namespace.replace(/^[\w-]+./, ''); await this.dbInstance.collection(name).deleteMany({ - $or: [ - { _id: { $regex: /^app.state.*/ } }, - { _id: { $regex: /^session-.*/ } }, - ], + $or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }], }); this.logger.verbose('instance files deleted: ' + name); }); - } else if (this.redis.ENABLED) { + // } else if (this.redis.ENABLED) { } else { const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' }); for await (const dirent of dir) { @@ -264,12 +242,7 @@ export class WAMonitoringService { public async loadInstance() { this.logger.verbose('load instances'); const set = async (name: string) => { - const instance = new WAStartupService( - this.configService, - this.eventEmitter, - this.repository, - this.cache, - ); + const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache); instance.instanceName = name; this.logger.verbose('instance loaded: ' + name); @@ -299,9 +272,7 @@ export class WAMonitoringService { const collections: any[] = await this.dbInstance.collections(); if (collections.length > 0) { this.logger.verbose('reading collections and setting instances'); - collections.forEach( - async (coll) => await set(coll.namespace.replace(/^[\w-]+\./, '')), - ); + collections.forEach(async (coll) => await set(coll.namespace.replace(/^[\w-]+\./, ''))); } else { this.logger.verbose('no collections found'); } @@ -337,7 +308,9 @@ export class WAMonitoringService { try { this.logger.verbose('instance: ' + instanceName + ' - removing from memory'); this.waInstances[instanceName] = undefined; - } catch {} + } catch (error) { + this.logger.error(error); + } try { this.logger.verbose('request cleaning up instance: ' + instanceName); diff --git a/src/whatsapp/services/settings.service.ts b/src/whatsapp/services/settings.service.ts index 9a82046a..6815ca40 100644 --- a/src/whatsapp/services/settings.service.ts +++ b/src/whatsapp/services/settings.service.ts @@ -1,7 +1,7 @@ +import { Logger } from '../../config/logger.config'; import { InstanceDto } from '../dto/instance.dto'; import { SettingsDto } from '../dto/settings.dto'; import { WAMonitoringService } from './monitor.service'; -import { Logger } from '../../config/logger.config'; export class SettingsService { constructor(private readonly waMonitor: WAMonitoringService) {} @@ -18,9 +18,7 @@ export class SettingsService { public async find(instance: InstanceDto): Promise { try { this.logger.verbose('find settings: ' + instance.instanceName); - const result = await this.waMonitor.waInstances[ - instance.instanceName - ].findSettings(); + const result = await this.waMonitor.waInstances[instance.instanceName].findSettings(); if (Object.keys(result).length === 0) { throw new Error('Settings not found'); diff --git a/src/whatsapp/services/webhook.service.ts b/src/whatsapp/services/webhook.service.ts index 2370e05b..dd0a88cd 100644 --- a/src/whatsapp/services/webhook.service.ts +++ b/src/whatsapp/services/webhook.service.ts @@ -1,7 +1,7 @@ +import { Logger } from '../../config/logger.config'; import { InstanceDto } from '../dto/instance.dto'; import { WebhookDto } from '../dto/webhook.dto'; import { WAMonitoringService } from './monitor.service'; -import { Logger } from '../../config/logger.config'; export class WebhookService { constructor(private readonly waMonitor: WAMonitoringService) {} @@ -18,9 +18,7 @@ export class WebhookService { public async find(instance: InstanceDto): Promise { try { this.logger.verbose('find webhook: ' + instance.instanceName); - const result = await this.waMonitor.waInstances[ - instance.instanceName - ].findWebhook(); + const result = await this.waMonitor.waInstances[instance.instanceName].findWebhook(); if (Object.keys(result).length === 0) { throw new Error('Webhook not found'); diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index 4c9bf62d..6de7d847 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -1,9 +1,10 @@ +import ffmpegPath from '@ffmpeg-installer/ffmpeg'; +import { Boom } from '@hapi/boom'; import makeWASocket, { AnyMessageContent, BufferedEventData, BufferJSON, CacheStore, - makeCacheableSignalKeyStore, Chat, ConnectionState, Contact, @@ -12,11 +13,13 @@ import makeWASocket, { downloadMediaMessage, fetchLatestBaileysVersion, generateWAMessageFromContent, + getAggregateVotesInPollMessage, getContentType, getDevice, GroupMetadata, isJidGroup, isJidUser, + makeCacheableSignalKeyStore, MessageUpsertType, MiscMessageGenerationOptions, ParticipantAction, @@ -29,8 +32,23 @@ import makeWASocket, { WAMessage, WAMessageUpdate, WASocket, - getAggregateVotesInPollMessage, } from '@whiskeysockets/baileys'; +import axios from 'axios'; +import { exec, execSync } from 'child_process'; +import { arrayUnique, isBase64, isURL } from 'class-validator'; +import EventEmitter2 from 'eventemitter2'; +import fs, { existsSync, readFileSync } from 'fs'; +import Long from 'long'; +import NodeCache from 'node-cache'; +import { getMIMEType } from 'node-mime-types'; +import { release } from 'os'; +import { join } from 'path'; +import P from 'pino'; +import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; +import qrcodeTerminal from 'qrcode-terminal'; +import sharp from 'sharp'; +import { v4 } from 'uuid'; + import { Auth, CleanStoreConf, @@ -38,31 +56,41 @@ import { ConfigSessionPhone, Database, HttpServer, + Log, QrCode, Redis, Webhook, } from '../../config/env.config'; -import fs from 'fs'; import { Logger } from '../../config/logger.config'; import { INSTANCE_DIR, ROOT_DIR } from '../../config/path.config'; -import { existsSync, readFileSync } from 'fs'; -import { join } from 'path'; -import axios from 'axios'; -import { v4 } from 'uuid'; -import qrcode, { QRCodeToDataURLOptions } from 'qrcode'; -import qrcodeTerminal from 'qrcode-terminal'; -import { Events, TypeMediaMessage, wa, MessageSubtype } from '../types/wa.types'; -import { Boom } from '@hapi/boom'; -import EventEmitter2 from 'eventemitter2'; -import { release } from 'os'; -import P from 'pino'; -import { execSync, exec } from 'child_process'; -import ffmpegPath from '@ffmpeg-installer/ffmpeg'; -import { RepositoryBroker } from '../repository/repository.manager'; -import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; -import { ContactRaw } from '../models/contact.model'; -import { ChatRaw } from '../models/chat.model'; -import { getMIMEType } from 'node-mime-types'; +import { dbserver } from '../../db/db.connect'; +import { RedisCache } from '../../db/redis.client'; +import { BadRequestException, InternalServerErrorException, NotFoundException } from '../../exceptions'; +import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; +import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; +import { + ArchiveChatDto, + DeleteMessage, + getBase64FromMediaMessageDto, + NumberBusiness, + OnWhatsAppDto, + PrivacySettingDto, + ReadMessageDto, + WhatsAppNumberDto, +} from '../dto/chat.dto'; +import { + CreateGroupDto, + GetParticipant, + GroupDescriptionDto, + GroupInvite, + GroupJid, + GroupPictureDto, + GroupSendInvite, + GroupSubjectDto, + GroupToggleEphemeralDto, + GroupUpdateParticipantDto, + GroupUpdateSettingDto, +} from '../dto/group.dto'; import { ContactMessage, MediaMessage, @@ -73,58 +101,26 @@ import { SendListDto, SendLocationDto, SendMediaDto, - SendReactionDto, - SendTextDto, SendPollDto, - SendStickerDto, + SendReactionDto, SendStatusDto, + SendStickerDto, + SendTextDto, StatusMessage, } from '../dto/sendMessage.dto'; -import { arrayUnique, isBase64, isURL } from 'class-validator'; -import { - ArchiveChatDto, - DeleteMessage, - NumberBusiness, - OnWhatsAppDto, - PrivacySettingDto, - ReadMessageDto, - WhatsAppNumberDto, - getBase64FromMediaMessageDto, -} from '../dto/chat.dto'; -import { MessageQuery } from '../repository/message.repository'; -import { ContactQuery } from '../repository/contact.repository'; -import { - BadRequestException, - InternalServerErrorException, - NotFoundException, -} from '../../exceptions'; -import { - CreateGroupDto, - GroupInvite, - GroupJid, - GroupPictureDto, - GroupUpdateParticipantDto, - GroupUpdateSettingDto, - GroupToggleEphemeralDto, - GroupSubjectDto, - GroupDescriptionDto, - GroupSendInvite, - GetParticipant, -} from '../dto/group.dto'; -import { MessageUpQuery } from '../repository/messageUp.repository'; -import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-db'; -import Long from 'long'; -import { WebhookRaw } from '../models/webhook.model'; -import { ChatwootRaw } from '../models/chatwoot.model'; import { SettingsRaw } from '../models'; -import { dbserver } from '../../db/db.connect'; -import NodeCache from 'node-cache'; -import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db'; -import sharp from 'sharp'; -import { RedisCache } from '../../db/redis.client'; -import { Log } from '../../config/env.config'; -import { ChatwootService } from './chatwoot.service'; +import { ChatRaw } from '../models/chat.model'; +import { ChatwootRaw } from '../models/chatwoot.model'; +import { ContactRaw } from '../models/contact.model'; +import { MessageRaw, MessageUpdateRaw } from '../models/message.model'; +import { WebhookRaw } from '../models/webhook.model'; +import { ContactQuery } from '../repository/contact.repository'; +import { MessageQuery } from '../repository/message.repository'; +import { MessageUpQuery } from '../repository/messageUp.repository'; +import { RepositoryBroker } from '../repository/repository.manager'; +import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types'; import { waMonitor } from '../whatsapp.module'; +import { ChatwootService } from './chatwoot.service'; export class WAStartupService { constructor( @@ -201,10 +197,7 @@ export class WAStartupService { this.logger.verbose('Database enabled, trying to get from database'); const collection = dbserver .getClient() - .db( - this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + - '-instances', - ) + .db(this.configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') .collection(this.instanceName); const data = await collection.findOne({ _id: 'creds' }); if (data) { @@ -316,14 +309,10 @@ export class WAStartupService { 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.logger.verbose(`Chatwoot reopen conversation: ${this.localChatwoot.reopen_conversation}`); this.localChatwoot.conversation_pending = data?.conversation_pending; - this.logger.verbose( - `Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`, - ); + this.logger.verbose(`Chatwoot conversation pending: ${this.localChatwoot.conversation_pending}`); this.logger.verbose('Chatwoot loaded'); } @@ -424,11 +413,10 @@ export class WAStartupService { const webhookGlobal = this.configService.get('WEBHOOK'); const webhookLocal = this.localWebhook.events; const serverUrl = this.configService.get('SERVER').URL; - const we = event.replace(/[\.-]/gm, '_').toUpperCase(); + const we = event.replace(/[.-]/gm, '_').toUpperCase(); const transformedWe = we.replace(/_/gm, '-').toLowerCase(); - const expose = - this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; + const expose = this.configService.get('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES; const tokenStore = await this.repository.auth.find(this.instanceName); const instanceApikey = tokenStore?.apikey || 'Apikey not found'; @@ -437,7 +425,7 @@ export class WAStartupService { if (local) { if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) { this.logger.verbose('Sending data to webhook local'); - let baseURL; + let baseURL: string; if (this.localWebhook.webhook_by_events) { baseURL = `${this.localWebhook.url}/${transformedWe}`; @@ -566,11 +554,7 @@ export class WAStartupService { } } - private async connectionUpdate({ - qr, - connection, - lastDisconnect, - }: Partial) { + private async connectionUpdate({ qr, connection, lastDisconnect }: Partial) { this.logger.verbose('Connection update'); if (qr) { this.logger.verbose('QR code found'); @@ -637,9 +621,7 @@ export class WAStartupService { if (this.phoneNumber) { await delay(2000); - this.instance.qrcode.pairingCode = await this.client.requestPairingCode( - this.phoneNumber, - ); + this.instance.qrcode.pairingCode = await this.client.requestPairingCode(this.phoneNumber); } else { this.instance.qrcode.pairingCode = null; } @@ -704,8 +686,7 @@ export class WAStartupService { if (connection === 'close') { this.logger.verbose('Connection closed'); - const shouldReconnect = - (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; + const shouldReconnect = (lastDisconnect.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; if (shouldReconnect) { this.logger.verbose('Reconnecting to whatsapp'); await this.connectToWhatsapp(); @@ -714,7 +695,7 @@ export class WAStartupService { this.logger.verbose('Sending data to webhook in event STATUS_INSTANCE'); this.sendDataWebhook(Events.STATUS_INSTANCE, { instance: this.instance.name, - status: 'removed', + status: 'closed', }); if (this.localChatwoot.enabled) { @@ -723,7 +704,7 @@ export class WAStartupService { { instanceName: this.instance.name }, { instance: this.instance.name, - status: 'removed', + status: 'closed', }, ); } @@ -739,9 +720,7 @@ export class WAStartupService { if (connection === 'open') { this.logger.verbose('Connection opened'); this.instance.wuid = this.client.user.id.replace(/:\d+/, ''); - this.instance.profilePictureUrl = ( - await this.profilePicture(this.instance.wuid) - ).profilePictureUrl; + this.instance.profilePictureUrl = (await this.profilePicture(this.instance.wuid)).profilePictureUrl; this.logger.info( ` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” @@ -774,8 +753,7 @@ export class WAStartupService { } if (webMessageInfo[0].message?.pollCreationMessage) { this.logger.verbose('Returning poll message'); - const messageSecretBase64 = - webMessageInfo[0].message?.messageContextInfo?.messageSecret; + const messageSecretBase64 = webMessageInfo[0].message?.messageContextInfo?.messageSecret; if (typeof messageSecretBase64 === 'string') { const messageSecret = Buffer.from(messageSecretBase64, 'base64'); @@ -809,22 +787,16 @@ export class WAStartupService { for (const [key, value] of Object.entries(cleanStore)) { if (value === true) { execSync( - `rm -rf ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, + `rm -rf ${join(this.storePath, key.toLowerCase().replace('_', '-'), this.instance.name)}/*.json`, ); this.logger.verbose( - `Cleaned ${join( - this.storePath, - key.toLowerCase().replace('_', '-'), - this.instance.name, - )}/*.json`, + `Cleaned ${join(this.storePath, key.toLowerCase().replace('_', '-'), this.instance.name)}/*.json`, ); } } - } catch (error) {} + } catch (error) { + this.logger.error(error); + } }, (cleanStore?.CLEANING_INTERVAL ?? 3600) * 1000); } } @@ -867,10 +839,7 @@ export class WAStartupService { const socketConfig: UserFacingSocketConfig = { auth: { creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore( - this.instance.authState.state.keys, - P({ level: 'error' }), - ), + keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })), }, logger: P({ level: this.logBaileys }), printQRInTerminal: false, @@ -882,18 +851,13 @@ export class WAStartupService { defaultQueryTimeoutMs: undefined, emitOwnEvents: false, msgRetryCounterCache: this.msgRetryCounterCache, - getMessage: async (key) => - (await this.getMessage(key)) as Promise, + getMessage: async (key) => (await this.getMessage(key)) as Promise, generateHighQualityLinkPreview: true, syncFullHistory: true, userDevicesCache: this.userDevicesCache, transactionOpts: { maxCommitRetries: 1, delayBetweenTriesMs: 10 }, patchMessageBeforeSending: (message) => { - const requiresPatch = !!( - message.buttonsMessage || - message.listMessage || - message.templateMessage - ); + const requiresPatch = !!(message.buttonsMessage || message.listMessage || message.templateMessage); if (requiresPatch) { message = { viewOnceMessageV2: { @@ -956,11 +920,7 @@ export class WAStartupService { await this.sendDataWebhook(Events.CHATS_UPSERT, chatsRaw); this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert( - chatsRaw, - this.instance.name, - database.SAVE_DATA.CHATS, - ); + await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); }, 'chats.update': async ( @@ -1025,11 +985,7 @@ export class WAStartupService { await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactsRaw); this.logger.verbose('Inserting contacts in database'); - await this.repository.contact.insert( - contactsRaw, - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); + await this.repository.contact.insert(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); }, 'contacts.update': async (contacts: Partial[], database: Database) => { @@ -1050,11 +1006,7 @@ export class WAStartupService { await this.sendDataWebhook(Events.CONTACTS_UPDATE, contactsRaw); this.logger.verbose('Updating contacts in database'); - await this.repository.contact.update( - contactsRaw, - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); + await this.repository.contact.update(contactsRaw, this.instance.name, database.SAVE_DATA.CONTACTS); }, }; @@ -1087,11 +1039,7 @@ export class WAStartupService { await this.sendDataWebhook(Events.CHATS_SET, chatsRaw); this.logger.verbose('Inserting chats in database'); - await this.repository.chat.insert( - chatsRaw, - this.instance.name, - database.SAVE_DATA.CHATS, - ); + await this.repository.chat.insert(chatsRaw, this.instance.name, database.SAVE_DATA.CHATS); } const messagesRaw: MessageRaw[] = []; @@ -1102,11 +1050,7 @@ export class WAStartupService { if (!m.message) { continue; } - if ( - messagesRepository.find( - (mr) => mr.owner === this.instance.name && mr.key.id === m.key.id, - ) - ) { + if (messagesRepository.find((mr) => mr.owner === this.instance.name && mr.key.id === m.key.id)) { continue; } @@ -1145,11 +1089,7 @@ export class WAStartupService { this.logger.verbose('Event received: messages.upsert'); const received = messages[0]; - if ( - type !== 'notify' || - received.message?.protocolMessage || - received.message?.pollUpdateMessage - ) { + if (type !== 'notify' || received.message?.protocolMessage || received.message?.pollUpdateMessage) { this.logger.verbose('message rejected'); return; } @@ -1195,11 +1135,7 @@ export class WAStartupService { } this.logger.verbose('Inserting message in database'); - await this.repository.message.insert( - [messageRaw], - this.instance.name, - database.SAVE_DATA.NEW_MESSAGE, - ); + await this.repository.message.insert([messageRaw], this.instance.name, database.SAVE_DATA.NEW_MESSAGE); this.logger.verbose('Verifying contact from message'); const contact = await this.repository.contact.find({ @@ -1209,8 +1145,7 @@ export class WAStartupService { const contactRaw: ContactRaw = { id: received.key.remoteJid, pushName: received.pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) - .profilePictureUrl, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, owner: this.instance.name, }; @@ -1224,8 +1159,7 @@ export class WAStartupService { const contactRaw: ContactRaw = { id: received.key.remoteJid, pushName: contact[0].pushName, - profilePictureUrl: (await this.profilePicture(received.key.remoteJid)) - .profilePictureUrl, + profilePictureUrl: (await this.profilePicture(received.key.remoteJid)).profilePictureUrl, owner: this.instance.name, }; @@ -1241,11 +1175,7 @@ export class WAStartupService { } this.logger.verbose('Updating contact in database'); - await this.repository.contact.update( - [contactRaw], - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); + await this.repository.contact.update([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); return; } @@ -1255,18 +1185,10 @@ export class WAStartupService { await this.sendDataWebhook(Events.CONTACTS_UPSERT, contactRaw); this.logger.verbose('Inserting contact in database'); - await this.repository.contact.insert( - [contactRaw], - this.instance.name, - database.SAVE_DATA.CONTACTS, - ); + await this.repository.contact.insert([contactRaw], this.instance.name, database.SAVE_DATA.CONTACTS); }, - 'messages.update': async ( - args: WAMessageUpdate[], - database: Database, - settings: SettingsRaw, - ) => { + 'messages.update': async (args: WAMessageUpdate[], database: Database, settings: SettingsRaw) => { this.logger.verbose('Event received: messages.update'); const status: Record = { 0: 'ERROR', @@ -1341,11 +1263,7 @@ export class WAStartupService { await this.sendDataWebhook(Events.MESSAGES_UPDATE, message); this.logger.verbose('Inserting message in database'); - await this.repository.messageUpdate.insert( - [message], - this.instance.name, - database.SAVE_DATA.MESSAGE_UPDATE, - ); + await this.repository.messageUpdate.insert([message], this.instance.name, database.SAVE_DATA.MESSAGE_UPDATE); } } }, @@ -1555,7 +1473,7 @@ export class WAStartupService { .replace(/\+/g, '') .replace(/\(/g, '') .replace(/\)/g, '') - .split(/\:/)[0] + .split(':')[0] .split('@')[0]; if (number.includes('-') && number.length >= 24) { @@ -1620,7 +1538,6 @@ export class WAStartupService { this.logger.verbose('Getting profile with jid: ' + jid); try { this.logger.verbose('Getting profile info'); - const info = await waMonitor.instanceInfo(instanceName); const business = await this.fetchBusinessProfile(jid); if (number) { @@ -1667,11 +1584,7 @@ export class WAStartupService { } } - private async sendMessageWithTyping( - number: string, - message: T, - options?: Options, - ) { + private async sendMessageWithTyping(number: string, message: T, options?: Options) { this.logger.verbose('Sending message with typing'); const numberWA = await this.whatsappNumber({ numbers: [number] }); @@ -1691,9 +1604,7 @@ export class WAStartupService { this.logger.verbose('Subscribing to presence'); await this.client.sendPresenceUpdate(options?.presence ?? 'composing', sender); - this.logger.verbose( - 'Sending presence update: ' + options?.presence ?? 'composing', - ); + this.logger.verbose('Sending presence update: ' + options?.presence ?? 'composing'); await delay(options.delay); this.logger.verbose('Set delay: ' + options.delay); @@ -1709,9 +1620,7 @@ export class WAStartupService { if (options?.quoted) { const m = options?.quoted; - const msg = m?.message - ? m - : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); if (!msg) { throw 'Message not found'; @@ -1912,9 +1821,7 @@ export class WAStartupService { } this.logger.verbose('Getting contacts with push name'); - status.statusJidList = contacts - .filter((contact) => contact.pushName) - .map((contact) => contact.id); + status.statusJidList = contacts.filter((contact) => contact.pushName).map((contact) => contact.id); this.logger.verbose(status.statusJidList); } @@ -2031,9 +1938,7 @@ export class WAStartupService { this.logger.verbose('Media type: ' + mediaType); if (mediaMessage.mediatype === 'document' && !mediaMessage.fileName) { - this.logger.verbose( - 'If media type is document and file name is not defined then', - ); + this.logger.verbose('If media type is document and file name is not defined then'); const regex = new RegExp(/.*\/(.+?)\./); const arrayMatch = regex.exec(mediaMessage.media); mediaMessage.fileName = arrayMatch[1]; @@ -2146,11 +2051,7 @@ export class WAStartupService { this.logger.verbose('Sending media message'); const generate = await this.prepareMediaMessage(data.mediaMessage); - return await this.sendMessageWithTyping( - data.number, - { ...generate.message }, - data?.options, - ); + return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options); } private async processAudio(audio: string, number: string) { @@ -2195,18 +2096,15 @@ export class WAStartupService { this.logger.verbose('Converting audio to mp4'); return new Promise((resolve, reject) => { - exec( - `${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, - (error, _stdout, _stderr) => { - fs.unlinkSync(tempAudioPath); - this.logger.verbose('Temp audio deleted'); + exec(`${ffmpegPath.path} -i ${tempAudioPath} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, (error) => { + fs.unlinkSync(tempAudioPath); + this.logger.verbose('Temp audio deleted'); - if (error) reject(error); + if (error) reject(error); - this.logger.verbose('Audio converted to mp4'); - resolve(outputAudio); - }, - ); + this.logger.verbose('Audio converted to mp4'); + resolve(outputAudio); + }); }); } @@ -2272,10 +2170,7 @@ export class WAStartupService { }; if (!arrayUnique(btnItems.text) || !arrayUnique(btnItems.ids)) { - throw new BadRequestException( - 'Button texts cannot be repeated', - 'Button IDs cannot be repeated.', - ); + throw new BadRequestException('Button texts cannot be repeated', 'Button IDs cannot be repeated.'); } return await this.sendMessageWithTyping( @@ -2342,11 +2237,7 @@ export class WAStartupService { const vcard = (contact: ContactMessage) => { this.logger.verbose('Creating vcard'); - let result = - 'BEGIN:VCARD\n' + - 'VERSION:3.0\n' + - `N:${contact.fullName}\n` + - `FN:${contact.fullName}\n`; + let result = 'BEGIN:VCARD\n' + 'VERSION:3.0\n' + `N:${contact.fullName}\n` + `FN:${contact.fullName}\n`; if (contact.organization) { this.logger.verbose('Organization defined'); @@ -2368,10 +2259,7 @@ export class WAStartupService { contact.wuid = this.createJid(contact.phoneNumber); } - result += - `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + - 'item1.X-ABLabel:Celular\n' + - 'END:VCARD'; + result += `item1.TEL;waid=${contact.wuid}:${contact.phoneNumber}\n` + 'item1.X-ABLabel:Celular\n' + 'END:VCARD'; this.logger.verbose('Vcard created'); return result; @@ -2461,8 +2349,7 @@ export class WAStartupService { public async archiveChat(data: ArchiveChatDto) { this.logger.verbose('Archiving chat'); try { - data.lastMessage.messageTimestamp = - data.lastMessage?.messageTimestamp ?? Date.now(); + data.lastMessage.messageTimestamp = data.lastMessage?.messageTimestamp ?? Date.now(); await this.client.chatModify( { archive: data.archive, @@ -2478,10 +2365,7 @@ export class WAStartupService { } catch (error) { throw new InternalServerErrorException({ archived: false, - message: [ - 'An error occurred while archiving the chat. Open a calling.', - error.toString(), - ], + message: ['An error occurred while archiving the chat. Open a calling.', error.toString()], }); } } @@ -2491,10 +2375,7 @@ export class WAStartupService { try { return await this.client.sendMessage(del.remoteJid, { delete: del }); } catch (error) { - throw new InternalServerErrorException( - 'Error while deleting message for everyone', - error?.toString(), - ); + throw new InternalServerErrorException('Error while deleting message for everyone', error?.toString()); } } @@ -2504,9 +2385,7 @@ export class WAStartupService { const m = data?.message; const convertToMp4 = data?.convertToMp4 ?? false; - const msg = m?.message - ? m - : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); + const msg = m?.message ? m : ((await this.getMessage(m.key, true)) as proto.IWebMessageInfo); if (!msg) { throw 'Message not found'; @@ -2696,10 +2575,7 @@ export class WAStartupService { }, }; } catch (error) { - throw new InternalServerErrorException( - 'Error updating privacy settings', - error.toString(), - ); + throw new InternalServerErrorException('Error updating privacy settings', error.toString()); } } @@ -2727,10 +2603,7 @@ export class WAStartupService { ...profile, }; } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile name', - error.toString(), - ); + throw new InternalServerErrorException('Error updating profile name', error.toString()); } } @@ -2741,10 +2614,7 @@ export class WAStartupService { return { update: 'success' }; } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile name', - error.toString(), - ); + throw new InternalServerErrorException('Error updating profile name', error.toString()); } } @@ -2755,10 +2625,7 @@ export class WAStartupService { return { update: 'success' }; } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile status', - error.toString(), - ); + throw new InternalServerErrorException('Error updating profile status', error.toString()); } } @@ -2787,10 +2654,7 @@ export class WAStartupService { return { update: 'success' }; } catch (error) { - throw new InternalServerErrorException( - 'Error updating profile picture', - error.toString(), - ); + throw new InternalServerErrorException('Error updating profile picture', error.toString()); } } @@ -2801,10 +2665,7 @@ export class WAStartupService { return { update: 'success' }; } catch (error) { - throw new InternalServerErrorException( - 'Error removing profile picture', - error.toString(), - ); + throw new InternalServerErrorException('Error removing profile picture', error.toString()); } } @@ -2865,10 +2726,7 @@ export class WAStartupService { return { update: 'success' }; } catch (error) { - throw new InternalServerErrorException( - 'Error update group picture', - error.toString(), - ); + throw new InternalServerErrorException('Error update group picture', error.toString()); } } @@ -2879,10 +2737,7 @@ export class WAStartupService { return { update: 'success' }; } catch (error) { - throw new InternalServerErrorException( - 'Error updating group subject', - error.toString(), - ); + throw new InternalServerErrorException('Error updating group subject', error.toString()); } } @@ -2893,10 +2748,7 @@ export class WAStartupService { return { update: 'success' }; } catch (error) { - throw new InternalServerErrorException( - 'Error updating group description', - error.toString(), - ); + throw new InternalServerErrorException('Error updating group description', error.toString()); } } @@ -3032,10 +2884,7 @@ export class WAStartupService { public async updateGSetting(update: GroupUpdateSettingDto) { this.logger.verbose('Updating setting for group: ' + update.groupJid); try { - const updateSetting = await this.client.groupSettingUpdate( - update.groupJid, - update.action, - ); + const updateSetting = await this.client.groupSettingUpdate(update.groupJid, update.action); return { updateSetting: updateSetting }; } catch (error) { throw new BadRequestException('Error updating setting', error.toString()); @@ -3045,10 +2894,7 @@ export class WAStartupService { public async toggleEphemeral(update: GroupToggleEphemeralDto) { this.logger.verbose('Toggling ephemeral for group: ' + update.groupJid); try { - const toggleEphemeral = await this.client.groupToggleEphemeral( - update.groupJid, - update.expiration, - ); + await this.client.groupToggleEphemeral(update.groupJid, update.expiration); return { success: true }; } catch (error) { throw new BadRequestException('Error updating setting', error.toString()); diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index a0d514d8..d4769a49 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -76,23 +76,10 @@ export declare namespace wa { statusReason?: number; }; - export type StatusMessage = - | 'ERROR' - | 'PENDING' - | 'SERVER_ACK' - | 'DELIVERY_ACK' - | 'READ' - | 'DELETED' - | 'PLAYED'; + export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED'; } -export const TypeMediaMessage = [ - 'imageMessage', - 'documentMessage', - 'audioMessage', - 'videoMessage', - 'stickerMessage', -]; +export const TypeMediaMessage = ['imageMessage', 'documentMessage', 'audioMessage', 'videoMessage', 'stickerMessage']; export const MessageSubtype = [ 'ephemeralMessage', diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index b8f3b1ad..b742afa9 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -1,43 +1,40 @@ -import { Auth, configService } from '../config/env.config'; -import { Logger } from '../config/logger.config'; +import { configService } from '../config/env.config'; import { eventEmitter } from '../config/event.config'; -import { MessageRepository } from './repository/message.repository'; -import { WAMonitoringService } from './services/monitor.service'; -import { ChatRepository } from './repository/chat.repository'; -import { ContactRepository } from './repository/contact.repository'; -import { MessageUpRepository } from './repository/messageUp.repository'; +import { Logger } from '../config/logger.config'; +import { dbserver } from '../db/db.connect'; +import { RedisCache } from '../db/redis.client'; import { ChatController } from './controllers/chat.controller'; +import { ChatwootController } from './controllers/chatwoot.controller'; +import { GroupController } from './controllers/group.controller'; import { InstanceController } from './controllers/instance.controller'; import { SendMessageController } from './controllers/sendMessage.controller'; -import { AuthService } from './services/auth.service'; -import { GroupController } from './controllers/group.controller'; +import { SettingsController } from './controllers/settings.controller'; import { ViewsController } from './controllers/views.controller'; -import { WebhookService } from './services/webhook.service'; import { WebhookController } from './controllers/webhook.controller'; -import { ChatwootService } from './services/chatwoot.service'; -import { ChatwootController } from './controllers/chatwoot.controller'; -import { RepositoryBroker } from './repository/repository.manager'; import { AuthModel, ChatModel, + ChatwootModel, ContactModel, MessageModel, MessageUpModel, - ChatwootModel, - WebhookModel, SettingsModel, + WebhookModel, } from './models'; -import { dbserver } from '../db/db.connect'; -import { WebhookRepository } from './repository/webhook.repository'; -import { ChatwootRepository } from './repository/chatwoot.repository'; import { AuthRepository } from './repository/auth.repository'; -import { WAStartupService } from './services/whatsapp.service'; -import { delay } from '@whiskeysockets/baileys'; -import { Events } from './types/wa.types'; -import { RedisCache } from '../db/redis.client'; +import { ChatRepository } from './repository/chat.repository'; +import { ChatwootRepository } from './repository/chatwoot.repository'; +import { ContactRepository } from './repository/contact.repository'; +import { MessageRepository } from './repository/message.repository'; +import { MessageUpRepository } from './repository/messageUp.repository'; +import { RepositoryBroker } from './repository/repository.manager'; import { SettingsRepository } from './repository/settings.repository'; +import { WebhookRepository } from './repository/webhook.repository'; +import { AuthService } from './services/auth.service'; +import { ChatwootService } from './services/chatwoot.service'; +import { WAMonitoringService } from './services/monitor.service'; import { SettingsService } from './services/settings.service'; -import { SettingsController } from './controllers/settings.controller'; +import { WebhookService } from './services/webhook.service'; const logger = new Logger('WA MODULE'); @@ -65,12 +62,7 @@ export const repository = new RepositoryBroker( export const cache = new RedisCache(); -export const waMonitor = new WAMonitoringService( - eventEmitter, - configService, - repository, - cache, -); +export const waMonitor = new WAMonitoringService(eventEmitter, configService, repository, cache); const authService = new AuthService(configService, waMonitor, repository);