mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-13 07:04:50 -06:00
wip
This commit is contained in:
parent
0a851b935e
commit
dc3d59bae1
@ -4,7 +4,7 @@ module.exports = {
|
|||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
printWidth: 120,
|
printWidth: 120,
|
||||||
arrowParens: 'always',
|
arrowParens: 'always',
|
||||||
tabWidth: 4,
|
tabWidth: 2,
|
||||||
useTabs: false,
|
useTabs: false,
|
||||||
bracketSameLine: false,
|
bracketSameLine: false,
|
||||||
bracketSpacing: true,
|
bracketSpacing: true,
|
||||||
|
@ -7,9 +7,9 @@ export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string };
|
|||||||
|
|
||||||
export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE';
|
export type HttpMethods = 'POST' | 'GET' | 'PUT' | 'DELETE';
|
||||||
export type Cors = {
|
export type Cors = {
|
||||||
ORIGIN: string[];
|
ORIGIN: string[];
|
||||||
METHODS: HttpMethods[];
|
METHODS: HttpMethods[];
|
||||||
CREDENTIALS: boolean;
|
CREDENTIALS: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
export type LogBaileys = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
||||||
@ -17,90 +17,90 @@ 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 = {
|
export type Log = {
|
||||||
LEVEL: LogLevel[];
|
LEVEL: LogLevel[];
|
||||||
COLOR: boolean;
|
COLOR: boolean;
|
||||||
BAILEYS: LogBaileys;
|
BAILEYS: LogBaileys;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SaveData = {
|
export type SaveData = {
|
||||||
INSTANCE: boolean;
|
INSTANCE: boolean;
|
||||||
NEW_MESSAGE: boolean;
|
NEW_MESSAGE: boolean;
|
||||||
MESSAGE_UPDATE: boolean;
|
MESSAGE_UPDATE: boolean;
|
||||||
CONTACTS: boolean;
|
CONTACTS: boolean;
|
||||||
CHATS: boolean;
|
CHATS: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StoreConf = {
|
export type StoreConf = {
|
||||||
MESSAGES: boolean;
|
MESSAGES: boolean;
|
||||||
MESSAGE_UP: boolean;
|
MESSAGE_UP: boolean;
|
||||||
CONTACTS: boolean;
|
CONTACTS: boolean;
|
||||||
CHATS: boolean;
|
CHATS: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CleanStoreConf = {
|
export type CleanStoreConf = {
|
||||||
CLEANING_INTERVAL: number;
|
CLEANING_INTERVAL: number;
|
||||||
MESSAGES: boolean;
|
MESSAGES: boolean;
|
||||||
MESSAGE_UP: boolean;
|
MESSAGE_UP: boolean;
|
||||||
CONTACTS: boolean;
|
CONTACTS: boolean;
|
||||||
CHATS: boolean;
|
CHATS: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DBConnection = {
|
export type DBConnection = {
|
||||||
URI: string;
|
URI: string;
|
||||||
DB_PREFIX_NAME: string;
|
DB_PREFIX_NAME: string;
|
||||||
};
|
};
|
||||||
export type Database = {
|
export type Database = {
|
||||||
CONNECTION: DBConnection;
|
CONNECTION: DBConnection;
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
SAVE_DATA: SaveData;
|
SAVE_DATA: SaveData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Redis = {
|
export type Redis = {
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
URI: string;
|
URI: string;
|
||||||
PREFIX_KEY: string;
|
PREFIX_KEY: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EventsWebhook = {
|
export type EventsWebhook = {
|
||||||
APPLICATION_STARTUP: boolean;
|
APPLICATION_STARTUP: boolean;
|
||||||
QRCODE_UPDATED: boolean;
|
QRCODE_UPDATED: boolean;
|
||||||
MESSAGES_SET: boolean;
|
MESSAGES_SET: boolean;
|
||||||
MESSAGES_UPSERT: boolean;
|
MESSAGES_UPSERT: boolean;
|
||||||
MESSAGES_UPDATE: boolean;
|
MESSAGES_UPDATE: boolean;
|
||||||
MESSAGES_DELETE: boolean;
|
MESSAGES_DELETE: boolean;
|
||||||
SEND_MESSAGE: boolean;
|
SEND_MESSAGE: boolean;
|
||||||
CONTACTS_SET: boolean;
|
CONTACTS_SET: boolean;
|
||||||
CONTACTS_UPDATE: boolean;
|
CONTACTS_UPDATE: boolean;
|
||||||
CONTACTS_UPSERT: boolean;
|
CONTACTS_UPSERT: boolean;
|
||||||
PRESENCE_UPDATE: boolean;
|
PRESENCE_UPDATE: boolean;
|
||||||
CHATS_SET: boolean;
|
CHATS_SET: boolean;
|
||||||
CHATS_UPDATE: boolean;
|
CHATS_UPDATE: boolean;
|
||||||
CHATS_DELETE: boolean;
|
CHATS_DELETE: boolean;
|
||||||
CHATS_UPSERT: boolean;
|
CHATS_UPSERT: boolean;
|
||||||
CONNECTION_UPDATE: boolean;
|
CONNECTION_UPDATE: boolean;
|
||||||
GROUPS_UPSERT: boolean;
|
GROUPS_UPSERT: boolean;
|
||||||
GROUP_UPDATE: boolean;
|
GROUP_UPDATE: boolean;
|
||||||
GROUP_PARTICIPANTS_UPDATE: boolean;
|
GROUP_PARTICIPANTS_UPDATE: boolean;
|
||||||
CALL: boolean;
|
CALL: boolean;
|
||||||
NEW_JWT_TOKEN: boolean;
|
NEW_JWT_TOKEN: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ApiKey = { KEY: string };
|
export type ApiKey = { KEY: string };
|
||||||
export type Jwt = { EXPIRIN_IN: number; SECRET: string };
|
export type Jwt = { EXPIRIN_IN: number; SECRET: string };
|
||||||
|
|
||||||
export type Auth = {
|
export type Auth = {
|
||||||
API_KEY: ApiKey;
|
API_KEY: ApiKey;
|
||||||
EXPOSE_IN_FETCH_INSTANCES: boolean;
|
EXPOSE_IN_FETCH_INSTANCES: boolean;
|
||||||
JWT: Jwt;
|
JWT: Jwt;
|
||||||
TYPE: 'jwt' | 'apikey';
|
TYPE: 'jwt' | 'apikey';
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DelInstance = number | boolean;
|
export type DelInstance = number | boolean;
|
||||||
|
|
||||||
export type GlobalWebhook = {
|
export type GlobalWebhook = {
|
||||||
URL: string;
|
URL: string;
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
WEBHOOK_BY_EVENTS: boolean;
|
WEBHOOK_BY_EVENTS: boolean;
|
||||||
};
|
};
|
||||||
export type SslConf = { PRIVKEY: string; FULLCHAIN: string };
|
export type SslConf = { PRIVKEY: string; FULLCHAIN: string };
|
||||||
export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook };
|
export type Webhook = { GLOBAL?: GlobalWebhook; EVENTS: EventsWebhook };
|
||||||
@ -109,158 +109,158 @@ export type QrCode = { LIMIT: number };
|
|||||||
export type Production = boolean;
|
export type Production = boolean;
|
||||||
|
|
||||||
export interface Env {
|
export interface Env {
|
||||||
SERVER: HttpServer;
|
SERVER: HttpServer;
|
||||||
CORS: Cors;
|
CORS: Cors;
|
||||||
SSL_CONF: SslConf;
|
SSL_CONF: SslConf;
|
||||||
STORE: StoreConf;
|
STORE: StoreConf;
|
||||||
CLEAN_STORE: CleanStoreConf;
|
CLEAN_STORE: CleanStoreConf;
|
||||||
DATABASE: Database;
|
DATABASE: Database;
|
||||||
REDIS: Redis;
|
REDIS: Redis;
|
||||||
LOG: Log;
|
LOG: Log;
|
||||||
DEL_INSTANCE: DelInstance;
|
DEL_INSTANCE: DelInstance;
|
||||||
WEBHOOK: Webhook;
|
WEBHOOK: Webhook;
|
||||||
CONFIG_SESSION_PHONE: ConfigSessionPhone;
|
CONFIG_SESSION_PHONE: ConfigSessionPhone;
|
||||||
QRCODE: QrCode;
|
QRCODE: QrCode;
|
||||||
AUTHENTICATION: Auth;
|
AUTHENTICATION: Auth;
|
||||||
PRODUCTION?: Production;
|
PRODUCTION?: Production;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Key = keyof Env;
|
export type Key = keyof Env;
|
||||||
|
|
||||||
export class ConfigService {
|
export class ConfigService {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.loadEnv();
|
this.loadEnv();
|
||||||
}
|
}
|
||||||
|
|
||||||
private env: Env;
|
private env: Env;
|
||||||
|
|
||||||
public get<T = any>(key: Key) {
|
public get<T = any>(key: Key) {
|
||||||
return this.env[key] as T;
|
return this.env[key] as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadEnv() {
|
private loadEnv() {
|
||||||
this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess();
|
this.env = !(process.env?.DOCKER_ENV === 'true') ? this.envYaml() : this.envProcess();
|
||||||
this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD';
|
this.env.PRODUCTION = process.env?.NODE_ENV === 'PROD';
|
||||||
if (process.env?.DOCKER_ENV === 'true') {
|
if (process.env?.DOCKER_ENV === 'true') {
|
||||||
this.env.SERVER.TYPE = 'http';
|
this.env.SERVER.TYPE = 'http';
|
||||||
this.env.SERVER.PORT = 8080;
|
this.env.SERVER.PORT = 8080;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private envYaml(): Env {
|
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 {
|
private envProcess(): Env {
|
||||||
return {
|
return {
|
||||||
SERVER: {
|
SERVER: {
|
||||||
TYPE: process.env.SERVER_TYPE as 'http' | 'https',
|
TYPE: process.env.SERVER_TYPE as 'http' | 'https',
|
||||||
PORT: Number.parseInt(process.env.SERVER_PORT),
|
PORT: Number.parseInt(process.env.SERVER_PORT),
|
||||||
URL: process.env.SERVER_URL,
|
URL: process.env.SERVER_URL,
|
||||||
},
|
},
|
||||||
CORS: {
|
CORS: {
|
||||||
ORIGIN: process.env.CORS_ORIGIN.split(','),
|
ORIGIN: process.env.CORS_ORIGIN.split(','),
|
||||||
METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[],
|
METHODS: process.env.CORS_METHODS.split(',') as HttpMethods[],
|
||||||
CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true',
|
CREDENTIALS: process.env?.CORS_CREDENTIALS === 'true',
|
||||||
},
|
},
|
||||||
SSL_CONF: {
|
SSL_CONF: {
|
||||||
PRIVKEY: process.env?.SSL_CONF_PRIVKEY,
|
PRIVKEY: process.env?.SSL_CONF_PRIVKEY,
|
||||||
FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN,
|
FULLCHAIN: process.env?.SSL_CONF_FULLCHAIN,
|
||||||
},
|
},
|
||||||
STORE: {
|
STORE: {
|
||||||
MESSAGES: process.env?.STORE_MESSAGES === 'true',
|
MESSAGES: process.env?.STORE_MESSAGES === 'true',
|
||||||
MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true',
|
MESSAGE_UP: process.env?.STORE_MESSAGE_UP === 'true',
|
||||||
CONTACTS: process.env?.STORE_CONTACTS === 'true',
|
CONTACTS: process.env?.STORE_CONTACTS === 'true',
|
||||||
CHATS: process.env?.STORE_CHATS === 'true',
|
CHATS: process.env?.STORE_CHATS === 'true',
|
||||||
},
|
},
|
||||||
CLEAN_STORE: {
|
CLEAN_STORE: {
|
||||||
CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL)
|
CLEANING_INTERVAL: Number.isInteger(process.env?.CLEAN_STORE_CLEANING_TERMINAL)
|
||||||
? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL)
|
? Number.parseInt(process.env.CLEAN_STORE_CLEANING_TERMINAL)
|
||||||
: 7200,
|
: 7200,
|
||||||
MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true',
|
MESSAGES: process.env?.CLEAN_STORE_MESSAGES === 'true',
|
||||||
MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true',
|
MESSAGE_UP: process.env?.CLEAN_STORE_MESSAGE_UP === 'true',
|
||||||
CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true',
|
CONTACTS: process.env?.CLEAN_STORE_CONTACTS === 'true',
|
||||||
CHATS: process.env?.CLEAN_STORE_CHATS === 'true',
|
CHATS: process.env?.CLEAN_STORE_CHATS === 'true',
|
||||||
},
|
},
|
||||||
DATABASE: {
|
DATABASE: {
|
||||||
CONNECTION: {
|
CONNECTION: {
|
||||||
URI: process.env.DATABASE_CONNECTION_URI,
|
URI: process.env.DATABASE_CONNECTION_URI,
|
||||||
DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME,
|
DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME,
|
||||||
},
|
},
|
||||||
ENABLED: process.env?.DATABASE_ENABLED === 'true',
|
ENABLED: process.env?.DATABASE_ENABLED === 'true',
|
||||||
SAVE_DATA: {
|
SAVE_DATA: {
|
||||||
INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true',
|
INSTANCE: process.env?.DATABASE_SAVE_DATA_INSTANCE === 'true',
|
||||||
NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true',
|
NEW_MESSAGE: process.env?.DATABASE_SAVE_DATA_NEW_MESSAGE === 'true',
|
||||||
MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true',
|
MESSAGE_UPDATE: process.env?.DATABASE_SAVE_MESSAGE_UPDATE === 'true',
|
||||||
CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true',
|
CONTACTS: process.env?.DATABASE_SAVE_DATA_CONTACTS === 'true',
|
||||||
CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true',
|
CHATS: process.env?.DATABASE_SAVE_DATA_CHATS === 'true',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
REDIS: {
|
REDIS: {
|
||||||
ENABLED: process.env?.REDIS_ENABLED === 'true',
|
ENABLED: process.env?.REDIS_ENABLED === 'true',
|
||||||
URI: process.env.REDIS_URI,
|
URI: process.env.REDIS_URI,
|
||||||
PREFIX_KEY: process.env.REDIS_PREFIX_KEY,
|
PREFIX_KEY: process.env.REDIS_PREFIX_KEY,
|
||||||
},
|
},
|
||||||
LOG: {
|
LOG: {
|
||||||
LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[],
|
LEVEL: process.env?.LOG_LEVEL.split(',') as LogLevel[],
|
||||||
COLOR: process.env?.LOG_COLOR === 'true',
|
COLOR: process.env?.LOG_COLOR === 'true',
|
||||||
BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error',
|
BAILEYS: (process.env?.LOG_BAILEYS as LogBaileys) || 'error',
|
||||||
},
|
},
|
||||||
DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE)
|
DEL_INSTANCE: isBooleanString(process.env?.DEL_INSTANCE)
|
||||||
? process.env.DEL_INSTANCE === 'true'
|
? process.env.DEL_INSTANCE === 'true'
|
||||||
: Number.parseInt(process.env.DEL_INSTANCE) || false,
|
: Number.parseInt(process.env.DEL_INSTANCE) || false,
|
||||||
WEBHOOK: {
|
WEBHOOK: {
|
||||||
GLOBAL: {
|
GLOBAL: {
|
||||||
URL: process.env?.WEBHOOK_GLOBAL_URL,
|
URL: process.env?.WEBHOOK_GLOBAL_URL,
|
||||||
ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true',
|
ENABLED: process.env?.WEBHOOK_GLOBAL_ENABLED === 'true',
|
||||||
WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true',
|
WEBHOOK_BY_EVENTS: process.env?.WEBHOOK_GLOBAL_WEBHOOK_BY_EVENTS === 'true',
|
||||||
},
|
},
|
||||||
EVENTS: {
|
EVENTS: {
|
||||||
APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true',
|
APPLICATION_STARTUP: process.env?.WEBHOOK_EVENTS_APPLICATION_STARTUP === 'true',
|
||||||
QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true',
|
QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true',
|
||||||
MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true',
|
MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true',
|
||||||
MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true',
|
MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true',
|
||||||
MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true',
|
MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true',
|
||||||
MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true',
|
MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true',
|
||||||
SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true',
|
SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true',
|
||||||
CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true',
|
CONTACTS_SET: process.env?.WEBHOOK_EVENTS_CONTACTS_SET === 'true',
|
||||||
CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true',
|
CONTACTS_UPDATE: process.env?.WEBHOOK_EVENTS_CONTACTS_UPDATE === 'true',
|
||||||
CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true',
|
CONTACTS_UPSERT: process.env?.WEBHOOK_EVENTS_CONTACTS_UPSERT === 'true',
|
||||||
PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true',
|
PRESENCE_UPDATE: process.env?.WEBHOOK_EVENTS_PRESENCE_UPDATE === 'true',
|
||||||
CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true',
|
CHATS_SET: process.env?.WEBHOOK_EVENTS_CHATS_SET === 'true',
|
||||||
CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true',
|
CHATS_UPDATE: process.env?.WEBHOOK_EVENTS_CHATS_UPDATE === 'true',
|
||||||
CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true',
|
CHATS_UPSERT: process.env?.WEBHOOK_EVENTS_CHATS_UPSERT === 'true',
|
||||||
CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true',
|
CHATS_DELETE: process.env?.WEBHOOK_EVENTS_CHATS_DELETE === 'true',
|
||||||
CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true',
|
CONNECTION_UPDATE: process.env?.WEBHOOK_EVENTS_CONNECTION_UPDATE === 'true',
|
||||||
GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true',
|
GROUPS_UPSERT: process.env?.WEBHOOK_EVENTS_GROUPS_UPSERT === 'true',
|
||||||
GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === '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',
|
CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true',
|
||||||
NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true',
|
NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CONFIG_SESSION_PHONE: {
|
CONFIG_SESSION_PHONE: {
|
||||||
CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API',
|
CLIENT: process.env?.CONFIG_SESSION_PHONE_CLIENT || 'Evolution API',
|
||||||
NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome',
|
NAME: process.env?.CONFIG_SESSION_PHONE_NAME || 'chrome',
|
||||||
},
|
},
|
||||||
QRCODE: {
|
QRCODE: {
|
||||||
LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30,
|
LIMIT: Number.parseInt(process.env.QRCODE_LIMIT) || 30,
|
||||||
},
|
},
|
||||||
AUTHENTICATION: {
|
AUTHENTICATION: {
|
||||||
TYPE: process.env.AUTHENTICATION_TYPE as 'jwt',
|
TYPE: process.env.AUTHENTICATION_TYPE as 'jwt',
|
||||||
API_KEY: {
|
API_KEY: {
|
||||||
KEY: process.env.AUTHENTICATION_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: {
|
JWT: {
|
||||||
EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN)
|
EXPIRIN_IN: Number.isInteger(process.env?.AUTHENTICATION_JWT_EXPIRIN_IN)
|
||||||
? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN)
|
? Number.parseInt(process.env.AUTHENTICATION_JWT_EXPIRIN_IN)
|
||||||
: 3600,
|
: 3600,
|
||||||
SECRET: process.env.AUTHENTICATION_JWT_SECRET,
|
SECRET: process.env.AUTHENTICATION_JWT_SECRET,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const configService = new ConfigService();
|
export const configService = new ConfigService();
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
import { Logger } from './logger.config';
|
import { Logger } from './logger.config';
|
||||||
|
|
||||||
export function onUnexpectedError() {
|
export function onUnexpectedError() {
|
||||||
process.on('uncaughtException', (error, origin) => {
|
process.on('uncaughtException', (error, origin) => {
|
||||||
const logger = new Logger('uncaughtException');
|
const logger = new Logger('uncaughtException');
|
||||||
logger.error({
|
logger.error({
|
||||||
origin,
|
origin,
|
||||||
stderr: process.stderr.fd,
|
stderr: process.stderr.fd,
|
||||||
error,
|
error,
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
process.on('unhandledRejection', (error, origin) => {
|
process.on('unhandledRejection', (error, origin) => {
|
||||||
const logger = new Logger('unhandledRejection');
|
const logger = new Logger('unhandledRejection');
|
||||||
logger.error({
|
logger.error({
|
||||||
origin,
|
origin,
|
||||||
stderr: process.stderr.fd,
|
stderr: process.stderr.fd,
|
||||||
error,
|
error,
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import EventEmitter2 from 'eventemitter2';
|
import EventEmitter2 from 'eventemitter2';
|
||||||
|
|
||||||
export const eventEmitter = new EventEmitter2({
|
export const eventEmitter = new EventEmitter2({
|
||||||
delimiter: '.',
|
delimiter: '.',
|
||||||
newListener: false,
|
newListener: false,
|
||||||
ignoreErrors: false,
|
ignoreErrors: false,
|
||||||
});
|
});
|
||||||
|
@ -3,135 +3,135 @@ import dayjs from 'dayjs';
|
|||||||
import { configService, Log } from './env.config';
|
import { configService, Log } from './env.config';
|
||||||
|
|
||||||
const formatDateLog = (timestamp: number) =>
|
const formatDateLog = (timestamp: number) =>
|
||||||
dayjs(timestamp)
|
dayjs(timestamp)
|
||||||
.toDate()
|
.toDate()
|
||||||
.toString()
|
.toString()
|
||||||
.replace(/\sGMT.+/, '');
|
.replace(/\sGMT.+/, '');
|
||||||
|
|
||||||
enum Color {
|
enum Color {
|
||||||
LOG = '\x1b[32m',
|
LOG = '\x1b[32m',
|
||||||
INFO = '\x1b[34m',
|
INFO = '\x1b[34m',
|
||||||
WARN = '\x1b[33m',
|
WARN = '\x1b[33m',
|
||||||
ERROR = '\x1b[31m',
|
ERROR = '\x1b[31m',
|
||||||
DEBUG = '\x1b[36m',
|
DEBUG = '\x1b[36m',
|
||||||
VERBOSE = '\x1b[37m',
|
VERBOSE = '\x1b[37m',
|
||||||
DARK = '\x1b[30m',
|
DARK = '\x1b[30m',
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Command {
|
enum Command {
|
||||||
RESET = '\x1b[0m',
|
RESET = '\x1b[0m',
|
||||||
BRIGHT = '\x1b[1m',
|
BRIGHT = '\x1b[1m',
|
||||||
UNDERSCORE = '\x1b[4m',
|
UNDERSCORE = '\x1b[4m',
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Level {
|
enum Level {
|
||||||
LOG = Color.LOG + '%s' + Command.RESET,
|
LOG = Color.LOG + '%s' + Command.RESET,
|
||||||
DARK = Color.DARK + '%s' + Command.RESET,
|
DARK = Color.DARK + '%s' + Command.RESET,
|
||||||
INFO = Color.INFO + '%s' + Command.RESET,
|
INFO = Color.INFO + '%s' + Command.RESET,
|
||||||
WARN = Color.WARN + '%s' + Command.RESET,
|
WARN = Color.WARN + '%s' + Command.RESET,
|
||||||
ERROR = Color.ERROR + '%s' + Command.RESET,
|
ERROR = Color.ERROR + '%s' + Command.RESET,
|
||||||
DEBUG = Color.DEBUG + '%s' + Command.RESET,
|
DEBUG = Color.DEBUG + '%s' + Command.RESET,
|
||||||
VERBOSE = Color.VERBOSE + '%s' + Command.RESET,
|
VERBOSE = Color.VERBOSE + '%s' + Command.RESET,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
LOG = 'LOG',
|
LOG = 'LOG',
|
||||||
WARN = 'WARN',
|
WARN = 'WARN',
|
||||||
INFO = 'INFO',
|
INFO = 'INFO',
|
||||||
DARK = 'DARK',
|
DARK = 'DARK',
|
||||||
ERROR = 'ERROR',
|
ERROR = 'ERROR',
|
||||||
DEBUG = 'DEBUG',
|
DEBUG = 'DEBUG',
|
||||||
VERBOSE = 'VERBOSE',
|
VERBOSE = 'VERBOSE',
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Background {
|
enum Background {
|
||||||
LOG = '\x1b[42m',
|
LOG = '\x1b[42m',
|
||||||
INFO = '\x1b[44m',
|
INFO = '\x1b[44m',
|
||||||
WARN = '\x1b[43m',
|
WARN = '\x1b[43m',
|
||||||
DARK = '\x1b[40m',
|
DARK = '\x1b[40m',
|
||||||
ERROR = '\x1b[41m',
|
ERROR = '\x1b[41m',
|
||||||
DEBUG = '\x1b[46m',
|
DEBUG = '\x1b[46m',
|
||||||
VERBOSE = '\x1b[47m',
|
VERBOSE = '\x1b[47m',
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Logger {
|
export class Logger {
|
||||||
private readonly configService = configService;
|
private readonly configService = configService;
|
||||||
constructor(private context = 'Logger') {}
|
constructor(private context = 'Logger') {}
|
||||||
|
|
||||||
public setContext(value: string) {
|
public setContext(value: string) {
|
||||||
this.context = value;
|
this.context = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private console(value: any, type: Type) {
|
||||||
|
const types: Type[] = [];
|
||||||
|
|
||||||
|
this.configService.get<Log>('LOG').LEVEL.forEach((level) => types.push(Type[level]));
|
||||||
|
|
||||||
|
const typeValue = typeof value;
|
||||||
|
if (types.includes(type)) {
|
||||||
|
if (configService.get<Log>('LOG').COLOR) {
|
||||||
|
console.log(
|
||||||
|
/*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type],
|
||||||
|
'[Evolution API]',
|
||||||
|
Command.BRIGHT + Color[type],
|
||||||
|
process.pid.toString(),
|
||||||
|
Command.RESET,
|
||||||
|
Command.BRIGHT + Color[type],
|
||||||
|
'-',
|
||||||
|
Command.BRIGHT + Color.VERBOSE,
|
||||||
|
`${formatDateLog(Date.now())} `,
|
||||||
|
Command.RESET,
|
||||||
|
Color[type] + Background[type] + Command.BRIGHT,
|
||||||
|
`${type} ` + Command.RESET,
|
||||||
|
Color.WARN + Command.BRIGHT,
|
||||||
|
`[${this.context}]` + Command.RESET,
|
||||||
|
Color[type] + Command.BRIGHT,
|
||||||
|
`[${typeValue}]` + Command.RESET,
|
||||||
|
Color[type],
|
||||||
|
typeValue !== 'object' ? value : '',
|
||||||
|
Command.RESET,
|
||||||
|
);
|
||||||
|
typeValue === 'object' ? console.log(/*Level.DARK,*/ value, '\n') : '';
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
'[Evolution API]',
|
||||||
|
process.pid.toString(),
|
||||||
|
'-',
|
||||||
|
`${formatDateLog(Date.now())} `,
|
||||||
|
`${type} `,
|
||||||
|
`[${this.context}]`,
|
||||||
|
`[${typeValue}]`,
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private console(value: any, type: Type) {
|
public log(value: any) {
|
||||||
const types: Type[] = [];
|
this.console(value, Type.LOG);
|
||||||
|
}
|
||||||
|
|
||||||
this.configService.get<Log>('LOG').LEVEL.forEach((level) => types.push(Type[level]));
|
public info(value: any) {
|
||||||
|
this.console(value, Type.INFO);
|
||||||
|
}
|
||||||
|
|
||||||
const typeValue = typeof value;
|
public warn(value: any) {
|
||||||
if (types.includes(type)) {
|
this.console(value, Type.WARN);
|
||||||
if (configService.get<Log>('LOG').COLOR) {
|
}
|
||||||
console.log(
|
|
||||||
/*Command.UNDERSCORE +*/ Command.BRIGHT + Level[type],
|
|
||||||
'[Evolution API]',
|
|
||||||
Command.BRIGHT + Color[type],
|
|
||||||
process.pid.toString(),
|
|
||||||
Command.RESET,
|
|
||||||
Command.BRIGHT + Color[type],
|
|
||||||
'-',
|
|
||||||
Command.BRIGHT + Color.VERBOSE,
|
|
||||||
`${formatDateLog(Date.now())} `,
|
|
||||||
Command.RESET,
|
|
||||||
Color[type] + Background[type] + Command.BRIGHT,
|
|
||||||
`${type} ` + Command.RESET,
|
|
||||||
Color.WARN + Command.BRIGHT,
|
|
||||||
`[${this.context}]` + Command.RESET,
|
|
||||||
Color[type] + Command.BRIGHT,
|
|
||||||
`[${typeValue}]` + Command.RESET,
|
|
||||||
Color[type],
|
|
||||||
typeValue !== 'object' ? value : '',
|
|
||||||
Command.RESET,
|
|
||||||
);
|
|
||||||
typeValue === 'object' ? console.log(/*Level.DARK,*/ value, '\n') : '';
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
'[Evolution API]',
|
|
||||||
process.pid.toString(),
|
|
||||||
'-',
|
|
||||||
`${formatDateLog(Date.now())} `,
|
|
||||||
`${type} `,
|
|
||||||
`[${this.context}]`,
|
|
||||||
`[${typeValue}]`,
|
|
||||||
value,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public log(value: any) {
|
public error(value: any) {
|
||||||
this.console(value, Type.LOG);
|
this.console(value, Type.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public info(value: any) {
|
public verbose(value: any) {
|
||||||
this.console(value, Type.INFO);
|
this.console(value, Type.VERBOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public warn(value: any) {
|
public debug(value: any) {
|
||||||
this.console(value, Type.WARN);
|
this.console(value, Type.DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public error(value: any) {
|
public dark(value: any) {
|
||||||
this.console(value, Type.ERROR);
|
this.console(value, Type.DARK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public verbose(value: any) {
|
|
||||||
this.console(value, Type.VERBOSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public debug(value: any) {
|
|
||||||
this.console(value, Type.DEBUG);
|
|
||||||
}
|
|
||||||
|
|
||||||
public dark(value: any) {
|
|
||||||
this.console(value, Type.DARK);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,19 +7,19 @@ const logger = new Logger('MongoDB');
|
|||||||
|
|
||||||
const db = configService.get<Database>('DATABASE');
|
const db = configService.get<Database>('DATABASE');
|
||||||
export const dbserver = (() => {
|
export const dbserver = (() => {
|
||||||
if (db.ENABLED) {
|
if (db.ENABLED) {
|
||||||
logger.verbose('connecting');
|
logger.verbose('connecting');
|
||||||
const dbs = mongoose.createConnection(db.CONNECTION.URI, {
|
const dbs = mongoose.createConnection(db.CONNECTION.URI, {
|
||||||
dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api',
|
dbName: db.CONNECTION.DB_PREFIX_NAME + '-whatsapp-api',
|
||||||
});
|
});
|
||||||
logger.verbose('connected in ' + db.CONNECTION.URI);
|
logger.verbose('connected in ' + db.CONNECTION.URI);
|
||||||
logger.info('ON - dbName: ' + dbs['$dbName']);
|
logger.info('ON - dbName: ' + dbs['$dbName']);
|
||||||
|
|
||||||
process.on('beforeExit', () => {
|
process.on('beforeExit', () => {
|
||||||
logger.verbose('instance destroyed');
|
logger.verbose('instance destroyed');
|
||||||
dbserver.destroy(true, (error) => logger.error(error));
|
dbserver.destroy(true, (error) => logger.error(error));
|
||||||
});
|
});
|
||||||
|
|
||||||
return dbs;
|
return dbs;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -5,101 +5,101 @@ import { Redis } from '../config/env.config';
|
|||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
|
|
||||||
export class RedisCache {
|
export class RedisCache {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.logger.verbose('instance created');
|
this.logger.verbose('instance created');
|
||||||
process.on('beforeExit', async () => {
|
process.on('beforeExit', async () => {
|
||||||
this.logger.verbose('instance destroyed');
|
this.logger.verbose('instance destroyed');
|
||||||
if (this.statusConnection) {
|
if (this.statusConnection) {
|
||||||
this.logger.verbose('instance disconnect');
|
this.logger.verbose('instance disconnect');
|
||||||
await this.client.disconnect();
|
await this.client.disconnect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private statusConnection = false;
|
||||||
|
private instanceName: string;
|
||||||
|
private redisEnv: Redis;
|
||||||
|
|
||||||
|
public set reference(reference: string) {
|
||||||
|
this.logger.verbose('set reference: ' + reference);
|
||||||
|
this.instanceName = reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async connect(redisEnv: Redis) {
|
||||||
|
this.logger.verbose('connecting');
|
||||||
|
this.client = createClient({ url: redisEnv.URI });
|
||||||
|
this.logger.verbose('connected in ' + redisEnv.URI);
|
||||||
|
await this.client.connect();
|
||||||
|
this.statusConnection = true;
|
||||||
|
this.redisEnv = redisEnv;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger(RedisCache.name);
|
||||||
|
private client: RedisClientType;
|
||||||
|
|
||||||
|
public async instanceKeys(): Promise<string[]> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*');
|
||||||
|
return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private statusConnection = false;
|
public async keyExists(key?: string) {
|
||||||
private instanceName: string;
|
if (key) {
|
||||||
private redisEnv: Redis;
|
this.logger.verbose('keyExists: ' + key);
|
||||||
|
return !!(await this.instanceKeys()).find((i) => i === key);
|
||||||
public set reference(reference: string) {
|
|
||||||
this.logger.verbose('set reference: ' + reference);
|
|
||||||
this.instanceName = reference;
|
|
||||||
}
|
}
|
||||||
|
this.logger.verbose('keyExists: ' + this.instanceName);
|
||||||
|
return !!(await this.instanceKeys()).find((i) => i === this.instanceName);
|
||||||
|
}
|
||||||
|
|
||||||
public async connect(redisEnv: Redis) {
|
public async writeData(field: string, data: any) {
|
||||||
this.logger.verbose('connecting');
|
try {
|
||||||
this.client = createClient({ url: redisEnv.URI });
|
this.logger.verbose('writeData: ' + field);
|
||||||
this.logger.verbose('connected in ' + redisEnv.URI);
|
const json = JSON.stringify(data, BufferJSON.replacer);
|
||||||
await this.client.connect();
|
|
||||||
this.statusConnection = true;
|
return await this.client.hSet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, json);
|
||||||
this.redisEnv = redisEnv;
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger(RedisCache.name);
|
public async readData(field: string) {
|
||||||
private client: RedisClientType;
|
try {
|
||||||
|
this.logger.verbose('readData: ' + field);
|
||||||
|
const data = await this.client.hGet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field);
|
||||||
|
|
||||||
public async instanceKeys(): Promise<string[]> {
|
if (data) {
|
||||||
try {
|
this.logger.verbose('readData: ' + field + ' success');
|
||||||
this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*');
|
return JSON.parse(data, BufferJSON.reviver);
|
||||||
return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']);
|
}
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
this.logger.verbose('readData: ' + field + ' not found');
|
||||||
}
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async keyExists(key?: string) {
|
public async removeData(field: string) {
|
||||||
if (key) {
|
try {
|
||||||
this.logger.verbose('keyExists: ' + key);
|
this.logger.verbose('removeData: ' + field);
|
||||||
return !!(await this.instanceKeys()).find((i) => i === key);
|
return await this.client.hDel(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field);
|
||||||
}
|
} catch (error) {
|
||||||
this.logger.verbose('keyExists: ' + this.instanceName);
|
this.logger.error(error);
|
||||||
return !!(await this.instanceKeys()).find((i) => i === this.instanceName);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async writeData(field: string, data: any) {
|
public async delAll(hash?: string) {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('writeData: ' + field);
|
this.logger.verbose('instance delAll: ' + hash);
|
||||||
const json = JSON.stringify(data, BufferJSON.replacer);
|
const result = await this.client.del(hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName);
|
||||||
|
|
||||||
return await this.client.hSet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, json);
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async readData(field: string) {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('readData: ' + field);
|
|
||||||
const data = await this.client.hGet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field);
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
this.logger.verbose('readData: ' + field + ' success');
|
|
||||||
return JSON.parse(data, BufferJSON.reviver);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('readData: ' + field + ' not found');
|
|
||||||
return null;
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async removeData(field: string) {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('removeData: ' + field);
|
|
||||||
return await this.client.hDel(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field);
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { HttpStatus } from '../whatsapp/routers/index.router';
|
import { HttpStatus } from '../whatsapp/routers/index.router';
|
||||||
|
|
||||||
export class BadRequestException {
|
export class BadRequestException {
|
||||||
constructor(...objectError: any[]) {
|
constructor(...objectError: any[]) {
|
||||||
throw {
|
throw {
|
||||||
status: HttpStatus.BAD_REQUEST,
|
status: HttpStatus.BAD_REQUEST,
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
message: objectError.length > 0 ? objectError : undefined,
|
message: objectError.length > 0 ? objectError : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { HttpStatus } from '../whatsapp/routers/index.router';
|
import { HttpStatus } from '../whatsapp/routers/index.router';
|
||||||
|
|
||||||
export class UnauthorizedException {
|
export class UnauthorizedException {
|
||||||
constructor(...objectError: any[]) {
|
constructor(...objectError: any[]) {
|
||||||
throw {
|
throw {
|
||||||
status: HttpStatus.UNAUTHORIZED,
|
status: HttpStatus.UNAUTHORIZED,
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
message: objectError.length > 0 ? objectError : undefined,
|
message: objectError.length > 0 ? objectError : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { HttpStatus } from '../whatsapp/routers/index.router';
|
import { HttpStatus } from '../whatsapp/routers/index.router';
|
||||||
|
|
||||||
export class ForbiddenException {
|
export class ForbiddenException {
|
||||||
constructor(...objectError: any[]) {
|
constructor(...objectError: any[]) {
|
||||||
throw {
|
throw {
|
||||||
status: HttpStatus.FORBIDDEN,
|
status: HttpStatus.FORBIDDEN,
|
||||||
error: 'Forbidden',
|
error: 'Forbidden',
|
||||||
message: objectError.length > 0 ? objectError : undefined,
|
message: objectError.length > 0 ? objectError : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { HttpStatus } from '../whatsapp/routers/index.router';
|
import { HttpStatus } from '../whatsapp/routers/index.router';
|
||||||
|
|
||||||
export class NotFoundException {
|
export class NotFoundException {
|
||||||
constructor(...objectError: any[]) {
|
constructor(...objectError: any[]) {
|
||||||
throw {
|
throw {
|
||||||
status: HttpStatus.NOT_FOUND,
|
status: HttpStatus.NOT_FOUND,
|
||||||
error: 'Not Found',
|
error: 'Not Found',
|
||||||
message: objectError.length > 0 ? objectError : undefined,
|
message: objectError.length > 0 ? objectError : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { HttpStatus } from '../whatsapp/routers/index.router';
|
import { HttpStatus } from '../whatsapp/routers/index.router';
|
||||||
|
|
||||||
export class InternalServerErrorException {
|
export class InternalServerErrorException {
|
||||||
constructor(...objectError: any[]) {
|
constructor(...objectError: any[]) {
|
||||||
throw {
|
throw {
|
||||||
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
error: 'Internal Server Error',
|
error: 'Internal Server Error',
|
||||||
message: objectError.length > 0 ? objectError : undefined,
|
message: objectError.length > 0 ? objectError : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
136
src/main.ts
136
src/main.ts
@ -15,94 +15,94 @@ import { HttpStatus, router } from './whatsapp/routers/index.router';
|
|||||||
import { waMonitor } from './whatsapp/whatsapp.module';
|
import { waMonitor } from './whatsapp/whatsapp.module';
|
||||||
|
|
||||||
function initWA() {
|
function initWA() {
|
||||||
waMonitor.loadInstance();
|
waMonitor.loadInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
function bootstrap() {
|
function bootstrap() {
|
||||||
const logger = new Logger('SERVER');
|
const logger = new Logger('SERVER');
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
// Sentry.init({
|
// Sentry.init({
|
||||||
// dsn: '',
|
// dsn: '',
|
||||||
// integrations: [
|
// integrations: [
|
||||||
// // enable HTTP calls tracing
|
// // enable HTTP calls tracing
|
||||||
// new Sentry.Integrations.Http({ tracing: true }),
|
// new Sentry.Integrations.Http({ tracing: true }),
|
||||||
// // enable Express.js middleware tracing
|
// // enable Express.js middleware tracing
|
||||||
// new Sentry.Integrations.Express({ app }),
|
// new Sentry.Integrations.Express({ app }),
|
||||||
// // Automatically instrument Node.js libraries and frameworks
|
// // Automatically instrument Node.js libraries and frameworks
|
||||||
// ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(),
|
// ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(),
|
||||||
// ],
|
// ],
|
||||||
|
|
||||||
// // Set tracesSampleRate to 1.0 to capture 100%
|
// // Set tracesSampleRate to 1.0 to capture 100%
|
||||||
// // of transactions for performance monitoring.
|
// // of transactions for performance monitoring.
|
||||||
// // We recommend adjusting this value in production
|
// // We recommend adjusting this value in production
|
||||||
// tracesSampleRate: 1.0,
|
// tracesSampleRate: 1.0,
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// app.use(Sentry.Handlers.requestHandler());
|
// app.use(Sentry.Handlers.requestHandler());
|
||||||
|
|
||||||
// app.use(Sentry.Handlers.tracingHandler());
|
// app.use(Sentry.Handlers.tracingHandler());
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
cors({
|
cors({
|
||||||
origin(requestOrigin, callback) {
|
origin(requestOrigin, callback) {
|
||||||
const { ORIGIN } = configService.get<Cors>('CORS');
|
const { ORIGIN } = configService.get<Cors>('CORS');
|
||||||
!requestOrigin ? (requestOrigin = '*') : undefined;
|
!requestOrigin ? (requestOrigin = '*') : undefined;
|
||||||
if (ORIGIN.indexOf(requestOrigin) !== -1) {
|
if (ORIGIN.indexOf(requestOrigin) !== -1) {
|
||||||
return callback(null, true);
|
return callback(null, true);
|
||||||
}
|
}
|
||||||
return callback(new Error('Not allowed by CORS'));
|
return callback(new Error('Not allowed by CORS'));
|
||||||
},
|
},
|
||||||
methods: [...configService.get<Cors>('CORS').METHODS],
|
methods: [...configService.get<Cors>('CORS').METHODS],
|
||||||
credentials: configService.get<Cors>('CORS').CREDENTIALS,
|
credentials: configService.get<Cors>('CORS').CREDENTIALS,
|
||||||
}),
|
}),
|
||||||
urlencoded({ extended: true, limit: '136mb' }),
|
urlencoded({ extended: true, limit: '136mb' }),
|
||||||
json({ limit: '136mb' }),
|
json({ limit: '136mb' }),
|
||||||
compression(),
|
compression(),
|
||||||
);
|
);
|
||||||
|
|
||||||
app.set('view engine', 'hbs');
|
app.set('view engine', 'hbs');
|
||||||
app.set('views', join(ROOT_DIR, 'views'));
|
app.set('views', join(ROOT_DIR, 'views'));
|
||||||
app.use(express.static(join(ROOT_DIR, 'public')));
|
app.use(express.static(join(ROOT_DIR, 'public')));
|
||||||
|
|
||||||
app.use('/', router);
|
app.use('/', router);
|
||||||
|
|
||||||
// app.use(Sentry.Handlers.errorHandler());
|
// app.use(Sentry.Handlers.errorHandler());
|
||||||
|
|
||||||
// app.use(function onError(err, req, res, next) {
|
// app.use(function onError(err, req, res, next) {
|
||||||
// res.statusCode = 500;
|
// res.statusCode = 500;
|
||||||
// res.end(res.sentry + '\n');
|
// res.end(res.sentry + '\n');
|
||||||
// });
|
// });
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
(err: Error, req: Request, res: Response) => {
|
(err: Error, req: Request, res: Response) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(err['status'] || 500).json(err);
|
return res.status(err['status'] || 500).json(err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(req: Request, res: Response, next: NextFunction) => {
|
(req: Request, res: Response, next: NextFunction) => {
|
||||||
const { method, url } = req;
|
const { method, url } = req;
|
||||||
|
|
||||||
res.status(HttpStatus.NOT_FOUND).json({
|
res.status(HttpStatus.NOT_FOUND).json({
|
||||||
status: HttpStatus.NOT_FOUND,
|
status: HttpStatus.NOT_FOUND,
|
||||||
message: `Cannot ${method.toUpperCase()} ${url}`,
|
message: `Cannot ${method.toUpperCase()} ${url}`,
|
||||||
error: 'Not Found',
|
error: 'Not Found',
|
||||||
});
|
});
|
||||||
|
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const httpServer = configService.get<HttpServer>('SERVER');
|
const httpServer = configService.get<HttpServer>('SERVER');
|
||||||
|
|
||||||
ServerUP.app = app;
|
ServerUP.app = app;
|
||||||
const server = ServerUP[httpServer.TYPE];
|
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();
|
initWA();
|
||||||
|
|
||||||
onUnexpectedError();
|
onUnexpectedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap();
|
bootstrap();
|
||||||
|
@ -6,24 +6,24 @@ import * as https from 'https';
|
|||||||
import { configService, SslConf } from '../config/env.config';
|
import { configService, SslConf } from '../config/env.config';
|
||||||
|
|
||||||
export class ServerUP {
|
export class ServerUP {
|
||||||
static #app: Express;
|
static #app: Express;
|
||||||
|
|
||||||
static set app(e: Express) {
|
static set app(e: Express) {
|
||||||
this.#app = e;
|
this.#app = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get https() {
|
static get https() {
|
||||||
const { FULLCHAIN, PRIVKEY } = configService.get<SslConf>('SSL_CONF');
|
const { FULLCHAIN, PRIVKEY } = configService.get<SslConf>('SSL_CONF');
|
||||||
return https.createServer(
|
return https.createServer(
|
||||||
{
|
{
|
||||||
cert: readFileSync(FULLCHAIN),
|
cert: readFileSync(FULLCHAIN),
|
||||||
key: readFileSync(PRIVKEY),
|
key: readFileSync(PRIVKEY),
|
||||||
},
|
},
|
||||||
ServerUP.#app,
|
ServerUP.#app,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get http() {
|
static get http() {
|
||||||
return http.createServer(ServerUP.#app);
|
return http.createServer(ServerUP.#app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
AuthenticationCreds,
|
AuthenticationCreds,
|
||||||
AuthenticationState,
|
AuthenticationState,
|
||||||
BufferJSON,
|
BufferJSON,
|
||||||
initAuthCreds,
|
initAuthCreds,
|
||||||
proto,
|
proto,
|
||||||
SignalDataTypeMap,
|
SignalDataTypeMap,
|
||||||
} from '@whiskeysockets/baileys';
|
} from '@whiskeysockets/baileys';
|
||||||
|
|
||||||
import { configService, Database } from '../config/env.config';
|
import { configService, Database } from '../config/env.config';
|
||||||
@ -12,86 +12,86 @@ import { Logger } from '../config/logger.config';
|
|||||||
import { dbserver } from '../db/db.connect';
|
import { dbserver } from '../db/db.connect';
|
||||||
|
|
||||||
export async function useMultiFileAuthStateDb(
|
export async function useMultiFileAuthStateDb(
|
||||||
coll: string,
|
coll: string,
|
||||||
): Promise<{ state: AuthenticationState; saveCreds: () => Promise<void> }> {
|
): Promise<{ state: AuthenticationState; saveCreds: () => Promise<void> }> {
|
||||||
const logger = new Logger(useMultiFileAuthStateDb.name);
|
const logger = new Logger(useMultiFileAuthStateDb.name);
|
||||||
|
|
||||||
const client = dbserver.getClient();
|
const client = dbserver.getClient();
|
||||||
|
|
||||||
const collection = client
|
const collection = client
|
||||||
.db(configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances')
|
.db(configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||||
.collection(coll);
|
.collection(coll);
|
||||||
|
|
||||||
const writeData = async (data: any, key: string): Promise<any> => {
|
const writeData = async (data: any, key: string): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
await client.connect();
|
await client.connect();
|
||||||
return await collection.replaceOne({ _id: key }, JSON.parse(JSON.stringify(data, BufferJSON.replacer)), {
|
return await collection.replaceOne({ _id: key }, JSON.parse(JSON.stringify(data, BufferJSON.replacer)), {
|
||||||
upsert: true,
|
upsert: true,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error);
|
logger.error(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const readData = async (key: string): Promise<any> => {
|
const readData = async (key: string): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
await client.connect();
|
await client.connect();
|
||||||
const data = await collection.findOne({ _id: key });
|
const data = await collection.findOne({ _id: key });
|
||||||
const creds = JSON.stringify(data);
|
const creds = JSON.stringify(data);
|
||||||
return JSON.parse(creds, BufferJSON.reviver);
|
return JSON.parse(creds, BufferJSON.reviver);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error);
|
logger.error(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeData = async (key: string) => {
|
const removeData = async (key: string) => {
|
||||||
try {
|
try {
|
||||||
await client.connect();
|
await client.connect();
|
||||||
return await collection.deleteOne({ _id: key });
|
return await collection.deleteOne({ _id: key });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error);
|
logger.error(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds();
|
const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state: {
|
state: {
|
||||||
creds,
|
creds,
|
||||||
keys: {
|
keys: {
|
||||||
get: async (type, ids: string[]) => {
|
get: async (type, ids: string[]) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const data: { [_: string]: SignalDataTypeMap[type] } = {};
|
const data: { [_: string]: SignalDataTypeMap[type] } = {};
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
ids.map(async (id) => {
|
ids.map(async (id) => {
|
||||||
let value = await readData(`${type}-${id}`);
|
let value = await readData(`${type}-${id}`);
|
||||||
if (type === 'app-state-sync-key' && value) {
|
if (type === 'app-state-sync-key' && value) {
|
||||||
value = proto.Message.AppStateSyncKeyData.fromObject(value);
|
value = proto.Message.AppStateSyncKeyData.fromObject(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
data[id] = value;
|
data[id] = value;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
|
||||||
set: async (data: any) => {
|
|
||||||
const tasks: Promise<void>[] = [];
|
|
||||||
for (const category in data) {
|
|
||||||
for (const id in data[category]) {
|
|
||||||
const value = data[category][id];
|
|
||||||
const key = `${category}-${id}`;
|
|
||||||
tasks.push(value ? writeData(value, key) : removeData(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(tasks);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
saveCreds: async () => {
|
set: async (data: any) => {
|
||||||
return writeData(creds, 'creds');
|
const tasks: Promise<void>[] = [];
|
||||||
|
for (const category in data) {
|
||||||
|
for (const id in data[category]) {
|
||||||
|
const value = data[category][id];
|
||||||
|
const key = `${category}-${id}`;
|
||||||
|
tasks.push(value ? writeData(value, key) : removeData(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(tasks);
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
|
},
|
||||||
|
saveCreds: async () => {
|
||||||
|
return writeData(creds, 'creds');
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,84 +1,84 @@
|
|||||||
import {
|
import {
|
||||||
AuthenticationCreds,
|
AuthenticationCreds,
|
||||||
AuthenticationState,
|
AuthenticationState,
|
||||||
initAuthCreds,
|
initAuthCreds,
|
||||||
proto,
|
proto,
|
||||||
SignalDataTypeMap,
|
SignalDataTypeMap,
|
||||||
} from '@whiskeysockets/baileys';
|
} from '@whiskeysockets/baileys';
|
||||||
|
|
||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
import { RedisCache } from '../db/redis.client';
|
import { RedisCache } from '../db/redis.client';
|
||||||
|
|
||||||
export async function useMultiFileAuthStateRedisDb(cache: RedisCache): Promise<{
|
export async function useMultiFileAuthStateRedisDb(cache: RedisCache): Promise<{
|
||||||
state: AuthenticationState;
|
state: AuthenticationState;
|
||||||
saveCreds: () => Promise<void>;
|
saveCreds: () => Promise<void>;
|
||||||
}> {
|
}> {
|
||||||
const logger = new Logger(useMultiFileAuthStateRedisDb.name);
|
const logger = new Logger(useMultiFileAuthStateRedisDb.name);
|
||||||
|
|
||||||
const writeData = async (data: any, key: string): Promise<any> => {
|
const writeData = async (data: any, key: string): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
return await cache.writeData(key, data);
|
return await cache.writeData(key, data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return logger.error({ localError: 'writeData', error });
|
return logger.error({ localError: 'writeData', error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const readData = async (key: string): Promise<any> => {
|
const readData = async (key: string): Promise<any> => {
|
||||||
try {
|
try {
|
||||||
return await cache.readData(key);
|
return await cache.readData(key);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error({ readData: 'writeData', error });
|
logger.error({ readData: 'writeData', error });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeData = async (key: string) => {
|
const removeData = async (key: string) => {
|
||||||
try {
|
try {
|
||||||
return await cache.removeData(key);
|
return await cache.removeData(key);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error({ readData: 'removeData', error });
|
logger.error({ readData: 'removeData', error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds();
|
const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state: {
|
state: {
|
||||||
creds,
|
creds,
|
||||||
keys: {
|
keys: {
|
||||||
get: async (type, ids: string[]) => {
|
get: async (type, ids: string[]) => {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const data: { [_: string]: SignalDataTypeMap[type] } = {};
|
const data: { [_: string]: SignalDataTypeMap[type] } = {};
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
ids.map(async (id) => {
|
ids.map(async (id) => {
|
||||||
let value = await readData(`${type}-${id}`);
|
let value = await readData(`${type}-${id}`);
|
||||||
if (type === 'app-state-sync-key' && value) {
|
if (type === 'app-state-sync-key' && value) {
|
||||||
value = proto.Message.AppStateSyncKeyData.fromObject(value);
|
value = proto.Message.AppStateSyncKeyData.fromObject(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
data[id] = value;
|
data[id] = value;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
|
||||||
set: async (data: any) => {
|
|
||||||
const tasks: Promise<void>[] = [];
|
|
||||||
for (const category in data) {
|
|
||||||
for (const id in data[category]) {
|
|
||||||
const value = data[category][id];
|
|
||||||
const key = `${category}-${id}`;
|
|
||||||
tasks.push(value ? await writeData(value, key) : await removeData(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(tasks);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
saveCreds: async () => {
|
set: async (data: any) => {
|
||||||
return await writeData(creds, 'creds');
|
const tasks: Promise<void>[] = [];
|
||||||
|
for (const category in data) {
|
||||||
|
for (const id in data[category]) {
|
||||||
|
const value = data[category][id];
|
||||||
|
const key = `${category}-${id}`;
|
||||||
|
tasks.push(value ? await writeData(value, key) : await removeData(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(tasks);
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
|
},
|
||||||
|
saveCreds: async () => {
|
||||||
|
return await writeData(creds, 'creds');
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,61 +7,61 @@ import { ROOT_DIR } from '../../config/path.config';
|
|||||||
export type IInsert = { insertCount: number };
|
export type IInsert = { insertCount: number };
|
||||||
|
|
||||||
export interface IRepository {
|
export interface IRepository {
|
||||||
insert(data: any, instanceName: string, saveDb?: boolean): Promise<IInsert>;
|
insert(data: any, instanceName: string, saveDb?: boolean): Promise<IInsert>;
|
||||||
update(data: any, instanceName: string, saveDb?: boolean): Promise<IInsert>;
|
update(data: any, instanceName: string, saveDb?: boolean): Promise<IInsert>;
|
||||||
find(query: any): Promise<any>;
|
find(query: any): Promise<any>;
|
||||||
delete(query: any, force?: boolean): Promise<any>;
|
delete(query: any, force?: boolean): Promise<any>;
|
||||||
|
|
||||||
dbSettings: Database;
|
dbSettings: Database;
|
||||||
readonly storePath: string;
|
readonly storePath: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type WriteStore<U> = {
|
type WriteStore<U> = {
|
||||||
path: string;
|
path: string;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
data: U;
|
data: U;
|
||||||
};
|
};
|
||||||
|
|
||||||
export abstract class Repository implements IRepository {
|
export abstract class Repository implements IRepository {
|
||||||
constructor(configService: ConfigService) {
|
constructor(configService: ConfigService) {
|
||||||
this.dbSettings = configService.get<Database>('DATABASE');
|
this.dbSettings = configService.get<Database>('DATABASE');
|
||||||
|
}
|
||||||
|
|
||||||
|
dbSettings: Database;
|
||||||
|
readonly storePath = join(ROOT_DIR, 'store');
|
||||||
|
|
||||||
|
public writeStore = <T = any>(create: WriteStore<T>) => {
|
||||||
|
if (!existsSync(create.path)) {
|
||||||
|
mkdirSync(create.path, { recursive: true });
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
writeFileSync(join(create.path, create.fileName + '.json'), JSON.stringify({ ...create.data }), {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
});
|
||||||
|
|
||||||
dbSettings: Database;
|
return { message: 'create - success' };
|
||||||
readonly storePath = join(ROOT_DIR, 'store');
|
} finally {
|
||||||
|
create.data = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public writeStore = <T = any>(create: WriteStore<T>) => {
|
// eslint-disable-next-line
|
||||||
if (!existsSync(create.path)) {
|
|
||||||
mkdirSync(create.path, { recursive: true });
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
writeFileSync(join(create.path, create.fileName + '.json'), JSON.stringify({ ...create.data }), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
});
|
|
||||||
|
|
||||||
return { message: 'create - success' };
|
|
||||||
} finally {
|
|
||||||
create.data = undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
|
||||||
public insert(data: any, instanceName: string, saveDb = false): Promise<IInsert> {
|
public insert(data: any, instanceName: string, saveDb = false): Promise<IInsert> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
public update(data: any, instanceName: string, saveDb = false): Promise<IInsert> {
|
public update(data: any, instanceName: string, saveDb = false): Promise<IInsert> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
public find(query: any): Promise<any> {
|
public find(query: any): Promise<any> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
delete(query: any, force?: boolean): Promise<any> {
|
delete(query: any, force?: boolean): Promise<any> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,214 +10,211 @@ import { GetParticipant, GroupInvite, GroupJid } from '../dto/group.dto';
|
|||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
|
|
||||||
type DataValidate<T> = {
|
type DataValidate<T> = {
|
||||||
request: Request;
|
request: Request;
|
||||||
schema: JSONSchema7;
|
schema: JSONSchema7;
|
||||||
ClassRef: any;
|
ClassRef: any;
|
||||||
execute: (instance: InstanceDto, data: T) => Promise<any>;
|
execute: (instance: InstanceDto, data: T) => Promise<any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const logger = new Logger('Validate');
|
const logger = new Logger('Validate');
|
||||||
|
|
||||||
export abstract class RouterBroker {
|
export abstract class RouterBroker {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
public routerPath(path: string, param = true) {
|
public routerPath(path: string, param = true) {
|
||||||
// const route = param ? '/:instanceName/' + path : '/' + path;
|
// const route = param ? '/:instanceName/' + path : '/' + path;
|
||||||
let route = '/' + path;
|
let route = '/' + path;
|
||||||
param ? (route += '/:instanceName') : null;
|
param ? (route += '/:instanceName') : null;
|
||||||
|
|
||||||
return route;
|
return route;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async dataValidate<T>(args: DataValidate<T>) {
|
||||||
|
const { request, schema, ClassRef, execute } = args;
|
||||||
|
|
||||||
|
const ref = new ClassRef();
|
||||||
|
const body = request.body;
|
||||||
|
const instance = request.params as unknown as InstanceDto;
|
||||||
|
|
||||||
|
if (request?.query && Object.keys(request.query).length > 0) {
|
||||||
|
Object.assign(instance, request.query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async dataValidate<T>(args: DataValidate<T>) {
|
if (request.originalUrl.includes('/instance/create')) {
|
||||||
const { request, schema, ClassRef, execute } = args;
|
Object.assign(instance, body);
|
||||||
|
|
||||||
const ref = new ClassRef();
|
|
||||||
const body = request.body;
|
|
||||||
const instance = request.params as unknown as InstanceDto;
|
|
||||||
|
|
||||||
if (request?.query && Object.keys(request.query).length > 0) {
|
|
||||||
Object.assign(instance, request.query);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.originalUrl.includes('/instance/create')) {
|
|
||||||
Object.assign(instance, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(ref, body);
|
|
||||||
|
|
||||||
const v = schema ? validate(ref, schema) : { valid: true, errors: [] };
|
|
||||||
|
|
||||||
if (!v.valid) {
|
|
||||||
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
|
||||||
let message: string;
|
|
||||||
if (schema['description']) {
|
|
||||||
message = schema['description'];
|
|
||||||
} else {
|
|
||||||
message = stack.replace('instance.', '');
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
property: property.replace('instance.', ''),
|
|
||||||
message,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
logger.error([...message]);
|
|
||||||
throw new BadRequestException(...message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await execute(instance, ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async groupNoValidate<T>(args: DataValidate<T>) {
|
Object.assign(ref, body);
|
||||||
const { request, ClassRef, schema, execute } = args;
|
|
||||||
|
|
||||||
const instance = request.params as unknown as InstanceDto;
|
const v = schema ? validate(ref, schema) : { valid: true, errors: [] };
|
||||||
|
|
||||||
const ref = new ClassRef();
|
if (!v.valid) {
|
||||||
|
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
||||||
Object.assign(ref, request.body);
|
let message: string;
|
||||||
|
if (schema['description']) {
|
||||||
const v = validate(ref, schema);
|
message = schema['description'];
|
||||||
|
} else {
|
||||||
if (!v.valid) {
|
message = stack.replace('instance.', '');
|
||||||
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
|
||||||
let message: string;
|
|
||||||
if (schema['description']) {
|
|
||||||
message = schema['description'];
|
|
||||||
} else {
|
|
||||||
message = stack.replace('instance.', '');
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
property: property.replace('instance.', ''),
|
|
||||||
message,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
logger.error([...message]);
|
|
||||||
throw new BadRequestException(...message);
|
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
return await execute(instance, ref);
|
property: property.replace('instance.', ''),
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
logger.error([...message]);
|
||||||
|
throw new BadRequestException(...message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async groupValidate<T>(args: DataValidate<T>) {
|
return await execute(instance, ref);
|
||||||
const { request, ClassRef, schema, execute } = args;
|
}
|
||||||
|
|
||||||
const groupJid = request.query as unknown as GroupJid;
|
public async groupNoValidate<T>(args: DataValidate<T>) {
|
||||||
|
const { request, ClassRef, schema, execute } = args;
|
||||||
|
|
||||||
if (!groupJid?.groupJid) {
|
const instance = request.params as unknown as InstanceDto;
|
||||||
throw new BadRequestException(
|
|
||||||
'The group id needs to be informed in the query',
|
const ref = new ClassRef();
|
||||||
'ex: "groupJid=120362@g.us"',
|
|
||||||
);
|
Object.assign(ref, request.body);
|
||||||
|
|
||||||
|
const v = validate(ref, schema);
|
||||||
|
|
||||||
|
if (!v.valid) {
|
||||||
|
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
||||||
|
let message: string;
|
||||||
|
if (schema['description']) {
|
||||||
|
message = schema['description'];
|
||||||
|
} else {
|
||||||
|
message = stack.replace('instance.', '');
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
const instance = request.params as unknown as InstanceDto;
|
property: property.replace('instance.', ''),
|
||||||
const body = request.body;
|
message,
|
||||||
|
};
|
||||||
const ref = new ClassRef();
|
});
|
||||||
|
logger.error([...message]);
|
||||||
Object.assign(body, groupJid);
|
throw new BadRequestException(...message);
|
||||||
Object.assign(ref, body);
|
|
||||||
|
|
||||||
const v = validate(ref, schema);
|
|
||||||
|
|
||||||
if (!v.valid) {
|
|
||||||
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
|
||||||
let message: string;
|
|
||||||
if (schema['description']) {
|
|
||||||
message = schema['description'];
|
|
||||||
} else {
|
|
||||||
message = stack.replace('instance.', '');
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
property: property.replace('instance.', ''),
|
|
||||||
message,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
logger.error([...message]);
|
|
||||||
throw new BadRequestException(...message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await execute(instance, ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async inviteCodeValidate<T>(args: DataValidate<T>) {
|
return await execute(instance, ref);
|
||||||
const { request, ClassRef, schema, execute } = args;
|
}
|
||||||
|
|
||||||
const inviteCode = request.query as unknown as GroupInvite;
|
public async groupValidate<T>(args: DataValidate<T>) {
|
||||||
|
const { request, ClassRef, schema, execute } = args;
|
||||||
|
|
||||||
if (!inviteCode?.inviteCode) {
|
const groupJid = request.query as unknown as GroupJid;
|
||||||
throw new BadRequestException(
|
|
||||||
'The group invite code id needs to be informed in the query',
|
|
||||||
'ex: "inviteCode=F1EX5QZxO181L3TMVP31gY" (Obtained from group join link)',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const instance = request.params as unknown as InstanceDto;
|
if (!groupJid?.groupJid) {
|
||||||
const body = request.body;
|
throw new BadRequestException('The group id needs to be informed in the query', 'ex: "groupJid=120362@g.us"');
|
||||||
|
|
||||||
const ref = new ClassRef();
|
|
||||||
|
|
||||||
Object.assign(body, inviteCode);
|
|
||||||
Object.assign(ref, body);
|
|
||||||
|
|
||||||
const v = validate(ref, schema);
|
|
||||||
|
|
||||||
if (!v.valid) {
|
|
||||||
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
|
||||||
let message: string;
|
|
||||||
if (schema['description']) {
|
|
||||||
message = schema['description'];
|
|
||||||
} else {
|
|
||||||
message = stack.replace('instance.', '');
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
property: property.replace('instance.', ''),
|
|
||||||
message,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
logger.error([...message]);
|
|
||||||
throw new BadRequestException(...message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await execute(instance, ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getParticipantsValidate<T>(args: DataValidate<T>) {
|
const instance = request.params as unknown as InstanceDto;
|
||||||
const { request, ClassRef, schema, execute } = args;
|
const body = request.body;
|
||||||
|
|
||||||
const getParticipants = request.query as unknown as GetParticipant;
|
const ref = new ClassRef();
|
||||||
|
|
||||||
if (!getParticipants?.getParticipants) {
|
Object.assign(body, groupJid);
|
||||||
throw new BadRequestException('The getParticipants needs to be informed in the query');
|
Object.assign(ref, body);
|
||||||
|
|
||||||
|
const v = validate(ref, schema);
|
||||||
|
|
||||||
|
if (!v.valid) {
|
||||||
|
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
||||||
|
let message: string;
|
||||||
|
if (schema['description']) {
|
||||||
|
message = schema['description'];
|
||||||
|
} else {
|
||||||
|
message = stack.replace('instance.', '');
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
const instance = request.params as unknown as InstanceDto;
|
property: property.replace('instance.', ''),
|
||||||
const body = request.body;
|
message,
|
||||||
|
};
|
||||||
const ref = new ClassRef();
|
});
|
||||||
|
logger.error([...message]);
|
||||||
Object.assign(body, getParticipants);
|
throw new BadRequestException(...message);
|
||||||
Object.assign(ref, body);
|
|
||||||
|
|
||||||
const v = validate(ref, schema);
|
|
||||||
|
|
||||||
if (!v.valid) {
|
|
||||||
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
|
||||||
let message: string;
|
|
||||||
if (schema['description']) {
|
|
||||||
message = schema['description'];
|
|
||||||
} else {
|
|
||||||
message = stack.replace('instance.', '');
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
property: property.replace('instance.', ''),
|
|
||||||
message,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
logger.error([...message]);
|
|
||||||
throw new BadRequestException(...message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await execute(instance, ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return await execute(instance, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async inviteCodeValidate<T>(args: DataValidate<T>) {
|
||||||
|
const { request, ClassRef, schema, execute } = args;
|
||||||
|
|
||||||
|
const inviteCode = request.query as unknown as GroupInvite;
|
||||||
|
|
||||||
|
if (!inviteCode?.inviteCode) {
|
||||||
|
throw new BadRequestException(
|
||||||
|
'The group invite code id needs to be informed in the query',
|
||||||
|
'ex: "inviteCode=F1EX5QZxO181L3TMVP31gY" (Obtained from group join link)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = request.params as unknown as InstanceDto;
|
||||||
|
const body = request.body;
|
||||||
|
|
||||||
|
const ref = new ClassRef();
|
||||||
|
|
||||||
|
Object.assign(body, inviteCode);
|
||||||
|
Object.assign(ref, body);
|
||||||
|
|
||||||
|
const v = validate(ref, schema);
|
||||||
|
|
||||||
|
if (!v.valid) {
|
||||||
|
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
||||||
|
let message: string;
|
||||||
|
if (schema['description']) {
|
||||||
|
message = schema['description'];
|
||||||
|
} else {
|
||||||
|
message = stack.replace('instance.', '');
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
property: property.replace('instance.', ''),
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
logger.error([...message]);
|
||||||
|
throw new BadRequestException(...message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await execute(instance, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getParticipantsValidate<T>(args: DataValidate<T>) {
|
||||||
|
const { request, ClassRef, schema, execute } = args;
|
||||||
|
|
||||||
|
const getParticipants = request.query as unknown as GetParticipant;
|
||||||
|
|
||||||
|
if (!getParticipants?.getParticipants) {
|
||||||
|
throw new BadRequestException('The getParticipants needs to be informed in the query');
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = request.params as unknown as InstanceDto;
|
||||||
|
const body = request.body;
|
||||||
|
|
||||||
|
const ref = new ClassRef();
|
||||||
|
|
||||||
|
Object.assign(body, getParticipants);
|
||||||
|
Object.assign(ref, body);
|
||||||
|
|
||||||
|
const v = validate(ref, schema);
|
||||||
|
|
||||||
|
if (!v.valid) {
|
||||||
|
const message: any[] = v.errors.map(({ property, stack, schema }) => {
|
||||||
|
let message: string;
|
||||||
|
if (schema['description']) {
|
||||||
|
message = schema['description'];
|
||||||
|
} else {
|
||||||
|
message = stack.replace('instance.', '');
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
property: property.replace('instance.', ''),
|
||||||
|
message,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
logger.error([...message]);
|
||||||
|
throw new BadRequestException(...message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await execute(instance, ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import {
|
import {
|
||||||
ArchiveChatDto,
|
ArchiveChatDto,
|
||||||
DeleteMessage,
|
DeleteMessage,
|
||||||
getBase64FromMediaMessageDto,
|
getBase64FromMediaMessageDto,
|
||||||
NumberDto,
|
NumberDto,
|
||||||
PrivacySettingDto,
|
PrivacySettingDto,
|
||||||
ProfileNameDto,
|
ProfileNameDto,
|
||||||
ProfilePictureDto,
|
ProfilePictureDto,
|
||||||
ProfileStatusDto,
|
ProfileStatusDto,
|
||||||
ReadMessageDto,
|
ReadMessageDto,
|
||||||
WhatsAppNumberDto,
|
WhatsAppNumberDto,
|
||||||
} from '../dto/chat.dto';
|
} from '../dto/chat.dto';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { ContactQuery } from '../repository/contact.repository';
|
import { ContactQuery } from '../repository/contact.repository';
|
||||||
@ -20,95 +20,95 @@ import { WAMonitoringService } from '../services/monitor.service';
|
|||||||
const logger = new Logger('ChatController');
|
const logger = new Logger('ChatController');
|
||||||
|
|
||||||
export class ChatController {
|
export class ChatController {
|
||||||
constructor(private readonly waMonitor: WAMonitoringService) {}
|
constructor(private readonly waMonitor: WAMonitoringService) {}
|
||||||
|
|
||||||
public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) {
|
public async whatsappNumber({ instanceName }: InstanceDto, data: WhatsAppNumberDto) {
|
||||||
logger.verbose('requested whatsappNumber from ' + instanceName + ' instance');
|
logger.verbose('requested whatsappNumber from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].whatsappNumber(data);
|
return await this.waMonitor.waInstances[instanceName].whatsappNumber(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async readMessage({ instanceName }: InstanceDto, data: ReadMessageDto) {
|
public async readMessage({ instanceName }: InstanceDto, data: ReadMessageDto) {
|
||||||
logger.verbose('requested readMessage from ' + instanceName + ' instance');
|
logger.verbose('requested readMessage from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].markMessageAsRead(data);
|
return await this.waMonitor.waInstances[instanceName].markMessageAsRead(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async archiveChat({ instanceName }: InstanceDto, data: ArchiveChatDto) {
|
public async archiveChat({ instanceName }: InstanceDto, data: ArchiveChatDto) {
|
||||||
logger.verbose('requested archiveChat from ' + instanceName + ' instance');
|
logger.verbose('requested archiveChat from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].archiveChat(data);
|
return await this.waMonitor.waInstances[instanceName].archiveChat(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async deleteMessage({ instanceName }: InstanceDto, data: DeleteMessage) {
|
public async deleteMessage({ instanceName }: InstanceDto, data: DeleteMessage) {
|
||||||
logger.verbose('requested deleteMessage from ' + instanceName + ' instance');
|
logger.verbose('requested deleteMessage from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].deleteMessage(data);
|
return await this.waMonitor.waInstances[instanceName].deleteMessage(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchProfilePicture({ instanceName }: InstanceDto, data: NumberDto) {
|
public async fetchProfilePicture({ instanceName }: InstanceDto, data: NumberDto) {
|
||||||
logger.verbose('requested fetchProfilePicture from ' + instanceName + ' instance');
|
logger.verbose('requested fetchProfilePicture from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].profilePicture(data.number);
|
return await this.waMonitor.waInstances[instanceName].profilePicture(data.number);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) {
|
public async fetchProfile({ instanceName }: InstanceDto, data: NumberDto) {
|
||||||
logger.verbose('requested fetchProfile from ' + instanceName + ' instance');
|
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) {
|
public async fetchContacts({ instanceName }: InstanceDto, query: ContactQuery) {
|
||||||
logger.verbose('requested fetchContacts from ' + instanceName + ' instance');
|
logger.verbose('requested fetchContacts from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].fetchContacts(query);
|
return await this.waMonitor.waInstances[instanceName].fetchContacts(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getBase64FromMediaMessage({ instanceName }: InstanceDto, data: getBase64FromMediaMessageDto) {
|
public async getBase64FromMediaMessage({ instanceName }: InstanceDto, data: getBase64FromMediaMessageDto) {
|
||||||
logger.verbose('requested getBase64FromMediaMessage from ' + instanceName + ' instance');
|
logger.verbose('requested getBase64FromMediaMessage from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data);
|
return await this.waMonitor.waInstances[instanceName].getBase64FromMediaMessage(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchMessages({ instanceName }: InstanceDto, query: MessageQuery) {
|
public async fetchMessages({ instanceName }: InstanceDto, query: MessageQuery) {
|
||||||
logger.verbose('requested fetchMessages from ' + instanceName + ' instance');
|
logger.verbose('requested fetchMessages from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].fetchMessages(query);
|
return await this.waMonitor.waInstances[instanceName].fetchMessages(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchStatusMessage({ instanceName }: InstanceDto, query: MessageUpQuery) {
|
public async fetchStatusMessage({ instanceName }: InstanceDto, query: MessageUpQuery) {
|
||||||
logger.verbose('requested fetchStatusMessage from ' + instanceName + ' instance');
|
logger.verbose('requested fetchStatusMessage from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].fetchStatusMessage(query);
|
return await this.waMonitor.waInstances[instanceName].fetchStatusMessage(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchChats({ instanceName }: InstanceDto) {
|
public async fetchChats({ instanceName }: InstanceDto) {
|
||||||
logger.verbose('requested fetchChats from ' + instanceName + ' instance');
|
logger.verbose('requested fetchChats from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].fetchChats();
|
return await this.waMonitor.waInstances[instanceName].fetchChats();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchPrivacySettings({ instanceName }: InstanceDto) {
|
public async fetchPrivacySettings({ instanceName }: InstanceDto) {
|
||||||
logger.verbose('requested fetchPrivacySettings from ' + instanceName + ' instance');
|
logger.verbose('requested fetchPrivacySettings from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].fetchPrivacySettings();
|
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');
|
logger.verbose('requested updatePrivacySettings from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].updatePrivacySettings(data);
|
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');
|
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) {
|
public async updateProfileName({ instanceName }: InstanceDto, data: ProfileNameDto) {
|
||||||
logger.verbose('requested updateProfileName from ' + instanceName + ' instance');
|
logger.verbose('requested updateProfileName from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].updateProfileName(data.name);
|
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');
|
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');
|
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) {
|
public async removeProfilePicture({ instanceName }: InstanceDto) {
|
||||||
logger.verbose('requested removeProfilePicture from ' + instanceName + ' instance');
|
logger.verbose('requested removeProfilePicture from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].removeProfilePicture();
|
return await this.waMonitor.waInstances[instanceName].removeProfilePicture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,89 +11,89 @@ import { waMonitor } from '../whatsapp.module';
|
|||||||
const logger = new Logger('ChatwootController');
|
const logger = new Logger('ChatwootController');
|
||||||
|
|
||||||
export class 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) {
|
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 (data.enabled) {
|
||||||
if (!isURL(data.url, { require_tld: false })) {
|
if (!isURL(data.url, { require_tld: false })) {
|
||||||
throw new BadRequestException('url is not valid');
|
throw new BadRequestException('url is not valid');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.account_id) {
|
if (!data.account_id) {
|
||||||
throw new BadRequestException('account_id is required');
|
throw new BadRequestException('account_id is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.token) {
|
if (!data.token) {
|
||||||
throw new BadRequestException('token is required');
|
throw new BadRequestException('token is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.sign_msg !== true && data.sign_msg !== false) {
|
if (data.sign_msg !== true && data.sign_msg !== false) {
|
||||||
throw new BadRequestException('sign_msg is required');
|
throw new BadRequestException('sign_msg is required');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.enabled) {
|
|
||||||
logger.verbose('chatwoot disabled');
|
|
||||||
data.account_id = '';
|
|
||||||
data.token = '';
|
|
||||||
data.url = '';
|
|
||||||
data.sign_msg = false;
|
|
||||||
data.reopen_conversation = false;
|
|
||||||
data.conversation_pending = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.name_inbox = instance.instanceName;
|
|
||||||
|
|
||||||
const result = this.chatwootService.create(instance, data);
|
|
||||||
|
|
||||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
|
||||||
|
|
||||||
const response = {
|
|
||||||
...result,
|
|
||||||
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
|
||||||
};
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findChatwoot(instance: InstanceDto) {
|
if (!data.enabled) {
|
||||||
logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance');
|
logger.verbose('chatwoot disabled');
|
||||||
const result = await this.chatwootService.find(instance);
|
data.account_id = '';
|
||||||
|
data.token = '';
|
||||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
data.url = '';
|
||||||
|
data.sign_msg = false;
|
||||||
if (Object.keys(result).length === 0) {
|
data.reopen_conversation = false;
|
||||||
return {
|
data.conversation_pending = false;
|
||||||
enabled: false,
|
|
||||||
url: '',
|
|
||||||
account_id: '',
|
|
||||||
token: '',
|
|
||||||
sign_msg: false,
|
|
||||||
name_inbox: '',
|
|
||||||
webhook_url: '',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = {
|
|
||||||
...result,
|
|
||||||
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
|
||||||
};
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async receiveWebhook(instance: InstanceDto, data: any) {
|
data.name_inbox = instance.instanceName;
|
||||||
logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance');
|
|
||||||
const chatwootService = new ChatwootService(waMonitor, this.configService);
|
|
||||||
|
|
||||||
return chatwootService.receiveWebhook(instance, data);
|
const result = this.chatwootService.create(instance, data);
|
||||||
|
|
||||||
|
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
...result,
|
||||||
|
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async findChatwoot(instance: InstanceDto) {
|
||||||
|
logger.verbose('requested findChatwoot from ' + instance.instanceName + ' instance');
|
||||||
|
const result = await this.chatwootService.find(instance);
|
||||||
|
|
||||||
|
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
|
if (Object.keys(result).length === 0) {
|
||||||
|
return {
|
||||||
|
enabled: false,
|
||||||
|
url: '',
|
||||||
|
account_id: '',
|
||||||
|
token: '',
|
||||||
|
sign_msg: false,
|
||||||
|
name_inbox: '',
|
||||||
|
webhook_url: '',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async newInstance(data: any) {
|
const response = {
|
||||||
const chatwootService = new ChatwootService(waMonitor, this.configService);
|
...result,
|
||||||
|
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
||||||
|
};
|
||||||
|
|
||||||
return chatwootService.newInstance(data);
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async receiveWebhook(instance: InstanceDto, data: any) {
|
||||||
|
logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance');
|
||||||
|
const chatwootService = new ChatwootService(waMonitor, this.configService);
|
||||||
|
|
||||||
|
return chatwootService.receiveWebhook(instance, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async newInstance(data: any) {
|
||||||
|
const chatwootService = new ChatwootService(waMonitor, this.configService);
|
||||||
|
|
||||||
|
return chatwootService.newInstance(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import {
|
import {
|
||||||
CreateGroupDto,
|
CreateGroupDto,
|
||||||
GetParticipant,
|
GetParticipant,
|
||||||
GroupDescriptionDto,
|
GroupDescriptionDto,
|
||||||
GroupInvite,
|
GroupInvite,
|
||||||
GroupJid,
|
GroupJid,
|
||||||
GroupPictureDto,
|
GroupPictureDto,
|
||||||
GroupSendInvite,
|
GroupSendInvite,
|
||||||
GroupSubjectDto,
|
GroupSubjectDto,
|
||||||
GroupToggleEphemeralDto,
|
GroupToggleEphemeralDto,
|
||||||
GroupUpdateParticipantDto,
|
GroupUpdateParticipantDto,
|
||||||
GroupUpdateSettingDto,
|
GroupUpdateSettingDto,
|
||||||
} from '../dto/group.dto';
|
} from '../dto/group.dto';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { WAMonitoringService } from '../services/monitor.service';
|
import { WAMonitoringService } from '../services/monitor.service';
|
||||||
@ -18,80 +18,80 @@ import { WAMonitoringService } from '../services/monitor.service';
|
|||||||
const logger = new Logger('ChatController');
|
const logger = new Logger('ChatController');
|
||||||
|
|
||||||
export class GroupController {
|
export class GroupController {
|
||||||
constructor(private readonly waMonitor: WAMonitoringService) {}
|
constructor(private readonly waMonitor: WAMonitoringService) {}
|
||||||
|
|
||||||
public async createGroup(instance: InstanceDto, create: CreateGroupDto) {
|
public async createGroup(instance: InstanceDto, create: CreateGroupDto) {
|
||||||
logger.verbose('requested createGroup from ' + instance.instanceName + ' instance');
|
logger.verbose('requested createGroup from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].createGroup(create);
|
return await this.waMonitor.waInstances[instance.instanceName].createGroup(create);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateGroupPicture(instance: InstanceDto, update: GroupPictureDto) {
|
public async updateGroupPicture(instance: InstanceDto, update: GroupPictureDto) {
|
||||||
logger.verbose('requested updateGroupPicture from ' + instance.instanceName + ' instance');
|
logger.verbose('requested updateGroupPicture from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture(update);
|
return await this.waMonitor.waInstances[instance.instanceName].updateGroupPicture(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateGroupSubject(instance: InstanceDto, update: GroupSubjectDto) {
|
public async updateGroupSubject(instance: InstanceDto, update: GroupSubjectDto) {
|
||||||
logger.verbose('requested updateGroupSubject from ' + instance.instanceName + ' instance');
|
logger.verbose('requested updateGroupSubject from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject(update);
|
return await this.waMonitor.waInstances[instance.instanceName].updateGroupSubject(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateGroupDescription(instance: InstanceDto, update: GroupDescriptionDto) {
|
public async updateGroupDescription(instance: InstanceDto, update: GroupDescriptionDto) {
|
||||||
logger.verbose('requested updateGroupDescription from ' + instance.instanceName + ' instance');
|
logger.verbose('requested updateGroupDescription from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription(update);
|
return await this.waMonitor.waInstances[instance.instanceName].updateGroupDescription(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findGroupInfo(instance: InstanceDto, groupJid: GroupJid) {
|
public async findGroupInfo(instance: InstanceDto, groupJid: GroupJid) {
|
||||||
logger.verbose('requested findGroupInfo from ' + instance.instanceName + ' instance');
|
logger.verbose('requested findGroupInfo from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].findGroup(groupJid);
|
return await this.waMonitor.waInstances[instance.instanceName].findGroup(groupJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async fetchAllGroups(instance: InstanceDto, getPaticipants: GetParticipant) {
|
public async fetchAllGroups(instance: InstanceDto, getPaticipants: GetParticipant) {
|
||||||
logger.verbose('requested fetchAllGroups from ' + instance.instanceName + ' instance');
|
logger.verbose('requested fetchAllGroups from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups(getPaticipants);
|
return await this.waMonitor.waInstances[instance.instanceName].fetchAllGroups(getPaticipants);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async inviteCode(instance: InstanceDto, groupJid: GroupJid) {
|
public async inviteCode(instance: InstanceDto, groupJid: GroupJid) {
|
||||||
logger.verbose('requested inviteCode from ' + instance.instanceName + ' instance');
|
logger.verbose('requested inviteCode from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].inviteCode(groupJid);
|
return await this.waMonitor.waInstances[instance.instanceName].inviteCode(groupJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async inviteInfo(instance: InstanceDto, inviteCode: GroupInvite) {
|
public async inviteInfo(instance: InstanceDto, inviteCode: GroupInvite) {
|
||||||
logger.verbose('requested inviteInfo from ' + instance.instanceName + ' instance');
|
logger.verbose('requested inviteInfo from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].inviteInfo(inviteCode);
|
return await this.waMonitor.waInstances[instance.instanceName].inviteInfo(inviteCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendInvite(instance: InstanceDto, data: GroupSendInvite) {
|
public async sendInvite(instance: InstanceDto, data: GroupSendInvite) {
|
||||||
logger.verbose('requested sendInvite from ' + instance.instanceName + ' instance');
|
logger.verbose('requested sendInvite from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].sendInvite(data);
|
return await this.waMonitor.waInstances[instance.instanceName].sendInvite(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async revokeInviteCode(instance: InstanceDto, groupJid: GroupJid) {
|
public async revokeInviteCode(instance: InstanceDto, groupJid: GroupJid) {
|
||||||
logger.verbose('requested revokeInviteCode from ' + instance.instanceName + ' instance');
|
logger.verbose('requested revokeInviteCode from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode(groupJid);
|
return await this.waMonitor.waInstances[instance.instanceName].revokeInviteCode(groupJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findParticipants(instance: InstanceDto, groupJid: GroupJid) {
|
public async findParticipants(instance: InstanceDto, groupJid: GroupJid) {
|
||||||
logger.verbose('requested findParticipants from ' + instance.instanceName + ' instance');
|
logger.verbose('requested findParticipants from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].findParticipants(groupJid);
|
return await this.waMonitor.waInstances[instance.instanceName].findParticipants(groupJid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateGParticipate(instance: InstanceDto, update: GroupUpdateParticipantDto) {
|
public async updateGParticipate(instance: InstanceDto, update: GroupUpdateParticipantDto) {
|
||||||
logger.verbose('requested updateGParticipate from ' + instance.instanceName + ' instance');
|
logger.verbose('requested updateGParticipate from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant(update);
|
return await this.waMonitor.waInstances[instance.instanceName].updateGParticipant(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateGSetting(instance: InstanceDto, update: GroupUpdateSettingDto) {
|
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);
|
return await this.waMonitor.waInstances[instance.instanceName].updateGSetting(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) {
|
public async toggleEphemeral(instance: InstanceDto, update: GroupToggleEphemeralDto) {
|
||||||
logger.verbose('requested toggleEphemeral from ' + instance.instanceName + ' instance');
|
logger.verbose('requested toggleEphemeral from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral(update);
|
return await this.waMonitor.waInstances[instance.instanceName].toggleEphemeral(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async leaveGroup(instance: InstanceDto, groupJid: GroupJid) {
|
public async leaveGroup(instance: InstanceDto, groupJid: GroupJid) {
|
||||||
logger.verbose('requested leaveGroup from ' + instance.instanceName + ' instance');
|
logger.verbose('requested leaveGroup from ' + instance.instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].leaveGroup(groupJid);
|
return await this.waMonitor.waInstances[instance.instanceName].leaveGroup(groupJid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,340 +17,340 @@ import { WAStartupService } from '../services/whatsapp.service';
|
|||||||
import { wa } from '../types/wa.types';
|
import { wa } from '../types/wa.types';
|
||||||
|
|
||||||
export class InstanceController {
|
export class InstanceController {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly waMonitor: WAMonitoringService,
|
private readonly waMonitor: WAMonitoringService,
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly repository: RepositoryBroker,
|
private readonly repository: RepositoryBroker,
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
private readonly authService: AuthService,
|
private readonly authService: AuthService,
|
||||||
private readonly webhookService: WebhookService,
|
private readonly webhookService: WebhookService,
|
||||||
private readonly chatwootService: ChatwootService,
|
private readonly chatwootService: ChatwootService,
|
||||||
private readonly settingsService: SettingsService,
|
private readonly settingsService: SettingsService,
|
||||||
private readonly cache: RedisCache,
|
private readonly cache: RedisCache,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private readonly logger = new Logger(InstanceController.name);
|
private readonly logger = new Logger(InstanceController.name);
|
||||||
|
|
||||||
public async createInstance({
|
public async createInstance({
|
||||||
instanceName,
|
instanceName,
|
||||||
|
webhook,
|
||||||
|
webhook_by_events,
|
||||||
|
events,
|
||||||
|
qrcode,
|
||||||
|
number,
|
||||||
|
token,
|
||||||
|
chatwoot_account_id,
|
||||||
|
chatwoot_token,
|
||||||
|
chatwoot_url,
|
||||||
|
chatwoot_sign_msg,
|
||||||
|
chatwoot_reopen_conversation,
|
||||||
|
chatwoot_conversation_pending,
|
||||||
|
reject_call,
|
||||||
|
msg_call,
|
||||||
|
groups_ignore,
|
||||||
|
always_online,
|
||||||
|
read_messages,
|
||||||
|
read_status,
|
||||||
|
}: InstanceDto) {
|
||||||
|
try {
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
instance.instanceName = instanceName
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9]/g, '')
|
||||||
|
.replace(' ', '');
|
||||||
|
|
||||||
|
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
||||||
|
|
||||||
|
this.waMonitor.waInstances[instance.instanceName] = instance;
|
||||||
|
this.waMonitor.delInstanceTime(instance.instanceName);
|
||||||
|
|
||||||
|
this.logger.verbose('generating hash');
|
||||||
|
const hash = await this.authService.generateHash(
|
||||||
|
{
|
||||||
|
instanceName: instance.instanceName,
|
||||||
|
},
|
||||||
|
token,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.logger.verbose('hash: ' + hash + ' generated');
|
||||||
|
|
||||||
|
let getEvents: string[];
|
||||||
|
|
||||||
|
if (webhook) {
|
||||||
|
if (!isURL(webhook, { require_tld: false })) {
|
||||||
|
throw new BadRequestException('Invalid "url" property in webhook');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('creating webhook');
|
||||||
|
try {
|
||||||
|
this.webhookService.create(instance, {
|
||||||
|
enabled: true,
|
||||||
|
url: webhook,
|
||||||
|
events,
|
||||||
|
webhook_by_events,
|
||||||
|
});
|
||||||
|
|
||||||
|
getEvents = (await this.webhookService.find(instance)).events;
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('creating settings');
|
||||||
|
const settings: wa.LocalSettings = {
|
||||||
|
reject_call: reject_call || false,
|
||||||
|
msg_call: msg_call || '',
|
||||||
|
groups_ignore: groups_ignore || false,
|
||||||
|
always_online: always_online || false,
|
||||||
|
read_messages: read_messages || false,
|
||||||
|
read_status: read_status || false,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.logger.verbose('settings: ' + JSON.stringify(settings));
|
||||||
|
|
||||||
|
this.settingsService.create(instance, settings);
|
||||||
|
|
||||||
|
if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) {
|
||||||
|
let getQrcode: wa.QrCode;
|
||||||
|
|
||||||
|
if (qrcode) {
|
||||||
|
this.logger.verbose('creating qrcode');
|
||||||
|
await instance.connectToWhatsapp(number);
|
||||||
|
await delay(5000);
|
||||||
|
getQrcode = instance.qrCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
instance: {
|
||||||
|
instanceName: instance.instanceName,
|
||||||
|
status: 'created',
|
||||||
|
},
|
||||||
|
hash,
|
||||||
|
webhook,
|
||||||
|
webhook_by_events,
|
||||||
|
events: getEvents,
|
||||||
|
settings,
|
||||||
|
qrcode: getQrcode,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.logger.verbose('instance created');
|
||||||
|
this.logger.verbose(result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chatwoot_account_id) {
|
||||||
|
throw new BadRequestException('account_id is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chatwoot_token) {
|
||||||
|
throw new BadRequestException('token is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!chatwoot_url) {
|
||||||
|
throw new BadRequestException('url is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isURL(chatwoot_url, { require_tld: false })) {
|
||||||
|
throw new BadRequestException('Invalid "url" property in chatwoot');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) {
|
||||||
|
throw new BadRequestException('sign_msg is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chatwoot_reopen_conversation !== true && chatwoot_reopen_conversation !== false) {
|
||||||
|
throw new BadRequestException('reopen_conversation is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chatwoot_conversation_pending !== true && chatwoot_conversation_pending !== false) {
|
||||||
|
throw new BadRequestException('conversation_pending is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.chatwootService.create(instance, {
|
||||||
|
enabled: true,
|
||||||
|
account_id: chatwoot_account_id,
|
||||||
|
token: chatwoot_token,
|
||||||
|
url: chatwoot_url,
|
||||||
|
sign_msg: chatwoot_sign_msg || false,
|
||||||
|
name_inbox: instance.instanceName,
|
||||||
|
number,
|
||||||
|
reopen_conversation: chatwoot_reopen_conversation || false,
|
||||||
|
conversation_pending: chatwoot_conversation_pending || false,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.chatwootService.initInstanceChatwoot(
|
||||||
|
instance,
|
||||||
|
instance.instanceName,
|
||||||
|
`${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
||||||
|
qrcode,
|
||||||
|
number,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
instance: {
|
||||||
|
instanceName: instance.instanceName,
|
||||||
|
status: 'created',
|
||||||
|
},
|
||||||
|
hash,
|
||||||
webhook,
|
webhook,
|
||||||
webhook_by_events,
|
webhook_by_events,
|
||||||
events,
|
events: getEvents,
|
||||||
qrcode,
|
settings,
|
||||||
number,
|
chatwoot: {
|
||||||
token,
|
enabled: true,
|
||||||
chatwoot_account_id,
|
account_id: chatwoot_account_id,
|
||||||
chatwoot_token,
|
token: chatwoot_token,
|
||||||
chatwoot_url,
|
url: chatwoot_url,
|
||||||
chatwoot_sign_msg,
|
sign_msg: chatwoot_sign_msg || false,
|
||||||
chatwoot_reopen_conversation,
|
reopen_conversation: chatwoot_reopen_conversation || false,
|
||||||
chatwoot_conversation_pending,
|
conversation_pending: chatwoot_conversation_pending || false,
|
||||||
reject_call,
|
number,
|
||||||
msg_call,
|
name_inbox: instance.instanceName,
|
||||||
groups_ignore,
|
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
||||||
always_online,
|
},
|
||||||
read_messages,
|
};
|
||||||
read_status,
|
} catch (error) {
|
||||||
}: InstanceDto) {
|
console.log(error);
|
||||||
try {
|
return { error: true, message: error.toString() };
|
||||||
this.logger.verbose('requested createInstance from ' + instanceName + ' instance');
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) {
|
public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) {
|
||||||
throw new BadRequestException('The instance name must be lowercase and without special characters');
|
try {
|
||||||
}
|
this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance');
|
||||||
|
|
||||||
this.logger.verbose('checking duplicate token');
|
const instance = this.waMonitor.waInstances[instanceName];
|
||||||
await this.authService.checkDuplicateToken(token);
|
const state = instance?.connectionStatus?.state;
|
||||||
|
|
||||||
this.logger.verbose('creating instance');
|
this.logger.verbose('state: ' + state);
|
||||||
const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache);
|
|
||||||
instance.instanceName = instanceName
|
|
||||||
.toLowerCase()
|
|
||||||
.replace(/[^a-z0-9]/g, '')
|
|
||||||
.replace(' ', '');
|
|
||||||
|
|
||||||
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
if (state == 'open') {
|
||||||
|
return await this.connectionState({ instanceName });
|
||||||
|
}
|
||||||
|
|
||||||
this.waMonitor.waInstances[instance.instanceName] = instance;
|
if (state == 'connecting') {
|
||||||
this.waMonitor.delInstanceTime(instance.instanceName);
|
return instance.qrCode;
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.verbose('generating hash');
|
if (state == 'close') {
|
||||||
const hash = await this.authService.generateHash(
|
this.logger.verbose('connecting');
|
||||||
{
|
await instance.connectToWhatsapp(number);
|
||||||
instanceName: instance.instanceName,
|
|
||||||
},
|
|
||||||
token,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.logger.verbose('hash: ' + hash + ' generated');
|
await delay(5000);
|
||||||
|
return instance.qrCode;
|
||||||
|
}
|
||||||
|
|
||||||
let getEvents: string[];
|
return {
|
||||||
|
instance: {
|
||||||
|
instanceName: instanceName,
|
||||||
|
status: state,
|
||||||
|
},
|
||||||
|
qrcode: instance?.qrCode,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (webhook) {
|
public async restartInstance({ instanceName }: InstanceDto) {
|
||||||
if (!isURL(webhook, { require_tld: false })) {
|
try {
|
||||||
throw new BadRequestException('Invalid "url" property in webhook');
|
this.logger.verbose('requested restartInstance from ' + instanceName + ' instance');
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('creating webhook');
|
this.logger.verbose('logging out instance: ' + instanceName);
|
||||||
try {
|
this.waMonitor.waInstances[instanceName]?.client?.ws?.close();
|
||||||
this.webhookService.create(instance, {
|
|
||||||
enabled: true,
|
|
||||||
url: webhook,
|
|
||||||
events,
|
|
||||||
webhook_by_events,
|
|
||||||
});
|
|
||||||
|
|
||||||
getEvents = (await this.webhookService.find(instance)).events;
|
return { error: false, message: 'Instance restarted' };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.log(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('creating settings');
|
public async connectionState({ instanceName }: InstanceDto) {
|
||||||
const settings: wa.LocalSettings = {
|
this.logger.verbose('requested connectionState from ' + instanceName + ' instance');
|
||||||
reject_call: reject_call || false,
|
return {
|
||||||
msg_call: msg_call || '',
|
instance: {
|
||||||
groups_ignore: groups_ignore || false,
|
instanceName: instanceName,
|
||||||
always_online: always_online || false,
|
state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state,
|
||||||
read_messages: read_messages || false,
|
},
|
||||||
read_status: read_status || false,
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
this.logger.verbose('settings: ' + JSON.stringify(settings));
|
public async fetchInstances({ instanceName }: InstanceDto) {
|
||||||
|
this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance');
|
||||||
this.settingsService.create(instance, settings);
|
if (instanceName) {
|
||||||
|
this.logger.verbose('instanceName: ' + instanceName);
|
||||||
if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) {
|
return this.waMonitor.instanceInfo(instanceName);
|
||||||
let getQrcode: wa.QrCode;
|
|
||||||
|
|
||||||
if (qrcode) {
|
|
||||||
this.logger.verbose('creating qrcode');
|
|
||||||
await instance.connectToWhatsapp(number);
|
|
||||||
await delay(5000);
|
|
||||||
getQrcode = instance.qrCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
instance: {
|
|
||||||
instanceName: instance.instanceName,
|
|
||||||
status: 'created',
|
|
||||||
},
|
|
||||||
hash,
|
|
||||||
webhook,
|
|
||||||
webhook_by_events,
|
|
||||||
events: getEvents,
|
|
||||||
settings,
|
|
||||||
qrcode: getQrcode,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.logger.verbose('instance created');
|
|
||||||
this.logger.verbose(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chatwoot_account_id) {
|
|
||||||
throw new BadRequestException('account_id is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chatwoot_token) {
|
|
||||||
throw new BadRequestException('token is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!chatwoot_url) {
|
|
||||||
throw new BadRequestException('url is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isURL(chatwoot_url, { require_tld: false })) {
|
|
||||||
throw new BadRequestException('Invalid "url" property in chatwoot');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chatwoot_sign_msg !== true && chatwoot_sign_msg !== false) {
|
|
||||||
throw new BadRequestException('sign_msg is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chatwoot_reopen_conversation !== true && chatwoot_reopen_conversation !== false) {
|
|
||||||
throw new BadRequestException('reopen_conversation is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chatwoot_conversation_pending !== true && chatwoot_conversation_pending !== false) {
|
|
||||||
throw new BadRequestException('conversation_pending is required');
|
|
||||||
}
|
|
||||||
|
|
||||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.chatwootService.create(instance, {
|
|
||||||
enabled: true,
|
|
||||||
account_id: chatwoot_account_id,
|
|
||||||
token: chatwoot_token,
|
|
||||||
url: chatwoot_url,
|
|
||||||
sign_msg: chatwoot_sign_msg || false,
|
|
||||||
name_inbox: instance.instanceName,
|
|
||||||
number,
|
|
||||||
reopen_conversation: chatwoot_reopen_conversation || false,
|
|
||||||
conversation_pending: chatwoot_conversation_pending || false,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.chatwootService.initInstanceChatwoot(
|
|
||||||
instance,
|
|
||||||
instance.instanceName,
|
|
||||||
`${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
|
||||||
qrcode,
|
|
||||||
number,
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.log(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
instance: {
|
|
||||||
instanceName: instance.instanceName,
|
|
||||||
status: 'created',
|
|
||||||
},
|
|
||||||
hash,
|
|
||||||
webhook,
|
|
||||||
webhook_by_events,
|
|
||||||
events: getEvents,
|
|
||||||
settings,
|
|
||||||
chatwoot: {
|
|
||||||
enabled: true,
|
|
||||||
account_id: chatwoot_account_id,
|
|
||||||
token: chatwoot_token,
|
|
||||||
url: chatwoot_url,
|
|
||||||
sign_msg: chatwoot_sign_msg || false,
|
|
||||||
reopen_conversation: chatwoot_reopen_conversation || false,
|
|
||||||
conversation_pending: chatwoot_conversation_pending || false,
|
|
||||||
number,
|
|
||||||
name_inbox: instance.instanceName,
|
|
||||||
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
return { error: true, message: error.toString() };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) {
|
return this.waMonitor.instanceInfo();
|
||||||
try {
|
}
|
||||||
this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance');
|
|
||||||
|
|
||||||
const instance = this.waMonitor.waInstances[instanceName];
|
public async logout({ instanceName }: InstanceDto) {
|
||||||
const state = instance?.connectionStatus?.state;
|
this.logger.verbose('requested logout from ' + instanceName + ' instance');
|
||||||
|
const { instance } = await this.connectionState({ instanceName });
|
||||||
|
|
||||||
this.logger.verbose('state: ' + state);
|
if (instance.state === 'close') {
|
||||||
|
throw new BadRequestException('The "' + instanceName + '" instance is not connected');
|
||||||
if (state == 'open') {
|
|
||||||
return await this.connectionState({ instanceName });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 'connecting') {
|
|
||||||
return instance.qrCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 'close') {
|
|
||||||
this.logger.verbose('connecting');
|
|
||||||
await instance.connectToWhatsapp(number);
|
|
||||||
|
|
||||||
await delay(5000);
|
|
||||||
return instance.qrCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
instance: {
|
|
||||||
instanceName: instanceName,
|
|
||||||
status: state,
|
|
||||||
},
|
|
||||||
qrcode: instance?.qrCode,
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async restartInstance({ instanceName }: InstanceDto) {
|
try {
|
||||||
try {
|
this.logger.verbose('logging out instance: ' + instanceName);
|
||||||
this.logger.verbose('requested restartInstance from ' + instanceName + ' instance');
|
await this.waMonitor.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName);
|
||||||
|
|
||||||
this.logger.verbose('logging out instance: ' + instanceName);
|
this.logger.verbose('close connection instance: ' + instanceName);
|
||||||
this.waMonitor.waInstances[instanceName]?.client?.ws?.close();
|
this.waMonitor.waInstances[instanceName]?.client?.ws?.close();
|
||||||
|
|
||||||
return { error: false, message: 'Instance restarted' };
|
return { error: false, message: 'Instance logged out' };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
throw new InternalServerErrorException(error.toString());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async connectionState({ instanceName }: InstanceDto) {
|
public async deleteInstance({ instanceName }: InstanceDto) {
|
||||||
this.logger.verbose('requested connectionState from ' + instanceName + ' instance');
|
this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance');
|
||||||
return {
|
const { instance } = await this.connectionState({ instanceName });
|
||||||
instance: {
|
|
||||||
instanceName: instanceName,
|
if (instance.state === 'open') {
|
||||||
state: this.waMonitor.waInstances[instanceName]?.connectionStatus?.state,
|
throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected');
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
if (instance.state === 'connecting') {
|
||||||
|
this.logger.verbose('logging out instance: ' + instanceName);
|
||||||
|
|
||||||
public async fetchInstances({ instanceName }: InstanceDto) {
|
await this.logout({ instanceName });
|
||||||
this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance');
|
delete this.waMonitor.waInstances[instanceName];
|
||||||
if (instanceName) {
|
return { error: false, message: 'Instance deleted' };
|
||||||
this.logger.verbose('instanceName: ' + instanceName);
|
} else {
|
||||||
return this.waMonitor.instanceInfo(instanceName);
|
this.logger.verbose('deleting instance: ' + instanceName);
|
||||||
}
|
|
||||||
|
|
||||||
return this.waMonitor.instanceInfo();
|
delete this.waMonitor.waInstances[instanceName];
|
||||||
|
this.eventEmitter.emit('remove.instance', instanceName, 'inner');
|
||||||
|
return { error: false, message: 'Instance deleted' };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw new BadRequestException(error.toString());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async logout({ instanceName }: InstanceDto) {
|
public async refreshToken(_: InstanceDto, oldToken: OldToken) {
|
||||||
this.logger.verbose('requested logout from ' + instanceName + ' instance');
|
this.logger.verbose('requested refreshToken');
|
||||||
const { instance } = await this.connectionState({ instanceName });
|
return await this.authService.refreshToken(oldToken);
|
||||||
|
}
|
||||||
if (instance.state === 'close') {
|
|
||||||
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);
|
|
||||||
|
|
||||||
this.logger.verbose('close connection instance: ' + instanceName);
|
|
||||||
this.waMonitor.waInstances[instanceName]?.client?.ws?.close();
|
|
||||||
|
|
||||||
return { error: false, message: 'Instance logged out' };
|
|
||||||
} catch (error) {
|
|
||||||
throw new InternalServerErrorException(error.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async deleteInstance({ instanceName }: InstanceDto) {
|
|
||||||
this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance');
|
|
||||||
const { instance } = await this.connectionState({ instanceName });
|
|
||||||
|
|
||||||
if (instance.state === 'open') {
|
|
||||||
throw new BadRequestException('The "' + instanceName + '" instance needs to be disconnected');
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (instance.state === 'connecting') {
|
|
||||||
this.logger.verbose('logging out instance: ' + instanceName);
|
|
||||||
|
|
||||||
await this.logout({ instanceName });
|
|
||||||
delete this.waMonitor.waInstances[instanceName];
|
|
||||||
return { error: false, message: 'Instance deleted' };
|
|
||||||
} else {
|
|
||||||
this.logger.verbose('deleting instance: ' + instanceName);
|
|
||||||
|
|
||||||
delete this.waMonitor.waInstances[instanceName];
|
|
||||||
this.eventEmitter.emit('remove.instance', instanceName, 'inner');
|
|
||||||
return { error: false, message: 'Instance deleted' };
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
throw new BadRequestException(error.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async refreshToken(_: InstanceDto, oldToken: OldToken) {
|
|
||||||
this.logger.verbose('requested refreshToken');
|
|
||||||
return await this.authService.refreshToken(oldToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,112 +4,108 @@ import { Logger } from '../../config/logger.config';
|
|||||||
import { BadRequestException } from '../../exceptions';
|
import { BadRequestException } from '../../exceptions';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import {
|
import {
|
||||||
SendAudioDto,
|
SendAudioDto,
|
||||||
SendButtonDto,
|
SendButtonDto,
|
||||||
SendContactDto,
|
SendContactDto,
|
||||||
SendListDto,
|
SendListDto,
|
||||||
SendLocationDto,
|
SendLocationDto,
|
||||||
SendMediaDto,
|
SendMediaDto,
|
||||||
SendPollDto,
|
SendPollDto,
|
||||||
SendReactionDto,
|
SendReactionDto,
|
||||||
SendStatusDto,
|
SendStatusDto,
|
||||||
SendStickerDto,
|
SendStickerDto,
|
||||||
SendTextDto,
|
SendTextDto,
|
||||||
} from '../dto/sendMessage.dto';
|
} from '../dto/sendMessage.dto';
|
||||||
import { WAMonitoringService } from '../services/monitor.service';
|
import { WAMonitoringService } from '../services/monitor.service';
|
||||||
|
|
||||||
const logger = new Logger('MessageRouter');
|
const logger = new Logger('MessageRouter');
|
||||||
|
|
||||||
export class SendMessageController {
|
export class SendMessageController {
|
||||||
constructor(private readonly waMonitor: WAMonitoringService) {}
|
constructor(private readonly waMonitor: WAMonitoringService) {}
|
||||||
|
|
||||||
public async sendText({ instanceName }: InstanceDto, data: SendTextDto) {
|
public async sendText({ instanceName }: InstanceDto, data: SendTextDto) {
|
||||||
logger.verbose('requested sendText from ' + instanceName + ' instance');
|
logger.verbose('requested sendText from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].textMessage(data);
|
return await this.waMonitor.waInstances[instanceName].textMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) {
|
||||||
|
logger.verbose('requested sendMedia from ' + instanceName + ' instance');
|
||||||
|
|
||||||
|
if (
|
||||||
|
isBase64(data?.mediaMessage?.media) &&
|
||||||
|
!data?.mediaMessage?.fileName &&
|
||||||
|
data?.mediaMessage?.mediatype === 'document'
|
||||||
|
) {
|
||||||
|
throw new BadRequestException('For base64 the file name must be informed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) {
|
logger.verbose('isURL: ' + isURL(data?.mediaMessage?.media) + ', isBase64: ' + isBase64(data?.mediaMessage?.media));
|
||||||
logger.verbose('requested sendMedia from ' + instanceName + ' instance');
|
if (isURL(data?.mediaMessage?.media) || isBase64(data?.mediaMessage?.media)) {
|
||||||
|
return await this.waMonitor.waInstances[instanceName].mediaMessage(data);
|
||||||
if (
|
|
||||||
isBase64(data?.mediaMessage?.media) &&
|
|
||||||
!data?.mediaMessage?.fileName &&
|
|
||||||
data?.mediaMessage?.mediatype === 'document'
|
|
||||||
) {
|
|
||||||
throw new BadRequestException('For base64 the file name must be informed.');
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
throw new BadRequestException('Owned media must be a url or base64');
|
|
||||||
}
|
}
|
||||||
|
throw new BadRequestException('Owned media must be a url or base64');
|
||||||
|
}
|
||||||
|
|
||||||
public async sendSticker({ instanceName }: InstanceDto, data: SendStickerDto) {
|
public async sendSticker({ instanceName }: InstanceDto, data: SendStickerDto) {
|
||||||
logger.verbose('requested sendSticker from ' + instanceName + ' instance');
|
logger.verbose('requested sendSticker from ' + instanceName + ' instance');
|
||||||
|
|
||||||
logger.verbose(
|
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)) {
|
if (isURL(data.stickerMessage.image) || isBase64(data.stickerMessage.image)) {
|
||||||
return await this.waMonitor.waInstances[instanceName].mediaSticker(data);
|
return await this.waMonitor.waInstances[instanceName].mediaSticker(data);
|
||||||
}
|
|
||||||
throw new BadRequestException('Owned media must be a url or base64');
|
|
||||||
}
|
}
|
||||||
|
throw new BadRequestException('Owned media must be a url or base64');
|
||||||
|
}
|
||||||
|
|
||||||
public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto) {
|
public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto) {
|
||||||
logger.verbose('requested sendWhatsAppAudio from ' + instanceName + ' instance');
|
logger.verbose('requested sendWhatsAppAudio from ' + instanceName + ' instance');
|
||||||
|
|
||||||
logger.verbose(
|
logger.verbose('isURL: ' + isURL(data?.audioMessage?.audio) + ', isBase64: ' + isBase64(data?.audioMessage?.audio));
|
||||||
'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);
|
||||||
if (isURL(data.audioMessage.audio) || isBase64(data.audioMessage.audio)) {
|
|
||||||
return await this.waMonitor.waInstances[instanceName].audioWhatsapp(data);
|
|
||||||
}
|
|
||||||
throw new BadRequestException('Owned media must be a url or base64');
|
|
||||||
}
|
}
|
||||||
|
throw new BadRequestException('Owned media must be a url or base64');
|
||||||
|
}
|
||||||
|
|
||||||
public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) {
|
public async sendButtons({ instanceName }: InstanceDto, data: SendButtonDto) {
|
||||||
logger.verbose('requested sendButtons from ' + instanceName + ' instance');
|
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.');
|
throw new BadRequestException('For bse64 the file name must be informed.');
|
||||||
}
|
|
||||||
return await this.waMonitor.waInstances[instanceName].buttonMessage(data);
|
|
||||||
}
|
}
|
||||||
|
return await this.waMonitor.waInstances[instanceName].buttonMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
public async sendLocation({ instanceName }: InstanceDto, data: SendLocationDto) {
|
public async sendLocation({ instanceName }: InstanceDto, data: SendLocationDto) {
|
||||||
logger.verbose('requested sendLocation from ' + instanceName + ' instance');
|
logger.verbose('requested sendLocation from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].locationMessage(data);
|
return await this.waMonitor.waInstances[instanceName].locationMessage(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendList({ instanceName }: InstanceDto, data: SendListDto) {
|
public async sendList({ instanceName }: InstanceDto, data: SendListDto) {
|
||||||
logger.verbose('requested sendList from ' + instanceName + ' instance');
|
logger.verbose('requested sendList from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].listMessage(data);
|
return await this.waMonitor.waInstances[instanceName].listMessage(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendContact({ instanceName }: InstanceDto, data: SendContactDto) {
|
public async sendContact({ instanceName }: InstanceDto, data: SendContactDto) {
|
||||||
logger.verbose('requested sendContact from ' + instanceName + ' instance');
|
logger.verbose('requested sendContact from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].contactMessage(data);
|
return await this.waMonitor.waInstances[instanceName].contactMessage(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) {
|
public async sendReaction({ instanceName }: InstanceDto, data: SendReactionDto) {
|
||||||
logger.verbose('requested sendReaction from ' + instanceName + ' instance');
|
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');
|
throw new BadRequestException('"reaction" must be an emoji');
|
||||||
}
|
|
||||||
return await this.waMonitor.waInstances[instanceName].reactionMessage(data);
|
|
||||||
}
|
}
|
||||||
|
return await this.waMonitor.waInstances[instanceName].reactionMessage(data);
|
||||||
|
}
|
||||||
|
|
||||||
public async sendPoll({ instanceName }: InstanceDto, data: SendPollDto) {
|
public async sendPoll({ instanceName }: InstanceDto, data: SendPollDto) {
|
||||||
logger.verbose('requested sendPoll from ' + instanceName + ' instance');
|
logger.verbose('requested sendPoll from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].pollMessage(data);
|
return await this.waMonitor.waInstances[instanceName].pollMessage(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto) {
|
public async sendStatus({ instanceName }: InstanceDto, data: SendStatusDto) {
|
||||||
logger.verbose('requested sendStatus from ' + instanceName + ' instance');
|
logger.verbose('requested sendStatus from ' + instanceName + ' instance');
|
||||||
return await this.waMonitor.waInstances[instanceName].statusMessage(data);
|
return await this.waMonitor.waInstances[instanceName].statusMessage(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,16 @@ import { SettingsService } from '../services/settings.service';
|
|||||||
const logger = new Logger('SettingsController');
|
const logger = new Logger('SettingsController');
|
||||||
|
|
||||||
export class SettingsController {
|
export class SettingsController {
|
||||||
constructor(private readonly settingsService: SettingsService) {}
|
constructor(private readonly settingsService: SettingsService) {}
|
||||||
|
|
||||||
public async createSettings(instance: InstanceDto, data: SettingsDto) {
|
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);
|
return this.settingsService.create(instance, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findSettings(instance: InstanceDto) {
|
public async findSettings(instance: InstanceDto) {
|
||||||
logger.verbose('requested findSettings from ' + instance.instanceName + ' instance');
|
logger.verbose('requested findSettings from ' + instance.instanceName + ' instance');
|
||||||
return this.settingsService.find(instance);
|
return this.settingsService.find(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,20 +7,20 @@ import { HttpStatus } from '../routers/index.router';
|
|||||||
import { WAMonitoringService } from '../services/monitor.service';
|
import { WAMonitoringService } from '../services/monitor.service';
|
||||||
|
|
||||||
export class ViewsController {
|
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) {
|
public async qrcode(request: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
const param = request.params as unknown as InstanceDto;
|
const param = request.params as unknown as InstanceDto;
|
||||||
const instance = this.waMonit.waInstances[param.instanceName];
|
const instance = this.waMonit.waInstances[param.instanceName];
|
||||||
if (instance.connectionStatus.state === 'open') {
|
if (instance.connectionStatus.state === 'open') {
|
||||||
throw new BadRequestException('The instance is already connected');
|
throw new BadRequestException('The instance is already connected');
|
||||||
}
|
}
|
||||||
const type = this.configService.get<Auth>('AUTHENTICATION').TYPE;
|
const type = this.configService.get<Auth>('AUTHENTICATION').TYPE;
|
||||||
|
|
||||||
return response.status(HttpStatus.OK).render('qrcode', { type, ...param });
|
return response.status(HttpStatus.OK).render('qrcode', { type, ...param });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('ERROR: ', error);
|
console.log('ERROR: ', error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,26 +9,26 @@ import { WebhookService } from '../services/webhook.service';
|
|||||||
const logger = new Logger('WebhookController');
|
const logger = new Logger('WebhookController');
|
||||||
|
|
||||||
export class WebhookController {
|
export class WebhookController {
|
||||||
constructor(private readonly webhookService: WebhookService) {}
|
constructor(private readonly webhookService: WebhookService) {}
|
||||||
|
|
||||||
public async createWebhook(instance: InstanceDto, data: WebhookDto) {
|
public async createWebhook(instance: InstanceDto, data: WebhookDto) {
|
||||||
logger.verbose('requested createWebhook from ' + instance.instanceName + ' instance');
|
logger.verbose('requested createWebhook from ' + instance.instanceName + ' instance');
|
||||||
|
|
||||||
if (data.enabled && !isURL(data.url, { require_tld: false })) {
|
if (data.enabled && !isURL(data.url, { require_tld: false })) {
|
||||||
throw new BadRequestException('Invalid "url" property');
|
throw new BadRequestException('Invalid "url" property');
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.enabled) {
|
|
||||||
logger.verbose('webhook disabled');
|
|
||||||
data.url = '';
|
|
||||||
data.events = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.webhookService.create(instance, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findWebhook(instance: InstanceDto) {
|
if (!data.enabled) {
|
||||||
logger.verbose('requested findWebhook from ' + instance.instanceName + ' instance');
|
logger.verbose('webhook disabled');
|
||||||
return this.webhookService.find(instance);
|
data.url = '';
|
||||||
|
data.events = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this.webhookService.create(instance, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async findWebhook(instance: InstanceDto) {
|
||||||
|
logger.verbose('requested findWebhook from ' + instance.instanceName + ' instance');
|
||||||
|
return this.webhookService.find(instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,84 +1,84 @@
|
|||||||
import { proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys';
|
import { proto, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys';
|
||||||
|
|
||||||
export class OnWhatsAppDto {
|
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 {
|
export class getBase64FromMediaMessageDto {
|
||||||
message: proto.WebMessageInfo;
|
message: proto.WebMessageInfo;
|
||||||
convertToMp4?: boolean;
|
convertToMp4?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WhatsAppNumberDto {
|
export class WhatsAppNumberDto {
|
||||||
numbers: string[];
|
numbers: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NumberDto {
|
export class NumberDto {
|
||||||
number: string;
|
number: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NumberBusiness {
|
export class NumberBusiness {
|
||||||
wid?: string;
|
wid?: string;
|
||||||
jid?: string;
|
jid?: string;
|
||||||
exists?: boolean;
|
exists?: boolean;
|
||||||
isBusiness: boolean;
|
isBusiness: boolean;
|
||||||
name?: string;
|
name?: string;
|
||||||
message?: string;
|
message?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
website?: string[];
|
website?: string[];
|
||||||
address?: string;
|
address?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProfileNameDto {
|
export class ProfileNameDto {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProfileStatusDto {
|
export class ProfileStatusDto {
|
||||||
status: string;
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProfilePictureDto {
|
export class ProfilePictureDto {
|
||||||
number?: string;
|
number?: string;
|
||||||
// url or base64
|
// url or base64
|
||||||
picture?: string;
|
picture?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Key {
|
class Key {
|
||||||
id: string;
|
id: string;
|
||||||
fromMe: boolean;
|
fromMe: boolean;
|
||||||
remoteJid: string;
|
remoteJid: string;
|
||||||
}
|
}
|
||||||
export class ReadMessageDto {
|
export class ReadMessageDto {
|
||||||
read_messages: Key[];
|
read_messages: Key[];
|
||||||
}
|
}
|
||||||
|
|
||||||
class LastMessage {
|
class LastMessage {
|
||||||
key: Key;
|
key: Key;
|
||||||
messageTimestamp?: number;
|
messageTimestamp?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ArchiveChatDto {
|
export class ArchiveChatDto {
|
||||||
lastMessage: LastMessage;
|
lastMessage: LastMessage;
|
||||||
archive: boolean;
|
archive: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrivacySetting {
|
class PrivacySetting {
|
||||||
readreceipts: WAReadReceiptsValue;
|
readreceipts: WAReadReceiptsValue;
|
||||||
profile: WAPrivacyValue;
|
profile: WAPrivacyValue;
|
||||||
status: WAPrivacyValue;
|
status: WAPrivacyValue;
|
||||||
online: WAPrivacyOnlineValue;
|
online: WAPrivacyOnlineValue;
|
||||||
last: WAPrivacyValue;
|
last: WAPrivacyValue;
|
||||||
groupadd: WAPrivacyValue;
|
groupadd: WAPrivacyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PrivacySettingDto {
|
export class PrivacySettingDto {
|
||||||
privacySettings: PrivacySetting;
|
privacySettings: PrivacySetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DeleteMessage {
|
export class DeleteMessage {
|
||||||
id: string;
|
id: string;
|
||||||
fromMe: boolean;
|
fromMe: boolean;
|
||||||
remoteJid: string;
|
remoteJid: string;
|
||||||
participant?: string;
|
participant?: string;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
export class ChatwootDto {
|
export class ChatwootDto {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
account_id?: string;
|
account_id?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
name_inbox?: string;
|
name_inbox?: string;
|
||||||
sign_msg?: boolean;
|
sign_msg?: boolean;
|
||||||
number?: string;
|
number?: string;
|
||||||
reopen_conversation?: boolean;
|
reopen_conversation?: boolean;
|
||||||
conversation_pending?: boolean;
|
conversation_pending?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -1,52 +1,52 @@
|
|||||||
export class CreateGroupDto {
|
export class CreateGroupDto {
|
||||||
subject: string;
|
subject: string;
|
||||||
participants: string[];
|
participants: string[];
|
||||||
description?: string;
|
description?: string;
|
||||||
promoteParticipants?: boolean;
|
promoteParticipants?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupPictureDto {
|
export class GroupPictureDto {
|
||||||
groupJid: string;
|
groupJid: string;
|
||||||
image: string;
|
image: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupSubjectDto {
|
export class GroupSubjectDto {
|
||||||
groupJid: string;
|
groupJid: string;
|
||||||
subject: string;
|
subject: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupDescriptionDto {
|
export class GroupDescriptionDto {
|
||||||
groupJid: string;
|
groupJid: string;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupJid {
|
export class GroupJid {
|
||||||
groupJid: string;
|
groupJid: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetParticipant {
|
export class GetParticipant {
|
||||||
getParticipants: string;
|
getParticipants: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupInvite {
|
export class GroupInvite {
|
||||||
inviteCode: string;
|
inviteCode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupSendInvite {
|
export class GroupSendInvite {
|
||||||
groupJid: string;
|
groupJid: string;
|
||||||
description: string;
|
description: string;
|
||||||
numbers: string[];
|
numbers: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupUpdateParticipantDto extends GroupJid {
|
export class GroupUpdateParticipantDto extends GroupJid {
|
||||||
action: 'add' | 'remove' | 'promote' | 'demote';
|
action: 'add' | 'remove' | 'promote' | 'demote';
|
||||||
participants: string[];
|
participants: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupUpdateSettingDto extends GroupJid {
|
export class GroupUpdateSettingDto extends GroupJid {
|
||||||
action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked';
|
action: 'announcement' | 'not_announcement' | 'unlocked' | 'locked';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GroupToggleEphemeralDto extends GroupJid {
|
export class GroupToggleEphemeralDto extends GroupJid {
|
||||||
expiration: 0 | 86400 | 604800 | 7776000;
|
expiration: 0 | 86400 | 604800 | 7776000;
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
export class InstanceDto {
|
export class InstanceDto {
|
||||||
instanceName: string;
|
instanceName: string;
|
||||||
qrcode?: boolean;
|
qrcode?: boolean;
|
||||||
number?: string;
|
number?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
webhook?: string;
|
webhook?: string;
|
||||||
webhook_by_events?: boolean;
|
webhook_by_events?: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
reject_call?: boolean;
|
reject_call?: boolean;
|
||||||
msg_call?: string;
|
msg_call?: string;
|
||||||
groups_ignore?: boolean;
|
groups_ignore?: boolean;
|
||||||
always_online?: boolean;
|
always_online?: boolean;
|
||||||
read_messages?: boolean;
|
read_messages?: boolean;
|
||||||
read_status?: boolean;
|
read_status?: boolean;
|
||||||
chatwoot_account_id?: string;
|
chatwoot_account_id?: string;
|
||||||
chatwoot_token?: string;
|
chatwoot_token?: string;
|
||||||
chatwoot_url?: string;
|
chatwoot_url?: string;
|
||||||
chatwoot_sign_msg?: boolean;
|
chatwoot_sign_msg?: boolean;
|
||||||
chatwoot_reopen_conversation?: boolean;
|
chatwoot_reopen_conversation?: boolean;
|
||||||
chatwoot_conversation_pending?: boolean;
|
chatwoot_conversation_pending?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -1,150 +1,150 @@
|
|||||||
import { proto, WAPresence } from '@whiskeysockets/baileys';
|
import { proto, WAPresence } from '@whiskeysockets/baileys';
|
||||||
|
|
||||||
export class Quoted {
|
export class Quoted {
|
||||||
key: proto.IMessageKey;
|
key: proto.IMessageKey;
|
||||||
message: proto.IMessage;
|
message: proto.IMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Mentions {
|
export class Mentions {
|
||||||
everyOne: boolean;
|
everyOne: boolean;
|
||||||
mentioned: string[];
|
mentioned: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Options {
|
export class Options {
|
||||||
delay?: number;
|
delay?: number;
|
||||||
presence?: WAPresence;
|
presence?: WAPresence;
|
||||||
quoted?: Quoted;
|
quoted?: Quoted;
|
||||||
mentions?: Mentions;
|
mentions?: Mentions;
|
||||||
linkPreview?: boolean;
|
linkPreview?: boolean;
|
||||||
encoding?: boolean;
|
encoding?: boolean;
|
||||||
}
|
}
|
||||||
class OptionsMessage {
|
class OptionsMessage {
|
||||||
options: Options;
|
options: Options;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Metadata extends OptionsMessage {
|
export class Metadata extends OptionsMessage {
|
||||||
number: string;
|
number: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TextMessage {
|
class TextMessage {
|
||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StatusMessage {
|
export class StatusMessage {
|
||||||
type: string;
|
type: string;
|
||||||
content: string;
|
content: string;
|
||||||
statusJidList?: string[];
|
statusJidList?: string[];
|
||||||
allContacts?: boolean;
|
allContacts?: boolean;
|
||||||
caption?: string;
|
caption?: string;
|
||||||
backgroundColor?: string;
|
backgroundColor?: string;
|
||||||
font?: number;
|
font?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PollMessage {
|
class PollMessage {
|
||||||
name: string;
|
name: string;
|
||||||
selectableCount: number;
|
selectableCount: number;
|
||||||
values: string[];
|
values: string[];
|
||||||
messageSecret?: Uint8Array;
|
messageSecret?: Uint8Array;
|
||||||
}
|
}
|
||||||
export class SendTextDto extends Metadata {
|
export class SendTextDto extends Metadata {
|
||||||
textMessage: TextMessage;
|
textMessage: TextMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SendStatusDto extends Metadata {
|
export class SendStatusDto extends Metadata {
|
||||||
statusMessage: StatusMessage;
|
statusMessage: StatusMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SendPollDto extends Metadata {
|
export class SendPollDto extends Metadata {
|
||||||
pollMessage: PollMessage;
|
pollMessage: PollMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MediaType = 'image' | 'document' | 'video' | 'audio';
|
export type MediaType = 'image' | 'document' | 'video' | 'audio';
|
||||||
export class MediaMessage {
|
export class MediaMessage {
|
||||||
mediatype: MediaType;
|
mediatype: MediaType;
|
||||||
caption?: string;
|
caption?: string;
|
||||||
// for document
|
// for document
|
||||||
fileName?: string;
|
fileName?: string;
|
||||||
// url or base64
|
// url or base64
|
||||||
media: string;
|
media: string;
|
||||||
}
|
}
|
||||||
export class SendMediaDto extends Metadata {
|
export class SendMediaDto extends Metadata {
|
||||||
mediaMessage: MediaMessage;
|
mediaMessage: MediaMessage;
|
||||||
}
|
}
|
||||||
class Sticker {
|
class Sticker {
|
||||||
image: string;
|
image: string;
|
||||||
}
|
}
|
||||||
export class SendStickerDto extends Metadata {
|
export class SendStickerDto extends Metadata {
|
||||||
stickerMessage: Sticker;
|
stickerMessage: Sticker;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Audio {
|
class Audio {
|
||||||
audio: string;
|
audio: string;
|
||||||
}
|
}
|
||||||
export class SendAudioDto extends Metadata {
|
export class SendAudioDto extends Metadata {
|
||||||
audioMessage: Audio;
|
audioMessage: Audio;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Button {
|
class Button {
|
||||||
buttonText: string;
|
buttonText: string;
|
||||||
buttonId: string;
|
buttonId: string;
|
||||||
}
|
}
|
||||||
class ButtonMessage {
|
class ButtonMessage {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
footerText?: string;
|
footerText?: string;
|
||||||
buttons: Button[];
|
buttons: Button[];
|
||||||
mediaMessage?: MediaMessage;
|
mediaMessage?: MediaMessage;
|
||||||
}
|
}
|
||||||
export class SendButtonDto extends Metadata {
|
export class SendButtonDto extends Metadata {
|
||||||
buttonMessage: ButtonMessage;
|
buttonMessage: ButtonMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocationMessage {
|
class LocationMessage {
|
||||||
latitude: number;
|
latitude: number;
|
||||||
longitude: number;
|
longitude: number;
|
||||||
name?: string;
|
name?: string;
|
||||||
address?: string;
|
address?: string;
|
||||||
}
|
}
|
||||||
export class SendLocationDto extends Metadata {
|
export class SendLocationDto extends Metadata {
|
||||||
locationMessage: LocationMessage;
|
locationMessage: LocationMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Row {
|
class Row {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
rowId: string;
|
rowId: string;
|
||||||
}
|
}
|
||||||
class Section {
|
class Section {
|
||||||
title: string;
|
title: string;
|
||||||
rows: Row[];
|
rows: Row[];
|
||||||
}
|
}
|
||||||
class ListMessage {
|
class ListMessage {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
footerText?: string;
|
footerText?: string;
|
||||||
buttonText: string;
|
buttonText: string;
|
||||||
sections: Section[];
|
sections: Section[];
|
||||||
}
|
}
|
||||||
export class SendListDto extends Metadata {
|
export class SendListDto extends Metadata {
|
||||||
listMessage: ListMessage;
|
listMessage: ListMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ContactMessage {
|
export class ContactMessage {
|
||||||
fullName: string;
|
fullName: string;
|
||||||
wuid: string;
|
wuid: string;
|
||||||
phoneNumber: string;
|
phoneNumber: string;
|
||||||
organization?: string;
|
organization?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
}
|
}
|
||||||
export class SendContactDto extends Metadata {
|
export class SendContactDto extends Metadata {
|
||||||
contactMessage: ContactMessage[];
|
contactMessage: ContactMessage[];
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReactionMessage {
|
class ReactionMessage {
|
||||||
key: proto.IMessageKey;
|
key: proto.IMessageKey;
|
||||||
reaction: string;
|
reaction: string;
|
||||||
}
|
}
|
||||||
export class SendReactionDto {
|
export class SendReactionDto {
|
||||||
reactionMessage: ReactionMessage;
|
reactionMessage: ReactionMessage;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
export class SettingsDto {
|
export class SettingsDto {
|
||||||
reject_call?: boolean;
|
reject_call?: boolean;
|
||||||
msg_call?: string;
|
msg_call?: string;
|
||||||
groups_ignore?: boolean;
|
groups_ignore?: boolean;
|
||||||
always_online?: boolean;
|
always_online?: boolean;
|
||||||
read_messages?: boolean;
|
read_messages?: boolean;
|
||||||
read_status?: boolean;
|
read_status?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export class WebhookDto {
|
export class WebhookDto {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
url?: string;
|
url?: string;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
webhook_by_events?: boolean;
|
webhook_by_events?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -13,77 +13,71 @@ import { repository } from '../whatsapp.module';
|
|||||||
const logger = new Logger('GUARD');
|
const logger = new Logger('GUARD');
|
||||||
|
|
||||||
async function jwtGuard(req: Request, res: Response, next: NextFunction) {
|
async function jwtGuard(req: Request, res: Response, next: NextFunction) {
|
||||||
const key = req.get('apikey');
|
const key = req.get('apikey');
|
||||||
|
|
||||||
if (key && configService.get<Auth>('AUTHENTICATION').API_KEY.KEY !== key) {
|
if (key && configService.get<Auth>('AUTHENTICATION').API_KEY.KEY !== key) {
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configService.get<Auth>('AUTHENTICATION').API_KEY.KEY === key) {
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
|
const jwtOpts = configService.get<Auth>('AUTHENTICATION').JWT;
|
||||||
|
try {
|
||||||
|
const [bearer, token] = req.get('authorization').split(' ');
|
||||||
|
|
||||||
|
if (bearer.toLowerCase() !== 'bearer') {
|
||||||
|
throw new UnauthorizedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configService.get<Auth>('AUTHENTICATION').API_KEY.KEY === key) {
|
if (!isJWT(token)) {
|
||||||
return next();
|
throw new UnauthorizedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
const param = req.params as unknown as InstanceDto;
|
||||||
(req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) &&
|
const decode = jwt.verify(token, jwtOpts.SECRET, {
|
||||||
!key
|
ignoreExpiration: jwtOpts.EXPIRIN_IN === 0,
|
||||||
) {
|
}) as JwtPayload;
|
||||||
throw new ForbiddenException('Missing global api key', 'The global api key must be set');
|
|
||||||
|
if (param.instanceName !== decode.instanceName || name !== decode.apiName) {
|
||||||
|
throw new UnauthorizedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
const jwtOpts = configService.get<Auth>('AUTHENTICATION').JWT;
|
return next();
|
||||||
try {
|
} catch (error) {
|
||||||
const [bearer, token] = req.get('authorization').split(' ');
|
logger.error(error);
|
||||||
|
throw new UnauthorizedException();
|
||||||
if (bearer.toLowerCase() !== 'bearer') {
|
}
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isJWT(token)) {
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
const param = req.params as unknown as InstanceDto;
|
|
||||||
const decode = jwt.verify(token, jwtOpts.SECRET, {
|
|
||||||
ignoreExpiration: jwtOpts.EXPIRIN_IN === 0,
|
|
||||||
}) as JwtPayload;
|
|
||||||
|
|
||||||
if (param.instanceName !== decode.instanceName || name !== decode.apiName) {
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return next();
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(error);
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function apikey(req: Request, res: Response, next: NextFunction) {
|
async function apikey(req: Request, res: Response, next: NextFunction) {
|
||||||
const env = configService.get<Auth>('AUTHENTICATION').API_KEY;
|
const env = configService.get<Auth>('AUTHENTICATION').API_KEY;
|
||||||
const key = req.get('apikey');
|
const key = req.get('apikey');
|
||||||
|
|
||||||
if (env.KEY === key) {
|
if (env.KEY === key) {
|
||||||
return next();
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const param = req.params as unknown as InstanceDto;
|
||||||
|
const instanceKey = await repository.auth.find(param.instanceName);
|
||||||
|
if (instanceKey.apikey === key) {
|
||||||
|
return next();
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
throw new UnauthorizedException();
|
||||||
(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 {
|
|
||||||
const param = req.params as unknown as InstanceDto;
|
|
||||||
const instanceKey = await repository.auth.find(param.instanceName);
|
|
||||||
if (instanceKey.apikey === key) {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const authGuard = { jwt: jwtGuard, apikey };
|
export const authGuard = { jwt: jwtGuard, apikey };
|
||||||
|
@ -10,55 +10,55 @@ import { InstanceDto } from '../dto/instance.dto';
|
|||||||
import { cache, waMonitor } from '../whatsapp.module';
|
import { cache, waMonitor } from '../whatsapp.module';
|
||||||
|
|
||||||
async function getInstance(instanceName: string) {
|
async function getInstance(instanceName: string) {
|
||||||
const db = configService.get<Database>('DATABASE');
|
const db = configService.get<Database>('DATABASE');
|
||||||
const redisConf = configService.get<Redis>('REDIS');
|
const redisConf = configService.get<Redis>('REDIS');
|
||||||
|
|
||||||
const exists = !!waMonitor.waInstances[instanceName];
|
const exists = !!waMonitor.waInstances[instanceName];
|
||||||
|
|
||||||
if (redisConf.ENABLED) {
|
if (redisConf.ENABLED) {
|
||||||
const keyExists = await cache.keyExists();
|
const keyExists = await cache.keyExists();
|
||||||
return exists || keyExists;
|
return exists || keyExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (db.ENABLED) {
|
if (db.ENABLED) {
|
||||||
const collection = dbserver
|
const collection = dbserver
|
||||||
.getClient()
|
.getClient()
|
||||||
.db(db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
.db(db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||||
.collection(instanceName);
|
.collection(instanceName);
|
||||||
return exists || (await collection.find({}).toArray()).length > 0;
|
return exists || (await collection.find({}).toArray()).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return exists || existsSync(join(INSTANCE_DIR, instanceName));
|
return exists || existsSync(join(INSTANCE_DIR, instanceName));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function instanceExistsGuard(req: Request, _: Response, next: NextFunction) {
|
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();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
const param = req.params as unknown as InstanceDto;
|
const param = req.params as unknown as InstanceDto;
|
||||||
if (!param?.instanceName) {
|
if (!param?.instanceName) {
|
||||||
throw new BadRequestException('"instanceName" not provided.');
|
throw new BadRequestException('"instanceName" not provided.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(await getInstance(param.instanceName))) {
|
if (!(await getInstance(param.instanceName))) {
|
||||||
throw new NotFoundException(`The "${param.instanceName}" instance does not exist`);
|
throw new NotFoundException(`The "${param.instanceName}" instance does not exist`);
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function instanceLoggedGuard(req: Request, _: Response, next: NextFunction) {
|
export async function instanceLoggedGuard(req: Request, _: Response, next: NextFunction) {
|
||||||
if (req.originalUrl.includes('/instance/create')) {
|
if (req.originalUrl.includes('/instance/create')) {
|
||||||
const instance = req.body as InstanceDto;
|
const instance = req.body as InstanceDto;
|
||||||
if (await getInstance(instance.instanceName)) {
|
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]) {
|
|
||||||
delete waMonitor.waInstances[instance.instanceName];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
if (waMonitor.waInstances[instance.instanceName]) {
|
||||||
|
delete waMonitor.waInstances[instance.instanceName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,15 @@ import { Schema } from 'mongoose';
|
|||||||
import { dbserver } from '../../db/db.connect';
|
import { dbserver } from '../../db/db.connect';
|
||||||
|
|
||||||
export class AuthRaw {
|
export class AuthRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
jwt?: string;
|
jwt?: string;
|
||||||
apikey?: string;
|
apikey?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const authSchema = new Schema<AuthRaw>({
|
const authSchema = new Schema<AuthRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
jwt: { type: String, minlength: 1 },
|
jwt: { type: String, minlength: 1 },
|
||||||
apikey: { type: String, minlength: 1 },
|
apikey: { type: String, minlength: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AuthModel = dbserver?.model(AuthRaw.name, authSchema, 'authentication');
|
export const AuthModel = dbserver?.model(AuthRaw.name, authSchema, 'authentication');
|
||||||
|
@ -3,16 +3,16 @@ import { Schema } from 'mongoose';
|
|||||||
import { dbserver } from '../../db/db.connect';
|
import { dbserver } from '../../db/db.connect';
|
||||||
|
|
||||||
export class ChatRaw {
|
export class ChatRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
owner: string;
|
owner: string;
|
||||||
lastMsgTimestamp?: number;
|
lastMsgTimestamp?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const chatSchema = new Schema<ChatRaw>({
|
const chatSchema = new Schema<ChatRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
id: { type: String, required: true, minlength: 1 },
|
id: { type: String, required: true, minlength: 1 },
|
||||||
owner: { type: String, required: true, minlength: 1 },
|
owner: { type: String, required: true, minlength: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ChatModel = dbserver?.model(ChatRaw.name, chatSchema, 'chats');
|
export const ChatModel = dbserver?.model(ChatRaw.name, chatSchema, 'chats');
|
||||||
|
@ -3,27 +3,27 @@ import { Schema } from 'mongoose';
|
|||||||
import { dbserver } from '../../db/db.connect';
|
import { dbserver } from '../../db/db.connect';
|
||||||
|
|
||||||
export class ChatwootRaw {
|
export class ChatwootRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
account_id?: string;
|
account_id?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
name_inbox?: string;
|
name_inbox?: string;
|
||||||
sign_msg?: boolean;
|
sign_msg?: boolean;
|
||||||
number?: string;
|
number?: string;
|
||||||
reopen_conversation?: boolean;
|
reopen_conversation?: boolean;
|
||||||
conversation_pending?: boolean;
|
conversation_pending?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const chatwootSchema = new Schema<ChatwootRaw>({
|
const chatwootSchema = new Schema<ChatwootRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
enabled: { type: Boolean, required: true },
|
enabled: { type: Boolean, required: true },
|
||||||
account_id: { type: String, required: true },
|
account_id: { type: String, required: true },
|
||||||
token: { type: String, required: true },
|
token: { type: String, required: true },
|
||||||
url: { type: String, required: true },
|
url: { type: String, required: true },
|
||||||
name_inbox: { type: String, required: true },
|
name_inbox: { type: String, required: true },
|
||||||
sign_msg: { type: Boolean, required: true },
|
sign_msg: { type: Boolean, required: true },
|
||||||
number: { type: String, required: true },
|
number: { type: String, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ChatwootModel = dbserver?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot');
|
export const ChatwootModel = dbserver?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot');
|
||||||
|
@ -3,19 +3,19 @@ import { Schema } from 'mongoose';
|
|||||||
import { dbserver } from '../../db/db.connect';
|
import { dbserver } from '../../db/db.connect';
|
||||||
|
|
||||||
export class ContactRaw {
|
export class ContactRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
pushName?: string;
|
pushName?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
profilePictureUrl?: string;
|
profilePictureUrl?: string;
|
||||||
owner: string;
|
owner: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const contactSchema = new Schema<ContactRaw>({
|
const contactSchema = new Schema<ContactRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
pushName: { type: String, minlength: 1 },
|
pushName: { type: String, minlength: 1 },
|
||||||
id: { type: String, required: true, minlength: 1 },
|
id: { type: String, required: true, minlength: 1 },
|
||||||
profilePictureUrl: { type: String, minlength: 1 },
|
profilePictureUrl: { type: String, minlength: 1 },
|
||||||
owner: { type: String, required: true, minlength: 1 },
|
owner: { type: String, required: true, minlength: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ContactModel = dbserver?.model(ContactRaw.name, contactSchema, 'contacts');
|
export const ContactModel = dbserver?.model(ContactRaw.name, contactSchema, 'contacts');
|
||||||
|
@ -4,65 +4,65 @@ import { dbserver } from '../../db/db.connect';
|
|||||||
import { wa } from '../types/wa.types';
|
import { wa } from '../types/wa.types';
|
||||||
|
|
||||||
class Key {
|
class Key {
|
||||||
id?: string;
|
id?: string;
|
||||||
remoteJid?: string;
|
remoteJid?: string;
|
||||||
fromMe?: boolean;
|
fromMe?: boolean;
|
||||||
participant?: string;
|
participant?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MessageRaw {
|
export class MessageRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
key?: Key;
|
key?: Key;
|
||||||
pushName?: string;
|
pushName?: string;
|
||||||
participant?: string;
|
participant?: string;
|
||||||
message?: object;
|
message?: object;
|
||||||
messageType?: string;
|
messageType?: string;
|
||||||
messageTimestamp?: number | Long.Long;
|
messageTimestamp?: number | Long.Long;
|
||||||
owner: string;
|
owner: string;
|
||||||
source?: 'android' | 'web' | 'ios';
|
source?: 'android' | 'web' | 'ios';
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageSchema = new Schema<MessageRaw>({
|
const messageSchema = new Schema<MessageRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
key: {
|
key: {
|
||||||
id: { type: String, required: true, minlength: 1 },
|
id: { type: String, required: true, minlength: 1 },
|
||||||
remoteJid: { type: String, required: true, minlength: 1 },
|
remoteJid: { type: String, required: true, minlength: 1 },
|
||||||
fromMe: { type: Boolean, required: true },
|
fromMe: { type: Boolean, required: true },
|
||||||
participant: { type: String, minlength: 1 },
|
participant: { type: String, minlength: 1 },
|
||||||
},
|
},
|
||||||
pushName: { type: String },
|
pushName: { type: String },
|
||||||
participant: { type: String },
|
participant: { type: String },
|
||||||
messageType: { type: String },
|
messageType: { type: String },
|
||||||
message: { type: Object },
|
message: { type: Object },
|
||||||
source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] },
|
source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] },
|
||||||
messageTimestamp: { type: Number, required: true },
|
messageTimestamp: { type: Number, required: true },
|
||||||
owner: { type: String, required: true, minlength: 1 },
|
owner: { type: String, required: true, minlength: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const MessageModel = dbserver?.model(MessageRaw.name, messageSchema, 'messages');
|
export const MessageModel = dbserver?.model(MessageRaw.name, messageSchema, 'messages');
|
||||||
export type IMessageModel = typeof MessageModel;
|
export type IMessageModel = typeof MessageModel;
|
||||||
|
|
||||||
export class MessageUpdateRaw {
|
export class MessageUpdateRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
remoteJid?: string;
|
remoteJid?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
fromMe?: boolean;
|
fromMe?: boolean;
|
||||||
participant?: string;
|
participant?: string;
|
||||||
datetime?: number;
|
datetime?: number;
|
||||||
status?: wa.StatusMessage;
|
status?: wa.StatusMessage;
|
||||||
owner: string;
|
owner: string;
|
||||||
pollUpdates?: any;
|
pollUpdates?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageUpdateSchema = new Schema<MessageUpdateRaw>({
|
const messageUpdateSchema = new Schema<MessageUpdateRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
remoteJid: { type: String, required: true, min: 1 },
|
remoteJid: { type: String, required: true, min: 1 },
|
||||||
id: { type: String, required: true, min: 1 },
|
id: { type: String, required: true, min: 1 },
|
||||||
fromMe: { type: Boolean, required: true },
|
fromMe: { type: Boolean, required: true },
|
||||||
participant: { type: String, min: 1 },
|
participant: { type: String, min: 1 },
|
||||||
datetime: { type: Number, required: true, min: 1 },
|
datetime: { type: Number, required: true, min: 1 },
|
||||||
status: { type: String, required: true },
|
status: { type: String, required: true },
|
||||||
owner: { type: String, required: true, min: 1 },
|
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');
|
||||||
|
@ -3,23 +3,23 @@ import { Schema } from 'mongoose';
|
|||||||
import { dbserver } from '../../db/db.connect';
|
import { dbserver } from '../../db/db.connect';
|
||||||
|
|
||||||
export class SettingsRaw {
|
export class SettingsRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
reject_call?: boolean;
|
reject_call?: boolean;
|
||||||
msg_call?: string;
|
msg_call?: string;
|
||||||
groups_ignore?: boolean;
|
groups_ignore?: boolean;
|
||||||
always_online?: boolean;
|
always_online?: boolean;
|
||||||
read_messages?: boolean;
|
read_messages?: boolean;
|
||||||
read_status?: boolean;
|
read_status?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsSchema = new Schema<SettingsRaw>({
|
const settingsSchema = new Schema<SettingsRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
reject_call: { type: Boolean, required: true },
|
reject_call: { type: Boolean, required: true },
|
||||||
msg_call: { type: String, required: true },
|
msg_call: { type: String, required: true },
|
||||||
groups_ignore: { type: Boolean, required: true },
|
groups_ignore: { type: Boolean, required: true },
|
||||||
always_online: { type: Boolean, required: true },
|
always_online: { type: Boolean, required: true },
|
||||||
read_messages: { type: Boolean, required: true },
|
read_messages: { type: Boolean, required: true },
|
||||||
read_status: { type: Boolean, required: true },
|
read_status: { type: Boolean, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SettingsModel = dbserver?.model(SettingsRaw.name, settingsSchema, 'settings');
|
export const SettingsModel = dbserver?.model(SettingsRaw.name, settingsSchema, 'settings');
|
||||||
|
@ -3,19 +3,19 @@ import { Schema } from 'mongoose';
|
|||||||
import { dbserver } from '../../db/db.connect';
|
import { dbserver } from '../../db/db.connect';
|
||||||
|
|
||||||
export class WebhookRaw {
|
export class WebhookRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
webhook_by_events?: boolean;
|
webhook_by_events?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const webhookSchema = new Schema<WebhookRaw>({
|
const webhookSchema = new Schema<WebhookRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
url: { type: String, required: true },
|
url: { type: String, required: true },
|
||||||
enabled: { type: Boolean, required: true },
|
enabled: { type: Boolean, required: true },
|
||||||
events: { type: [String], required: true },
|
events: { type: [String], required: true },
|
||||||
webhook_by_events: { type: Boolean, required: true },
|
webhook_by_events: { type: Boolean, required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const WebhookModel = dbserver?.model(WebhookRaw.name, webhookSchema, 'webhook');
|
export const WebhookModel = dbserver?.model(WebhookRaw.name, webhookSchema, 'webhook');
|
||||||
|
@ -8,58 +8,58 @@ import { IInsert, Repository } from '../abstract/abstract.repository';
|
|||||||
import { AuthRaw, IAuthModel } from '../models';
|
import { AuthRaw, IAuthModel } from '../models';
|
||||||
|
|
||||||
export class AuthRepository extends Repository {
|
export class AuthRepository extends Repository {
|
||||||
constructor(private readonly authModel: IAuthModel, readonly configService: ConfigService) {
|
constructor(private readonly authModel: IAuthModel, readonly configService: ConfigService) {
|
||||||
super(configService);
|
super(configService);
|
||||||
this.auth = configService.get<Auth>('AUTHENTICATION');
|
this.auth = configService.get<Auth>('AUTHENTICATION');
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly auth: Auth;
|
||||||
|
private readonly logger = new Logger('AuthRepository');
|
||||||
|
|
||||||
|
public async create(data: AuthRaw, instance: string): Promise<IInsert> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('creating auth');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('saving auth to db');
|
||||||
|
const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||||
|
|
||||||
|
this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth');
|
||||||
|
return { insertCount: insert.modifiedCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('saving auth to store');
|
||||||
|
|
||||||
|
this.writeStore<AuthRaw>({
|
||||||
|
path: join(AUTH_DIR, this.auth.TYPE),
|
||||||
|
fileName: instance,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance);
|
||||||
|
|
||||||
|
this.logger.verbose('auth created');
|
||||||
|
return { insertCount: 1 };
|
||||||
|
} catch (error) {
|
||||||
|
return { error } as any;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly auth: Auth;
|
public async find(instance: string): Promise<AuthRaw> {
|
||||||
private readonly logger = new Logger('AuthRepository');
|
try {
|
||||||
|
this.logger.verbose('finding auth');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('finding auth in db');
|
||||||
|
return await this.authModel.findOne({ _id: instance });
|
||||||
|
}
|
||||||
|
|
||||||
public async create(data: AuthRaw, instance: string): Promise<IInsert> {
|
this.logger.verbose('finding auth in store');
|
||||||
try {
|
|
||||||
this.logger.verbose('creating auth');
|
|
||||||
if (this.dbSettings.ENABLED) {
|
|
||||||
this.logger.verbose('saving auth to db');
|
|
||||||
const insert = await this.authModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
|
||||||
|
|
||||||
this.logger.verbose('auth saved to db: ' + insert.modifiedCount + ' auth');
|
return JSON.parse(
|
||||||
return { insertCount: insert.modifiedCount };
|
readFileSync(join(AUTH_DIR, this.auth.TYPE, instance + '.json'), {
|
||||||
}
|
encoding: 'utf-8',
|
||||||
|
}),
|
||||||
this.logger.verbose('saving auth to store');
|
) as AuthRaw;
|
||||||
|
} catch (error) {
|
||||||
this.writeStore<AuthRaw>({
|
return {};
|
||||||
path: join(AUTH_DIR, this.auth.TYPE),
|
|
||||||
fileName: instance,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
this.logger.verbose('auth saved to store in path: ' + join(AUTH_DIR, this.auth.TYPE) + '/' + instance);
|
|
||||||
|
|
||||||
this.logger.verbose('auth created');
|
|
||||||
return { insertCount: 1 };
|
|
||||||
} catch (error) {
|
|
||||||
return { error } as any;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async find(instance: string): Promise<AuthRaw> {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('finding auth');
|
|
||||||
if (this.dbSettings.ENABLED) {
|
|
||||||
this.logger.verbose('finding auth in db');
|
|
||||||
return await this.authModel.findOne({ _id: instance });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('finding auth in store');
|
|
||||||
|
|
||||||
return JSON.parse(
|
|
||||||
readFileSync(join(AUTH_DIR, this.auth.TYPE, instance + '.json'), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
}),
|
|
||||||
) as AuthRaw;
|
|
||||||
} catch (error) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,111 +7,111 @@ import { IInsert, Repository } from '../abstract/abstract.repository';
|
|||||||
import { ChatRaw, IChatModel } from '../models';
|
import { ChatRaw, IChatModel } from '../models';
|
||||||
|
|
||||||
export class ChatQuery {
|
export class ChatQuery {
|
||||||
where: ChatRaw;
|
where: ChatRaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ChatRepository extends Repository {
|
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);
|
super(configService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger('ChatRepository');
|
||||||
|
|
||||||
|
public async insert(data: ChatRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||||
|
this.logger.verbose('inserting chats');
|
||||||
|
if (data.length === 0) {
|
||||||
|
this.logger.verbose('no chats to insert');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('ChatRepository');
|
try {
|
||||||
|
this.logger.verbose('saving chats to store');
|
||||||
|
if (this.dbSettings.ENABLED && saveDb) {
|
||||||
|
this.logger.verbose('saving chats to db');
|
||||||
|
const insert = await this.chatModel.insertMany([...data]);
|
||||||
|
|
||||||
public async insert(data: ChatRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
this.logger.verbose('chats saved to db: ' + insert.length + ' chats');
|
||||||
this.logger.verbose('inserting chats');
|
return { insertCount: insert.length };
|
||||||
if (data.length === 0) {
|
}
|
||||||
this.logger.verbose('no chats to insert');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
this.logger.verbose('saving chats to store');
|
||||||
this.logger.verbose('saving chats to store');
|
|
||||||
if (this.dbSettings.ENABLED && saveDb) {
|
|
||||||
this.logger.verbose('saving chats to db');
|
|
||||||
const insert = await this.chatModel.insertMany([...data]);
|
|
||||||
|
|
||||||
this.logger.verbose('chats saved to db: ' + insert.length + ' chats');
|
const store = this.configService.get<StoreConf>('STORE');
|
||||||
return { insertCount: insert.length };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('saving chats to store');
|
if (store.CHATS) {
|
||||||
|
this.logger.verbose('saving chats to store');
|
||||||
|
data.forEach((chat) => {
|
||||||
|
this.writeStore<ChatRaw>({
|
||||||
|
path: join(this.storePath, 'chats', instanceName),
|
||||||
|
fileName: chat.id,
|
||||||
|
data: chat,
|
||||||
|
});
|
||||||
|
this.logger.verbose(
|
||||||
|
'chats saved to store in path: ' + join(this.storePath, 'chats', instanceName) + '/' + chat.id,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const store = this.configService.get<StoreConf>('STORE');
|
this.logger.verbose('chats saved to store');
|
||||||
|
return { insertCount: data.length };
|
||||||
|
}
|
||||||
|
|
||||||
if (store.CHATS) {
|
this.logger.verbose('chats not saved to store');
|
||||||
this.logger.verbose('saving chats to store');
|
return { insertCount: 0 };
|
||||||
data.forEach((chat) => {
|
} catch (error) {
|
||||||
this.writeStore<ChatRaw>({
|
return error;
|
||||||
path: join(this.storePath, 'chats', instanceName),
|
} finally {
|
||||||
fileName: chat.id,
|
data = undefined;
|
||||||
data: chat,
|
|
||||||
});
|
|
||||||
this.logger.verbose(
|
|
||||||
'chats saved to store in path: ' + join(this.storePath, 'chats', instanceName) + '/' + chat.id,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose('chats saved to store');
|
|
||||||
return { insertCount: data.length };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('chats not saved to store');
|
|
||||||
return { insertCount: 0 };
|
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
} finally {
|
|
||||||
data = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async find(query: ChatQuery): Promise<ChatRaw[]> {
|
public async find(query: ChatQuery): Promise<ChatRaw[]> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('finding chats');
|
this.logger.verbose('finding chats');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('finding chats in db');
|
this.logger.verbose('finding chats in db');
|
||||||
return await this.chatModel.find({ owner: query.where.owner });
|
return await this.chatModel.find({ owner: query.where.owner });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('finding chats in store');
|
this.logger.verbose('finding chats in store');
|
||||||
|
|
||||||
const chats: ChatRaw[] = [];
|
const chats: ChatRaw[] = [];
|
||||||
const openDir = opendirSync(join(this.storePath, 'chats', query.where.owner));
|
const openDir = opendirSync(join(this.storePath, 'chats', query.where.owner));
|
||||||
for await (const dirent of openDir) {
|
for await (const dirent of openDir) {
|
||||||
if (dirent.isFile()) {
|
if (dirent.isFile()) {
|
||||||
chats.push(
|
chats.push(
|
||||||
JSON.parse(
|
JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'chats', query.where.owner, dirent.name), {
|
readFileSync(join(this.storePath, 'chats', query.where.owner, dirent.name), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('chats found in store: ' + chats.length + ' chats');
|
|
||||||
return chats;
|
|
||||||
} catch (error) {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('chats found in store: ' + chats.length + ' chats');
|
||||||
|
return chats;
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async delete(query: ChatQuery) {
|
public async delete(query: ChatQuery) {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('deleting chats');
|
this.logger.verbose('deleting chats');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('deleting chats in db');
|
this.logger.verbose('deleting chats in db');
|
||||||
return await this.chatModel.deleteOne({ ...query.where });
|
return await this.chatModel.deleteOne({ ...query.where });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('deleting chats in store');
|
this.logger.verbose('deleting chats in store');
|
||||||
rmSync(join(this.storePath, 'chats', query.where.owner, query.where.id + '.josn'), {
|
rmSync(join(this.storePath, 'chats', query.where.owner, query.where.id + '.josn'), {
|
||||||
force: true,
|
force: true,
|
||||||
recursive: true,
|
recursive: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return { deleted: { chatId: query.where.id } };
|
return { deleted: { chatId: query.where.id } };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { error: error?.toString() };
|
return { error: error?.toString() };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,58 +7,56 @@ import { IInsert, Repository } from '../abstract/abstract.repository';
|
|||||||
import { ChatwootRaw, IChatwootModel } from '../models';
|
import { ChatwootRaw, IChatwootModel } from '../models';
|
||||||
|
|
||||||
export class ChatwootRepository extends Repository {
|
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);
|
super(configService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger('ChatwootRepository');
|
||||||
|
|
||||||
|
public async create(data: ChatwootRaw, instance: string): Promise<IInsert> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('creating chatwoot');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('saving chatwoot to db');
|
||||||
|
const insert = await this.chatwootModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||||
|
|
||||||
|
this.logger.verbose('chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot');
|
||||||
|
return { insertCount: insert.modifiedCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('saving chatwoot to store');
|
||||||
|
|
||||||
|
this.writeStore<ChatwootRaw>({
|
||||||
|
path: join(this.storePath, 'chatwoot'),
|
||||||
|
fileName: instance,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.logger.verbose('chatwoot saved to store in path: ' + join(this.storePath, 'chatwoot') + '/' + instance);
|
||||||
|
|
||||||
|
this.logger.verbose('chatwoot created');
|
||||||
|
return { insertCount: 1 };
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('ChatwootRepository');
|
public async find(instance: string): Promise<ChatwootRaw> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('finding chatwoot');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('finding chatwoot in db');
|
||||||
|
return await this.chatwootModel.findOne({ _id: instance });
|
||||||
|
}
|
||||||
|
|
||||||
public async create(data: ChatwootRaw, instance: string): Promise<IInsert> {
|
this.logger.verbose('finding chatwoot in store');
|
||||||
try {
|
return JSON.parse(
|
||||||
this.logger.verbose('creating chatwoot');
|
readFileSync(join(this.storePath, 'chatwoot', instance + '.json'), {
|
||||||
if (this.dbSettings.ENABLED) {
|
encoding: 'utf-8',
|
||||||
this.logger.verbose('saving chatwoot to db');
|
}),
|
||||||
const insert = await this.chatwootModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
) as ChatwootRaw;
|
||||||
|
} catch (error) {
|
||||||
this.logger.verbose('chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot');
|
return {};
|
||||||
return { insertCount: insert.modifiedCount };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('saving chatwoot to store');
|
|
||||||
|
|
||||||
this.writeStore<ChatwootRaw>({
|
|
||||||
path: join(this.storePath, 'chatwoot'),
|
|
||||||
fileName: instance,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose(
|
|
||||||
'chatwoot saved to store in path: ' + join(this.storePath, 'chatwoot') + '/' + instance,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.logger.verbose('chatwoot created');
|
|
||||||
return { insertCount: 1 };
|
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async find(instance: string): Promise<ChatwootRaw> {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('finding chatwoot');
|
|
||||||
if (this.dbSettings.ENABLED) {
|
|
||||||
this.logger.verbose('finding chatwoot in db');
|
|
||||||
return await this.chatwootModel.findOne({ _id: instance });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('finding chatwoot in store');
|
|
||||||
return JSON.parse(
|
|
||||||
readFileSync(join(this.storePath, 'chatwoot', instance + '.json'), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
}),
|
|
||||||
) as ChatwootRaw;
|
|
||||||
} catch (error) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,171 +7,165 @@ import { IInsert, Repository } from '../abstract/abstract.repository';
|
|||||||
import { ContactRaw, IContactModel } from '../models';
|
import { ContactRaw, IContactModel } from '../models';
|
||||||
|
|
||||||
export class ContactQuery {
|
export class ContactQuery {
|
||||||
where: ContactRaw;
|
where: ContactRaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ContactRepository extends Repository {
|
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);
|
super(configService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger('ContactRepository');
|
||||||
|
|
||||||
|
public async insert(data: ContactRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||||
|
this.logger.verbose('inserting contacts');
|
||||||
|
|
||||||
|
if (data.length === 0) {
|
||||||
|
this.logger.verbose('no contacts to insert');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('ContactRepository');
|
try {
|
||||||
|
if (this.dbSettings.ENABLED && saveDb) {
|
||||||
|
this.logger.verbose('saving contacts to db');
|
||||||
|
|
||||||
public async insert(data: ContactRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
const insert = await this.contactModel.insertMany([...data]);
|
||||||
this.logger.verbose('inserting contacts');
|
|
||||||
|
|
||||||
if (data.length === 0) {
|
this.logger.verbose('contacts saved to db: ' + insert.length + ' contacts');
|
||||||
this.logger.verbose('no contacts to insert');
|
return { insertCount: insert.length };
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
this.logger.verbose('saving contacts to store');
|
||||||
if (this.dbSettings.ENABLED && saveDb) {
|
|
||||||
this.logger.verbose('saving contacts to db');
|
|
||||||
|
|
||||||
const insert = await this.contactModel.insertMany([...data]);
|
const store = this.configService.get<StoreConf>('STORE');
|
||||||
|
|
||||||
this.logger.verbose('contacts saved to db: ' + insert.length + ' contacts');
|
if (store.CONTACTS) {
|
||||||
return { insertCount: insert.length };
|
this.logger.verbose('saving contacts to store');
|
||||||
}
|
data.forEach((contact) => {
|
||||||
|
this.writeStore({
|
||||||
|
path: join(this.storePath, 'contacts', instanceName),
|
||||||
|
fileName: contact.id,
|
||||||
|
data: contact,
|
||||||
|
});
|
||||||
|
this.logger.verbose(
|
||||||
|
'contacts saved to store in path: ' + join(this.storePath, 'contacts', instanceName) + '/' + contact.id,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
this.logger.verbose('saving contacts to store');
|
this.logger.verbose('contacts saved to store: ' + data.length + ' contacts');
|
||||||
|
return { insertCount: data.length };
|
||||||
|
}
|
||||||
|
|
||||||
const store = this.configService.get<StoreConf>('STORE');
|
this.logger.verbose('contacts not saved');
|
||||||
|
return { insertCount: 0 };
|
||||||
if (store.CONTACTS) {
|
} catch (error) {
|
||||||
this.logger.verbose('saving contacts to store');
|
return error;
|
||||||
data.forEach((contact) => {
|
} finally {
|
||||||
this.writeStore({
|
data = undefined;
|
||||||
path: join(this.storePath, 'contacts', instanceName),
|
|
||||||
fileName: contact.id,
|
|
||||||
data: contact,
|
|
||||||
});
|
|
||||||
this.logger.verbose(
|
|
||||||
'contacts saved to store in path: ' +
|
|
||||||
join(this.storePath, 'contacts', instanceName) +
|
|
||||||
'/' +
|
|
||||||
contact.id,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose('contacts saved to store: ' + data.length + ' contacts');
|
|
||||||
return { insertCount: data.length };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('contacts not saved');
|
|
||||||
return { insertCount: 0 };
|
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
} finally {
|
|
||||||
data = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async update(data: ContactRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
public async update(data: ContactRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('updating contacts');
|
this.logger.verbose('updating contacts');
|
||||||
|
|
||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
this.logger.verbose('no contacts to update');
|
this.logger.verbose('no contacts to update');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.dbSettings.ENABLED && saveDb) {
|
if (this.dbSettings.ENABLED && saveDb) {
|
||||||
this.logger.verbose('updating contacts in db');
|
this.logger.verbose('updating contacts in db');
|
||||||
|
|
||||||
const contacts = data.map((contact) => {
|
const contacts = data.map((contact) => {
|
||||||
return {
|
return {
|
||||||
updateOne: {
|
updateOne: {
|
||||||
filter: { id: contact.id },
|
filter: { id: contact.id },
|
||||||
update: { ...contact },
|
update: { ...contact },
|
||||||
upsert: true,
|
upsert: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const { nModified } = await this.contactModel.bulkWrite(contacts);
|
const { nModified } = await this.contactModel.bulkWrite(contacts);
|
||||||
|
|
||||||
this.logger.verbose('contacts updated in db: ' + nModified + ' contacts');
|
this.logger.verbose('contacts updated in db: ' + nModified + ' contacts');
|
||||||
return { insertCount: nModified };
|
return { insertCount: nModified };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('updating contacts in store');
|
this.logger.verbose('updating contacts in store');
|
||||||
|
|
||||||
const store = this.configService.get<StoreConf>('STORE');
|
const store = this.configService.get<StoreConf>('STORE');
|
||||||
|
|
||||||
if (store.CONTACTS) {
|
if (store.CONTACTS) {
|
||||||
this.logger.verbose('updating contacts in store');
|
this.logger.verbose('updating contacts in store');
|
||||||
data.forEach((contact) => {
|
data.forEach((contact) => {
|
||||||
this.writeStore({
|
this.writeStore({
|
||||||
path: join(this.storePath, 'contacts', instanceName),
|
path: join(this.storePath, 'contacts', instanceName),
|
||||||
fileName: contact.id,
|
fileName: contact.id,
|
||||||
data: contact,
|
data: contact,
|
||||||
});
|
});
|
||||||
this.logger.verbose(
|
this.logger.verbose(
|
||||||
'contacts updated in store in path: ' +
|
'contacts updated in store in path: ' + join(this.storePath, 'contacts', instanceName) + '/' + contact.id,
|
||||||
join(this.storePath, 'contacts', instanceName) +
|
);
|
||||||
'/' +
|
});
|
||||||
contact.id,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose('contacts updated in store: ' + data.length + ' contacts');
|
this.logger.verbose('contacts updated in store: ' + data.length + ' contacts');
|
||||||
|
|
||||||
return { insertCount: data.length };
|
return { insertCount: data.length };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('contacts not updated');
|
this.logger.verbose('contacts not updated');
|
||||||
return { insertCount: 0 };
|
return { insertCount: 0 };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return error;
|
return error;
|
||||||
} finally {
|
} finally {
|
||||||
data = undefined;
|
data = undefined;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async find(query: ContactQuery): Promise<ContactRaw[]> {
|
public async find(query: ContactQuery): Promise<ContactRaw[]> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('finding contacts');
|
this.logger.verbose('finding contacts');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('finding contacts in db');
|
this.logger.verbose('finding contacts in db');
|
||||||
return await this.contactModel.find({ ...query.where });
|
return await this.contactModel.find({ ...query.where });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('finding contacts in store');
|
this.logger.verbose('finding contacts in store');
|
||||||
const contacts: ContactRaw[] = [];
|
const contacts: ContactRaw[] = [];
|
||||||
if (query?.where?.id) {
|
if (query?.where?.id) {
|
||||||
this.logger.verbose('finding contacts in store by id');
|
this.logger.verbose('finding contacts in store by id');
|
||||||
contacts.push(
|
contacts.push(
|
||||||
JSON.parse(
|
JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'contacts', query.where.owner, query.where.id + '.json'), {
|
readFileSync(join(this.storePath, 'contacts', query.where.owner, query.where.id + '.json'), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.logger.verbose('finding contacts in store by owner');
|
this.logger.verbose('finding contacts in store by owner');
|
||||||
|
|
||||||
const openDir = opendirSync(join(this.storePath, 'contacts', query.where.owner), {
|
const openDir = opendirSync(join(this.storePath, 'contacts', query.where.owner), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
});
|
});
|
||||||
for await (const dirent of openDir) {
|
for await (const dirent of openDir) {
|
||||||
if (dirent.isFile()) {
|
if (dirent.isFile()) {
|
||||||
contacts.push(
|
contacts.push(
|
||||||
JSON.parse(
|
JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'contacts', query.where.owner, dirent.name), {
|
readFileSync(join(this.storePath, 'contacts', query.where.owner, dirent.name), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('contacts found in store: ' + contacts.length + ' contacts');
|
|
||||||
return contacts;
|
|
||||||
} catch (error) {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('contacts found in store: ' + contacts.length + ' contacts');
|
||||||
|
return contacts;
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,145 +7,141 @@ import { IInsert, Repository } from '../abstract/abstract.repository';
|
|||||||
import { IMessageModel, MessageRaw } from '../models';
|
import { IMessageModel, MessageRaw } from '../models';
|
||||||
|
|
||||||
export class MessageQuery {
|
export class MessageQuery {
|
||||||
where: MessageRaw;
|
where: MessageRaw;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MessageRepository extends Repository {
|
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);
|
super(configService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger('MessageRepository');
|
||||||
|
|
||||||
|
public async insert(data: MessageRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
||||||
|
this.logger.verbose('inserting messages');
|
||||||
|
|
||||||
|
if (!Array.isArray(data) || data.length === 0) {
|
||||||
|
this.logger.verbose('no messages to insert');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('MessageRepository');
|
try {
|
||||||
|
if (this.dbSettings.ENABLED && saveDb) {
|
||||||
|
this.logger.verbose('saving messages to db');
|
||||||
|
const cleanedData = data.map((obj) => {
|
||||||
|
const cleanedObj = { ...obj };
|
||||||
|
if ('extendedTextMessage' in obj.message) {
|
||||||
|
const extendedTextMessage = obj.message.extendedTextMessage as {
|
||||||
|
contextInfo?: {
|
||||||
|
mentionedJid?: any;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
public async insert(data: MessageRaw[], instanceName: string, saveDb = false): Promise<IInsert> {
|
if (typeof extendedTextMessage === 'object' && extendedTextMessage !== null) {
|
||||||
this.logger.verbose('inserting messages');
|
if ('contextInfo' in extendedTextMessage) {
|
||||||
|
delete extendedTextMessage.contextInfo?.mentionedJid;
|
||||||
if (!Array.isArray(data) || data.length === 0) {
|
extendedTextMessage.contextInfo = {};
|
||||||
this.logger.verbose('no messages to insert');
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (this.dbSettings.ENABLED && saveDb) {
|
|
||||||
this.logger.verbose('saving messages to db');
|
|
||||||
const cleanedData = data.map((obj) => {
|
|
||||||
const cleanedObj = { ...obj };
|
|
||||||
if ('extendedTextMessage' in obj.message) {
|
|
||||||
const extendedTextMessage = obj.message.extendedTextMessage as {
|
|
||||||
contextInfo?: {
|
|
||||||
mentionedJid?: any;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof extendedTextMessage === 'object' && extendedTextMessage !== null) {
|
|
||||||
if ('contextInfo' in extendedTextMessage) {
|
|
||||||
delete extendedTextMessage.contextInfo?.mentionedJid;
|
|
||||||
extendedTextMessage.contextInfo = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cleanedObj;
|
|
||||||
});
|
|
||||||
|
|
||||||
const insert = await this.messageModel.insertMany([...cleanedData]);
|
|
||||||
|
|
||||||
this.logger.verbose('messages saved to db: ' + insert.length + ' messages');
|
|
||||||
return { insertCount: insert.length };
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return cleanedObj;
|
||||||
|
});
|
||||||
|
|
||||||
this.logger.verbose('saving messages to store');
|
const insert = await this.messageModel.insertMany([...cleanedData]);
|
||||||
|
|
||||||
const store = this.configService.get<StoreConf>('STORE');
|
this.logger.verbose('messages saved to db: ' + insert.length + ' messages');
|
||||||
|
return { insertCount: insert.length };
|
||||||
|
}
|
||||||
|
|
||||||
if (store.MESSAGES) {
|
this.logger.verbose('saving messages to store');
|
||||||
this.logger.verbose('saving messages to store');
|
|
||||||
|
|
||||||
data.forEach((message) => {
|
const store = this.configService.get<StoreConf>('STORE');
|
||||||
this.writeStore({
|
|
||||||
path: join(this.storePath, 'messages', instanceName),
|
|
||||||
fileName: message.key.id,
|
|
||||||
data: message,
|
|
||||||
});
|
|
||||||
this.logger.verbose(
|
|
||||||
'messages saved to store in path: ' +
|
|
||||||
join(this.storePath, 'messages', instanceName) +
|
|
||||||
'/' +
|
|
||||||
message.key.id,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose('messages saved to store: ' + data.length + ' messages');
|
if (store.MESSAGES) {
|
||||||
return { insertCount: data.length };
|
this.logger.verbose('saving messages to store');
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('messages not saved to store');
|
data.forEach((message) => {
|
||||||
return { insertCount: 0 };
|
this.writeStore({
|
||||||
} catch (error) {
|
path: join(this.storePath, 'messages', instanceName),
|
||||||
console.log('ERROR: ', error);
|
fileName: message.key.id,
|
||||||
return error;
|
data: message,
|
||||||
} finally {
|
});
|
||||||
data = undefined;
|
this.logger.verbose(
|
||||||
}
|
'messages saved to store in path: ' + join(this.storePath, 'messages', instanceName) + '/' + message.key.id,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.logger.verbose('messages saved to store: ' + data.length + ' messages');
|
||||||
|
return { insertCount: data.length };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('messages not saved to store');
|
||||||
|
return { insertCount: 0 };
|
||||||
|
} catch (error) {
|
||||||
|
console.log('ERROR: ', error);
|
||||||
|
return error;
|
||||||
|
} finally {
|
||||||
|
data = undefined;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async find(query: MessageQuery) {
|
public async find(query: MessageQuery) {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('finding messages');
|
this.logger.verbose('finding messages');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('finding messages in db');
|
this.logger.verbose('finding messages in db');
|
||||||
if (query?.where?.key) {
|
if (query?.where?.key) {
|
||||||
for (const [k, v] of Object.entries(query.where.key)) {
|
for (const [k, v] of Object.entries(query.where.key)) {
|
||||||
query.where['key.' + k] = v;
|
query.where['key.' + k] = v;
|
||||||
}
|
}
|
||||||
delete query?.where?.key;
|
delete query?.where?.key;
|
||||||
}
|
|
||||||
|
|
||||||
return await this.messageModel
|
|
||||||
.find({ ...query.where })
|
|
||||||
.sort({ messageTimestamp: -1 })
|
|
||||||
.limit(query?.limit ?? 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('finding messages in store');
|
|
||||||
const messages: MessageRaw[] = [];
|
|
||||||
if (query?.where?.key?.id) {
|
|
||||||
this.logger.verbose('finding messages in store by id');
|
|
||||||
messages.push(
|
|
||||||
JSON.parse(
|
|
||||||
readFileSync(
|
|
||||||
join(this.storePath, 'messages', query.where.owner, query.where.key.id + '.json'),
|
|
||||||
{ encoding: 'utf-8' },
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.logger.verbose('finding messages in store by owner');
|
|
||||||
const openDir = opendirSync(join(this.storePath, 'messages', query.where.owner), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
});
|
|
||||||
|
|
||||||
for await (const dirent of openDir) {
|
|
||||||
if (dirent.isFile()) {
|
|
||||||
messages.push(
|
|
||||||
JSON.parse(
|
|
||||||
readFileSync(join(this.storePath, 'messages', query.where.owner, dirent.name), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('messages found in store: ' + messages.length + ' messages');
|
|
||||||
return messages
|
|
||||||
.sort((x, y) => {
|
|
||||||
return (y.messageTimestamp as number) - (x.messageTimestamp as number);
|
|
||||||
})
|
|
||||||
.splice(0, query?.limit ?? messages.length);
|
|
||||||
} catch (error) {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return await this.messageModel
|
||||||
|
.find({ ...query.where })
|
||||||
|
.sort({ messageTimestamp: -1 })
|
||||||
|
.limit(query?.limit ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('finding messages in store');
|
||||||
|
const messages: MessageRaw[] = [];
|
||||||
|
if (query?.where?.key?.id) {
|
||||||
|
this.logger.verbose('finding messages in store by id');
|
||||||
|
messages.push(
|
||||||
|
JSON.parse(
|
||||||
|
readFileSync(join(this.storePath, 'messages', query.where.owner, query.where.key.id + '.json'), {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.logger.verbose('finding messages in store by owner');
|
||||||
|
const openDir = opendirSync(join(this.storePath, 'messages', query.where.owner), {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
});
|
||||||
|
|
||||||
|
for await (const dirent of openDir) {
|
||||||
|
if (dirent.isFile()) {
|
||||||
|
messages.push(
|
||||||
|
JSON.parse(
|
||||||
|
readFileSync(join(this.storePath, 'messages', query.where.owner, dirent.name), {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('messages found in store: ' + messages.length + ' messages');
|
||||||
|
return messages
|
||||||
|
.sort((x, y) => {
|
||||||
|
return (y.messageTimestamp as number) - (x.messageTimestamp as number);
|
||||||
|
})
|
||||||
|
.splice(0, query?.limit ?? messages.length);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,117 +7,114 @@ import { IInsert, Repository } from '../abstract/abstract.repository';
|
|||||||
import { IMessageUpModel, MessageUpdateRaw } from '../models';
|
import { IMessageUpModel, MessageUpdateRaw } from '../models';
|
||||||
|
|
||||||
export class MessageUpQuery {
|
export class MessageUpQuery {
|
||||||
where: MessageUpdateRaw;
|
where: MessageUpdateRaw;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MessageUpRepository extends Repository {
|
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);
|
super(configService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger('MessageUpRepository');
|
||||||
|
|
||||||
|
public async insert(data: MessageUpdateRaw[], instanceName: string, saveDb?: boolean): Promise<IInsert> {
|
||||||
|
this.logger.verbose('inserting message up');
|
||||||
|
|
||||||
|
if (data.length === 0) {
|
||||||
|
this.logger.verbose('no message up to insert');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('MessageUpRepository');
|
try {
|
||||||
|
if (this.dbSettings.ENABLED && saveDb) {
|
||||||
|
this.logger.verbose('saving message up to db');
|
||||||
|
const insert = await this.messageUpModel.insertMany([...data]);
|
||||||
|
|
||||||
public async insert(data: MessageUpdateRaw[], instanceName: string, saveDb?: boolean): Promise<IInsert> {
|
this.logger.verbose('message up saved to db: ' + insert.length + ' message up');
|
||||||
this.logger.verbose('inserting message up');
|
return { insertCount: insert.length };
|
||||||
|
}
|
||||||
|
|
||||||
if (data.length === 0) {
|
this.logger.verbose('saving message up to store');
|
||||||
this.logger.verbose('no message up to insert');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
const store = this.configService.get<StoreConf>('STORE');
|
||||||
if (this.dbSettings.ENABLED && saveDb) {
|
|
||||||
this.logger.verbose('saving message up to db');
|
|
||||||
const insert = await this.messageUpModel.insertMany([...data]);
|
|
||||||
|
|
||||||
this.logger.verbose('message up saved to db: ' + insert.length + ' message up');
|
if (store.MESSAGE_UP) {
|
||||||
return { insertCount: insert.length };
|
this.logger.verbose('saving message up to store');
|
||||||
}
|
data.forEach((update) => {
|
||||||
|
this.writeStore<MessageUpdateRaw>({
|
||||||
|
path: join(this.storePath, 'message-up', instanceName),
|
||||||
|
fileName: update.id,
|
||||||
|
data: update,
|
||||||
|
});
|
||||||
|
this.logger.verbose(
|
||||||
|
'message up saved to store in path: ' + join(this.storePath, 'message-up', instanceName) + '/' + update.id,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
this.logger.verbose('saving message up to store');
|
this.logger.verbose('message up saved to store: ' + data.length + ' message up');
|
||||||
|
return { insertCount: data.length };
|
||||||
|
}
|
||||||
|
|
||||||
const store = this.configService.get<StoreConf>('STORE');
|
this.logger.verbose('message up not saved to store');
|
||||||
|
return { insertCount: 0 };
|
||||||
if (store.MESSAGE_UP) {
|
} catch (error) {
|
||||||
this.logger.verbose('saving message up to store');
|
return error;
|
||||||
data.forEach((update) => {
|
|
||||||
this.writeStore<MessageUpdateRaw>({
|
|
||||||
path: join(this.storePath, 'message-up', instanceName),
|
|
||||||
fileName: update.id,
|
|
||||||
data: update,
|
|
||||||
});
|
|
||||||
this.logger.verbose(
|
|
||||||
'message up saved to store in path: ' +
|
|
||||||
join(this.storePath, 'message-up', instanceName) +
|
|
||||||
'/' +
|
|
||||||
update.id,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose('message up saved to store: ' + data.length + ' message up');
|
|
||||||
return { insertCount: data.length };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('message up not saved to store');
|
|
||||||
return { insertCount: 0 };
|
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async find(query: MessageUpQuery) {
|
public async find(query: MessageUpQuery) {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('finding message up');
|
this.logger.verbose('finding message up');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('finding message up in db');
|
this.logger.verbose('finding message up in db');
|
||||||
return await this.messageUpModel
|
return await this.messageUpModel
|
||||||
.find({ ...query.where })
|
.find({ ...query.where })
|
||||||
.sort({ datetime: -1 })
|
.sort({ datetime: -1 })
|
||||||
.limit(query?.limit ?? 0);
|
.limit(query?.limit ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('finding message up in store');
|
this.logger.verbose('finding message up in store');
|
||||||
|
|
||||||
const messageUpdate: MessageUpdateRaw[] = [];
|
const messageUpdate: MessageUpdateRaw[] = [];
|
||||||
if (query?.where?.id) {
|
if (query?.where?.id) {
|
||||||
this.logger.verbose('finding message up in store by id');
|
this.logger.verbose('finding message up in store by id');
|
||||||
|
|
||||||
messageUpdate.push(
|
messageUpdate.push(
|
||||||
JSON.parse(
|
JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'message-up', query.where.owner, query.where.id + '.json'), {
|
readFileSync(join(this.storePath, 'message-up', query.where.owner, query.where.id + '.json'), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.logger.verbose('finding message up in store by owner');
|
this.logger.verbose('finding message up in store by owner');
|
||||||
|
|
||||||
const openDir = opendirSync(join(this.storePath, 'message-up', query.where.owner), {
|
const openDir = opendirSync(join(this.storePath, 'message-up', query.where.owner), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
});
|
});
|
||||||
|
|
||||||
for await (const dirent of openDir) {
|
for await (const dirent of openDir) {
|
||||||
if (dirent.isFile()) {
|
if (dirent.isFile()) {
|
||||||
messageUpdate.push(
|
messageUpdate.push(
|
||||||
JSON.parse(
|
JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'message-up', query.where.owner, dirent.name), {
|
readFileSync(join(this.storePath, 'message-up', query.where.owner, dirent.name), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('message up found in store: ' + messageUpdate.length + ' message up');
|
|
||||||
return messageUpdate
|
|
||||||
.sort((x, y) => {
|
|
||||||
return y.datetime - x.datetime;
|
|
||||||
})
|
|
||||||
.splice(0, query?.limit ?? messageUpdate.length);
|
|
||||||
} catch (error) {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('message up found in store: ' + messageUpdate.length + ' message up');
|
||||||
|
return messageUpdate
|
||||||
|
.sort((x, y) => {
|
||||||
|
return y.datetime - x.datetime;
|
||||||
|
})
|
||||||
|
.splice(0, query?.limit ?? messageUpdate.length);
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,105 +13,105 @@ import { MessageUpRepository } from './messageUp.repository';
|
|||||||
import { SettingsRepository } from './settings.repository';
|
import { SettingsRepository } from './settings.repository';
|
||||||
import { WebhookRepository } from './webhook.repository';
|
import { WebhookRepository } from './webhook.repository';
|
||||||
export class RepositoryBroker {
|
export class RepositoryBroker {
|
||||||
constructor(
|
constructor(
|
||||||
public readonly message: MessageRepository,
|
public readonly message: MessageRepository,
|
||||||
public readonly chat: ChatRepository,
|
public readonly chat: ChatRepository,
|
||||||
public readonly contact: ContactRepository,
|
public readonly contact: ContactRepository,
|
||||||
public readonly messageUpdate: MessageUpRepository,
|
public readonly messageUpdate: MessageUpRepository,
|
||||||
public readonly webhook: WebhookRepository,
|
public readonly webhook: WebhookRepository,
|
||||||
public readonly chatwoot: ChatwootRepository,
|
public readonly chatwoot: ChatwootRepository,
|
||||||
public readonly settings: SettingsRepository,
|
public readonly settings: SettingsRepository,
|
||||||
public readonly auth: AuthRepository,
|
public readonly auth: AuthRepository,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
dbServer?: MongoClient,
|
dbServer?: MongoClient,
|
||||||
) {
|
) {
|
||||||
this.dbClient = dbServer;
|
this.dbClient = dbServer;
|
||||||
this.__init_repo_without_db__();
|
this.__init_repo_without_db__();
|
||||||
}
|
}
|
||||||
|
|
||||||
private dbClient?: MongoClient;
|
private dbClient?: MongoClient;
|
||||||
private readonly logger = new Logger('RepositoryBroker');
|
private readonly logger = new Logger('RepositoryBroker');
|
||||||
|
|
||||||
public get dbServer() {
|
public get dbServer() {
|
||||||
return this.dbClient;
|
return this.dbClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
private __init_repo_without_db__() {
|
private __init_repo_without_db__() {
|
||||||
this.logger.verbose('initializing repository without db');
|
this.logger.verbose('initializing repository without db');
|
||||||
if (!this.configService.get<Database>('DATABASE').ENABLED) {
|
if (!this.configService.get<Database>('DATABASE').ENABLED) {
|
||||||
const storePath = join(process.cwd(), 'store');
|
const storePath = join(process.cwd(), 'store');
|
||||||
|
|
||||||
this.logger.verbose('creating store path: ' + storePath);
|
this.logger.verbose('creating store path: ' + storePath);
|
||||||
try {
|
try {
|
||||||
const authDir = join(storePath, 'auth', this.configService.get<Auth>('AUTHENTICATION').TYPE);
|
const authDir = join(storePath, 'auth', this.configService.get<Auth>('AUTHENTICATION').TYPE);
|
||||||
const chatsDir = join(storePath, 'chats');
|
const chatsDir = join(storePath, 'chats');
|
||||||
const contactsDir = join(storePath, 'contacts');
|
const contactsDir = join(storePath, 'contacts');
|
||||||
const messagesDir = join(storePath, 'messages');
|
const messagesDir = join(storePath, 'messages');
|
||||||
const messageUpDir = join(storePath, 'message-up');
|
const messageUpDir = join(storePath, 'message-up');
|
||||||
const webhookDir = join(storePath, 'webhook');
|
const webhookDir = join(storePath, 'webhook');
|
||||||
const chatwootDir = join(storePath, 'chatwoot');
|
const chatwootDir = join(storePath, 'chatwoot');
|
||||||
const settingsDir = join(storePath, 'settings');
|
const settingsDir = join(storePath, 'settings');
|
||||||
const tempDir = join(storePath, 'temp');
|
const tempDir = join(storePath, 'temp');
|
||||||
|
|
||||||
if (!fs.existsSync(authDir)) {
|
if (!fs.existsSync(authDir)) {
|
||||||
this.logger.verbose('creating auth dir: ' + authDir);
|
this.logger.verbose('creating auth dir: ' + authDir);
|
||||||
fs.mkdirSync(authDir, { recursive: true });
|
fs.mkdirSync(authDir, { recursive: true });
|
||||||
}
|
|
||||||
if (!fs.existsSync(chatsDir)) {
|
|
||||||
this.logger.verbose('creating chats dir: ' + chatsDir);
|
|
||||||
fs.mkdirSync(chatsDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(contactsDir)) {
|
|
||||||
this.logger.verbose('creating contacts dir: ' + contactsDir);
|
|
||||||
fs.mkdirSync(contactsDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(messagesDir)) {
|
|
||||||
this.logger.verbose('creating messages dir: ' + messagesDir);
|
|
||||||
fs.mkdirSync(messagesDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(messageUpDir)) {
|
|
||||||
this.logger.verbose('creating message-up dir: ' + messageUpDir);
|
|
||||||
fs.mkdirSync(messageUpDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(webhookDir)) {
|
|
||||||
this.logger.verbose('creating webhook dir: ' + webhookDir);
|
|
||||||
fs.mkdirSync(webhookDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(chatwootDir)) {
|
|
||||||
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
|
||||||
fs.mkdirSync(chatwootDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(settingsDir)) {
|
|
||||||
this.logger.verbose('creating settings dir: ' + settingsDir);
|
|
||||||
fs.mkdirSync(settingsDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(tempDir)) {
|
|
||||||
this.logger.verbose('creating temp dir: ' + tempDir);
|
|
||||||
fs.mkdirSync(tempDir, { recursive: true });
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
const storePath = join(process.cwd(), 'store');
|
|
||||||
|
|
||||||
this.logger.verbose('creating store path: ' + storePath);
|
|
||||||
|
|
||||||
const tempDir = join(storePath, 'temp');
|
|
||||||
const chatwootDir = join(storePath, 'chatwoot');
|
|
||||||
|
|
||||||
if (!fs.existsSync(chatwootDir)) {
|
|
||||||
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
|
||||||
fs.mkdirSync(chatwootDir, { recursive: true });
|
|
||||||
}
|
|
||||||
if (!fs.existsSync(tempDir)) {
|
|
||||||
this.logger.verbose('creating temp dir: ' + tempDir);
|
|
||||||
fs.mkdirSync(tempDir, { recursive: true });
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!fs.existsSync(chatsDir)) {
|
||||||
|
this.logger.verbose('creating chats dir: ' + chatsDir);
|
||||||
|
fs.mkdirSync(chatsDir, { recursive: true });
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(contactsDir)) {
|
||||||
|
this.logger.verbose('creating contacts dir: ' + contactsDir);
|
||||||
|
fs.mkdirSync(contactsDir, { recursive: true });
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(messagesDir)) {
|
||||||
|
this.logger.verbose('creating messages dir: ' + messagesDir);
|
||||||
|
fs.mkdirSync(messagesDir, { recursive: true });
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(messageUpDir)) {
|
||||||
|
this.logger.verbose('creating message-up dir: ' + messageUpDir);
|
||||||
|
fs.mkdirSync(messageUpDir, { recursive: true });
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(webhookDir)) {
|
||||||
|
this.logger.verbose('creating webhook dir: ' + webhookDir);
|
||||||
|
fs.mkdirSync(webhookDir, { recursive: true });
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(chatwootDir)) {
|
||||||
|
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
||||||
|
fs.mkdirSync(chatwootDir, { recursive: true });
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(settingsDir)) {
|
||||||
|
this.logger.verbose('creating settings dir: ' + settingsDir);
|
||||||
|
fs.mkdirSync(settingsDir, { recursive: true });
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(tempDir)) {
|
||||||
|
this.logger.verbose('creating temp dir: ' + tempDir);
|
||||||
|
fs.mkdirSync(tempDir, { recursive: true });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const storePath = join(process.cwd(), 'store');
|
||||||
|
|
||||||
|
this.logger.verbose('creating store path: ' + storePath);
|
||||||
|
|
||||||
|
const tempDir = join(storePath, 'temp');
|
||||||
|
const chatwootDir = join(storePath, 'chatwoot');
|
||||||
|
|
||||||
|
if (!fs.existsSync(chatwootDir)) {
|
||||||
|
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
||||||
|
fs.mkdirSync(chatwootDir, { recursive: true });
|
||||||
|
}
|
||||||
|
if (!fs.existsSync(tempDir)) {
|
||||||
|
this.logger.verbose('creating temp dir: ' + tempDir);
|
||||||
|
fs.mkdirSync(tempDir, { recursive: true });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,58 +7,56 @@ import { IInsert, Repository } from '../abstract/abstract.repository';
|
|||||||
import { ISettingsModel, SettingsRaw } from '../models';
|
import { ISettingsModel, SettingsRaw } from '../models';
|
||||||
|
|
||||||
export class SettingsRepository extends Repository {
|
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);
|
super(configService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger('SettingsRepository');
|
||||||
|
|
||||||
|
public async create(data: SettingsRaw, instance: string): Promise<IInsert> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('creating settings');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('saving settings to db');
|
||||||
|
const insert = await this.settingsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||||
|
|
||||||
|
this.logger.verbose('settings saved to db: ' + insert.modifiedCount + ' settings');
|
||||||
|
return { insertCount: insert.modifiedCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('saving settings to store');
|
||||||
|
|
||||||
|
this.writeStore<SettingsRaw>({
|
||||||
|
path: join(this.storePath, 'settings'),
|
||||||
|
fileName: instance,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.logger.verbose('settings saved to store in path: ' + join(this.storePath, 'settings') + '/' + instance);
|
||||||
|
|
||||||
|
this.logger.verbose('settings created');
|
||||||
|
return { insertCount: 1 };
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('SettingsRepository');
|
public async find(instance: string): Promise<SettingsRaw> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('finding settings');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('finding settings in db');
|
||||||
|
return await this.settingsModel.findOne({ _id: instance });
|
||||||
|
}
|
||||||
|
|
||||||
public async create(data: SettingsRaw, instance: string): Promise<IInsert> {
|
this.logger.verbose('finding settings in store');
|
||||||
try {
|
return JSON.parse(
|
||||||
this.logger.verbose('creating settings');
|
readFileSync(join(this.storePath, 'settings', instance + '.json'), {
|
||||||
if (this.dbSettings.ENABLED) {
|
encoding: 'utf-8',
|
||||||
this.logger.verbose('saving settings to db');
|
}),
|
||||||
const insert = await this.settingsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
) as SettingsRaw;
|
||||||
|
} catch (error) {
|
||||||
this.logger.verbose('settings saved to db: ' + insert.modifiedCount + ' settings');
|
return {};
|
||||||
return { insertCount: insert.modifiedCount };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('saving settings to store');
|
|
||||||
|
|
||||||
this.writeStore<SettingsRaw>({
|
|
||||||
path: join(this.storePath, 'settings'),
|
|
||||||
fileName: instance,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose(
|
|
||||||
'settings saved to store in path: ' + join(this.storePath, 'settings') + '/' + instance,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.logger.verbose('settings created');
|
|
||||||
return { insertCount: 1 };
|
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async find(instance: string): Promise<SettingsRaw> {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('finding settings');
|
|
||||||
if (this.dbSettings.ENABLED) {
|
|
||||||
this.logger.verbose('finding settings in db');
|
|
||||||
return await this.settingsModel.findOne({ _id: instance });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('finding settings in store');
|
|
||||||
return JSON.parse(
|
|
||||||
readFileSync(join(this.storePath, 'settings', instance + '.json'), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
}),
|
|
||||||
) as SettingsRaw;
|
|
||||||
} catch (error) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,56 +7,56 @@ import { IInsert, Repository } from '../abstract/abstract.repository';
|
|||||||
import { IWebhookModel, WebhookRaw } from '../models';
|
import { IWebhookModel, WebhookRaw } from '../models';
|
||||||
|
|
||||||
export class WebhookRepository extends Repository {
|
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);
|
super(configService);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly logger = new Logger('WebhookRepository');
|
||||||
|
|
||||||
|
public async create(data: WebhookRaw, instance: string): Promise<IInsert> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('creating webhook');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('saving webhook to db');
|
||||||
|
const insert = await this.webhookModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||||
|
|
||||||
|
this.logger.verbose('webhook saved to db: ' + insert.modifiedCount + ' webhook');
|
||||||
|
return { insertCount: insert.modifiedCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('saving webhook to store');
|
||||||
|
|
||||||
|
this.writeStore<WebhookRaw>({
|
||||||
|
path: join(this.storePath, 'webhook'),
|
||||||
|
fileName: instance,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.logger.verbose('webhook saved to store in path: ' + join(this.storePath, 'webhook') + '/' + instance);
|
||||||
|
|
||||||
|
this.logger.verbose('webhook created');
|
||||||
|
return { insertCount: 1 };
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('WebhookRepository');
|
public async find(instance: string): Promise<WebhookRaw> {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('finding webhook');
|
||||||
|
if (this.dbSettings.ENABLED) {
|
||||||
|
this.logger.verbose('finding webhook in db');
|
||||||
|
return await this.webhookModel.findOne({ _id: instance });
|
||||||
|
}
|
||||||
|
|
||||||
public async create(data: WebhookRaw, instance: string): Promise<IInsert> {
|
this.logger.verbose('finding webhook in store');
|
||||||
try {
|
return JSON.parse(
|
||||||
this.logger.verbose('creating webhook');
|
readFileSync(join(this.storePath, 'webhook', instance + '.json'), {
|
||||||
if (this.dbSettings.ENABLED) {
|
encoding: 'utf-8',
|
||||||
this.logger.verbose('saving webhook to db');
|
}),
|
||||||
const insert = await this.webhookModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
) as WebhookRaw;
|
||||||
|
} catch (error) {
|
||||||
this.logger.verbose('webhook saved to db: ' + insert.modifiedCount + ' webhook');
|
return {};
|
||||||
return { insertCount: insert.modifiedCount };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('saving webhook to store');
|
|
||||||
|
|
||||||
this.writeStore<WebhookRaw>({
|
|
||||||
path: join(this.storePath, 'webhook'),
|
|
||||||
fileName: instance,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.logger.verbose('webhook saved to store in path: ' + join(this.storePath, 'webhook') + '/' + instance);
|
|
||||||
|
|
||||||
this.logger.verbose('webhook created');
|
|
||||||
return { insertCount: 1 };
|
|
||||||
} catch (error) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async find(instance: string): Promise<WebhookRaw> {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('finding webhook');
|
|
||||||
if (this.dbSettings.ENABLED) {
|
|
||||||
this.logger.verbose('finding webhook in db');
|
|
||||||
return await this.webhookModel.findOne({ _id: instance });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('finding webhook in store');
|
|
||||||
return JSON.parse(
|
|
||||||
readFileSync(join(this.storePath, 'webhook', instance + '.json'), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
}),
|
|
||||||
) as WebhookRaw;
|
|
||||||
} catch (error) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,31 +2,31 @@ import { RequestHandler, Router } from 'express';
|
|||||||
|
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import {
|
import {
|
||||||
archiveChatSchema,
|
archiveChatSchema,
|
||||||
contactValidateSchema,
|
contactValidateSchema,
|
||||||
deleteMessageSchema,
|
deleteMessageSchema,
|
||||||
messageUpSchema,
|
messageUpSchema,
|
||||||
messageValidateSchema,
|
messageValidateSchema,
|
||||||
privacySettingsSchema,
|
privacySettingsSchema,
|
||||||
profileNameSchema,
|
profileNameSchema,
|
||||||
profilePictureSchema,
|
profilePictureSchema,
|
||||||
profileSchema,
|
profileSchema,
|
||||||
profileStatusSchema,
|
profileStatusSchema,
|
||||||
readMessageSchema,
|
readMessageSchema,
|
||||||
whatsappNumberSchema,
|
whatsappNumberSchema,
|
||||||
} from '../../validate/validate.schema';
|
} from '../../validate/validate.schema';
|
||||||
import { RouterBroker } from '../abstract/abstract.router';
|
import { RouterBroker } from '../abstract/abstract.router';
|
||||||
import {
|
import {
|
||||||
ArchiveChatDto,
|
ArchiveChatDto,
|
||||||
DeleteMessage,
|
DeleteMessage,
|
||||||
getBase64FromMediaMessageDto,
|
getBase64FromMediaMessageDto,
|
||||||
NumberDto,
|
NumberDto,
|
||||||
PrivacySettingDto,
|
PrivacySettingDto,
|
||||||
ProfileNameDto,
|
ProfileNameDto,
|
||||||
ProfilePictureDto,
|
ProfilePictureDto,
|
||||||
ProfileStatusDto,
|
ProfileStatusDto,
|
||||||
ReadMessageDto,
|
ReadMessageDto,
|
||||||
WhatsAppNumberDto,
|
WhatsAppNumberDto,
|
||||||
} from '../dto/chat.dto';
|
} from '../dto/chat.dto';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { ContactQuery } from '../repository/contact.repository';
|
import { ContactQuery } from '../repository/contact.repository';
|
||||||
@ -38,317 +38,317 @@ import { HttpStatus } from './index.router';
|
|||||||
const logger = new Logger('ChatRouter');
|
const logger = new Logger('ChatRouter');
|
||||||
|
|
||||||
export class ChatRouter extends RouterBroker {
|
export class ChatRouter extends RouterBroker {
|
||||||
constructor(...guards: RequestHandler[]) {
|
constructor(...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
this.router
|
this.router
|
||||||
.post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => {
|
.post(this.routerPath('whatsappNumbers'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in whatsappNumbers');
|
logger.verbose('request received in whatsappNumbers');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<WhatsAppNumberDto>({
|
const response = await this.dataValidate<WhatsAppNumberDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: whatsappNumberSchema,
|
schema: whatsappNumberSchema,
|
||||||
ClassRef: WhatsAppNumberDto,
|
ClassRef: WhatsAppNumberDto,
|
||||||
execute: (instance, data) => chatController.whatsappNumber(instance, data),
|
execute: (instance, data) => chatController.whatsappNumber(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => {
|
.put(this.routerPath('markMessageAsRead'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in markMessageAsRead');
|
logger.verbose('request received in markMessageAsRead');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<ReadMessageDto>({
|
const response = await this.dataValidate<ReadMessageDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: readMessageSchema,
|
schema: readMessageSchema,
|
||||||
ClassRef: ReadMessageDto,
|
ClassRef: ReadMessageDto,
|
||||||
execute: (instance, data) => chatController.readMessage(instance, data),
|
execute: (instance, data) => chatController.readMessage(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('archiveChat'), ...guards, async (req, res) => {
|
.put(this.routerPath('archiveChat'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in archiveChat');
|
logger.verbose('request received in archiveChat');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<ArchiveChatDto>({
|
const response = await this.dataValidate<ArchiveChatDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: archiveChatSchema,
|
schema: archiveChatSchema,
|
||||||
ClassRef: ArchiveChatDto,
|
ClassRef: ArchiveChatDto,
|
||||||
execute: (instance, data) => chatController.archiveChat(instance, data),
|
execute: (instance, data) => chatController.archiveChat(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.delete(this.routerPath('deleteMessageForEveryone'), ...guards, async (req, res) => {
|
.delete(this.routerPath('deleteMessageForEveryone'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in deleteMessageForEveryone');
|
logger.verbose('request received in deleteMessageForEveryone');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<DeleteMessage>({
|
const response = await this.dataValidate<DeleteMessage>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: deleteMessageSchema,
|
schema: deleteMessageSchema,
|
||||||
ClassRef: DeleteMessage,
|
ClassRef: DeleteMessage,
|
||||||
execute: (instance, data) => chatController.deleteMessage(instance, data),
|
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) => {
|
.post(this.routerPath('fetchProfilePictureUrl'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in fetchProfilePictureUrl');
|
logger.verbose('request received in fetchProfilePictureUrl');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<NumberDto>({
|
const response = await this.dataValidate<NumberDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: profilePictureSchema,
|
schema: profilePictureSchema,
|
||||||
ClassRef: NumberDto,
|
ClassRef: NumberDto,
|
||||||
execute: (instance, data) => chatController.fetchProfilePicture(instance, data),
|
execute: (instance, data) => chatController.fetchProfilePicture(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('fetchProfile'), ...guards, async (req, res) => {
|
.post(this.routerPath('fetchProfile'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in fetchProfile');
|
logger.verbose('request received in fetchProfile');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<NumberDto>({
|
const response = await this.dataValidate<NumberDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: profileSchema,
|
schema: profileSchema,
|
||||||
ClassRef: NumberDto,
|
ClassRef: NumberDto,
|
||||||
execute: (instance, data) => chatController.fetchProfile(instance, data),
|
execute: (instance, data) => chatController.fetchProfile(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('findContacts'), ...guards, async (req, res) => {
|
.post(this.routerPath('findContacts'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findContacts');
|
logger.verbose('request received in findContacts');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<ContactQuery>({
|
const response = await this.dataValidate<ContactQuery>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: contactValidateSchema,
|
schema: contactValidateSchema,
|
||||||
ClassRef: ContactQuery,
|
ClassRef: ContactQuery,
|
||||||
execute: (instance, data) => chatController.fetchContacts(instance, data),
|
execute: (instance, data) => chatController.fetchContacts(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('getBase64FromMediaMessage'), ...guards, async (req, res) => {
|
.post(this.routerPath('getBase64FromMediaMessage'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in getBase64FromMediaMessage');
|
logger.verbose('request received in getBase64FromMediaMessage');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<getBase64FromMediaMessageDto>({
|
const response = await this.dataValidate<getBase64FromMediaMessageDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: null,
|
schema: null,
|
||||||
ClassRef: getBase64FromMediaMessageDto,
|
ClassRef: getBase64FromMediaMessageDto,
|
||||||
execute: (instance, data) => chatController.getBase64FromMediaMessage(instance, data),
|
execute: (instance, data) => chatController.getBase64FromMediaMessage(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('findMessages'), ...guards, async (req, res) => {
|
.post(this.routerPath('findMessages'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findMessages');
|
logger.verbose('request received in findMessages');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<MessageQuery>({
|
const response = await this.dataValidate<MessageQuery>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: messageValidateSchema,
|
schema: messageValidateSchema,
|
||||||
ClassRef: MessageQuery,
|
ClassRef: MessageQuery,
|
||||||
execute: (instance, data) => chatController.fetchMessages(instance, data),
|
execute: (instance, data) => chatController.fetchMessages(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('findStatusMessage'), ...guards, async (req, res) => {
|
.post(this.routerPath('findStatusMessage'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findStatusMessage');
|
logger.verbose('request received in findStatusMessage');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<MessageUpQuery>({
|
const response = await this.dataValidate<MessageUpQuery>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: messageUpSchema,
|
schema: messageUpSchema,
|
||||||
ClassRef: MessageUpQuery,
|
ClassRef: MessageUpQuery,
|
||||||
execute: (instance, data) => chatController.fetchStatusMessage(instance, data),
|
execute: (instance, data) => chatController.fetchStatusMessage(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('findChats'), ...guards, async (req, res) => {
|
.get(this.routerPath('findChats'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findChats');
|
logger.verbose('request received in findChats');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: null,
|
schema: null,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => chatController.fetchChats(instance),
|
execute: (instance) => chatController.fetchChats(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
// Profile routes
|
// Profile routes
|
||||||
.get(this.routerPath('fetchPrivacySettings'), ...guards, async (req, res) => {
|
.get(this.routerPath('fetchPrivacySettings'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in fetchPrivacySettings');
|
logger.verbose('request received in fetchPrivacySettings');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: null,
|
schema: null,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => chatController.fetchPrivacySettings(instance),
|
execute: (instance) => chatController.fetchPrivacySettings(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('updatePrivacySettings'), ...guards, async (req, res) => {
|
.put(this.routerPath('updatePrivacySettings'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updatePrivacySettings');
|
logger.verbose('request received in updatePrivacySettings');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<PrivacySettingDto>({
|
const response = await this.dataValidate<PrivacySettingDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: privacySettingsSchema,
|
schema: privacySettingsSchema,
|
||||||
ClassRef: PrivacySettingDto,
|
ClassRef: PrivacySettingDto,
|
||||||
execute: (instance, data) => chatController.updatePrivacySettings(instance, data),
|
execute: (instance, data) => chatController.updatePrivacySettings(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('fetchBusinessProfile'), ...guards, async (req, res) => {
|
.post(this.routerPath('fetchBusinessProfile'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in fetchBusinessProfile');
|
logger.verbose('request received in fetchBusinessProfile');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<ProfilePictureDto>({
|
const response = await this.dataValidate<ProfilePictureDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: profilePictureSchema,
|
schema: profilePictureSchema,
|
||||||
ClassRef: ProfilePictureDto,
|
ClassRef: ProfilePictureDto,
|
||||||
execute: (instance, data) => chatController.fetchBusinessProfile(instance, data),
|
execute: (instance, data) => chatController.fetchBusinessProfile(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('updateProfileName'), ...guards, async (req, res) => {
|
.post(this.routerPath('updateProfileName'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updateProfileName');
|
logger.verbose('request received in updateProfileName');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<ProfileNameDto>({
|
const response = await this.dataValidate<ProfileNameDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: profileNameSchema,
|
schema: profileNameSchema,
|
||||||
ClassRef: ProfileNameDto,
|
ClassRef: ProfileNameDto,
|
||||||
execute: (instance, data) => chatController.updateProfileName(instance, data),
|
execute: (instance, data) => chatController.updateProfileName(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('updateProfileStatus'), ...guards, async (req, res) => {
|
.post(this.routerPath('updateProfileStatus'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updateProfileStatus');
|
logger.verbose('request received in updateProfileStatus');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<ProfileStatusDto>({
|
const response = await this.dataValidate<ProfileStatusDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: profileStatusSchema,
|
schema: profileStatusSchema,
|
||||||
ClassRef: ProfileStatusDto,
|
ClassRef: ProfileStatusDto,
|
||||||
execute: (instance, data) => chatController.updateProfileStatus(instance, data),
|
execute: (instance, data) => chatController.updateProfileStatus(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('updateProfilePicture'), ...guards, async (req, res) => {
|
.put(this.routerPath('updateProfilePicture'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updateProfilePicture');
|
logger.verbose('request received in updateProfilePicture');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<ProfilePictureDto>({
|
const response = await this.dataValidate<ProfilePictureDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: profilePictureSchema,
|
schema: profilePictureSchema,
|
||||||
ClassRef: ProfilePictureDto,
|
ClassRef: ProfilePictureDto,
|
||||||
execute: (instance, data) => chatController.updateProfilePicture(instance, data),
|
execute: (instance, data) => chatController.updateProfilePicture(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.delete(this.routerPath('removeProfilePicture'), ...guards, async (req, res) => {
|
.delete(this.routerPath('removeProfilePicture'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in removeProfilePicture');
|
logger.verbose('request received in removeProfilePicture');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<ProfilePictureDto>({
|
const response = await this.dataValidate<ProfilePictureDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: profilePictureSchema,
|
schema: profilePictureSchema,
|
||||||
ClassRef: ProfilePictureDto,
|
ClassRef: ProfilePictureDto,
|
||||||
execute: (instance) => chatController.removeProfilePicture(instance),
|
execute: (instance) => chatController.removeProfilePicture(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
@ -12,58 +12,58 @@ import { HttpStatus } from './index.router';
|
|||||||
const logger = new Logger('ChatwootRouter');
|
const logger = new Logger('ChatwootRouter');
|
||||||
|
|
||||||
export class ChatwootRouter extends RouterBroker {
|
export class ChatwootRouter extends RouterBroker {
|
||||||
constructor(...guards: RequestHandler[]) {
|
constructor(...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
this.router
|
this.router
|
||||||
.post(this.routerPath('set'), ...guards, async (req, res) => {
|
.post(this.routerPath('set'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in setChatwoot');
|
logger.verbose('request received in setChatwoot');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<ChatwootDto>({
|
const response = await this.dataValidate<ChatwootDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: chatwootSchema,
|
schema: chatwootSchema,
|
||||||
ClassRef: ChatwootDto,
|
ClassRef: ChatwootDto,
|
||||||
execute: (instance, data) => chatwootController.createChatwoot(instance, data),
|
execute: (instance, data) => chatwootController.createChatwoot(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('find'), ...guards, async (req, res) => {
|
.get(this.routerPath('find'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findChatwoot');
|
logger.verbose('request received in findChatwoot');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: instanceNameSchema,
|
schema: instanceNameSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => chatwootController.findChatwoot(instance),
|
execute: (instance) => chatwootController.findChatwoot(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('webhook'), async (req, res) => {
|
.post(this.routerPath('webhook'), async (req, res) => {
|
||||||
logger.verbose('request received in findChatwoot');
|
logger.verbose('request received in findChatwoot');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: instanceNameSchema,
|
schema: instanceNameSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance, data) => chatwootController.receiveWebhook(instance, data),
|
execute: (instance, data) => chatwootController.receiveWebhook(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
@ -2,31 +2,31 @@ import { RequestHandler, Router } from 'express';
|
|||||||
|
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import {
|
import {
|
||||||
createGroupSchema,
|
createGroupSchema,
|
||||||
getParticipantsSchema,
|
getParticipantsSchema,
|
||||||
groupInviteSchema,
|
groupInviteSchema,
|
||||||
groupJidSchema,
|
groupJidSchema,
|
||||||
groupSendInviteSchema,
|
groupSendInviteSchema,
|
||||||
toggleEphemeralSchema,
|
toggleEphemeralSchema,
|
||||||
updateGroupDescriptionSchema,
|
updateGroupDescriptionSchema,
|
||||||
updateGroupPictureSchema,
|
updateGroupPictureSchema,
|
||||||
updateGroupSubjectSchema,
|
updateGroupSubjectSchema,
|
||||||
updateParticipantsSchema,
|
updateParticipantsSchema,
|
||||||
updateSettingsSchema,
|
updateSettingsSchema,
|
||||||
} from '../../validate/validate.schema';
|
} from '../../validate/validate.schema';
|
||||||
import { RouterBroker } from '../abstract/abstract.router';
|
import { RouterBroker } from '../abstract/abstract.router';
|
||||||
import {
|
import {
|
||||||
CreateGroupDto,
|
CreateGroupDto,
|
||||||
GetParticipant,
|
GetParticipant,
|
||||||
GroupDescriptionDto,
|
GroupDescriptionDto,
|
||||||
GroupInvite,
|
GroupInvite,
|
||||||
GroupJid,
|
GroupJid,
|
||||||
GroupPictureDto,
|
GroupPictureDto,
|
||||||
GroupSendInvite,
|
GroupSendInvite,
|
||||||
GroupSubjectDto,
|
GroupSubjectDto,
|
||||||
GroupToggleEphemeralDto,
|
GroupToggleEphemeralDto,
|
||||||
GroupUpdateParticipantDto,
|
GroupUpdateParticipantDto,
|
||||||
GroupUpdateSettingDto,
|
GroupUpdateSettingDto,
|
||||||
} from '../dto/group.dto';
|
} from '../dto/group.dto';
|
||||||
import { groupController } from '../whatsapp.module';
|
import { groupController } from '../whatsapp.module';
|
||||||
import { HttpStatus } from './index.router';
|
import { HttpStatus } from './index.router';
|
||||||
@ -34,251 +34,251 @@ import { HttpStatus } from './index.router';
|
|||||||
const logger = new Logger('GroupRouter');
|
const logger = new Logger('GroupRouter');
|
||||||
|
|
||||||
export class GroupRouter extends RouterBroker {
|
export class GroupRouter extends RouterBroker {
|
||||||
constructor(...guards: RequestHandler[]) {
|
constructor(...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
this.router
|
this.router
|
||||||
.post(this.routerPath('create'), ...guards, async (req, res) => {
|
.post(this.routerPath('create'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in createGroup');
|
logger.verbose('request received in createGroup');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<CreateGroupDto>({
|
const response = await this.dataValidate<CreateGroupDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: createGroupSchema,
|
schema: createGroupSchema,
|
||||||
ClassRef: CreateGroupDto,
|
ClassRef: CreateGroupDto,
|
||||||
execute: (instance, data) => groupController.createGroup(instance, data),
|
execute: (instance, data) => groupController.createGroup(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('updateGroupSubject'), ...guards, async (req, res) => {
|
.put(this.routerPath('updateGroupSubject'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updateGroupSubject');
|
logger.verbose('request received in updateGroupSubject');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.groupValidate<GroupSubjectDto>({
|
const response = await this.groupValidate<GroupSubjectDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: updateGroupSubjectSchema,
|
schema: updateGroupSubjectSchema,
|
||||||
ClassRef: GroupSubjectDto,
|
ClassRef: GroupSubjectDto,
|
||||||
execute: (instance, data) => groupController.updateGroupSubject(instance, data),
|
execute: (instance, data) => groupController.updateGroupSubject(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('updateGroupPicture'), ...guards, async (req, res) => {
|
.put(this.routerPath('updateGroupPicture'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updateGroupPicture');
|
logger.verbose('request received in updateGroupPicture');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupPictureDto>({
|
const response = await this.groupValidate<GroupPictureDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: updateGroupPictureSchema,
|
schema: updateGroupPictureSchema,
|
||||||
ClassRef: GroupPictureDto,
|
ClassRef: GroupPictureDto,
|
||||||
execute: (instance, data) => groupController.updateGroupPicture(instance, data),
|
execute: (instance, data) => groupController.updateGroupPicture(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('updateGroupDescription'), ...guards, async (req, res) => {
|
.put(this.routerPath('updateGroupDescription'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updateGroupDescription');
|
logger.verbose('request received in updateGroupDescription');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupDescriptionDto>({
|
const response = await this.groupValidate<GroupDescriptionDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: updateGroupDescriptionSchema,
|
schema: updateGroupDescriptionSchema,
|
||||||
ClassRef: GroupDescriptionDto,
|
ClassRef: GroupDescriptionDto,
|
||||||
execute: (instance, data) => groupController.updateGroupDescription(instance, data),
|
execute: (instance, data) => groupController.updateGroupDescription(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('findGroupInfos'), ...guards, async (req, res) => {
|
.get(this.routerPath('findGroupInfos'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findGroupInfos');
|
logger.verbose('request received in findGroupInfos');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupJid>({
|
const response = await this.groupValidate<GroupJid>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: groupJidSchema,
|
schema: groupJidSchema,
|
||||||
ClassRef: GroupJid,
|
ClassRef: GroupJid,
|
||||||
execute: (instance, data) => groupController.findGroupInfo(instance, data),
|
execute: (instance, data) => groupController.findGroupInfo(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('fetchAllGroups'), ...guards, async (req, res) => {
|
.get(this.routerPath('fetchAllGroups'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in fetchAllGroups');
|
logger.verbose('request received in fetchAllGroups');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.getParticipantsValidate<GetParticipant>({
|
const response = await this.getParticipantsValidate<GetParticipant>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: getParticipantsSchema,
|
schema: getParticipantsSchema,
|
||||||
ClassRef: GetParticipant,
|
ClassRef: GetParticipant,
|
||||||
execute: (instance, data) => groupController.fetchAllGroups(instance, data),
|
execute: (instance, data) => groupController.fetchAllGroups(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('participants'), ...guards, async (req, res) => {
|
.get(this.routerPath('participants'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in participants');
|
logger.verbose('request received in participants');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupJid>({
|
const response = await this.groupValidate<GroupJid>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: groupJidSchema,
|
schema: groupJidSchema,
|
||||||
ClassRef: GroupJid,
|
ClassRef: GroupJid,
|
||||||
execute: (instance, data) => groupController.findParticipants(instance, data),
|
execute: (instance, data) => groupController.findParticipants(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('inviteCode'), ...guards, async (req, res) => {
|
.get(this.routerPath('inviteCode'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in inviteCode');
|
logger.verbose('request received in inviteCode');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupJid>({
|
const response = await this.groupValidate<GroupJid>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: groupJidSchema,
|
schema: groupJidSchema,
|
||||||
ClassRef: GroupJid,
|
ClassRef: GroupJid,
|
||||||
execute: (instance, data) => groupController.inviteCode(instance, data),
|
execute: (instance, data) => groupController.inviteCode(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('inviteInfo'), ...guards, async (req, res) => {
|
.get(this.routerPath('inviteInfo'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in inviteInfo');
|
logger.verbose('request received in inviteInfo');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.inviteCodeValidate<GroupInvite>({
|
const response = await this.inviteCodeValidate<GroupInvite>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: groupInviteSchema,
|
schema: groupInviteSchema,
|
||||||
ClassRef: GroupInvite,
|
ClassRef: GroupInvite,
|
||||||
execute: (instance, data) => groupController.inviteInfo(instance, data),
|
execute: (instance, data) => groupController.inviteInfo(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendInvite'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendInvite'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendInvite');
|
logger.verbose('request received in sendInvite');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupNoValidate<GroupSendInvite>({
|
const response = await this.groupNoValidate<GroupSendInvite>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: groupSendInviteSchema,
|
schema: groupSendInviteSchema,
|
||||||
ClassRef: GroupSendInvite,
|
ClassRef: GroupSendInvite,
|
||||||
execute: (instance, data) => groupController.sendInvite(instance, data),
|
execute: (instance, data) => groupController.sendInvite(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('revokeInviteCode'), ...guards, async (req, res) => {
|
.put(this.routerPath('revokeInviteCode'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in revokeInviteCode');
|
logger.verbose('request received in revokeInviteCode');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupJid>({
|
const response = await this.groupValidate<GroupJid>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: groupJidSchema,
|
schema: groupJidSchema,
|
||||||
ClassRef: GroupJid,
|
ClassRef: GroupJid,
|
||||||
execute: (instance, data) => groupController.revokeInviteCode(instance, data),
|
execute: (instance, data) => groupController.revokeInviteCode(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('updateParticipant'), ...guards, async (req, res) => {
|
.put(this.routerPath('updateParticipant'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updateParticipant');
|
logger.verbose('request received in updateParticipant');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupUpdateParticipantDto>({
|
const response = await this.groupValidate<GroupUpdateParticipantDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: updateParticipantsSchema,
|
schema: updateParticipantsSchema,
|
||||||
ClassRef: GroupUpdateParticipantDto,
|
ClassRef: GroupUpdateParticipantDto,
|
||||||
execute: (instance, data) => groupController.updateGParticipate(instance, data),
|
execute: (instance, data) => groupController.updateGParticipate(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('updateSetting'), ...guards, async (req, res) => {
|
.put(this.routerPath('updateSetting'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in updateSetting');
|
logger.verbose('request received in updateSetting');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupUpdateSettingDto>({
|
const response = await this.groupValidate<GroupUpdateSettingDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: updateSettingsSchema,
|
schema: updateSettingsSchema,
|
||||||
ClassRef: GroupUpdateSettingDto,
|
ClassRef: GroupUpdateSettingDto,
|
||||||
execute: (instance, data) => groupController.updateGSetting(instance, data),
|
execute: (instance, data) => groupController.updateGSetting(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('toggleEphemeral'), ...guards, async (req, res) => {
|
.put(this.routerPath('toggleEphemeral'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in toggleEphemeral');
|
logger.verbose('request received in toggleEphemeral');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupToggleEphemeralDto>({
|
const response = await this.groupValidate<GroupToggleEphemeralDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: toggleEphemeralSchema,
|
schema: toggleEphemeralSchema,
|
||||||
ClassRef: GroupToggleEphemeralDto,
|
ClassRef: GroupToggleEphemeralDto,
|
||||||
execute: (instance, data) => groupController.toggleEphemeral(instance, data),
|
execute: (instance, data) => groupController.toggleEphemeral(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.delete(this.routerPath('leaveGroup'), ...guards, async (req, res) => {
|
.delete(this.routerPath('leaveGroup'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in leaveGroup');
|
logger.verbose('request received in leaveGroup');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.groupValidate<GroupJid>({
|
const response = await this.groupValidate<GroupJid>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: {},
|
schema: {},
|
||||||
ClassRef: GroupJid,
|
ClassRef: GroupJid,
|
||||||
execute: (instance, data) => groupController.leaveGroup(instance, data),
|
execute: (instance, data) => groupController.leaveGroup(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,13 @@ import { ViewsRouter } from './view.router';
|
|||||||
import { WebhookRouter } from './webhook.router';
|
import { WebhookRouter } from './webhook.router';
|
||||||
|
|
||||||
enum HttpStatus {
|
enum HttpStatus {
|
||||||
OK = 200,
|
OK = 200,
|
||||||
CREATED = 201,
|
CREATED = 201,
|
||||||
NOT_FOUND = 404,
|
NOT_FOUND = 404,
|
||||||
FORBIDDEN = 403,
|
FORBIDDEN = 403,
|
||||||
BAD_REQUEST = 400,
|
BAD_REQUEST = 400,
|
||||||
UNAUTHORIZED = 401,
|
UNAUTHORIZED = 401,
|
||||||
INTERNAL_SERVER_ERROR = 500,
|
INTERNAL_SERVER_ERROR = 500,
|
||||||
}
|
}
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
@ -30,19 +30,19 @@ const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard[authType]];
|
|||||||
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
|
||||||
|
|
||||||
router
|
router
|
||||||
.get('/', (req, res) => {
|
.get('/', (req, res) => {
|
||||||
res.status(HttpStatus.OK).json({
|
res.status(HttpStatus.OK).json({
|
||||||
status: HttpStatus.OK,
|
status: HttpStatus.OK,
|
||||||
message: 'Welcome to the Evolution API, it is working!',
|
message: 'Welcome to the Evolution API, it is working!',
|
||||||
version: packageJson.version,
|
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('/message', new MessageRouter(...guards).router)
|
||||||
.use('/chat', new ChatRouter(...guards).router)
|
.use('/chat', new ChatRouter(...guards).router)
|
||||||
.use('/group', new GroupRouter(...guards).router)
|
.use('/group', new GroupRouter(...guards).router)
|
||||||
.use('/webhook', new WebhookRouter(...guards).router)
|
.use('/webhook', new WebhookRouter(...guards).router)
|
||||||
.use('/chatwoot', new ChatwootRouter(...guards).router)
|
.use('/chatwoot', new ChatwootRouter(...guards).router)
|
||||||
.use('/settings', new SettingsRouter(...guards).router);
|
.use('/settings', new SettingsRouter(...guards).router);
|
||||||
|
|
||||||
export { HttpStatus, router };
|
export { HttpStatus, router };
|
||||||
|
@ -13,165 +13,163 @@ import { HttpStatus } from './index.router';
|
|||||||
const logger = new Logger('InstanceRouter');
|
const logger = new Logger('InstanceRouter');
|
||||||
|
|
||||||
export class InstanceRouter extends RouterBroker {
|
export class InstanceRouter extends RouterBroker {
|
||||||
constructor(readonly configService: ConfigService, ...guards: RequestHandler[]) {
|
constructor(readonly configService: ConfigService, ...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
const auth = configService.get<Auth>('AUTHENTICATION');
|
const auth = configService.get<Auth>('AUTHENTICATION');
|
||||||
this.router
|
this.router
|
||||||
.post('/create', ...guards, async (req, res) => {
|
.post('/create', ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in createInstance');
|
logger.verbose('request received in createInstance');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: instanceNameSchema,
|
schema: instanceNameSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => instanceController.createInstance(instance),
|
execute: (instance) => instanceController.createInstance(instance),
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
|
||||||
})
|
|
||||||
.put(this.routerPath('restart'), ...guards, async (req, res) => {
|
|
||||||
logger.verbose('request received in restartInstance');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
|
||||||
request: req,
|
|
||||||
schema: instanceNameSchema,
|
|
||||||
ClassRef: InstanceDto,
|
|
||||||
execute: (instance) => instanceController.restartInstance(instance),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
|
||||||
})
|
|
||||||
.get(this.routerPath('connect'), ...guards, async (req, res) => {
|
|
||||||
logger.verbose('request received in connectInstance');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
|
||||||
request: req,
|
|
||||||
schema: instanceNameSchema,
|
|
||||||
ClassRef: InstanceDto,
|
|
||||||
execute: (instance) => instanceController.connectToWhatsapp(instance),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
|
||||||
})
|
|
||||||
.get(this.routerPath('connectionState'), ...guards, async (req, res) => {
|
|
||||||
logger.verbose('request received in connectionState');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
|
||||||
request: req,
|
|
||||||
schema: instanceNameSchema,
|
|
||||||
ClassRef: InstanceDto,
|
|
||||||
execute: (instance) => instanceController.connectionState(instance),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
|
||||||
})
|
|
||||||
.get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => {
|
|
||||||
logger.verbose('request received in fetchInstances');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
|
||||||
request: req,
|
|
||||||
schema: null,
|
|
||||||
ClassRef: InstanceDto,
|
|
||||||
execute: (instance) => instanceController.fetchInstances(instance),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
|
||||||
})
|
|
||||||
.delete(this.routerPath('logout'), ...guards, async (req, res) => {
|
|
||||||
logger.verbose('request received in logoutInstances');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
|
||||||
request: req,
|
|
||||||
schema: instanceNameSchema,
|
|
||||||
ClassRef: InstanceDto,
|
|
||||||
execute: (instance) => instanceController.logout(instance),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
|
||||||
})
|
|
||||||
.delete(this.routerPath('delete'), ...guards, async (req, res) => {
|
|
||||||
logger.verbose('request received in deleteInstances');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
|
||||||
request: req,
|
|
||||||
schema: instanceNameSchema,
|
|
||||||
ClassRef: InstanceDto,
|
|
||||||
execute: (instance) => instanceController.deleteInstance(instance),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (auth.TYPE === 'jwt') {
|
|
||||||
this.router.put('/refreshToken', async (req, res) => {
|
|
||||||
logger.verbose('request received in refreshToken');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const response = await this.dataValidate<OldToken>({
|
|
||||||
request: req,
|
|
||||||
schema: oldTokenSchema,
|
|
||||||
ClassRef: OldToken,
|
|
||||||
execute: (_, data) => instanceController.refreshToken(_, data),
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.router.delete('/deleteDatabase', async (req, res) => {
|
|
||||||
logger.verbose('request received in deleteDatabase');
|
|
||||||
logger.verbose('request body: ');
|
|
||||||
logger.verbose(req.body);
|
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
|
||||||
logger.verbose(req.query);
|
|
||||||
const db = this.configService.get<Database>('DATABASE');
|
|
||||||
if (db.ENABLED) {
|
|
||||||
try {
|
|
||||||
await dbserver.dropDatabase();
|
|
||||||
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: 'Database is not enabled' });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
|
})
|
||||||
|
.put(this.routerPath('restart'), ...guards, async (req, res) => {
|
||||||
|
logger.verbose('request received in restartInstance');
|
||||||
|
logger.verbose('request body: ');
|
||||||
|
logger.verbose(req.body);
|
||||||
|
|
||||||
|
logger.verbose('request query: ');
|
||||||
|
logger.verbose(req.query);
|
||||||
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
|
request: req,
|
||||||
|
schema: instanceNameSchema,
|
||||||
|
ClassRef: InstanceDto,
|
||||||
|
execute: (instance) => instanceController.restartInstance(instance),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(HttpStatus.OK).json(response);
|
||||||
|
})
|
||||||
|
.get(this.routerPath('connect'), ...guards, async (req, res) => {
|
||||||
|
logger.verbose('request received in connectInstance');
|
||||||
|
logger.verbose('request body: ');
|
||||||
|
logger.verbose(req.body);
|
||||||
|
|
||||||
|
logger.verbose('request query: ');
|
||||||
|
logger.verbose(req.query);
|
||||||
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
|
request: req,
|
||||||
|
schema: instanceNameSchema,
|
||||||
|
ClassRef: InstanceDto,
|
||||||
|
execute: (instance) => instanceController.connectToWhatsapp(instance),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(HttpStatus.OK).json(response);
|
||||||
|
})
|
||||||
|
.get(this.routerPath('connectionState'), ...guards, async (req, res) => {
|
||||||
|
logger.verbose('request received in connectionState');
|
||||||
|
logger.verbose('request body: ');
|
||||||
|
logger.verbose(req.body);
|
||||||
|
|
||||||
|
logger.verbose('request query: ');
|
||||||
|
logger.verbose(req.query);
|
||||||
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
|
request: req,
|
||||||
|
schema: instanceNameSchema,
|
||||||
|
ClassRef: InstanceDto,
|
||||||
|
execute: (instance) => instanceController.connectionState(instance),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(HttpStatus.OK).json(response);
|
||||||
|
})
|
||||||
|
.get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => {
|
||||||
|
logger.verbose('request received in fetchInstances');
|
||||||
|
logger.verbose('request body: ');
|
||||||
|
logger.verbose(req.body);
|
||||||
|
|
||||||
|
logger.verbose('request query: ');
|
||||||
|
logger.verbose(req.query);
|
||||||
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
|
request: req,
|
||||||
|
schema: null,
|
||||||
|
ClassRef: InstanceDto,
|
||||||
|
execute: (instance) => instanceController.fetchInstances(instance),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(HttpStatus.OK).json(response);
|
||||||
|
})
|
||||||
|
.delete(this.routerPath('logout'), ...guards, async (req, res) => {
|
||||||
|
logger.verbose('request received in logoutInstances');
|
||||||
|
logger.verbose('request body: ');
|
||||||
|
logger.verbose(req.body);
|
||||||
|
|
||||||
|
logger.verbose('request query: ');
|
||||||
|
logger.verbose(req.query);
|
||||||
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
|
request: req,
|
||||||
|
schema: instanceNameSchema,
|
||||||
|
ClassRef: InstanceDto,
|
||||||
|
execute: (instance) => instanceController.logout(instance),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(HttpStatus.OK).json(response);
|
||||||
|
})
|
||||||
|
.delete(this.routerPath('delete'), ...guards, async (req, res) => {
|
||||||
|
logger.verbose('request received in deleteInstances');
|
||||||
|
logger.verbose('request body: ');
|
||||||
|
logger.verbose(req.body);
|
||||||
|
|
||||||
|
logger.verbose('request query: ');
|
||||||
|
logger.verbose(req.query);
|
||||||
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
|
request: req,
|
||||||
|
schema: instanceNameSchema,
|
||||||
|
ClassRef: InstanceDto,
|
||||||
|
execute: (instance) => instanceController.deleteInstance(instance),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(HttpStatus.OK).json(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (auth.TYPE === 'jwt') {
|
||||||
|
this.router.put('/refreshToken', async (req, res) => {
|
||||||
|
logger.verbose('request received in refreshToken');
|
||||||
|
logger.verbose('request body: ');
|
||||||
|
logger.verbose(req.body);
|
||||||
|
|
||||||
|
logger.verbose('request query: ');
|
||||||
|
logger.verbose(req.query);
|
||||||
|
const response = await this.dataValidate<OldToken>({
|
||||||
|
request: req,
|
||||||
|
schema: oldTokenSchema,
|
||||||
|
ClassRef: OldToken,
|
||||||
|
execute: (_, data) => instanceController.refreshToken(_, data),
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
this.router.delete('/deleteDatabase', async (req, res) => {
|
||||||
|
logger.verbose('request received in deleteDatabase');
|
||||||
|
logger.verbose('request body: ');
|
||||||
|
logger.verbose(req.body);
|
||||||
|
|
||||||
|
logger.verbose('request query: ');
|
||||||
|
logger.verbose(req.query);
|
||||||
|
const db = this.configService.get<Database>('DATABASE');
|
||||||
|
if (db.ENABLED) {
|
||||||
|
try {
|
||||||
|
await dbserver.dropDatabase();
|
||||||
|
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: 'Database is not enabled' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
@ -2,31 +2,31 @@ import { RequestHandler, Router } from 'express';
|
|||||||
|
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import {
|
import {
|
||||||
audioMessageSchema,
|
audioMessageSchema,
|
||||||
buttonMessageSchema,
|
buttonMessageSchema,
|
||||||
contactMessageSchema,
|
contactMessageSchema,
|
||||||
listMessageSchema,
|
listMessageSchema,
|
||||||
locationMessageSchema,
|
locationMessageSchema,
|
||||||
mediaMessageSchema,
|
mediaMessageSchema,
|
||||||
pollMessageSchema,
|
pollMessageSchema,
|
||||||
reactionMessageSchema,
|
reactionMessageSchema,
|
||||||
statusMessageSchema,
|
statusMessageSchema,
|
||||||
stickerMessageSchema,
|
stickerMessageSchema,
|
||||||
textMessageSchema,
|
textMessageSchema,
|
||||||
} from '../../validate/validate.schema';
|
} from '../../validate/validate.schema';
|
||||||
import { RouterBroker } from '../abstract/abstract.router';
|
import { RouterBroker } from '../abstract/abstract.router';
|
||||||
import {
|
import {
|
||||||
SendAudioDto,
|
SendAudioDto,
|
||||||
SendButtonDto,
|
SendButtonDto,
|
||||||
SendContactDto,
|
SendContactDto,
|
||||||
SendListDto,
|
SendListDto,
|
||||||
SendLocationDto,
|
SendLocationDto,
|
||||||
SendMediaDto,
|
SendMediaDto,
|
||||||
SendPollDto,
|
SendPollDto,
|
||||||
SendReactionDto,
|
SendReactionDto,
|
||||||
SendStatusDto,
|
SendStatusDto,
|
||||||
SendStickerDto,
|
SendStickerDto,
|
||||||
SendTextDto,
|
SendTextDto,
|
||||||
} from '../dto/sendMessage.dto';
|
} from '../dto/sendMessage.dto';
|
||||||
import { sendMessageController } from '../whatsapp.module';
|
import { sendMessageController } from '../whatsapp.module';
|
||||||
import { HttpStatus } from './index.router';
|
import { HttpStatus } from './index.router';
|
||||||
@ -34,186 +34,186 @@ import { HttpStatus } from './index.router';
|
|||||||
const logger = new Logger('MessageRouter');
|
const logger = new Logger('MessageRouter');
|
||||||
|
|
||||||
export class MessageRouter extends RouterBroker {
|
export class MessageRouter extends RouterBroker {
|
||||||
constructor(...guards: RequestHandler[]) {
|
constructor(...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
this.router
|
this.router
|
||||||
.post(this.routerPath('sendText'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendText'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendText');
|
logger.verbose('request received in sendText');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendTextDto>({
|
const response = await this.dataValidate<SendTextDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: textMessageSchema,
|
schema: textMessageSchema,
|
||||||
ClassRef: SendTextDto,
|
ClassRef: SendTextDto,
|
||||||
execute: (instance, data) => sendMessageController.sendText(instance, data),
|
execute: (instance, data) => sendMessageController.sendText(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendMedia'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendMedia'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendMedia');
|
logger.verbose('request received in sendMedia');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendMediaDto>({
|
const response = await this.dataValidate<SendMediaDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: mediaMessageSchema,
|
schema: mediaMessageSchema,
|
||||||
ClassRef: SendMediaDto,
|
ClassRef: SendMediaDto,
|
||||||
execute: (instance, data) => sendMessageController.sendMedia(instance, data),
|
execute: (instance, data) => sendMessageController.sendMedia(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendWhatsAppAudio'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendWhatsAppAudio'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendWhatsAppAudio');
|
logger.verbose('request received in sendWhatsAppAudio');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendAudioDto>({
|
const response = await this.dataValidate<SendAudioDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: audioMessageSchema,
|
schema: audioMessageSchema,
|
||||||
ClassRef: SendMediaDto,
|
ClassRef: SendMediaDto,
|
||||||
execute: (instance, data) => sendMessageController.sendWhatsAppAudio(instance, data),
|
execute: (instance, data) => sendMessageController.sendWhatsAppAudio(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendButtons'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendButtons'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendButtons');
|
logger.verbose('request received in sendButtons');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendButtonDto>({
|
const response = await this.dataValidate<SendButtonDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: buttonMessageSchema,
|
schema: buttonMessageSchema,
|
||||||
ClassRef: SendButtonDto,
|
ClassRef: SendButtonDto,
|
||||||
execute: (instance, data) => sendMessageController.sendButtons(instance, data),
|
execute: (instance, data) => sendMessageController.sendButtons(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendLocation'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendLocation'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendLocation');
|
logger.verbose('request received in sendLocation');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendLocationDto>({
|
const response = await this.dataValidate<SendLocationDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: locationMessageSchema,
|
schema: locationMessageSchema,
|
||||||
ClassRef: SendLocationDto,
|
ClassRef: SendLocationDto,
|
||||||
execute: (instance, data) => sendMessageController.sendLocation(instance, data),
|
execute: (instance, data) => sendMessageController.sendLocation(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendList'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendList'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendList');
|
logger.verbose('request received in sendList');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendListDto>({
|
const response = await this.dataValidate<SendListDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: listMessageSchema,
|
schema: listMessageSchema,
|
||||||
ClassRef: SendListDto,
|
ClassRef: SendListDto,
|
||||||
execute: (instance, data) => sendMessageController.sendList(instance, data),
|
execute: (instance, data) => sendMessageController.sendList(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendContact'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendContact'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendContact');
|
logger.verbose('request received in sendContact');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendContactDto>({
|
const response = await this.dataValidate<SendContactDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: contactMessageSchema,
|
schema: contactMessageSchema,
|
||||||
ClassRef: SendContactDto,
|
ClassRef: SendContactDto,
|
||||||
execute: (instance, data) => sendMessageController.sendContact(instance, data),
|
execute: (instance, data) => sendMessageController.sendContact(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendReaction'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendReaction'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendReaction');
|
logger.verbose('request received in sendReaction');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendReactionDto>({
|
const response = await this.dataValidate<SendReactionDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: reactionMessageSchema,
|
schema: reactionMessageSchema,
|
||||||
ClassRef: SendReactionDto,
|
ClassRef: SendReactionDto,
|
||||||
execute: (instance, data) => sendMessageController.sendReaction(instance, data),
|
execute: (instance, data) => sendMessageController.sendReaction(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendPoll'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendPoll'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendPoll');
|
logger.verbose('request received in sendPoll');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendPollDto>({
|
const response = await this.dataValidate<SendPollDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: pollMessageSchema,
|
schema: pollMessageSchema,
|
||||||
ClassRef: SendPollDto,
|
ClassRef: SendPollDto,
|
||||||
execute: (instance, data) => sendMessageController.sendPoll(instance, data),
|
execute: (instance, data) => sendMessageController.sendPoll(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendStatus'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendStatus'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendStatus');
|
logger.verbose('request received in sendStatus');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendStatusDto>({
|
const response = await this.dataValidate<SendStatusDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: statusMessageSchema,
|
schema: statusMessageSchema,
|
||||||
ClassRef: SendStatusDto,
|
ClassRef: SendStatusDto,
|
||||||
execute: (instance, data) => sendMessageController.sendStatus(instance, data),
|
execute: (instance, data) => sendMessageController.sendStatus(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('sendSticker'), ...guards, async (req, res) => {
|
.post(this.routerPath('sendSticker'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in sendSticker');
|
logger.verbose('request received in sendSticker');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SendStickerDto>({
|
const response = await this.dataValidate<SendStickerDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: stickerMessageSchema,
|
schema: stickerMessageSchema,
|
||||||
ClassRef: SendStickerDto,
|
ClassRef: SendStickerDto,
|
||||||
execute: (instance, data) => sendMessageController.sendSticker(instance, data),
|
execute: (instance, data) => sendMessageController.sendSticker(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
@ -12,42 +12,42 @@ import { HttpStatus } from './index.router';
|
|||||||
const logger = new Logger('SettingsRouter');
|
const logger = new Logger('SettingsRouter');
|
||||||
|
|
||||||
export class SettingsRouter extends RouterBroker {
|
export class SettingsRouter extends RouterBroker {
|
||||||
constructor(...guards: RequestHandler[]) {
|
constructor(...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
this.router
|
this.router
|
||||||
.post(this.routerPath('set'), ...guards, async (req, res) => {
|
.post(this.routerPath('set'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in setSettings');
|
logger.verbose('request received in setSettings');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<SettingsDto>({
|
const response = await this.dataValidate<SettingsDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: settingsSchema,
|
schema: settingsSchema,
|
||||||
ClassRef: SettingsDto,
|
ClassRef: SettingsDto,
|
||||||
execute: (instance, data) => settingsController.createSettings(instance, data),
|
execute: (instance, data) => settingsController.createSettings(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('find'), ...guards, async (req, res) => {
|
.get(this.routerPath('find'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findSettings');
|
logger.verbose('request received in findSettings');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: instanceNameSchema,
|
schema: instanceNameSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => settingsController.findSettings(instance),
|
execute: (instance) => settingsController.findSettings(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ import { RouterBroker } from '../abstract/abstract.router';
|
|||||||
import { viewsController } from '../whatsapp.module';
|
import { viewsController } from '../whatsapp.module';
|
||||||
|
|
||||||
export class ViewsRouter extends RouterBroker {
|
export class ViewsRouter extends RouterBroker {
|
||||||
constructor(...guards: RequestHandler[]) {
|
constructor(...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.router.get(this.routerPath('qrcode'), ...guards, (req, res) => {
|
this.router.get(this.routerPath('qrcode'), ...guards, (req, res) => {
|
||||||
return viewsController.qrcode(req, res);
|
return viewsController.qrcode(req, res);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
@ -11,42 +11,42 @@ import { HttpStatus } from './index.router';
|
|||||||
const logger = new Logger('WebhookRouter');
|
const logger = new Logger('WebhookRouter');
|
||||||
|
|
||||||
export class WebhookRouter extends RouterBroker {
|
export class WebhookRouter extends RouterBroker {
|
||||||
constructor(...guards: RequestHandler[]) {
|
constructor(...guards: RequestHandler[]) {
|
||||||
super();
|
super();
|
||||||
this.router
|
this.router
|
||||||
.post(this.routerPath('set'), ...guards, async (req, res) => {
|
.post(this.routerPath('set'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in setWebhook');
|
logger.verbose('request received in setWebhook');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<WebhookDto>({
|
const response = await this.dataValidate<WebhookDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: webhookSchema,
|
schema: webhookSchema,
|
||||||
ClassRef: WebhookDto,
|
ClassRef: WebhookDto,
|
||||||
execute: (instance, data) => webhookController.createWebhook(instance, data),
|
execute: (instance, data) => webhookController.createWebhook(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('find'), ...guards, async (req, res) => {
|
.get(this.routerPath('find'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findWebhook');
|
logger.verbose('request received in findWebhook');
|
||||||
logger.verbose('request body: ');
|
logger.verbose('request body: ');
|
||||||
logger.verbose(req.body);
|
logger.verbose(req.body);
|
||||||
|
|
||||||
logger.verbose('request query: ');
|
logger.verbose('request query: ');
|
||||||
logger.verbose(req.query);
|
logger.verbose(req.query);
|
||||||
const response = await this.dataValidate<InstanceDto>({
|
const response = await this.dataValidate<InstanceDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: instanceNameSchema,
|
schema: instanceNameSchema,
|
||||||
ClassRef: InstanceDto,
|
ClassRef: InstanceDto,
|
||||||
execute: (instance) => webhookController.findWebhook(instance),
|
execute: (instance) => webhookController.findWebhook(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
@ -12,166 +12,166 @@ import { RepositoryBroker } from '../repository/repository.manager';
|
|||||||
import { WAMonitoringService } from './monitor.service';
|
import { WAMonitoringService } from './monitor.service';
|
||||||
|
|
||||||
export type JwtPayload = {
|
export type JwtPayload = {
|
||||||
instanceName: string;
|
instanceName: string;
|
||||||
apiName: string;
|
apiName: string;
|
||||||
jwt?: string;
|
jwt?: string;
|
||||||
apikey?: string;
|
apikey?: string;
|
||||||
tokenId: string;
|
tokenId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class OldToken {
|
export class OldToken {
|
||||||
oldToken: string;
|
oldToken: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly waMonitor: WAMonitoringService,
|
private readonly waMonitor: WAMonitoringService,
|
||||||
private readonly repository: RepositoryBroker,
|
private readonly repository: RepositoryBroker,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private readonly logger = new Logger(AuthService.name);
|
private readonly logger = new Logger(AuthService.name);
|
||||||
|
|
||||||
private async jwt(instance: InstanceDto) {
|
private async jwt(instance: InstanceDto) {
|
||||||
const jwtOpts = this.configService.get<Auth>('AUTHENTICATION').JWT;
|
const jwtOpts = this.configService.get<Auth>('AUTHENTICATION').JWT;
|
||||||
const token = sign(
|
const token = sign(
|
||||||
|
{
|
||||||
|
instanceName: instance.instanceName,
|
||||||
|
apiName,
|
||||||
|
tokenId: v4(),
|
||||||
|
},
|
||||||
|
jwtOpts.SECRET,
|
||||||
|
{ expiresIn: jwtOpts.EXPIRIN_IN, encoding: 'utf8', subject: 'g-t' },
|
||||||
|
);
|
||||||
|
|
||||||
|
this.logger.verbose('JWT token created: ' + token);
|
||||||
|
|
||||||
|
const auth = await this.repository.auth.create({ jwt: token }, instance.instanceName);
|
||||||
|
|
||||||
|
this.logger.verbose('JWT token saved in database');
|
||||||
|
|
||||||
|
if (auth['error']) {
|
||||||
|
this.logger.error({
|
||||||
|
localError: AuthService.name + '.jwt',
|
||||||
|
error: auth['error'],
|
||||||
|
});
|
||||||
|
throw new BadRequestException('Authentication error', auth['error']?.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return { jwt: token };
|
||||||
|
}
|
||||||
|
|
||||||
|
private async apikey(instance: InstanceDto, token?: string) {
|
||||||
|
const apikey = token ? token : v4().toUpperCase();
|
||||||
|
|
||||||
|
this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey);
|
||||||
|
|
||||||
|
const auth = await this.repository.auth.create({ apikey }, instance.instanceName);
|
||||||
|
|
||||||
|
this.logger.verbose('APIKEY saved in database');
|
||||||
|
|
||||||
|
if (auth['error']) {
|
||||||
|
this.logger.error({
|
||||||
|
localError: AuthService.name + '.apikey',
|
||||||
|
error: auth['error'],
|
||||||
|
});
|
||||||
|
throw new BadRequestException('Authentication error', auth['error']?.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return { apikey };
|
||||||
|
}
|
||||||
|
|
||||||
|
public async checkDuplicateToken(token: string) {
|
||||||
|
const instances = await this.waMonitor.instanceInfo();
|
||||||
|
|
||||||
|
this.logger.verbose('checking duplicate token');
|
||||||
|
|
||||||
|
const instance = instances.find((instance) => instance.instance.apikey === token);
|
||||||
|
|
||||||
|
if (instance) {
|
||||||
|
throw new BadRequestException('Token already exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('available token');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async generateHash(instance: InstanceDto, token?: string) {
|
||||||
|
const options = this.configService.get<Auth>('AUTHENTICATION');
|
||||||
|
|
||||||
|
this.logger.verbose('generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName);
|
||||||
|
|
||||||
|
return (await this[options.TYPE](instance, token)) as { jwt: string } | { apikey: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
public async refreshToken({ oldToken }: OldToken) {
|
||||||
|
this.logger.verbose('refreshing token');
|
||||||
|
|
||||||
|
if (!isJWT(oldToken)) {
|
||||||
|
throw new BadRequestException('Invalid "oldToken"');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const jwtOpts = this.configService.get<Auth>('AUTHENTICATION').JWT;
|
||||||
|
|
||||||
|
this.logger.verbose('checking oldToken');
|
||||||
|
|
||||||
|
const decode = verify(oldToken, jwtOpts.SECRET, {
|
||||||
|
ignoreExpiration: true,
|
||||||
|
}) as Pick<JwtPayload, 'apiName' | 'instanceName' | 'tokenId'>;
|
||||||
|
|
||||||
|
this.logger.verbose('checking token in database');
|
||||||
|
|
||||||
|
const tokenStore = await this.repository.auth.find(decode.instanceName);
|
||||||
|
|
||||||
|
const decodeTokenStore = verify(tokenStore.jwt, jwtOpts.SECRET, {
|
||||||
|
ignoreExpiration: true,
|
||||||
|
}) as Pick<JwtPayload, 'apiName' | 'instanceName' | 'tokenId'>;
|
||||||
|
|
||||||
|
this.logger.verbose('checking tokenId');
|
||||||
|
|
||||||
|
if (decode.tokenId !== decodeTokenStore.tokenId) {
|
||||||
|
throw new BadRequestException('Invalid "oldToken"');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('generating new token');
|
||||||
|
|
||||||
|
const token = {
|
||||||
|
jwt: (await this.jwt({ instanceName: decode.instanceName })).jwt,
|
||||||
|
instanceName: decode.instanceName,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.logger.verbose('checking webhook');
|
||||||
|
const webhook = await this.repository.webhook.find(decode.instanceName);
|
||||||
|
if (webhook?.enabled && this.configService.get<Webhook>('WEBHOOK').EVENTS.NEW_JWT_TOKEN) {
|
||||||
|
this.logger.verbose('sending webhook');
|
||||||
|
|
||||||
|
const httpService = axios.create({ baseURL: webhook.url });
|
||||||
|
await httpService.post(
|
||||||
|
'',
|
||||||
{
|
{
|
||||||
instanceName: instance.instanceName,
|
event: 'new.jwt',
|
||||||
apiName,
|
instance: decode.instanceName,
|
||||||
tokenId: v4(),
|
data: token,
|
||||||
},
|
},
|
||||||
jwtOpts.SECRET,
|
{ params: { owner: this.waMonitor.waInstances[decode.instanceName].wuid } },
|
||||||
{ expiresIn: jwtOpts.EXPIRIN_IN, encoding: 'utf8', subject: 'g-t' },
|
);
|
||||||
);
|
|
||||||
|
|
||||||
this.logger.verbose('JWT token created: ' + token);
|
|
||||||
|
|
||||||
const auth = await this.repository.auth.create({ jwt: token }, instance.instanceName);
|
|
||||||
|
|
||||||
this.logger.verbose('JWT token saved in database');
|
|
||||||
|
|
||||||
if (auth['error']) {
|
|
||||||
this.logger.error({
|
|
||||||
localError: AuthService.name + '.jwt',
|
|
||||||
error: auth['error'],
|
|
||||||
});
|
|
||||||
throw new BadRequestException('Authentication error', auth['error']?.toString());
|
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
return { jwt: token };
|
this.logger.verbose('token refreshed');
|
||||||
}
|
|
||||||
|
return token;
|
||||||
private async apikey(instance: InstanceDto, token?: string) {
|
} catch (error) {
|
||||||
const apikey = token ? token : v4().toUpperCase();
|
this.logger.error({
|
||||||
|
localError: AuthService.name + '.refreshToken',
|
||||||
this.logger.verbose(token ? 'APIKEY defined: ' + apikey : 'APIKEY created: ' + apikey);
|
error,
|
||||||
|
});
|
||||||
const auth = await this.repository.auth.create({ apikey }, instance.instanceName);
|
throw new BadRequestException('Invalid "oldToken"');
|
||||||
|
|
||||||
this.logger.verbose('APIKEY saved in database');
|
|
||||||
|
|
||||||
if (auth['error']) {
|
|
||||||
this.logger.error({
|
|
||||||
localError: AuthService.name + '.apikey',
|
|
||||||
error: auth['error'],
|
|
||||||
});
|
|
||||||
throw new BadRequestException('Authentication error', auth['error']?.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return { apikey };
|
|
||||||
}
|
|
||||||
|
|
||||||
public async checkDuplicateToken(token: string) {
|
|
||||||
const instances = await this.waMonitor.instanceInfo();
|
|
||||||
|
|
||||||
this.logger.verbose('checking duplicate token');
|
|
||||||
|
|
||||||
const instance = instances.find((instance) => instance.instance.apikey === token);
|
|
||||||
|
|
||||||
if (instance) {
|
|
||||||
throw new BadRequestException('Token already exists');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('available token');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async generateHash(instance: InstanceDto, token?: string) {
|
|
||||||
const options = this.configService.get<Auth>('AUTHENTICATION');
|
|
||||||
|
|
||||||
this.logger.verbose('generating hash ' + options.TYPE + ' to instance: ' + instance.instanceName);
|
|
||||||
|
|
||||||
return (await this[options.TYPE](instance, token)) as { jwt: string } | { apikey: string };
|
|
||||||
}
|
|
||||||
|
|
||||||
public async refreshToken({ oldToken }: OldToken) {
|
|
||||||
this.logger.verbose('refreshing token');
|
|
||||||
|
|
||||||
if (!isJWT(oldToken)) {
|
|
||||||
throw new BadRequestException('Invalid "oldToken"');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const jwtOpts = this.configService.get<Auth>('AUTHENTICATION').JWT;
|
|
||||||
|
|
||||||
this.logger.verbose('checking oldToken');
|
|
||||||
|
|
||||||
const decode = verify(oldToken, jwtOpts.SECRET, {
|
|
||||||
ignoreExpiration: true,
|
|
||||||
}) as Pick<JwtPayload, 'apiName' | 'instanceName' | 'tokenId'>;
|
|
||||||
|
|
||||||
this.logger.verbose('checking token in database');
|
|
||||||
|
|
||||||
const tokenStore = await this.repository.auth.find(decode.instanceName);
|
|
||||||
|
|
||||||
const decodeTokenStore = verify(tokenStore.jwt, jwtOpts.SECRET, {
|
|
||||||
ignoreExpiration: true,
|
|
||||||
}) as Pick<JwtPayload, 'apiName' | 'instanceName' | 'tokenId'>;
|
|
||||||
|
|
||||||
this.logger.verbose('checking tokenId');
|
|
||||||
|
|
||||||
if (decode.tokenId !== decodeTokenStore.tokenId) {
|
|
||||||
throw new BadRequestException('Invalid "oldToken"');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('generating new token');
|
|
||||||
|
|
||||||
const token = {
|
|
||||||
jwt: (await this.jwt({ instanceName: decode.instanceName })).jwt,
|
|
||||||
instanceName: decode.instanceName,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.logger.verbose('checking webhook');
|
|
||||||
const webhook = await this.repository.webhook.find(decode.instanceName);
|
|
||||||
if (webhook?.enabled && this.configService.get<Webhook>('WEBHOOK').EVENTS.NEW_JWT_TOKEN) {
|
|
||||||
this.logger.verbose('sending webhook');
|
|
||||||
|
|
||||||
const httpService = axios.create({ baseURL: webhook.url });
|
|
||||||
await httpService.post(
|
|
||||||
'',
|
|
||||||
{
|
|
||||||
event: 'new.jwt',
|
|
||||||
instance: decode.instanceName,
|
|
||||||
data: token,
|
|
||||||
},
|
|
||||||
{ params: { owner: this.waMonitor.waInstances[decode.instanceName].wuid } },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('token refreshed');
|
|
||||||
|
|
||||||
return token;
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error({
|
|
||||||
localError: AuthService.name + '.refreshToken',
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
throw new BadRequestException('Invalid "oldToken"');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -11,344 +11,344 @@ import { dbserver } from '../../db/db.connect';
|
|||||||
import { RedisCache } from '../../db/redis.client';
|
import { RedisCache } from '../../db/redis.client';
|
||||||
import { NotFoundException } from '../../exceptions';
|
import { NotFoundException } from '../../exceptions';
|
||||||
import {
|
import {
|
||||||
AuthModel,
|
AuthModel,
|
||||||
ChatwootModel,
|
ChatwootModel,
|
||||||
ContactModel,
|
ContactModel,
|
||||||
MessageModel,
|
MessageModel,
|
||||||
MessageUpModel,
|
MessageUpModel,
|
||||||
SettingsModel,
|
SettingsModel,
|
||||||
WebhookModel,
|
WebhookModel,
|
||||||
} from '../models';
|
} from '../models';
|
||||||
import { RepositoryBroker } from '../repository/repository.manager';
|
import { RepositoryBroker } from '../repository/repository.manager';
|
||||||
import { WAStartupService } from './whatsapp.service';
|
import { WAStartupService } from './whatsapp.service';
|
||||||
|
|
||||||
export class WAMonitoringService {
|
export class WAMonitoringService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
private readonly configService: ConfigService,
|
private readonly configService: ConfigService,
|
||||||
private readonly repository: RepositoryBroker,
|
private readonly repository: RepositoryBroker,
|
||||||
private readonly cache: RedisCache,
|
private readonly cache: RedisCache,
|
||||||
) {
|
) {
|
||||||
this.logger.verbose('instance created');
|
this.logger.verbose('instance created');
|
||||||
|
|
||||||
this.removeInstance();
|
this.removeInstance();
|
||||||
this.noConnection();
|
this.noConnection();
|
||||||
this.delInstanceFiles();
|
this.delInstanceFiles();
|
||||||
|
|
||||||
Object.assign(this.db, configService.get<Database>('DATABASE'));
|
Object.assign(this.db, configService.get<Database>('DATABASE'));
|
||||||
Object.assign(this.redis, configService.get<Redis>('REDIS'));
|
Object.assign(this.redis, configService.get<Redis>('REDIS'));
|
||||||
|
|
||||||
this.dbInstance = this.db.ENABLED
|
this.dbInstance = this.db.ENABLED
|
||||||
? this.repository.dbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
? this.repository.dbServer?.db(this.db.CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||||
: undefined;
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly db: Partial<Database> = {};
|
||||||
|
private readonly redis: Partial<Redis> = {};
|
||||||
|
|
||||||
|
private dbInstance: Db;
|
||||||
|
|
||||||
|
private dbStore = dbserver;
|
||||||
|
|
||||||
|
private readonly logger = new Logger(WAMonitoringService.name);
|
||||||
|
public readonly waInstances: Record<string, WAStartupService> = {};
|
||||||
|
|
||||||
|
public delInstanceTime(instance: string) {
|
||||||
|
const time = this.configService.get<DelInstance>('DEL_INSTANCE');
|
||||||
|
if (typeof time === 'number' && time > 0) {
|
||||||
|
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);
|
||||||
|
this.waInstances[instance]?.client?.ws?.close();
|
||||||
|
this.waInstances[instance]?.client?.end(undefined);
|
||||||
|
delete this.waInstances[instance];
|
||||||
|
} else {
|
||||||
|
delete this.waInstances[instance];
|
||||||
|
this.eventEmitter.emit('remove.instance', instance, 'inner');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000 * 60 * time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async instanceInfo(instanceName?: string) {
|
||||||
|
this.logger.verbose('get instance info');
|
||||||
|
if (instanceName && !this.waInstances[instanceName]) {
|
||||||
|
throw new NotFoundException(`Instance "${instanceName}" not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly db: Partial<Database> = {};
|
const instances: any[] = [];
|
||||||
private readonly redis: Partial<Redis> = {};
|
|
||||||
|
|
||||||
private dbInstance: Db;
|
for await (const [key, value] of Object.entries(this.waInstances)) {
|
||||||
|
if (value) {
|
||||||
|
this.logger.verbose('get instance info: ' + key);
|
||||||
|
let chatwoot: any;
|
||||||
|
|
||||||
private dbStore = dbserver;
|
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
private readonly logger = new Logger(WAMonitoringService.name);
|
const findChatwoot = await this.waInstances[key].findChatwoot();
|
||||||
public readonly waInstances: Record<string, WAStartupService> = {};
|
|
||||||
|
|
||||||
public delInstanceTime(instance: string) {
|
if (findChatwoot && findChatwoot.enabled) {
|
||||||
const time = this.configService.get<DelInstance>('DEL_INSTANCE');
|
chatwoot = {
|
||||||
if (typeof time === 'number' && time > 0) {
|
...findChatwoot,
|
||||||
this.logger.verbose(`Instance "${instance}" don't have connection, will be removed in ${time} minutes`);
|
webhook_url: `${urlServer}/chatwoot/webhook/${key}`,
|
||||||
|
};
|
||||||
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);
|
|
||||||
this.waInstances[instance]?.client?.ws?.close();
|
|
||||||
this.waInstances[instance]?.client?.end(undefined);
|
|
||||||
delete this.waInstances[instance];
|
|
||||||
} else {
|
|
||||||
delete this.waInstances[instance];
|
|
||||||
this.eventEmitter.emit('remove.instance', instance, 'inner');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 1000 * 60 * time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value.connectionStatus.state === 'open') {
|
||||||
|
this.logger.verbose('instance: ' + key + ' - connectionStatus: open');
|
||||||
|
|
||||||
|
const instanceData = {
|
||||||
|
instance: {
|
||||||
|
instanceName: key,
|
||||||
|
owner: value.wuid,
|
||||||
|
profileName: (await value.getProfileName()) || 'not loaded',
|
||||||
|
profilePictureUrl: value.profilePictureUrl,
|
||||||
|
profileStatus: (await value.getProfileStatus()) || '',
|
||||||
|
status: value.connectionStatus.state,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||||
|
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
const instanceData = {
|
||||||
|
instance: {
|
||||||
|
instanceName: key,
|
||||||
|
status: value.connectionStatus.state,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||||
|
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
|
instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey;
|
||||||
|
|
||||||
|
instanceData.instance['chatwoot'] = chatwoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
instances.push(instanceData);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async instanceInfo(instanceName?: string) {
|
this.logger.verbose('return instance info: ' + instances.length);
|
||||||
this.logger.verbose('get instance info');
|
|
||||||
if (instanceName && !this.waInstances[instanceName]) {
|
|
||||||
throw new NotFoundException(`Instance "${instanceName}" not found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const instances: any[] = [];
|
return instances.find((i) => i.instance.instanceName === instanceName) ?? instances;
|
||||||
|
}
|
||||||
|
|
||||||
for await (const [key, value] of Object.entries(this.waInstances)) {
|
private delInstanceFiles() {
|
||||||
if (value) {
|
this.logger.verbose('cron to delete instance files started');
|
||||||
this.logger.verbose('get instance info: ' + key);
|
setInterval(async () => {
|
||||||
let chatwoot: any;
|
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
|
const collections = await this.dbInstance.collections();
|
||||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
collections.forEach(async (collection) => {
|
||||||
|
const name = collection.namespace.replace(/^[\w-]+./, '');
|
||||||
const findChatwoot = await this.waInstances[key].findChatwoot();
|
await this.dbInstance.collection(name).deleteMany({
|
||||||
|
$or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }],
|
||||||
if (findChatwoot && findChatwoot.enabled) {
|
});
|
||||||
chatwoot = {
|
this.logger.verbose('instance files deleted: ' + name);
|
||||||
...findChatwoot,
|
});
|
||||||
webhook_url: `${urlServer}/chatwoot/webhook/${key}`,
|
// } else if (this.redis.ENABLED) {
|
||||||
};
|
} else {
|
||||||
}
|
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
||||||
|
for await (const dirent of dir) {
|
||||||
if (value.connectionStatus.state === 'open') {
|
if (dirent.isDirectory()) {
|
||||||
this.logger.verbose('instance: ' + key + ' - connectionStatus: open');
|
const files = readdirSync(join(INSTANCE_DIR, dirent.name), {
|
||||||
|
encoding: 'utf-8',
|
||||||
const instanceData = {
|
});
|
||||||
instance: {
|
files.forEach(async (file) => {
|
||||||
instanceName: key,
|
if (file.match(/^app.state.*/) || file.match(/^session-.*/)) {
|
||||||
owner: value.wuid,
|
rmSync(join(INSTANCE_DIR, dirent.name, file), {
|
||||||
profileName: (await value.getProfileName()) || 'not loaded',
|
recursive: true,
|
||||||
profilePictureUrl: value.profilePictureUrl,
|
force: true,
|
||||||
profileStatus: (await value.getProfileStatus()) || '',
|
|
||||||
status: value.connectionStatus.state,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
|
||||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
const instanceData = {
|
|
||||||
instance: {
|
|
||||||
instanceName: key,
|
|
||||||
status: value.connectionStatus.state,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
|
||||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
|
||||||
|
|
||||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey;
|
|
||||||
|
|
||||||
instanceData.instance['chatwoot'] = chatwoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
instances.push(instanceData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('return instance info: ' + instances.length);
|
|
||||||
|
|
||||||
return instances.find((i) => i.instance.instanceName === instanceName) ?? instances;
|
|
||||||
}
|
|
||||||
|
|
||||||
private delInstanceFiles() {
|
|
||||||
this.logger.verbose('cron to delete instance files started');
|
|
||||||
setInterval(async () => {
|
|
||||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
|
||||||
const collections = await this.dbInstance.collections();
|
|
||||||
collections.forEach(async (collection) => {
|
|
||||||
const name = collection.namespace.replace(/^[\w-]+./, '');
|
|
||||||
await this.dbInstance.collection(name).deleteMany({
|
|
||||||
$or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }],
|
|
||||||
});
|
|
||||||
this.logger.verbose('instance files deleted: ' + name);
|
|
||||||
});
|
});
|
||||||
// } else if (this.redis.ENABLED) {
|
}
|
||||||
} else {
|
});
|
||||||
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
this.logger.verbose('instance files deleted: ' + dirent.name);
|
||||||
for await (const dirent of dir) {
|
}
|
||||||
if (dirent.isDirectory()) {
|
}
|
||||||
const files = readdirSync(join(INSTANCE_DIR, dirent.name), {
|
}
|
||||||
encoding: 'utf-8',
|
}, 3600 * 1000 * 2);
|
||||||
});
|
}
|
||||||
files.forEach(async (file) => {
|
|
||||||
if (file.match(/^app.state.*/) || file.match(/^session-.*/)) {
|
public async cleaningUp(instanceName: string) {
|
||||||
rmSync(join(INSTANCE_DIR, dirent.name, file), {
|
this.logger.verbose('cleaning up instance: ' + instanceName);
|
||||||
recursive: true,
|
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
force: true,
|
this.logger.verbose('cleaning up instance in database: ' + instanceName);
|
||||||
});
|
await this.repository.dbServer.connect();
|
||||||
}
|
const collections: any[] = await this.dbInstance.collections();
|
||||||
});
|
if (collections.length > 0) {
|
||||||
this.logger.verbose('instance files deleted: ' + dirent.name);
|
await this.dbInstance.dropCollection(instanceName);
|
||||||
}
|
}
|
||||||
}
|
return;
|
||||||
}
|
|
||||||
}, 3600 * 1000 * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async cleaningUp(instanceName: string) {
|
if (this.redis.ENABLED) {
|
||||||
this.logger.verbose('cleaning up instance: ' + instanceName);
|
this.logger.verbose('cleaning up instance in redis: ' + instanceName);
|
||||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
this.cache.reference = instanceName;
|
||||||
this.logger.verbose('cleaning up instance in database: ' + instanceName);
|
await this.cache.delAll();
|
||||||
await this.repository.dbServer.connect();
|
return;
|
||||||
const collections: any[] = await this.dbInstance.collections();
|
|
||||||
if (collections.length > 0) {
|
|
||||||
await this.dbInstance.dropCollection(instanceName);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.redis.ENABLED) {
|
|
||||||
this.logger.verbose('cleaning up instance in redis: ' + instanceName);
|
|
||||||
this.cache.reference = instanceName;
|
|
||||||
await this.cache.delAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('cleaning up instance in files: ' + instanceName);
|
|
||||||
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async cleaningStoreFiles(instanceName: string) {
|
this.logger.verbose('cleaning up instance in files: ' + instanceName);
|
||||||
if (!this.db.ENABLED) {
|
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
||||||
this.logger.verbose('cleaning store files instance: ' + instanceName);
|
}
|
||||||
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
|
||||||
|
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`);
|
public async cleaningStoreFiles(instanceName: string) {
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`);
|
if (!this.db.ENABLED) {
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`);
|
this.logger.verbose('cleaning store files instance: ' + instanceName);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`);
|
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
||||||
|
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`);
|
||||||
|
|
||||||
return;
|
execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`);
|
||||||
|
execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`);
|
||||||
|
execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`);
|
||||||
|
execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('cleaning store database instance: ' + instanceName);
|
||||||
|
|
||||||
|
await AuthModel.deleteMany({ owner: instanceName });
|
||||||
|
await ContactModel.deleteMany({ owner: instanceName });
|
||||||
|
await MessageModel.deleteMany({ owner: instanceName });
|
||||||
|
await MessageUpModel.deleteMany({ owner: instanceName });
|
||||||
|
await AuthModel.deleteMany({ _id: instanceName });
|
||||||
|
await WebhookModel.deleteMany({ _id: instanceName });
|
||||||
|
await ChatwootModel.deleteMany({ _id: instanceName });
|
||||||
|
await SettingsModel.deleteMany({ _id: instanceName });
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
instance.instanceName = name;
|
||||||
|
this.logger.verbose('instance loaded: ' + name);
|
||||||
|
|
||||||
|
await instance.connectToWhatsapp();
|
||||||
|
this.logger.verbose('connectToWhatsapp: ' + name);
|
||||||
|
|
||||||
|
this.waInstances[name] = instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (this.redis.ENABLED) {
|
||||||
|
this.logger.verbose('redis enabled');
|
||||||
|
await this.cache.connect(this.redis as Redis);
|
||||||
|
const keys = await this.cache.instanceKeys();
|
||||||
|
if (keys?.length > 0) {
|
||||||
|
this.logger.verbose('reading instance keys and setting instances');
|
||||||
|
keys.forEach(async (k) => await set(k.split(':')[1]));
|
||||||
|
} else {
|
||||||
|
this.logger.verbose('no instance keys found');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('cleaning store database instance: ' + instanceName);
|
|
||||||
|
|
||||||
await AuthModel.deleteMany({ owner: instanceName });
|
|
||||||
await ContactModel.deleteMany({ owner: instanceName });
|
|
||||||
await MessageModel.deleteMany({ owner: instanceName });
|
|
||||||
await MessageUpModel.deleteMany({ owner: instanceName });
|
|
||||||
await AuthModel.deleteMany({ _id: instanceName });
|
|
||||||
await WebhookModel.deleteMany({ _id: instanceName });
|
|
||||||
await ChatwootModel.deleteMany({ _id: instanceName });
|
|
||||||
await SettingsModel.deleteMany({ _id: instanceName });
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadInstance() {
|
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
this.logger.verbose('load instances');
|
this.logger.verbose('database enabled');
|
||||||
const set = async (name: string) => {
|
await this.repository.dbServer.connect();
|
||||||
const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache);
|
const collections: any[] = await this.dbInstance.collections();
|
||||||
instance.instanceName = name;
|
if (collections.length > 0) {
|
||||||
this.logger.verbose('instance loaded: ' + name);
|
this.logger.verbose('reading collections and setting instances');
|
||||||
|
collections.forEach(async (coll) => await set(coll.namespace.replace(/^[\w-]+\./, '')));
|
||||||
await instance.connectToWhatsapp();
|
} else {
|
||||||
this.logger.verbose('connectToWhatsapp: ' + name);
|
this.logger.verbose('no collections found');
|
||||||
|
|
||||||
this.waInstances[name] = instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (this.redis.ENABLED) {
|
|
||||||
this.logger.verbose('redis enabled');
|
|
||||||
await this.cache.connect(this.redis as Redis);
|
|
||||||
const keys = await this.cache.instanceKeys();
|
|
||||||
if (keys?.length > 0) {
|
|
||||||
this.logger.verbose('reading instance keys and setting instances');
|
|
||||||
keys.forEach(async (k) => await set(k.split(':')[1]));
|
|
||||||
} else {
|
|
||||||
this.logger.verbose('no instance keys found');
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
|
||||||
this.logger.verbose('database enabled');
|
|
||||||
await this.repository.dbServer.connect();
|
|
||||||
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-]+\./, '')));
|
|
||||||
} else {
|
|
||||||
this.logger.verbose('no collections found');
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.verbose('store in files enabled');
|
|
||||||
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
|
||||||
for await (const dirent of dir) {
|
|
||||||
if (dirent.isDirectory()) {
|
|
||||||
this.logger.verbose('reading instance files and setting instances');
|
|
||||||
const files = readdirSync(join(INSTANCE_DIR, dirent.name), {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
});
|
|
||||||
if (files.length === 0) {
|
|
||||||
rmSync(join(INSTANCE_DIR, dirent.name), { recursive: true, force: true });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
await set(dirent.name);
|
|
||||||
} else {
|
|
||||||
this.logger.verbose('no instance files found');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.verbose('store in files enabled');
|
||||||
|
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
||||||
|
for await (const dirent of dir) {
|
||||||
|
if (dirent.isDirectory()) {
|
||||||
|
this.logger.verbose('reading instance files and setting instances');
|
||||||
|
const files = readdirSync(join(INSTANCE_DIR, dirent.name), {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
});
|
||||||
|
if (files.length === 0) {
|
||||||
|
rmSync(join(INSTANCE_DIR, dirent.name), { recursive: true, force: true });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await set(dirent.name);
|
||||||
|
} else {
|
||||||
|
this.logger.verbose('no instance files found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private removeInstance() {
|
private removeInstance() {
|
||||||
this.eventEmitter.on('remove.instance', async (instanceName: string) => {
|
this.eventEmitter.on('remove.instance', async (instanceName: string) => {
|
||||||
this.logger.verbose('remove instance: ' + instanceName);
|
this.logger.verbose('remove instance: ' + instanceName);
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('instance: ' + instanceName + ' - removing from memory');
|
this.logger.verbose('instance: ' + instanceName + ' - removing from memory');
|
||||||
this.waInstances[instanceName] = undefined;
|
this.waInstances[instanceName] = undefined;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
||||||
this.cleaningUp(instanceName);
|
this.cleaningUp(instanceName);
|
||||||
this.cleaningStoreFiles(instanceName);
|
this.cleaningStoreFiles(instanceName);
|
||||||
} finally {
|
} finally {
|
||||||
this.logger.warn(`Instance "${instanceName}" - REMOVED`);
|
this.logger.warn(`Instance "${instanceName}" - REMOVED`);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
this.eventEmitter.on('logout.instance', async (instanceName: string) => {
|
||||||
|
this.logger.verbose('logout instance: ' + instanceName);
|
||||||
|
try {
|
||||||
|
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
||||||
|
this.cleaningUp(instanceName);
|
||||||
|
} finally {
|
||||||
|
this.logger.warn(`Instance "${instanceName}" - LOGOUT`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private noConnection() {
|
||||||
|
this.logger.verbose('checking instances without connection');
|
||||||
|
this.eventEmitter.on('no.connection', async (instanceName) => {
|
||||||
|
try {
|
||||||
|
this.logger.verbose('instance: ' + instanceName + ' - removing from memory');
|
||||||
|
this.waInstances[instanceName] = undefined;
|
||||||
|
|
||||||
|
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
||||||
|
this.cleaningUp(instanceName);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error({
|
||||||
|
localError: 'noConnection',
|
||||||
|
warn: 'Error deleting instance from memory.',
|
||||||
|
error,
|
||||||
});
|
});
|
||||||
this.eventEmitter.on('logout.instance', async (instanceName: string) => {
|
} finally {
|
||||||
this.logger.verbose('logout instance: ' + instanceName);
|
this.logger.warn(`Instance "${instanceName}" - NOT CONNECTION`);
|
||||||
try {
|
}
|
||||||
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
});
|
||||||
this.cleaningUp(instanceName);
|
}
|
||||||
} finally {
|
|
||||||
this.logger.warn(`Instance "${instanceName}" - LOGOUT`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private noConnection() {
|
|
||||||
this.logger.verbose('checking instances without connection');
|
|
||||||
this.eventEmitter.on('no.connection', async (instanceName) => {
|
|
||||||
try {
|
|
||||||
this.logger.verbose('instance: ' + instanceName + ' - removing from memory');
|
|
||||||
this.waInstances[instanceName] = undefined;
|
|
||||||
|
|
||||||
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
|
||||||
this.cleaningUp(instanceName);
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error({
|
|
||||||
localError: 'noConnection',
|
|
||||||
warn: 'Error deleting instance from memory.',
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
this.logger.warn(`Instance "${instanceName}" - NOT CONNECTION`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,29 +4,29 @@ import { SettingsDto } from '../dto/settings.dto';
|
|||||||
import { WAMonitoringService } from './monitor.service';
|
import { WAMonitoringService } from './monitor.service';
|
||||||
|
|
||||||
export class SettingsService {
|
export class SettingsService {
|
||||||
constructor(private readonly waMonitor: WAMonitoringService) {}
|
constructor(private readonly waMonitor: WAMonitoringService) {}
|
||||||
|
|
||||||
private readonly logger = new Logger(SettingsService.name);
|
private readonly logger = new Logger(SettingsService.name);
|
||||||
|
|
||||||
public create(instance: InstanceDto, data: SettingsDto) {
|
public create(instance: InstanceDto, data: SettingsDto) {
|
||||||
this.logger.verbose('create settings: ' + instance.instanceName);
|
this.logger.verbose('create settings: ' + instance.instanceName);
|
||||||
this.waMonitor.waInstances[instance.instanceName].setSettings(data);
|
this.waMonitor.waInstances[instance.instanceName].setSettings(data);
|
||||||
|
|
||||||
return { settings: { ...instance, settings: data } };
|
return { settings: { ...instance, settings: data } };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async find(instance: InstanceDto): Promise<SettingsDto> {
|
public async find(instance: InstanceDto): Promise<SettingsDto> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('find settings: ' + instance.instanceName);
|
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) {
|
if (Object.keys(result).length === 0) {
|
||||||
throw new Error('Settings not found');
|
throw new Error('Settings not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { reject_call: false, msg_call: '', groups_ignore: false };
|
return { reject_call: false, msg_call: '', groups_ignore: false };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,29 +4,29 @@ import { WebhookDto } from '../dto/webhook.dto';
|
|||||||
import { WAMonitoringService } from './monitor.service';
|
import { WAMonitoringService } from './monitor.service';
|
||||||
|
|
||||||
export class WebhookService {
|
export class WebhookService {
|
||||||
constructor(private readonly waMonitor: WAMonitoringService) {}
|
constructor(private readonly waMonitor: WAMonitoringService) {}
|
||||||
|
|
||||||
private readonly logger = new Logger(WebhookService.name);
|
private readonly logger = new Logger(WebhookService.name);
|
||||||
|
|
||||||
public create(instance: InstanceDto, data: WebhookDto) {
|
public create(instance: InstanceDto, data: WebhookDto) {
|
||||||
this.logger.verbose('create webhook: ' + instance.instanceName);
|
this.logger.verbose('create webhook: ' + instance.instanceName);
|
||||||
this.waMonitor.waInstances[instance.instanceName].setWebhook(data);
|
this.waMonitor.waInstances[instance.instanceName].setWebhook(data);
|
||||||
|
|
||||||
return { webhook: { ...instance, webhook: data } };
|
return { webhook: { ...instance, webhook: data } };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async find(instance: InstanceDto): Promise<WebhookDto> {
|
public async find(instance: InstanceDto): Promise<WebhookDto> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('find webhook: ' + instance.instanceName);
|
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) {
|
if (Object.keys(result).length === 0) {
|
||||||
throw new Error('Webhook not found');
|
throw new Error('Webhook not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { enabled: false, url: '', events: [], webhook_by_events: false };
|
return { enabled: false, url: '', events: [], webhook_by_events: false };
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,88 +2,88 @@
|
|||||||
import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys';
|
import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys';
|
||||||
|
|
||||||
export enum Events {
|
export enum Events {
|
||||||
APPLICATION_STARTUP = 'application.startup',
|
APPLICATION_STARTUP = 'application.startup',
|
||||||
QRCODE_UPDATED = 'qrcode.updated',
|
QRCODE_UPDATED = 'qrcode.updated',
|
||||||
CONNECTION_UPDATE = 'connection.update',
|
CONNECTION_UPDATE = 'connection.update',
|
||||||
STATUS_INSTANCE = 'status.instance',
|
STATUS_INSTANCE = 'status.instance',
|
||||||
MESSAGES_SET = 'messages.set',
|
MESSAGES_SET = 'messages.set',
|
||||||
MESSAGES_UPSERT = 'messages.upsert',
|
MESSAGES_UPSERT = 'messages.upsert',
|
||||||
MESSAGES_UPDATE = 'messages.update',
|
MESSAGES_UPDATE = 'messages.update',
|
||||||
MESSAGES_DELETE = 'messages.delete',
|
MESSAGES_DELETE = 'messages.delete',
|
||||||
SEND_MESSAGE = 'send.message',
|
SEND_MESSAGE = 'send.message',
|
||||||
CONTACTS_SET = 'contacts.set',
|
CONTACTS_SET = 'contacts.set',
|
||||||
CONTACTS_UPSERT = 'contacts.upsert',
|
CONTACTS_UPSERT = 'contacts.upsert',
|
||||||
CONTACTS_UPDATE = 'contacts.update',
|
CONTACTS_UPDATE = 'contacts.update',
|
||||||
PRESENCE_UPDATE = 'presence.update',
|
PRESENCE_UPDATE = 'presence.update',
|
||||||
CHATS_SET = 'chats.set',
|
CHATS_SET = 'chats.set',
|
||||||
CHATS_UPDATE = 'chats.update',
|
CHATS_UPDATE = 'chats.update',
|
||||||
CHATS_UPSERT = 'chats.upsert',
|
CHATS_UPSERT = 'chats.upsert',
|
||||||
CHATS_DELETE = 'chats.delete',
|
CHATS_DELETE = 'chats.delete',
|
||||||
GROUPS_UPSERT = 'groups.upsert',
|
GROUPS_UPSERT = 'groups.upsert',
|
||||||
GROUPS_UPDATE = 'groups.update',
|
GROUPS_UPDATE = 'groups.update',
|
||||||
GROUP_PARTICIPANTS_UPDATE = 'group-participants.update',
|
GROUP_PARTICIPANTS_UPDATE = 'group-participants.update',
|
||||||
CALL = 'call',
|
CALL = 'call',
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare namespace wa {
|
export declare namespace wa {
|
||||||
export type QrCode = {
|
export type QrCode = {
|
||||||
count?: number;
|
count?: number;
|
||||||
pairingCode?: string;
|
pairingCode?: string;
|
||||||
base64?: string;
|
base64?: string;
|
||||||
code?: string;
|
code?: string;
|
||||||
};
|
};
|
||||||
export type Instance = {
|
export type Instance = {
|
||||||
qrcode?: QrCode;
|
qrcode?: QrCode;
|
||||||
pairingCode?: string;
|
pairingCode?: string;
|
||||||
authState?: { state: AuthenticationState; saveCreds: () => void };
|
authState?: { state: AuthenticationState; saveCreds: () => void };
|
||||||
name?: string;
|
name?: string;
|
||||||
wuid?: string;
|
wuid?: string;
|
||||||
profileName?: string;
|
profileName?: string;
|
||||||
profilePictureUrl?: string;
|
profilePictureUrl?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalWebHook = {
|
export type LocalWebHook = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
url?: string;
|
url?: string;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
webhook_by_events?: boolean;
|
webhook_by_events?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalChatwoot = {
|
export type LocalChatwoot = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
account_id?: string;
|
account_id?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
name_inbox?: string;
|
name_inbox?: string;
|
||||||
sign_msg?: boolean;
|
sign_msg?: boolean;
|
||||||
number?: string;
|
number?: string;
|
||||||
reopen_conversation?: boolean;
|
reopen_conversation?: boolean;
|
||||||
conversation_pending?: boolean;
|
conversation_pending?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalSettings = {
|
export type LocalSettings = {
|
||||||
reject_call?: boolean;
|
reject_call?: boolean;
|
||||||
msg_call?: string;
|
msg_call?: string;
|
||||||
groups_ignore?: boolean;
|
groups_ignore?: boolean;
|
||||||
always_online?: boolean;
|
always_online?: boolean;
|
||||||
read_messages?: boolean;
|
read_messages?: boolean;
|
||||||
read_status?: boolean;
|
read_status?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StateConnection = {
|
export type StateConnection = {
|
||||||
instance?: string;
|
instance?: string;
|
||||||
state?: WAConnectionState | 'refused';
|
state?: WAConnectionState | 'refused';
|
||||||
statusReason?: number;
|
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 = [
|
export const MessageSubtype = [
|
||||||
'ephemeralMessage',
|
'ephemeralMessage',
|
||||||
'documentWithCaptionMessage',
|
'documentWithCaptionMessage',
|
||||||
'viewOnceMessage',
|
'viewOnceMessage',
|
||||||
'viewOnceMessageV2',
|
'viewOnceMessageV2',
|
||||||
];
|
];
|
||||||
|
@ -12,14 +12,14 @@ import { SettingsController } from './controllers/settings.controller';
|
|||||||
import { ViewsController } from './controllers/views.controller';
|
import { ViewsController } from './controllers/views.controller';
|
||||||
import { WebhookController } from './controllers/webhook.controller';
|
import { WebhookController } from './controllers/webhook.controller';
|
||||||
import {
|
import {
|
||||||
AuthModel,
|
AuthModel,
|
||||||
ChatModel,
|
ChatModel,
|
||||||
ChatwootModel,
|
ChatwootModel,
|
||||||
ContactModel,
|
ContactModel,
|
||||||
MessageModel,
|
MessageModel,
|
||||||
MessageUpModel,
|
MessageUpModel,
|
||||||
SettingsModel,
|
SettingsModel,
|
||||||
WebhookModel,
|
WebhookModel,
|
||||||
} from './models';
|
} from './models';
|
||||||
import { AuthRepository } from './repository/auth.repository';
|
import { AuthRepository } from './repository/auth.repository';
|
||||||
import { ChatRepository } from './repository/chat.repository';
|
import { ChatRepository } from './repository/chat.repository';
|
||||||
@ -48,16 +48,16 @@ const settingsRepository = new SettingsRepository(SettingsModel, configService);
|
|||||||
const authRepository = new AuthRepository(AuthModel, configService);
|
const authRepository = new AuthRepository(AuthModel, configService);
|
||||||
|
|
||||||
export const repository = new RepositoryBroker(
|
export const repository = new RepositoryBroker(
|
||||||
messageRepository,
|
messageRepository,
|
||||||
chatRepository,
|
chatRepository,
|
||||||
contactRepository,
|
contactRepository,
|
||||||
messageUpdateRepository,
|
messageUpdateRepository,
|
||||||
webhookRepository,
|
webhookRepository,
|
||||||
chatwootRepository,
|
chatwootRepository,
|
||||||
settingsRepository,
|
settingsRepository,
|
||||||
authRepository,
|
authRepository,
|
||||||
configService,
|
configService,
|
||||||
dbserver?.getClient(),
|
dbserver?.getClient(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const cache = new RedisCache();
|
export const cache = new RedisCache();
|
||||||
@ -79,15 +79,15 @@ const settingsService = new SettingsService(waMonitor);
|
|||||||
export const settingsController = new SettingsController(settingsService);
|
export const settingsController = new SettingsController(settingsService);
|
||||||
|
|
||||||
export const instanceController = new InstanceController(
|
export const instanceController = new InstanceController(
|
||||||
waMonitor,
|
waMonitor,
|
||||||
configService,
|
configService,
|
||||||
repository,
|
repository,
|
||||||
eventEmitter,
|
eventEmitter,
|
||||||
authService,
|
authService,
|
||||||
webhookService,
|
webhookService,
|
||||||
chatwootService,
|
chatwootService,
|
||||||
settingsService,
|
settingsService,
|
||||||
cache,
|
cache,
|
||||||
);
|
);
|
||||||
export const viewsController = new ViewsController(waMonitor, configService);
|
export const viewsController = new ViewsController(waMonitor, configService);
|
||||||
export const sendMessageController = new SendMessageController(waMonitor);
|
export const sendMessageController = new SendMessageController(waMonitor);
|
||||||
|
Loading…
Reference in New Issue
Block a user