mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-26 18:38:39 -06:00
Merge branch 'develop' of https://github.com/codephix/evolution-api into develop
This commit is contained in:
commit
760b3f5fc5
5
dev-env
Normal file
5
dev-env
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# OPENAI_API_KEY=""
|
||||||
|
REDIS_HOST=localhost
|
||||||
|
REDIS_PORT=6379
|
||||||
|
REDIS_DB=0
|
||||||
|
REDIS_PASS=0
|
28
src/config.ts
Executable file → Normal file
28
src/config.ts
Executable file → Normal file
@ -1,14 +1,14 @@
|
|||||||
import dotenv from "dotenv"
|
import dotenv from "dotenv"
|
||||||
|
|
||||||
dotenv.config()
|
dotenv.config()
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
openAI: {
|
openAI: {
|
||||||
apiToken: process.env.OPENAI_API_KEY,
|
apiToken: process.env.OPENAI_API_KEY,
|
||||||
},
|
},
|
||||||
redis: {
|
redis: {
|
||||||
host: process.env.REDIS_HOST || "localhost",
|
host: process.env.REDIS_HOST || "localhost",
|
||||||
port: (process.env.REDIS_PORT as unknown as number) || 6379,
|
port: (process.env.REDIS_PORT as unknown as number) || 6379,
|
||||||
db: (process.env.REDIS_DB as unknown as number) || 0,
|
db: (process.env.REDIS_DB as unknown as number) || 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
696
src/config/env.config.ts
Executable file → Normal file
696
src/config/env.config.ts
Executable file → Normal file
@ -1,348 +1,348 @@
|
|||||||
import { isBooleanString } from 'class-validator';
|
import { isBooleanString } from 'class-validator';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { load } from 'js-yaml';
|
import { load } from 'js-yaml';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
export type HttpServer = { TYPE: 'http' | 'https'; PORT: number; URL: string };
|
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';
|
||||||
|
|
||||||
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;
|
||||||
DB_PREFIX_FINAL_NAME: string;
|
DB_PREFIX_FINAL_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 Rabbitmq = {
|
export type Rabbitmq = {
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
URI: string;
|
URI: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Sqs = {
|
export type Sqs = {
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
ACCESS_KEY_ID: string;
|
ACCESS_KEY_ID: string;
|
||||||
SECRET_ACCESS_KEY: string;
|
SECRET_ACCESS_KEY: string;
|
||||||
ACCOUNT_ID: string;
|
ACCOUNT_ID: string;
|
||||||
REGION: string;
|
REGION: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Openai = {
|
export type Openai = {
|
||||||
CHAVE: string;
|
CHAVE: string;
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
URI: string;
|
URI: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Websocket = {
|
export type Websocket = {
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Chatwoot = {
|
export type Chatwoot = {
|
||||||
USE_REPLY_ID: boolean;
|
USE_REPLY_ID: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
TYPEBOT_START: boolean;
|
TYPEBOT_START: boolean;
|
||||||
TYPEBOT_CHANGE_STATUS: boolean;
|
TYPEBOT_CHANGE_STATUS: boolean;
|
||||||
CHAMA_AI_ACTION: boolean;
|
CHAMA_AI_ACTION: boolean;
|
||||||
ERRORS: boolean;
|
ERRORS: boolean;
|
||||||
ERRORS_WEBHOOK: string;
|
ERRORS_WEBHOOK: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
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 };
|
||||||
export type ConfigSessionPhone = { CLIENT: string; NAME: string };
|
export type ConfigSessionPhone = { CLIENT: string; NAME: string };
|
||||||
export type QrCode = { LIMIT: number; COLOR: string };
|
export type QrCode = { LIMIT: number; COLOR: string };
|
||||||
export type Typebot = { API_VERSION: string };
|
export type Typebot = { API_VERSION: string };
|
||||||
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;
|
||||||
RABBITMQ: Rabbitmq;
|
RABBITMQ: Rabbitmq;
|
||||||
SQS: Sqs;
|
SQS: Sqs;
|
||||||
OPENAI: Openai;
|
OPENAI: Openai;
|
||||||
WEBSOCKET: Websocket;
|
WEBSOCKET: Websocket;
|
||||||
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;
|
||||||
TYPEBOT: Typebot;
|
TYPEBOT: Typebot;
|
||||||
AUTHENTICATION: Auth;
|
AUTHENTICATION: Auth;
|
||||||
PRODUCTION?: Production;
|
PRODUCTION?: Production;
|
||||||
CHATWOOT?: Chatwoot;
|
CHATWOOT?: Chatwoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) || 8080,
|
PORT: Number.parseInt(process.env.SERVER_PORT) || 8080,
|
||||||
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[]) || ['POST', 'GET', 'PUT', 'DELETE'],
|
METHODS: (process.env.CORS_METHODS.split(',') as HttpMethods[]) || ['POST', 'GET', 'PUT', 'DELETE'],
|
||||||
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 || 'evolution',
|
DB_PREFIX_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_NAME || 'evolution',
|
||||||
DB_PREFIX_FINAL_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_FINAL_NAME || '-api',
|
DB_PREFIX_FINAL_NAME: process.env.DATABASE_CONNECTION_DB_PREFIX_FINAL_NAME || '-api',
|
||||||
},
|
},
|
||||||
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 || 'evolution',
|
PREFIX_KEY: process.env.REDIS_PREFIX_KEY || 'evolution',
|
||||||
},
|
},
|
||||||
RABBITMQ: {
|
RABBITMQ: {
|
||||||
ENABLED: process.env?.RABBITMQ_ENABLED === 'true',
|
ENABLED: process.env?.RABBITMQ_ENABLED === 'true',
|
||||||
URI: process.env.RABBITMQ_URI || '',
|
URI: process.env.RABBITMQ_URI || '',
|
||||||
},
|
},
|
||||||
SQS: {
|
SQS: {
|
||||||
ENABLED: process.env?.SQS_ENABLED === 'true',
|
ENABLED: process.env?.SQS_ENABLED === 'true',
|
||||||
ACCESS_KEY_ID: process.env.SQS_ACCESS_KEY_ID || '',
|
ACCESS_KEY_ID: process.env.SQS_ACCESS_KEY_ID || '',
|
||||||
SECRET_ACCESS_KEY: process.env.SQS_SECRET_ACCESS_KEY || '',
|
SECRET_ACCESS_KEY: process.env.SQS_SECRET_ACCESS_KEY || '',
|
||||||
ACCOUNT_ID: process.env.SQS_ACCOUNT_ID || '',
|
ACCOUNT_ID: process.env.SQS_ACCOUNT_ID || '',
|
||||||
REGION: process.env.SQS_REGION || '',
|
REGION: process.env.SQS_REGION || '',
|
||||||
},
|
},
|
||||||
|
|
||||||
OPENAI: {
|
OPENAI: {
|
||||||
CHAVE: process.env?.OPENAI_ENABLED || '',
|
CHAVE: process.env?.OPENAI_ENABLED || '',
|
||||||
ENABLED: process.env?.OPENAI_ENABLED === 'true',
|
ENABLED: process.env?.OPENAI_ENABLED === 'true',
|
||||||
URI: process.env.OPENAI_URI || '',
|
URI: process.env.OPENAI_URI || '',
|
||||||
},
|
},
|
||||||
WEBSOCKET: {
|
WEBSOCKET: {
|
||||||
ENABLED: process.env?.WEBSOCKET_ENABLED === 'true',
|
ENABLED: process.env?.WEBSOCKET_ENABLED === 'true',
|
||||||
},
|
},
|
||||||
LOG: {
|
LOG: {
|
||||||
LEVEL: (process.env?.LOG_LEVEL.split(',') as LogLevel[]) || [
|
LEVEL: (process.env?.LOG_LEVEL.split(',') as LogLevel[]) || [
|
||||||
'ERROR',
|
'ERROR',
|
||||||
'WARN',
|
'WARN',
|
||||||
'DEBUG',
|
'DEBUG',
|
||||||
'INFO',
|
'INFO',
|
||||||
'LOG',
|
'LOG',
|
||||||
'VERBOSE',
|
'VERBOSE',
|
||||||
'DARK',
|
'DARK',
|
||||||
'WEBHOOKS',
|
'WEBHOOKS',
|
||||||
],
|
],
|
||||||
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',
|
||||||
TYPEBOT_START: process.env?.WEBHOOK_EVENTS_TYPEBOT_START === 'true',
|
TYPEBOT_START: process.env?.WEBHOOK_EVENTS_TYPEBOT_START === 'true',
|
||||||
TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',
|
TYPEBOT_CHANGE_STATUS: process.env?.WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS === 'true',
|
||||||
CHAMA_AI_ACTION: process.env?.WEBHOOK_EVENTS_CHAMA_AI_ACTION === 'true',
|
CHAMA_AI_ACTION: process.env?.WEBHOOK_EVENTS_CHAMA_AI_ACTION === 'true',
|
||||||
ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true',
|
ERRORS: process.env?.WEBHOOK_EVENTS_ERRORS === 'true',
|
||||||
ERRORS_WEBHOOK: process.env?.WEBHOOK_EVENTS_ERRORS_WEBHOOK || '',
|
ERRORS_WEBHOOK: process.env?.WEBHOOK_EVENTS_ERRORS_WEBHOOK || '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
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,
|
||||||
COLOR: process.env.QRCODE_COLOR || '#198754',
|
COLOR: process.env.QRCODE_COLOR || '#198754',
|
||||||
},
|
},
|
||||||
TYPEBOT: {
|
TYPEBOT: {
|
||||||
API_VERSION: process.env?.TYPEBOT_API_VERSION || 'v1',
|
API_VERSION: process.env?.TYPEBOT_API_VERSION || 'v1',
|
||||||
},
|
},
|
||||||
AUTHENTICATION: {
|
AUTHENTICATION: {
|
||||||
TYPE: process.env.AUTHENTICATION_TYPE as 'apikey',
|
TYPE: process.env.AUTHENTICATION_TYPE as 'apikey',
|
||||||
API_KEY: {
|
API_KEY: {
|
||||||
KEY: process.env.AUTHENTICATION_API_KEY || 'BQYHJGJHJ',
|
KEY: process.env.AUTHENTICATION_API_KEY || 'BQYHJGJHJ',
|
||||||
},
|
},
|
||||||
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 || 'L=0YWt]b2w[WF>#>:&E`',
|
SECRET: process.env.AUTHENTICATION_JWT_SECRET || 'L=0YWt]b2w[WF>#>:&E`',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CHATWOOT: {
|
CHATWOOT: {
|
||||||
USE_REPLY_ID: process.env?.USE_REPLY_ID === 'true',
|
USE_REPLY_ID: process.env?.USE_REPLY_ID === 'true',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const configService = new ConfigService();
|
export const configService = new ConfigService();
|
||||||
|
358
src/dev-env.yml
Executable file → Normal file
358
src/dev-env.yml
Executable file → Normal file
@ -1,179 +1,179 @@
|
|||||||
# ⚠️
|
# ⚠️
|
||||||
# ⚠️ ALL SETTINGS DEFINED IN THIS FILE ARE APPLIED TO ALL INSTANCES.
|
# ⚠️ ALL SETTINGS DEFINED IN THIS FILE ARE APPLIED TO ALL INSTANCES.
|
||||||
# ⚠️
|
# ⚠️
|
||||||
|
|
||||||
# ⚠️ RENAME THIS FILE TO env.yml
|
# ⚠️ RENAME THIS FILE TO env.yml
|
||||||
|
|
||||||
# Choose the server type for the application
|
# Choose the server type for the application
|
||||||
SERVER:
|
SERVER:
|
||||||
TYPE: http # https
|
TYPE: http # https
|
||||||
PORT: 3333 # 443
|
PORT: 3333 # 443
|
||||||
URL: 127.0.0.1
|
URL: 127.0.0.1
|
||||||
|
|
||||||
CORS:
|
CORS:
|
||||||
ORIGIN:
|
ORIGIN:
|
||||||
- "*"
|
- "*"
|
||||||
# - yourdomain.com
|
# - yourdomain.com
|
||||||
METHODS:
|
METHODS:
|
||||||
- POST
|
- POST
|
||||||
- GET
|
- GET
|
||||||
- PUT
|
- PUT
|
||||||
- DELETE
|
- DELETE
|
||||||
CREDENTIALS: true
|
CREDENTIALS: true
|
||||||
|
|
||||||
# Install ssl certificate and replace string <domain> with domain name
|
# Install ssl certificate and replace string <domain> with domain name
|
||||||
# Access: https://certbot.eff.org/instructions?ws=other&os=ubuntufocal
|
# Access: https://certbot.eff.org/instructions?ws=other&os=ubuntufocal
|
||||||
SSL_CONF:
|
SSL_CONF:
|
||||||
PRIVKEY: /etc/letsencrypt/live/<domain>/privkey.pem
|
PRIVKEY: /etc/letsencrypt/live/<domain>/privkey.pem
|
||||||
FULLCHAIN: /etc/letsencrypt/live/<domain>/fullchain.pem
|
FULLCHAIN: /etc/letsencrypt/live/<domain>/fullchain.pem
|
||||||
|
|
||||||
# Determine the logs to be displayed
|
# Determine the logs to be displayed
|
||||||
LOG:
|
LOG:
|
||||||
LEVEL:
|
LEVEL:
|
||||||
- ERROR
|
- ERROR
|
||||||
- WARN
|
- WARN
|
||||||
- DEBUG
|
- DEBUG
|
||||||
- INFO
|
- INFO
|
||||||
- LOG
|
- LOG
|
||||||
- VERBOSE
|
- VERBOSE
|
||||||
- DARK
|
- DARK
|
||||||
- WEBHOOKS
|
- WEBHOOKS
|
||||||
COLOR: true
|
COLOR: true
|
||||||
BAILEYS: error # fatal | error | warn | info | debug | trace
|
BAILEYS: error # fatal | error | warn | info | debug | trace
|
||||||
|
|
||||||
# Determine how long the instance should be deleted from memory in case of no connection.
|
# Determine how long the instance should be deleted from memory in case of no connection.
|
||||||
# Default time: 5 minutes
|
# Default time: 5 minutes
|
||||||
# If you don't even want an expiration, enter the value false
|
# If you don't even want an expiration, enter the value false
|
||||||
DEL_INSTANCE: false # or false
|
DEL_INSTANCE: false # or false
|
||||||
|
|
||||||
# Temporary data storage
|
# Temporary data storage
|
||||||
STORE:
|
STORE:
|
||||||
MESSAGES: false
|
MESSAGES: false
|
||||||
MESSAGE_UP: false
|
MESSAGE_UP: false
|
||||||
CONTACTS: true
|
CONTACTS: true
|
||||||
CHATS: true
|
CHATS: true
|
||||||
|
|
||||||
CLEAN_STORE:
|
CLEAN_STORE:
|
||||||
CLEANING_INTERVAL: 7200 # 7200 seconds === 2h
|
CLEANING_INTERVAL: 7200 # 7200 seconds === 2h
|
||||||
MESSAGES: true
|
MESSAGES: true
|
||||||
MESSAGE_UP: true
|
MESSAGE_UP: true
|
||||||
CONTACTS: true
|
CONTACTS: true
|
||||||
CHATS: true
|
CHATS: true
|
||||||
|
|
||||||
# Permanent data storage
|
# Permanent data storage
|
||||||
DATABASE:
|
DATABASE:
|
||||||
ENABLED: true
|
ENABLED: true
|
||||||
CONNECTION:
|
CONNECTION:
|
||||||
URI: "mongodb://root:root@localhost:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true"
|
URI: "mongodb://root:root@localhost:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true"
|
||||||
|
|
||||||
DB_PREFIX_NAME: whatsapp
|
DB_PREFIX_NAME: whatsapp
|
||||||
DB_PREFIX_FINAL_NAME: "-api"
|
DB_PREFIX_FINAL_NAME: "-api"
|
||||||
DB_PREFIX_FINAL_NAME_VENOM: "-venom"
|
DB_PREFIX_FINAL_NAME_VENOM: "-venom"
|
||||||
# Choose the data you want to save in the application's database or store
|
# Choose the data you want to save in the application's database or store
|
||||||
SAVE_DATA:
|
SAVE_DATA:
|
||||||
INSTANCE: true
|
INSTANCE: true
|
||||||
NEW_MESSAGE: false
|
NEW_MESSAGE: false
|
||||||
MESSAGE_UPDATE: false
|
MESSAGE_UPDATE: false
|
||||||
CONTACTS: true
|
CONTACTS: true
|
||||||
CHATS: true
|
CHATS: true
|
||||||
|
|
||||||
REDIS:
|
REDIS:
|
||||||
ENABLED: false
|
ENABLED: false
|
||||||
URI: "redis://localhost:6379"
|
URI: "redis://localhost:6379"
|
||||||
PREFIX_KEY: "evolution"
|
PREFIX_KEY: "evolution"
|
||||||
|
|
||||||
RABBITMQ:
|
RABBITMQ:
|
||||||
ENABLED: false
|
ENABLED: false
|
||||||
URI: "amqp://guest:guest@localhost:5672"
|
URI: "amqp://guest:guest@localhost:5672"
|
||||||
|
|
||||||
OPENAI:
|
OPENAI:
|
||||||
CHAVE: ""
|
CHAVE: ""
|
||||||
ENABLED: false
|
ENABLED: false
|
||||||
PROMPTS: false
|
PROMPTS: false
|
||||||
URI: ""
|
URI: ""
|
||||||
|
|
||||||
SQS:
|
SQS:
|
||||||
ENABLED: false
|
ENABLED: false
|
||||||
ACCESS_KEY_ID: ""
|
ACCESS_KEY_ID: ""
|
||||||
SECRET_ACCESS_KEY: ""
|
SECRET_ACCESS_KEY: ""
|
||||||
ACCOUNT_ID: ""
|
ACCOUNT_ID: ""
|
||||||
REGION: "us-east-1"
|
REGION: "us-east-1"
|
||||||
|
|
||||||
WEBSOCKET:
|
WEBSOCKET:
|
||||||
ENABLED: false
|
ENABLED: false
|
||||||
|
|
||||||
TYPEBOT:
|
TYPEBOT:
|
||||||
API_VERSION: 'v1' # v1 | v2
|
API_VERSION: 'v1' # v1 | v2
|
||||||
|
|
||||||
# Global Webhook Settings
|
# Global Webhook Settings
|
||||||
# Each instance's Webhook URL and events will be requested at the time it is created
|
# Each instance's Webhook URL and events will be requested at the time it is created
|
||||||
WEBHOOK:
|
WEBHOOK:
|
||||||
# Define a global webhook that will listen for enabled events from all instances
|
# Define a global webhook that will listen for enabled events from all instances
|
||||||
GLOBAL:
|
GLOBAL:
|
||||||
URL: ""
|
URL: ""
|
||||||
ENABLED: false
|
ENABLED: false
|
||||||
# With this option activated, you work with a url per webhook event, respecting the global url and the name of each event
|
# With this option activated, you work with a url per webhook event, respecting the global url and the name of each event
|
||||||
WEBHOOK_BY_EVENTS: false
|
WEBHOOK_BY_EVENTS: false
|
||||||
# Automatically maps webhook paths
|
# Automatically maps webhook paths
|
||||||
# Set the events you want to hear
|
# Set the events you want to hear
|
||||||
EVENTS:
|
EVENTS:
|
||||||
APPLICATION_STARTUP: false
|
APPLICATION_STARTUP: false
|
||||||
QRCODE_UPDATED: true
|
QRCODE_UPDATED: true
|
||||||
MESSAGES_SET: true
|
MESSAGES_SET: true
|
||||||
MESSAGES_UPSERT: true
|
MESSAGES_UPSERT: true
|
||||||
MESSAGES_UPDATE: true
|
MESSAGES_UPDATE: true
|
||||||
MESSAGES_DELETE: true
|
MESSAGES_DELETE: true
|
||||||
SEND_MESSAGE: true
|
SEND_MESSAGE: true
|
||||||
CONTACTS_SET: true
|
CONTACTS_SET: true
|
||||||
CONTACTS_UPSERT: true
|
CONTACTS_UPSERT: true
|
||||||
CONTACTS_UPDATE: true
|
CONTACTS_UPDATE: true
|
||||||
PRESENCE_UPDATE: true
|
PRESENCE_UPDATE: true
|
||||||
CHATS_SET: true
|
CHATS_SET: true
|
||||||
CHATS_UPSERT: true
|
CHATS_UPSERT: true
|
||||||
CHATS_UPDATE: true
|
CHATS_UPDATE: true
|
||||||
CHATS_DELETE: true
|
CHATS_DELETE: true
|
||||||
GROUPS_UPSERT: true
|
GROUPS_UPSERT: true
|
||||||
GROUP_UPDATE: true
|
GROUP_UPDATE: true
|
||||||
GROUP_PARTICIPANTS_UPDATE: true
|
GROUP_PARTICIPANTS_UPDATE: true
|
||||||
CONNECTION_UPDATE: true
|
CONNECTION_UPDATE: true
|
||||||
CALL: true
|
CALL: true
|
||||||
# This event fires every time a new token is requested via the refresh route
|
# This event fires every time a new token is requested via the refresh route
|
||||||
NEW_JWT_TOKEN: false
|
NEW_JWT_TOKEN: false
|
||||||
# This events is used with Typebot
|
# This events is used with Typebot
|
||||||
TYPEBOT_START: false
|
TYPEBOT_START: false
|
||||||
TYPEBOT_CHANGE_STATUS: false
|
TYPEBOT_CHANGE_STATUS: false
|
||||||
# This event is used with Chama AI
|
# This event is used with Chama AI
|
||||||
CHAMA_AI_ACTION: false
|
CHAMA_AI_ACTION: false
|
||||||
# This event is used to send errors to the webhook
|
# This event is used to send errors to the webhook
|
||||||
ERRORS: false
|
ERRORS: false
|
||||||
ERRORS_WEBHOOK: ""
|
ERRORS_WEBHOOK: ""
|
||||||
|
|
||||||
CONFIG_SESSION_PHONE:
|
CONFIG_SESSION_PHONE:
|
||||||
# Name that will be displayed on smartphone connection
|
# Name that will be displayed on smartphone connection
|
||||||
CLIENT: "Evolution API"
|
CLIENT: "Chat API"
|
||||||
NAME: Chrome # Chrome | Firefox | Edge | Opera | Safari
|
NAME: Chrome # Chrome | Firefox | Edge | Opera | Safari
|
||||||
|
|
||||||
# Set qrcode display limit
|
# Set qrcode display limit
|
||||||
QRCODE:
|
QRCODE:
|
||||||
LIMIT: 30
|
LIMIT: 30
|
||||||
COLOR: "#198754"
|
COLOR: "#198754"
|
||||||
|
|
||||||
# Defines an authentication type for the api
|
# Defines an authentication type for the api
|
||||||
# We recommend using the apikey because it will allow you to use a custom token,
|
# We recommend using the apikey because it will allow you to use a custom token,
|
||||||
# if you use jwt, a random token will be generated and may be expired and you will have to generate a new token
|
# if you use jwt, a random token will be generated and may be expired and you will have to generate a new token
|
||||||
AUTHENTICATION:
|
AUTHENTICATION:
|
||||||
TYPE: apikey # jwt or apikey
|
TYPE: apikey # jwt or apikey
|
||||||
# Define a global apikey to access all instances
|
# Define a global apikey to access all instances
|
||||||
API_KEY:
|
API_KEY:
|
||||||
# OBS: This key must be inserted in the request header to create an instance.
|
# OBS: This key must be inserted in the request header to create an instance.
|
||||||
KEY: B6D711FCDE4D4FD5936544120E713976
|
KEY: B6D711FCDE4D4FD5936544120E713976
|
||||||
# Expose the api key on return from fetch instances
|
# Expose the api key on return from fetch instances
|
||||||
EXPOSE_IN_FETCH_INSTANCES: true
|
EXPOSE_IN_FETCH_INSTANCES: true
|
||||||
# Set the secret key to encrypt and decrypt your token and its expiration time.
|
# Set the secret key to encrypt and decrypt your token and its expiration time.
|
||||||
JWT:
|
JWT:
|
||||||
EXPIRIN_IN: 0 # seconds - 3600s === 1h | zero (0) - never expires
|
EXPIRIN_IN: 0 # seconds - 3600s === 1h | zero (0) - never expires
|
||||||
SECRET: L=0YWt]b2w[WF>#>:&E`
|
SECRET: L=0YWt]b2w[WF>#>:&E`
|
||||||
|
|
||||||
# Configure to chatwoot
|
# Configure to chatwoot
|
||||||
CHATWOOT:
|
CHATWOOT:
|
||||||
USE_REPLY_ID: false
|
USE_REPLY_ID: false
|
||||||
|
5194
src/docs/swagger.yaml
Executable file → Normal file
5194
src/docs/swagger.yaml
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
200
src/libs/amqp.server.ts
Executable file → Normal file
200
src/libs/amqp.server.ts
Executable file → Normal file
@ -1,100 +1,100 @@
|
|||||||
import * as amqp from 'amqplib/callback_api';
|
import * as amqp from 'amqplib/callback_api';
|
||||||
|
|
||||||
import { configService, Rabbitmq, Openai } from '../config/env.config';
|
import { configService, Rabbitmq, Openai } from '../config/env.config';
|
||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
|
|
||||||
const logger = new Logger('AMQP');
|
const logger = new Logger('AMQP');
|
||||||
|
|
||||||
let amqpChannel: amqp.Channel | null = null;
|
let amqpChannel: amqp.Channel | null = null;
|
||||||
|
|
||||||
export const initAMQP = () => {
|
export const initAMQP = () => {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
const uri = configService.get<Rabbitmq>('RABBITMQ').URI;
|
const uri = configService.get<Rabbitmq>('RABBITMQ').URI;
|
||||||
amqp.connect(uri, (error, connection) => {
|
amqp.connect(uri, (error, connection) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.createChannel((channelError, channel) => {
|
connection.createChannel((channelError, channel) => {
|
||||||
if (channelError) {
|
if (channelError) {
|
||||||
reject(channelError);
|
reject(channelError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const exchangeName = 'evolution_exchange';
|
const exchangeName = 'evolution_exchange';
|
||||||
|
|
||||||
channel.assertExchange(exchangeName, 'topic', {
|
channel.assertExchange(exchangeName, 'topic', {
|
||||||
durable: true,
|
durable: true,
|
||||||
autoDelete: false,
|
autoDelete: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
amqpChannel = channel;
|
amqpChannel = channel;
|
||||||
|
|
||||||
logger.info('AMQP initialized');
|
logger.info('AMQP initialized');
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAMQP = (): amqp.Channel | null => {
|
export const getAMQP = (): amqp.Channel | null => {
|
||||||
return amqpChannel;
|
return amqpChannel;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initQueues = (instanceName: string, events: string[]) => {
|
export const initQueues = (instanceName: string, events: string[]) => {
|
||||||
if (!events || !events.length) return;
|
if (!events || !events.length) return;
|
||||||
|
|
||||||
const queues = events.map((event) => {
|
const queues = events.map((event) => {
|
||||||
return `${event.replace(/_/g, '.').toLowerCase()}`;
|
return `${event.replace(/_/g, '.').toLowerCase()}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
queues.forEach((event) => {
|
queues.forEach((event) => {
|
||||||
const amqp = getAMQP();
|
const amqp = getAMQP();
|
||||||
const exchangeName = instanceName ?? 'evolution_exchange';
|
const exchangeName = instanceName ?? 'evolution_exchange';
|
||||||
|
|
||||||
amqp.assertExchange(exchangeName, 'topic', {
|
amqp.assertExchange(exchangeName, 'topic', {
|
||||||
durable: true,
|
durable: true,
|
||||||
autoDelete: false,
|
autoDelete: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const queueName = `${instanceName}.${event}`;
|
const queueName = `${instanceName}.${event}`;
|
||||||
|
|
||||||
amqp.assertQueue(queueName, {
|
amqp.assertQueue(queueName, {
|
||||||
durable: true,
|
durable: true,
|
||||||
autoDelete: false,
|
autoDelete: false,
|
||||||
arguments: {
|
arguments: {
|
||||||
'x-queue-type': 'quorum',
|
'x-queue-type': 'quorum',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
amqp.bindQueue(queueName, exchangeName, event);
|
amqp.bindQueue(queueName, exchangeName, event);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeQueues = (instanceName: string, events: string[]) => {
|
export const removeQueues = (instanceName: string, events: string[]) => {
|
||||||
if (!events || !events.length) return;
|
if (!events || !events.length) return;
|
||||||
|
|
||||||
const channel = getAMQP();
|
const channel = getAMQP();
|
||||||
|
|
||||||
const queues = events.map((event) => {
|
const queues = events.map((event) => {
|
||||||
return `${event.replace(/_/g, '.').toLowerCase()}`;
|
return `${event.replace(/_/g, '.').toLowerCase()}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const exchangeName = instanceName ?? 'evolution_exchange';
|
const exchangeName = instanceName ?? 'evolution_exchange';
|
||||||
|
|
||||||
queues.forEach((event) => {
|
queues.forEach((event) => {
|
||||||
const amqp = getAMQP();
|
const amqp = getAMQP();
|
||||||
|
|
||||||
amqp.assertExchange(exchangeName, 'topic', {
|
amqp.assertExchange(exchangeName, 'topic', {
|
||||||
durable: true,
|
durable: true,
|
||||||
autoDelete: false,
|
autoDelete: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const queueName = `${instanceName}.${event}`;
|
const queueName = `${instanceName}.${event}`;
|
||||||
|
|
||||||
amqp.deleteQueue(queueName);
|
amqp.deleteQueue(queueName);
|
||||||
});
|
});
|
||||||
|
|
||||||
channel.deleteExchange(exchangeName);
|
channel.deleteExchange(exchangeName);
|
||||||
};
|
};
|
||||||
|
52
src/libs/db.connect.ts
Executable file → Normal file
52
src/libs/db.connect.ts
Executable file → Normal file
@ -1,26 +1,26 @@
|
|||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
import { configService, Database } from '../config/env.config';
|
import { configService, Database } from '../config/env.config';
|
||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
|
|
||||||
const logger = new Logger('MongoDB');
|
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 + db.CONNECTION.DB_PREFIX_FINAL_NAME + '-config',
|
dbName: db.CONNECTION.DB_PREFIX_NAME + db.CONNECTION.DB_PREFIX_FINAL_NAME + '-config',
|
||||||
});
|
});
|
||||||
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;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
68
src/libs/openai.ts
Executable file → Normal file
68
src/libs/openai.ts
Executable file → Normal file
@ -1,34 +1,34 @@
|
|||||||
import { Configuration, OpenAIApi } from "openai"
|
import { Configuration, OpenAIApi } from "openai"
|
||||||
|
|
||||||
import { config } from "../config"
|
import { config } from "../config"
|
||||||
|
|
||||||
const configuration = new Configuration({
|
const configuration = new Configuration({
|
||||||
apiKey: config.openAI.apiToken,
|
apiKey: config.openAI.apiToken,
|
||||||
})
|
})
|
||||||
|
|
||||||
export const openai = new OpenAIApi(configuration)
|
export const openai = new OpenAIApi(configuration)
|
||||||
|
|
||||||
|
|
||||||
export class OpenAIService {
|
export class OpenAIService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly apikey: String,
|
private readonly apikey: String,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private WaOpenai: OpenAIApi;
|
private WaOpenai: OpenAIApi;
|
||||||
|
|
||||||
public SetOpenai() {
|
public SetOpenai() {
|
||||||
|
|
||||||
const configuration = new Configuration({
|
const configuration = new Configuration({
|
||||||
apiKey: config.openAI.apiToken,
|
apiKey: config.openAI.apiToken,
|
||||||
})
|
})
|
||||||
|
|
||||||
this.WaOpenai = new OpenAIApi(configuration)
|
this.WaOpenai = new OpenAIApi(configuration)
|
||||||
}
|
}
|
||||||
|
|
||||||
public openai() {
|
public openai() {
|
||||||
|
|
||||||
return this.WaOpenai;
|
return this.WaOpenai;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
264
src/libs/redis.client.ts
Executable file → Normal file
264
src/libs/redis.client.ts
Executable file → Normal file
@ -1,132 +1,132 @@
|
|||||||
import { createClient, RedisClientType } from '@redis/client';
|
import { createClient, RedisClientType } from '@redis/client';
|
||||||
import { BufferJSON } from '@whiskeysockets/baileys';
|
import { BufferJSON } from '@whiskeysockets/baileys';
|
||||||
|
|
||||||
import { Redis } from '../config/env.config';
|
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('RedisCache instance created');
|
this.logger.verbose('RedisCache instance created');
|
||||||
process.on('beforeExit', () => {
|
process.on('beforeExit', () => {
|
||||||
this.logger.verbose('RedisCache instance destroyed');
|
this.logger.verbose('RedisCache instance destroyed');
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 statusConnection = false;
|
||||||
private instanceName: string;
|
private instanceName: string;
|
||||||
private redisEnv: Redis;
|
private redisEnv: Redis;
|
||||||
|
|
||||||
public set reference(reference: string) {
|
public set reference(reference: string) {
|
||||||
this.logger.verbose('set reference: ' + reference);
|
this.logger.verbose('set reference: ' + reference);
|
||||||
this.instanceName = reference;
|
this.instanceName = reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async connect(redisEnv: Redis) {
|
public async connect(redisEnv: Redis) {
|
||||||
this.logger.verbose('Connecting to Redis...');
|
this.logger.verbose('Connecting to Redis...');
|
||||||
this.client = createClient({ url: redisEnv.URI });
|
this.client = createClient({ url: redisEnv.URI });
|
||||||
//this.logger.verbose('connected in ' + redisEnv.URI);
|
//this.logger.verbose('connected in ' + redisEnv.URI);
|
||||||
this.client.on('error', (err) => this.logger.error('Redis Client Error ' + err));
|
this.client.on('error', (err) => this.logger.error('Redis Client Error ' + err));
|
||||||
await this.client.connect();
|
await this.client.connect();
|
||||||
this.statusConnection = true;
|
this.statusConnection = true;
|
||||||
this.redisEnv = redisEnv;
|
this.redisEnv = redisEnv;
|
||||||
this.logger.verbose(`Connected to ${redisEnv.URI}`);
|
this.logger.verbose(`Connected to ${redisEnv.URI}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger(RedisCache.name);
|
private readonly logger = new Logger(RedisCache.name);
|
||||||
private client: RedisClientType;
|
private client: RedisClientType;
|
||||||
|
|
||||||
|
|
||||||
public async disconnect() {
|
public async disconnect() {
|
||||||
if (this.statusConnection) {
|
if (this.statusConnection) {
|
||||||
await this.client.disconnect();
|
await this.client.disconnect();
|
||||||
this.statusConnection = false;
|
this.statusConnection = false;
|
||||||
this.logger.verbose('Redis client disconnected');
|
this.logger.verbose('Redis client disconnected');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async instanceKeys(): Promise<string[]> {
|
public async instanceKeys(): Promise<string[]> {
|
||||||
const keys: string[] = [];
|
const keys: string[] = [];
|
||||||
try {
|
try {
|
||||||
//this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*');
|
//this.logger.verbose('instance keys: ' + this.redisEnv.PREFIX_KEY + ':*');
|
||||||
//return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']);
|
//return await this.client.sendCommand(['keys', this.redisEnv.PREFIX_KEY + ':*']);
|
||||||
this.logger.verbose('Fetching instance keys');
|
this.logger.verbose('Fetching instance keys');
|
||||||
for await (const key of this.client.scanIterator({ MATCH: `${this.redisEnv.PREFIX_KEY}:*` })) {
|
for await (const key of this.client.scanIterator({ MATCH: `${this.redisEnv.PREFIX_KEY}:*` })) {
|
||||||
keys.push(key);
|
keys.push(key);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
this.logger.error('Error fetching instance keys ' + error);
|
this.logger.error('Error fetching instance keys ' + error);
|
||||||
}
|
}
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async keyExists(key?: string) {
|
public async keyExists(key?: string) {
|
||||||
if (key) {
|
if (key) {
|
||||||
this.logger.verbose('keyExists: ' + key);
|
this.logger.verbose('keyExists: ' + key);
|
||||||
return !!(await this.instanceKeys()).find((i) => i === key);
|
return !!(await this.instanceKeys()).find((i) => i === key);
|
||||||
}
|
}
|
||||||
this.logger.verbose('keyExists: ' + this.instanceName);
|
this.logger.verbose('keyExists: ' + this.instanceName);
|
||||||
return !!(await this.instanceKeys()).find((i) => i === this.instanceName);
|
return !!(await this.instanceKeys()).find((i) => i === this.instanceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async writeData(field: string, data: any) {
|
public async writeData(field: string, data: any) {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('writeData: ' + field);
|
this.logger.verbose('writeData: ' + field);
|
||||||
const json = JSON.stringify(data, BufferJSON.replacer);
|
const json = JSON.stringify(data, BufferJSON.replacer);
|
||||||
|
|
||||||
return await this.client.hSet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, json);
|
return await this.client.hSet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field, json);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async readData(field: string) {
|
public async readData(field: string) {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('readData: ' + field);
|
this.logger.verbose('readData: ' + field);
|
||||||
const data = await this.client.hGet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field);
|
const data = await this.client.hGet(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
this.logger.verbose('readData: ' + field + ' success');
|
this.logger.verbose('readData: ' + field + ' success');
|
||||||
return JSON.parse(data, BufferJSON.reviver);
|
return JSON.parse(data, BufferJSON.reviver);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('readData: ' + field + ' not found');
|
this.logger.verbose('readData: ' + field + ' not found');
|
||||||
return null;
|
return null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async removeData(field: string) {
|
public async removeData(field: string) {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('removeData: ' + field);
|
this.logger.verbose('removeData: ' + field);
|
||||||
return await this.client.hDel(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field);
|
return await this.client.hDel(this.redisEnv.PREFIX_KEY + ':' + this.instanceName, field);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async delAll(hash?: string) {
|
public async delAll(hash?: string) {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('instance delAll: ' + hash);
|
this.logger.verbose('instance delAll: ' + hash);
|
||||||
const result = await this.client.del(hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName);
|
const result = await this.client.del(hash || this.redisEnv.PREFIX_KEY + ':' + this.instanceName);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
src/libs/redis.ts
Executable file → Normal file
18
src/libs/redis.ts
Executable file → Normal file
@ -1,9 +1,9 @@
|
|||||||
import { Redis } from "ioredis"
|
import { Redis } from "ioredis"
|
||||||
|
|
||||||
import { config } from "../config"
|
import { config } from "../config"
|
||||||
|
|
||||||
export const redis = new Redis({
|
export const redis = new Redis({
|
||||||
host: config.redis.host,
|
host: config.redis.host,
|
||||||
port: config.redis.port,
|
port: config.redis.port,
|
||||||
db: config.redis.db,
|
db: config.redis.db,
|
||||||
})
|
})
|
||||||
|
192
src/libs/sqs.server.ts
Executable file → Normal file
192
src/libs/sqs.server.ts
Executable file → Normal file
@ -1,97 +1,97 @@
|
|||||||
import { SQS } from 'aws-sdk';
|
import { SQS } from 'aws-sdk';
|
||||||
|
|
||||||
import { configService, Sqs } from '../config/env.config';
|
import { configService, Sqs } from '../config/env.config';
|
||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
|
|
||||||
const logger = new Logger('SQS');
|
const logger = new Logger('SQS');
|
||||||
|
|
||||||
let sqs: SQS;
|
let sqs: SQS;
|
||||||
|
|
||||||
export const initSQS = () => {
|
export const initSQS = () => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
const awsConfig = configService.get<Sqs>('SQS');
|
const awsConfig = configService.get<Sqs>('SQS');
|
||||||
sqs = new SQS({
|
sqs = new SQS({
|
||||||
accessKeyId: awsConfig.ACCESS_KEY_ID,
|
accessKeyId: awsConfig.ACCESS_KEY_ID,
|
||||||
secretAccessKey: awsConfig.SECRET_ACCESS_KEY,
|
secretAccessKey: awsConfig.SECRET_ACCESS_KEY,
|
||||||
region: awsConfig.REGION,
|
region: awsConfig.REGION,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.info('SQS initialized');
|
logger.info('SQS initialized');
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSQS = (): SQS => {
|
export const getSQS = (): SQS => {
|
||||||
return sqs;
|
return sqs;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initQueues = (instanceName: string, events: string[]) => {
|
export const initQueues = (instanceName: string, events: string[]) => {
|
||||||
if (!events || !events.length) return;
|
if (!events || !events.length) return;
|
||||||
|
|
||||||
const queues = events.map((event) => {
|
const queues = events.map((event) => {
|
||||||
return `${event.replace(/_/g, '_').toLowerCase()}`;
|
return `${event.replace(/_/g, '_').toLowerCase()}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
const sqs = getSQS();
|
const sqs = getSQS();
|
||||||
|
|
||||||
queues.forEach((event) => {
|
queues.forEach((event) => {
|
||||||
const queueName = `${instanceName}_${event}.fifo`;
|
const queueName = `${instanceName}_${event}.fifo`;
|
||||||
|
|
||||||
sqs.createQueue(
|
sqs.createQueue(
|
||||||
{
|
{
|
||||||
QueueName: queueName,
|
QueueName: queueName,
|
||||||
Attributes: {
|
Attributes: {
|
||||||
FifoQueue: 'true',
|
FifoQueue: 'true',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
(err, data) => {
|
(err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(`Error creating queue ${queueName}: ${err.message}`);
|
logger.error(`Error creating queue ${queueName}: ${err.message}`);
|
||||||
} else {
|
} else {
|
||||||
logger.info(`Queue ${queueName} created: ${data.QueueUrl}`);
|
logger.info(`Queue ${queueName} created: ${data.QueueUrl}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeQueues = (instanceName: string, events: string[]) => {
|
export const removeQueues = (instanceName: string, events: string[]) => {
|
||||||
if (!events || !events.length) return;
|
if (!events || !events.length) return;
|
||||||
|
|
||||||
const sqs = getSQS();
|
const sqs = getSQS();
|
||||||
|
|
||||||
const queues = events.map((event) => {
|
const queues = events.map((event) => {
|
||||||
return `${event.replace(/_/g, '_').toLowerCase()}`;
|
return `${event.replace(/_/g, '_').toLowerCase()}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
queues.forEach((event) => {
|
queues.forEach((event) => {
|
||||||
const queueName = `${instanceName}_${event}.fifo`;
|
const queueName = `${instanceName}_${event}.fifo`;
|
||||||
|
|
||||||
sqs.getQueueUrl(
|
sqs.getQueueUrl(
|
||||||
{
|
{
|
||||||
QueueName: queueName,
|
QueueName: queueName,
|
||||||
},
|
},
|
||||||
(err, data) => {
|
(err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(`Error getting queue URL for ${queueName}: ${err.message}`);
|
logger.error(`Error getting queue URL for ${queueName}: ${err.message}`);
|
||||||
} else {
|
} else {
|
||||||
const queueUrl = data.QueueUrl;
|
const queueUrl = data.QueueUrl;
|
||||||
|
|
||||||
sqs.deleteQueue(
|
sqs.deleteQueue(
|
||||||
{
|
{
|
||||||
QueueUrl: queueUrl,
|
QueueUrl: queueUrl,
|
||||||
},
|
},
|
||||||
(deleteErr) => {
|
(deleteErr) => {
|
||||||
if (deleteErr) {
|
if (deleteErr) {
|
||||||
logger.error(`Error deleting queue ${queueName}: ${deleteErr.message}`);
|
logger.error(`Error deleting queue ${queueName}: ${deleteErr.message}`);
|
||||||
} else {
|
} else {
|
||||||
logger.info(`Queue ${queueName} deleted`);
|
logger.info(`Queue ${queueName} deleted`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
274
src/main.ts
Executable file → Normal file
274
src/main.ts
Executable file → Normal file
@ -1,137 +1,137 @@
|
|||||||
import 'express-async-errors';
|
import 'express-async-errors';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import compression from 'compression';
|
import compression from 'compression';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import express, { json, NextFunction, Request, Response, urlencoded } from 'express';
|
import express, { json, NextFunction, Request, Response, urlencoded } from 'express';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { Auth, configService, Cors, HttpServer, Rabbitmq, Sqs, Webhook } from './config/env.config';
|
import { Auth, configService, Cors, HttpServer, Rabbitmq, Sqs, Webhook } from './config/env.config';
|
||||||
import { onUnexpectedError } from './config/error.config';
|
import { onUnexpectedError } from './config/error.config';
|
||||||
import { Logger } from './config/logger.config';
|
import { Logger } from './config/logger.config';
|
||||||
import { ROOT_DIR } from './config/path.config';
|
import { ROOT_DIR } from './config/path.config';
|
||||||
import { swaggerRouter } from './docs/swagger.conf';
|
import { swaggerRouter } from './docs/swagger.conf';
|
||||||
import { initAMQP } from './libs/amqp.server';
|
import { initAMQP } from './libs/amqp.server';
|
||||||
import { initIO } from './libs/socket.server';
|
import { initIO } from './libs/socket.server';
|
||||||
import { initSQS } from './libs/sqs.server';
|
import { initSQS } from './libs/sqs.server';
|
||||||
import { ServerUP } from './utils/server-up';
|
import { ServerUP } from './utils/server-up';
|
||||||
import { HttpStatus, router } from './whatsapp/routers/index.router';
|
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();
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
cors({
|
cors({
|
||||||
origin(requestOrigin, callback) {
|
origin(requestOrigin, callback) {
|
||||||
const { ORIGIN } = configService.get<Cors>('CORS');
|
const { ORIGIN } = configService.get<Cors>('CORS');
|
||||||
if (ORIGIN.includes('*')) {
|
if (ORIGIN.includes('*')) {
|
||||||
return callback(null, true);
|
return callback(null, true);
|
||||||
}
|
}
|
||||||
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('/store', express.static(join(ROOT_DIR, 'store')));
|
app.use('/store', express.static(join(ROOT_DIR, 'store')));
|
||||||
|
|
||||||
app.use('/', router);
|
app.use('/', router);
|
||||||
app.use(swaggerRouter);
|
app.use(swaggerRouter);
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
(err: Error, req: Request, res: Response, next: NextFunction) => {
|
(err: Error, req: Request, res: Response, next: NextFunction) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
const webhook = configService.get<Webhook>('WEBHOOK');
|
const webhook = configService.get<Webhook>('WEBHOOK');
|
||||||
|
|
||||||
if (webhook.EVENTS.ERRORS_WEBHOOK && webhook.EVENTS.ERRORS_WEBHOOK != '' && webhook.EVENTS.ERRORS) {
|
if (webhook.EVENTS.ERRORS_WEBHOOK && webhook.EVENTS.ERRORS_WEBHOOK != '' && webhook.EVENTS.ERRORS) {
|
||||||
const tzoffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds
|
const tzoffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds
|
||||||
const localISOTime = new Date(Date.now() - tzoffset).toISOString();
|
const localISOTime = new Date(Date.now() - tzoffset).toISOString();
|
||||||
const now = localISOTime;
|
const now = localISOTime;
|
||||||
const globalApiKey = configService.get<Auth>('AUTHENTICATION').API_KEY.KEY;
|
const globalApiKey = configService.get<Auth>('AUTHENTICATION').API_KEY.KEY;
|
||||||
const serverUrl = configService.get<HttpServer>('SERVER').URL;
|
const serverUrl = configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
const errorData = {
|
const errorData = {
|
||||||
event: 'error',
|
event: 'error',
|
||||||
data: {
|
data: {
|
||||||
error: err['error'] || 'Internal Server Error',
|
error: err['error'] || 'Internal Server Error',
|
||||||
message: err['message'] || 'Internal Server Error',
|
message: err['message'] || 'Internal Server Error',
|
||||||
status: err['status'] || 500,
|
status: err['status'] || 500,
|
||||||
response: {
|
response: {
|
||||||
message: err['message'] || 'Internal Server Error',
|
message: err['message'] || 'Internal Server Error',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
date_time: now,
|
date_time: now,
|
||||||
api_key: globalApiKey,
|
api_key: globalApiKey,
|
||||||
server_url: serverUrl,
|
server_url: serverUrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
logger.error(errorData);
|
logger.error(errorData);
|
||||||
|
|
||||||
const baseURL = webhook.EVENTS.ERRORS_WEBHOOK;
|
const baseURL = webhook.EVENTS.ERRORS_WEBHOOK;
|
||||||
const httpService = axios.create({ baseURL });
|
const httpService = axios.create({ baseURL });
|
||||||
|
|
||||||
httpService.post('', errorData);
|
httpService.post('', errorData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(err['status'] || 500).json({
|
return res.status(err['status'] || 500).json({
|
||||||
status: err['status'] || 500,
|
status: err['status'] || 500,
|
||||||
error: err['error'] || 'Internal Server Error',
|
error: err['error'] || 'Internal Server Error',
|
||||||
response: {
|
response: {
|
||||||
message: err['message'] || 'Internal Server Error',
|
message: err['message'] || 'Internal Server Error',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
(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,
|
||||||
error: 'Not Found',
|
error: 'Not Found',
|
||||||
response: {
|
response: {
|
||||||
message: [`Cannot ${method.toUpperCase()} ${url}`],
|
message: [`Cannot ${method.toUpperCase()} ${url}`],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
initIO(server);
|
initIO(server);
|
||||||
|
|
||||||
if (configService.get<Rabbitmq>('RABBITMQ')?.ENABLED) initAMQP();
|
if (configService.get<Rabbitmq>('RABBITMQ')?.ENABLED) initAMQP();
|
||||||
|
|
||||||
if (configService.get<Sqs>('SQS')?.ENABLED) initSQS();
|
if (configService.get<Sqs>('SQS')?.ENABLED) initSQS();
|
||||||
|
|
||||||
onUnexpectedError();
|
onUnexpectedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap();
|
bootstrap();
|
||||||
|
98
src/prompts/contabilAgent.ts
Executable file → Normal file
98
src/prompts/contabilAgent.ts
Executable file → Normal file
@ -1,49 +1,49 @@
|
|||||||
export const promptContabil = `Você é uma assistente virtual de atendimento de um escritorio de contabilidade chamado {{ storeName }}. Você deve ser educada, atenciosa, amigável, cordial e muito paciente.
|
export const promptContabil = `Você é uma assistente virtual de atendimento de um escritorio de contabilidade chamado {{ storeName }}. Você deve ser educada, atenciosa, amigável, cordial e muito paciente.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
O roteiro de atendimento é:
|
O roteiro de atendimento é:
|
||||||
|
|
||||||
1. Saudação inicial: Cumprimente o cliente e agradeça por entrar em contato.
|
1. Saudação inicial: Cumprimente o cliente e agradeça por entrar em contato.
|
||||||
2. Coleta de informações: Solicite ao cliente seu nome para registro caso ainda não tenha registrado. Informe que os dados são apenas para controle de atendimento e não serão compartilhados com terceiros.
|
2. Coleta de informações: Solicite ao cliente seu nome para registro caso ainda não tenha registrado. Informe que os dados são apenas para controle de atendimento e não serão compartilhados com terceiros.
|
||||||
3. Pergunte o setor que deseja seguir, sendo o seguinte Financeiro, suporte ou novo cliente.
|
3. Pergunte o setor que deseja seguir, sendo o seguinte Financeiro, suporte ou novo cliente.
|
||||||
|
|
||||||
4. Serviços de Contabilidade:
|
4. Serviços de Contabilidade:
|
||||||
4.1 Apresente os principais serviços de contabilidade oferecidos pelo escritório.
|
4.1 Apresente os principais serviços de contabilidade oferecidos pelo escritório.
|
||||||
4.2 Oferecemos uma ampla gama de serviços contábeis, incluindo ABERTURA DE EMPRESA, ABERTURA DE FILIAL, ASSESSORIA CONTÁBIL, ASSESSORIA FISCAL, BAIXA E REGULARIZAÇÃO DE EMPRESAS, CONSULTORIA CONTÁBIL, PLANEJAMENTO TRIBUTÁRIO, RECURSOS HUMANOS, REVISÃO TRIBUTÁRIA, Administração de Condomínios. Como posso ajudá-lo com seus desafios financeiros hoje?
|
4.2 Oferecemos uma ampla gama de serviços contábeis, incluindo ABERTURA DE EMPRESA, ABERTURA DE FILIAL, ASSESSORIA CONTÁBIL, ASSESSORIA FISCAL, BAIXA E REGULARIZAÇÃO DE EMPRESAS, CONSULTORIA CONTÁBIL, PLANEJAMENTO TRIBUTÁRIO, RECURSOS HUMANOS, REVISÃO TRIBUTÁRIA, Administração de Condomínios. Como posso ajudá-lo com seus desafios financeiros hoje?
|
||||||
5. Perguntas Frequentes (FAQ):
|
5. Perguntas Frequentes (FAQ):
|
||||||
5.1 Forneça respostas para perguntas frequentes sobre impostos, contabilidade e serviços específicos.
|
5.1 Forneça respostas para perguntas frequentes sobre impostos, contabilidade e serviços específicos.
|
||||||
5.2 Aqui estão algumas perguntas frequentes sobre nossos serviços: [
|
5.2 Aqui estão algumas perguntas frequentes sobre nossos serviços: [
|
||||||
Pergunta 1: Vou precisar falar com meu antigo contador ou escritório de contabilidade sobre a migração?
|
Pergunta 1: Vou precisar falar com meu antigo contador ou escritório de contabilidade sobre a migração?
|
||||||
Resposta 1: Não. Fique tranquilo pois a Anexo Gestão Contábil cuida disso para você. Você só precisará enviar o seu Certificado Digital. Caso não tenha um e-CNPJ(A1), vamos te ajudar no processo de migração de outra forma, falando com o contador ou auxiliando na contratação de um Certificado Digital. Depois dessa etapa nós vamos fazer todo o seu processo com o seu antigo contador ou escritório de contabilidade. É simples, transparente e sem burocracia para você.
|
Resposta 1: Não. Fique tranquilo pois a Anexo Gestão Contábil cuida disso para você. Você só precisará enviar o seu Certificado Digital. Caso não tenha um e-CNPJ(A1), vamos te ajudar no processo de migração de outra forma, falando com o contador ou auxiliando na contratação de um Certificado Digital. Depois dessa etapa nós vamos fazer todo o seu processo com o seu antigo contador ou escritório de contabilidade. É simples, transparente e sem burocracia para você.
|
||||||
|
|
||||||
Pergunta 2: Quanto tempo demora para mudar para a Anexo Gestão Contábil?
|
Pergunta 2: Quanto tempo demora para mudar para a Anexo Gestão Contábil?
|
||||||
Resposta 2: O processo é rápido, prático e você não precisa sair de casa. Aproximadamente 5 dias úteis é o prazo após conseguirmos acessar a documentação via Certificado Digital ou com o contador antigo.
|
Resposta 2: O processo é rápido, prático e você não precisa sair de casa. Aproximadamente 5 dias úteis é o prazo após conseguirmos acessar a documentação via Certificado Digital ou com o contador antigo.
|
||||||
].
|
].
|
||||||
|
|
||||||
5. Agendamento de Consulta:
|
5. Agendamento de Consulta:
|
||||||
5.2 Permita que os usuários agendem uma consulta com um contador.
|
5.2 Permita que os usuários agendem uma consulta com um contador.
|
||||||
5.3 Pergunte sobre a data e hora preferidas.
|
5.3 Pergunte sobre a data e hora preferidas.
|
||||||
5.3 Se você gostaria de agendar uma consulta com um de nossos contadores, por favor, informe-nos sobre a data e horário que funcionam melhor para você.
|
5.3 Se você gostaria de agendar uma consulta com um de nossos contadores, por favor, informe-nos sobre a data e horário que funcionam melhor para você.
|
||||||
|
|
||||||
6. Impostos:
|
6. Impostos:
|
||||||
6.1 Forneça informações sobre prazos de declaração de impostos, documentos necessários e dicas fiscais.
|
6.1 Forneça informações sobre prazos de declaração de impostos, documentos necessários e dicas fiscais.
|
||||||
6.2 Os prazos para a declaração de impostos estão se aproximando. Aqui estão algumas dicas sobre como se preparar e os documentos necessários.
|
6.2 Os prazos para a declaração de impostos estão se aproximando. Aqui estão algumas dicas sobre como se preparar e os documentos necessários.
|
||||||
|
|
||||||
7. Contato e Localização:
|
7. Contato e Localização:
|
||||||
7.1 Fornecer informações de contato, incluindo número de telefone, endereço de e-mail e endereço físico do escritório.
|
7.1 Fornecer informações de contato, incluindo número de telefone, endereço de e-mail e endereço físico do escritório.
|
||||||
7.2 Você pode nos contatar pelo telefone [número], enviar um e-mail para [e-mail] ou nos visitar no seguinte endereço [endereço].
|
7.2 Você pode nos contatar pelo telefone [número], enviar um e-mail para [e-mail] ou nos visitar no seguinte endereço [endereço].
|
||||||
|
|
||||||
8. Encaminhamento para um Contador:
|
8. Encaminhamento para um Contador:
|
||||||
8.1 Se o chatbot não puder responder a uma pergunta específica, ofereça a opção de ser encaminhado para um contador real.
|
8.1 Se o chatbot não puder responder a uma pergunta específica, ofereça a opção de ser encaminhado para um contador real.
|
||||||
8.2 Se você tiver uma pergunta mais complexa que eu não possa responder, gostaria de ser encaminhado para um dos nossos contadores?"
|
8.2 Se você tiver uma pergunta mais complexa que eu não possa responder, gostaria de ser encaminhado para um dos nossos contadores?"
|
||||||
|
|
||||||
9. Despedida:
|
9. Despedida:
|
||||||
9.1 Encerre a conversa de maneira cortês e ofereça informações de contato adicionais.
|
9.1 Encerre a conversa de maneira cortês e ofereça informações de contato adicionais.
|
||||||
9.2 Obrigado por usar nossos serviços! Se precisar de assistência futura, estamos à disposição. Tenha um ótimo dia!"
|
9.2 Obrigado por usar nossos serviços! Se precisar de assistência futura, estamos à disposição. Tenha um ótimo dia!"
|
||||||
|
|
||||||
10. Feedback:
|
10. Feedback:
|
||||||
10.1 Solicite feedback aos usuários para melhorar o desempenho do chatbot.
|
10.1 Solicite feedback aos usuários para melhorar o desempenho do chatbot.
|
||||||
10.2 Gostaríamos de ouvir sua opinião! Em uma escala de 1 a 5, quão útil você achou nosso chatbot hoje?
|
10.2 Gostaríamos de ouvir sua opinião! Em uma escala de 1 a 5, quão útil você achou nosso chatbot hoje?
|
||||||
|
|
||||||
`
|
`
|
||||||
|
188
src/prompts/pizzaAgent.ts
Executable file → Normal file
188
src/prompts/pizzaAgent.ts
Executable file → Normal file
@ -1,94 +1,94 @@
|
|||||||
export const promptPizza = `Você é uma assistente virtual de atendimento de uma pizzaria chamada {{ storeName }}. Você deve ser educada, atenciosa, amigável, cordial e muito paciente.
|
export const promptPizza = `Você é uma assistente virtual de atendimento de uma pizzaria chamada {{ storeName }}. Você deve ser educada, atenciosa, amigável, cordial e muito paciente.
|
||||||
|
|
||||||
Você não pode oferecer nenhum item ou sabor que não esteja em nosso cardápio. Siga estritamente as listas de opções.
|
Você não pode oferecer nenhum item ou sabor que não esteja em nosso cardápio. Siga estritamente as listas de opções.
|
||||||
|
|
||||||
O código do pedido é: {{ orderCode }}
|
O código do pedido é: {{ orderCode }}
|
||||||
|
|
||||||
O roteiro de atendimento é:
|
O roteiro de atendimento é:
|
||||||
|
|
||||||
1. Saudação inicial: Cumprimente o cliente e agradeça por entrar em contato.
|
1. Saudação inicial: Cumprimente o cliente e agradeça por entrar em contato.
|
||||||
2. Coleta de informações: Solicite ao cliente seu nome para registro caso ainda não tenha registrado. Informe que os dados são apenas para controle de pedidos e não serão compartilhados com terceiros.
|
2. Coleta de informações: Solicite ao cliente seu nome para registro caso ainda não tenha registrado. Informe que os dados são apenas para controle de pedidos e não serão compartilhados com terceiros.
|
||||||
3. Quantidade de pizzas: Pergunte ao cliente quantas pizzas ele deseja pedir.
|
3. Quantidade de pizzas: Pergunte ao cliente quantas pizzas ele deseja pedir.
|
||||||
4. Sabores: Envie a lista resumida apenas com os nomes de sabores salgados e doces e pergunte ao cliente quais sabores de pizza ele deseja pedir.
|
4. Sabores: Envie a lista resumida apenas com os nomes de sabores salgados e doces e pergunte ao cliente quais sabores de pizza ele deseja pedir.
|
||||||
4.1 O cliente pode escolher a pizza fracionada em até 2 sabores na mesma pizza.
|
4.1 O cliente pode escolher a pizza fracionada em até 2 sabores na mesma pizza.
|
||||||
4.2 Se o cliente escolher mais de uma pizza, pergunte se ele deseja que os sabores sejam repetidos ou diferentes.
|
4.2 Se o cliente escolher mais de uma pizza, pergunte se ele deseja que os sabores sejam repetidos ou diferentes.
|
||||||
4.3 Se o cliente escolher sabores diferentes, pergunte quais são os sabores de cada pizza.
|
4.3 Se o cliente escolher sabores diferentes, pergunte quais são os sabores de cada pizza.
|
||||||
4.4 Se o cliente escolher sabores repetidos, pergunte quantas pizzas de cada sabor ele deseja.
|
4.4 Se o cliente escolher sabores repetidos, pergunte quantas pizzas de cada sabor ele deseja.
|
||||||
4.5 Se o cliente estiver indeciso, ofereça sugestões de sabores ou se deseja receber o cardápio completo.
|
4.5 Se o cliente estiver indeciso, ofereça sugestões de sabores ou se deseja receber o cardápio completo.
|
||||||
4.6 Se o sabor não estiver no cardápio, não deve prosseguir com o atendimento. Nesse caso informe que o sabor não está disponível e agradeça o cliente.
|
4.6 Se o sabor não estiver no cardápio, não deve prosseguir com o atendimento. Nesse caso informe que o sabor não está disponível e agradeça o cliente.
|
||||||
5. Tamanho: Pergunte ao cliente qual o tamanho das pizzas.
|
5. Tamanho: Pergunte ao cliente qual o tamanho das pizzas.
|
||||||
5.1 Se o cliente escolher mais de um tamanho, pergunte se ele deseja que os tamanhos sejam repetidos ou diferentes.
|
5.1 Se o cliente escolher mais de um tamanho, pergunte se ele deseja que os tamanhos sejam repetidos ou diferentes.
|
||||||
5.2 Se o cliente escolher tamanhos diferentes, pergunte qual o tamanho de cada pizza.
|
5.2 Se o cliente escolher tamanhos diferentes, pergunte qual o tamanho de cada pizza.
|
||||||
5.3 Se o cliente escolher tamanhos repetidos, pergunte quantas pizzas de cada tamanho ele deseja.
|
5.3 Se o cliente escolher tamanhos repetidos, pergunte quantas pizzas de cada tamanho ele deseja.
|
||||||
5.4 Se o cliente estiver indeciso, ofereça sugestões de tamanhos. Se for para 1 pessoa o tamanho pequeno é ideal, para 2 pessoas o tamanho médio é ideal e para 3 ou mais pessoas o tamanho grande é ideal.
|
5.4 Se o cliente estiver indeciso, ofereça sugestões de tamanhos. Se for para 1 pessoa o tamanho pequeno é ideal, para 2 pessoas o tamanho médio é ideal e para 3 ou mais pessoas o tamanho grande é ideal.
|
||||||
6. Ingredientes adicionais: Pergunte ao cliente se ele deseja adicionar algum ingrediente extra.
|
6. Ingredientes adicionais: Pergunte ao cliente se ele deseja adicionar algum ingrediente extra.
|
||||||
6.1 Se o cliente escolher ingredientes extras, pergunte quais são os ingredientes adicionais de cada pizza.
|
6.1 Se o cliente escolher ingredientes extras, pergunte quais são os ingredientes adicionais de cada pizza.
|
||||||
6.2 Se o cliente estiver indeciso, ofereça sugestões de ingredientes extras.
|
6.2 Se o cliente estiver indeciso, ofereça sugestões de ingredientes extras.
|
||||||
7. Remover ingredientes: Pergunte ao cliente se ele deseja remover algum ingrediente, por exemplo, cebola.
|
7. Remover ingredientes: Pergunte ao cliente se ele deseja remover algum ingrediente, por exemplo, cebola.
|
||||||
7.1 Se o cliente escolher ingredientes para remover, pergunte quais são os ingredientes que ele deseja remover de cada pizza.
|
7.1 Se o cliente escolher ingredientes para remover, pergunte quais são os ingredientes que ele deseja remover de cada pizza.
|
||||||
7.2 Não é possível remover ingredientes que não existam no cardápio.
|
7.2 Não é possível remover ingredientes que não existam no cardápio.
|
||||||
8. Borda: Pergunte ao cliente se ele deseja borda recheada.
|
8. Borda: Pergunte ao cliente se ele deseja borda recheada.
|
||||||
8.1 Se o cliente escolher borda recheada, pergunte qual o sabor da borda recheada.
|
8.1 Se o cliente escolher borda recheada, pergunte qual o sabor da borda recheada.
|
||||||
8.2 Se o cliente estiver indeciso, ofereça sugestões de sabores de borda recheada. Uma dica é oferecer a borda como sobremesa com sabor de chocolate.
|
8.2 Se o cliente estiver indeciso, ofereça sugestões de sabores de borda recheada. Uma dica é oferecer a borda como sobremesa com sabor de chocolate.
|
||||||
9. Bebidas: Pergunte ao cliente se ele deseja pedir alguma bebida.
|
9. Bebidas: Pergunte ao cliente se ele deseja pedir alguma bebida.
|
||||||
9.1 Se o cliente escolher bebidas, pergunte quais são as bebidas que ele deseja pedir.
|
9.1 Se o cliente escolher bebidas, pergunte quais são as bebidas que ele deseja pedir.
|
||||||
9.2 Se o cliente estiver indeciso, ofereça sugestões de bebidas.
|
9.2 Se o cliente estiver indeciso, ofereça sugestões de bebidas.
|
||||||
10. Entrega: Pergunte ao cliente se ele deseja receber o pedido em casa ou se prefere retirar no balcão.
|
10. Entrega: Pergunte ao cliente se ele deseja receber o pedido em casa ou se prefere retirar no balcão.
|
||||||
10.1 Se o cliente escolher entrega, pergunte qual o endereço de entrega. O endereço deverá conter Rua, Número, Bairro e CEP.
|
10.1 Se o cliente escolher entrega, pergunte qual o endereço de entrega. O endereço deverá conter Rua, Número, Bairro e CEP.
|
||||||
10.2 Os CEPs de 12.220-000 até 12.330-000 possuem uma taxa de entrega de R$ 10,00.
|
10.2 Os CEPs de 12.220-000 até 12.330-000 possuem uma taxa de entrega de R$ 10,00.
|
||||||
10.3 Se o cliente escolher retirar no balcão, informe o endereço da pizzaria e o horário de funcionamento: Rua Abaeté, 123, Centro, São José dos Campos, SP. Horário de funcionamento: 18h às 23h.
|
10.3 Se o cliente escolher retirar no balcão, informe o endereço da pizzaria e o horário de funcionamento: Rua Abaeté, 123, Centro, São José dos Campos, SP. Horário de funcionamento: 18h às 23h.
|
||||||
11. Forma de pagamento: Pergunte ao cliente qual a forma de pagamento desejada, oferecendo opções como dinheiro, PIX, cartão de crédito ou débito na entrega.
|
11. Forma de pagamento: Pergunte ao cliente qual a forma de pagamento desejada, oferecendo opções como dinheiro, PIX, cartão de crédito ou débito na entrega.
|
||||||
11.1 Se o cliente escolher dinheiro, pergunte o valor em mãos e calcule o troco. O valor informado não pode ser menor que o valor total do pedido.
|
11.1 Se o cliente escolher dinheiro, pergunte o valor em mãos e calcule o troco. O valor informado não pode ser menor que o valor total do pedido.
|
||||||
11.2 Se o cliente escolher PIX, forneça a chave PIX CNPJ: 1234
|
11.2 Se o cliente escolher PIX, forneça a chave PIX CNPJ: 1234
|
||||||
11.3 Se o cliente escolher cartão de crédito/débito, informe que a máquininha será levada pelo entregador.
|
11.3 Se o cliente escolher cartão de crédito/débito, informe que a máquininha será levada pelo entregador.
|
||||||
12. Mais alguma coisa? Pergunte ao cliente se ele deseja pedir mais alguma coisa.
|
12. Mais alguma coisa? Pergunte ao cliente se ele deseja pedir mais alguma coisa.
|
||||||
12.1 Se o cliente desejar pedir mais alguma coisa, pergunte o que ele deseja pedir.
|
12.1 Se o cliente desejar pedir mais alguma coisa, pergunte o que ele deseja pedir.
|
||||||
12.2 Se o cliente não desejar pedir mais nada, informe o resumo do pedido: Dados do cliente, quantidade de pizzas, sabores, tamanhos, ingredientes adicionais, ingredientes removidos, borda, bebidas, endereço de entrega, forma de pagamento e valor total.
|
12.2 Se o cliente não desejar pedir mais nada, informe o resumo do pedido: Dados do cliente, quantidade de pizzas, sabores, tamanhos, ingredientes adicionais, ingredientes removidos, borda, bebidas, endereço de entrega, forma de pagamento e valor total.
|
||||||
12.3 Confirmação do pedido: Pergunte ao cliente se o pedido está correto.
|
12.3 Confirmação do pedido: Pergunte ao cliente se o pedido está correto.
|
||||||
12.4 Se o cliente confirmar o pedido, informe o tempo de entrega médio de 45 minutos e agradeça.
|
12.4 Se o cliente confirmar o pedido, informe o tempo de entrega médio de 45 minutos e agradeça.
|
||||||
12.5 Se o cliente não confirmar o pedido, pergunte o que está errado e corrija o pedido.
|
12.5 Se o cliente não confirmar o pedido, pergunte o que está errado e corrija o pedido.
|
||||||
13. Despedida: Agradeça o cliente por entrar em contato. É muito importante que se despeça informando o número do pedido.
|
13. Despedida: Agradeça o cliente por entrar em contato. É muito importante que se despeça informando o número do pedido.
|
||||||
|
|
||||||
Cardápio de pizzas salgadas (os valores estão separados por tamanho - Broto, Médio e Grande):
|
Cardápio de pizzas salgadas (os valores estão separados por tamanho - Broto, Médio e Grande):
|
||||||
|
|
||||||
- Muzzarella: Queijo mussarela, tomate e orégano. R$ 25,00 / R$ 30,00 / R$ 35,00
|
- Muzzarella: Queijo mussarela, tomate e orégano. R$ 25,00 / R$ 30,00 / R$ 35,00
|
||||||
- Calabresa: Calabresa, cebola e orégano. R$ 30,00 / R$ 35,00 / R$ 40,00
|
- Calabresa: Calabresa, cebola e orégano. R$ 30,00 / R$ 35,00 / R$ 40,00
|
||||||
- Nordestina: Carne de sol, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Nordestina: Carne de sol, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
- Frango: Frango desfiado, milho e orégano. R$ 30,00 / R$ 35,00 / R$ 40,00
|
- Frango: Frango desfiado, milho e orégano. R$ 30,00 / R$ 35,00 / R$ 40,00
|
||||||
- Frango c/ Catupiry: Frango desfiado, catupiry e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Frango c/ Catupiry: Frango desfiado, catupiry e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
- A moda da Casa: Carne de sol, bacon, cebola e orégano. R$ 40,00 / R$ 45,00 / R$ 50,00
|
- A moda da Casa: Carne de sol, bacon, cebola e orégano. R$ 40,00 / R$ 45,00 / R$ 50,00
|
||||||
- Presunto: Presunto, queijo mussarela e orégano. R$ 30,00 / R$ 35,00 / R$ 40,00
|
- Presunto: Presunto, queijo mussarela e orégano. R$ 30,00 / R$ 35,00 / R$ 40,00
|
||||||
- Quatro Estações: Presunto, queijo mussarela, ervilha, milho, palmito e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Quatro Estações: Presunto, queijo mussarela, ervilha, milho, palmito e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
- Mista: Presunto, queijo mussarela, calabresa, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Mista: Presunto, queijo mussarela, calabresa, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
- Toscana: Calabresa, bacon, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Toscana: Calabresa, bacon, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
- Portuguesa: Presunto, queijo mussarela, calabresa, ovo, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Portuguesa: Presunto, queijo mussarela, calabresa, ovo, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
- Dois Queijos: Queijo mussarela, catupiry e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Dois Queijos: Queijo mussarela, catupiry e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
- Quatro Queijos: Queijo mussarela, provolone, catupiry, parmesão e orégano. R$ 40,00 / R$ 45,00 / R$ 50,00
|
- Quatro Queijos: Queijo mussarela, provolone, catupiry, parmesão e orégano. R$ 40,00 / R$ 45,00 / R$ 50,00
|
||||||
- Salame: Salame, queijo mussarela e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Salame: Salame, queijo mussarela e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
- Atum: Atum, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
- Atum: Atum, cebola e orégano. R$ 35,00 / R$ 40,00 / R$ 45,00
|
||||||
|
|
||||||
Cardápio de pizzas doces (os valores estão separados por tamanho - Broto, Médio e Grande):
|
Cardápio de pizzas doces (os valores estão separados por tamanho - Broto, Médio e Grande):
|
||||||
|
|
||||||
- Chocolate: Chocolate ao leite e granulado. R$ 30,00 / R$ 35,00 / R$ 40,00
|
- Chocolate: Chocolate ao leite e granulado. R$ 30,00 / R$ 35,00 / R$ 40,00
|
||||||
- Romeu e Julieta: Goiabada e queijo mussarela. R$ 30,00 / R$ 35,00 / R$ 40,00
|
- Romeu e Julieta: Goiabada e queijo mussarela. R$ 30,00 / R$ 35,00 / R$ 40,00
|
||||||
- California: Banana, canela e açúcar. R$ 30,00 / R$ 35,00 / R$ 40,00
|
- California: Banana, canela e açúcar. R$ 30,00 / R$ 35,00 / R$ 40,00
|
||||||
|
|
||||||
Extras/Adicionais (os valores estão separados por tamanho - Broto, Médio e Grande):
|
Extras/Adicionais (os valores estão separados por tamanho - Broto, Médio e Grande):
|
||||||
|
|
||||||
- Catupiry: R$ 5,00 / R$ 7,00 / R$ 9,00
|
- Catupiry: R$ 5,00 / R$ 7,00 / R$ 9,00
|
||||||
|
|
||||||
Bordas (os valores estão separados por tamanho - Broto, Médio e Grande):
|
Bordas (os valores estão separados por tamanho - Broto, Médio e Grande):
|
||||||
|
|
||||||
- Chocolate: R$ 5,00 / R$ 7,00 / R$ 9,00
|
- Chocolate: R$ 5,00 / R$ 7,00 / R$ 9,00
|
||||||
- Cheddar: R$ 5,00 / R$ 7,00 / R$ 9,00
|
- Cheddar: R$ 5,00 / R$ 7,00 / R$ 9,00
|
||||||
- Catupiry: R$ 5,00 / R$ 7,00 / R$ 9,00
|
- Catupiry: R$ 5,00 / R$ 7,00 / R$ 9,00
|
||||||
|
|
||||||
Bebidas:
|
Bebidas:
|
||||||
|
|
||||||
- Coca-Cola 2L: R$ 10,00
|
- Coca-Cola 2L: R$ 10,00
|
||||||
- Coca-Cola Lata: R$ 8,00
|
- Coca-Cola Lata: R$ 8,00
|
||||||
- Guaraná 2L: R$ 10,00
|
- Guaraná 2L: R$ 10,00
|
||||||
- Guaraná Lata: R$ 7,00
|
- Guaraná Lata: R$ 7,00
|
||||||
- Água com Gás 500 ml: R$ 5,00
|
- Água com Gás 500 ml: R$ 5,00
|
||||||
- Água sem Gás 500 ml: R$ 4,00
|
- Água sem Gás 500 ml: R$ 4,00
|
||||||
`
|
`
|
||||||
|
26
src/utils/initPrompt.ts
Executable file → Normal file
26
src/utils/initPrompt.ts
Executable file → Normal file
@ -1,13 +1,13 @@
|
|||||||
import { promptPizza } from "../prompts/pizzaAgent"
|
import { promptPizza } from "../prompts/pizzaAgent"
|
||||||
|
|
||||||
export function initPrompt(storeName: string, orderCode: string, prompt?: string ): string {
|
export function initPrompt(storeName: string, orderCode: string, prompt?: string ): string {
|
||||||
if(prompt){
|
if(prompt){
|
||||||
return prompt
|
return prompt
|
||||||
.replace(/{{[\s]?storeName[\s]?}}/g, storeName)
|
.replace(/{{[\s]?storeName[\s]?}}/g, storeName)
|
||||||
.replace(/{{[\s]?orderCode[\s]?}}/g, orderCode)
|
.replace(/{{[\s]?orderCode[\s]?}}/g, orderCode)
|
||||||
}else{
|
}else{
|
||||||
return promptPizza
|
return promptPizza
|
||||||
.replace(/{{[\s]?storeName[\s]?}}/g, storeName)
|
.replace(/{{[\s]?storeName[\s]?}}/g, storeName)
|
||||||
.replace(/{{[\s]?orderCode[\s]?}}/g, orderCode)
|
.replace(/{{[\s]?orderCode[\s]?}}/g, orderCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
224
src/utils/use-multi-file-auth-state-db.ts
Executable file → Normal file
224
src/utils/use-multi-file-auth-state-db.ts
Executable file → Normal file
@ -1,112 +1,112 @@
|
|||||||
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';
|
||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
import { dbserver } from '../libs/db.connect';
|
import { dbserver } from '../libs/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(
|
.db(
|
||||||
configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME +
|
configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME +
|
||||||
configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_FINAL_NAME
|
configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_FINAL_NAME
|
||||||
)
|
)
|
||||||
.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();
|
||||||
let msgParsed = JSON.parse(JSON.stringify(data, BufferJSON.replacer));
|
let msgParsed = JSON.parse(JSON.stringify(data, BufferJSON.replacer));
|
||||||
if (Array.isArray(msgParsed)) {
|
if (Array.isArray(msgParsed)) {
|
||||||
msgParsed = {
|
msgParsed = {
|
||||||
_id: key,
|
_id: key,
|
||||||
content_array: msgParsed,
|
content_array: msgParsed,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return await collection.replaceOne({ _id: key }, msgParsed, {
|
return await collection.replaceOne({ _id: key }, msgParsed, {
|
||||||
//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();
|
||||||
let data = (await collection.findOne({ _id: key })) as any;
|
let data = (await collection.findOne({ _id: key })) as any;
|
||||||
if (data?.content_array) {
|
if (data?.content_array) {
|
||||||
data = data.content_array;
|
data = data.content_array;
|
||||||
}
|
}
|
||||||
//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) => {
|
set: async (data: any) => {
|
||||||
const tasks: Promise<void>[] = [];
|
const tasks: Promise<void>[] = [];
|
||||||
for (const category in data) {
|
for (const category in data) {
|
||||||
for (const id in data[category]) {
|
for (const id in data[category]) {
|
||||||
const value = data[category][id];
|
const value = data[category][id];
|
||||||
const key = `${category}-${id}`;
|
const key = `${category}-${id}`;
|
||||||
tasks.push(value ? writeData(value, key) : removeData(key));
|
tasks.push(value ? writeData(value, key) : removeData(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(tasks);
|
await Promise.all(tasks);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
saveCreds: async () => {
|
saveCreds: async () => {
|
||||||
return writeData(creds, 'creds');
|
return await writeData(creds, 'creds');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
2280
src/validate/validate.schema.ts
Executable file → Normal file
2280
src/validate/validate.schema.ts
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1480
src/whatsapp/controllers/instance.controller.ts
Executable file → Normal file
1480
src/whatsapp/controllers/instance.controller.ts
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
170
src/whatsapp/controllers/openai.controller.ts
Executable file → Normal file
170
src/whatsapp/controllers/openai.controller.ts
Executable file → Normal file
@ -1,85 +1,85 @@
|
|||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { OpenaiDto } from '../dto/openai.dto';
|
import { OpenaiDto } from '../dto/openai.dto';
|
||||||
import { ContactOpenaiDto } from '../dto/contactopenai.dto';
|
import { ContactOpenaiDto } from '../dto/contactopenai.dto';
|
||||||
import { OpenaiService } from '../services/openai.service';
|
import { OpenaiService } from '../services/openai.service';
|
||||||
|
|
||||||
const logger = new Logger('OpenaiController');
|
const logger = new Logger('OpenaiController');
|
||||||
|
|
||||||
export class OpenaiController {
|
export class OpenaiController {
|
||||||
constructor(private readonly openaiService: OpenaiService) {}
|
constructor(private readonly openaiService: OpenaiService) {}
|
||||||
|
|
||||||
public async createOpenai(instance: InstanceDto, data: OpenaiDto) {
|
public async createOpenai(instance: InstanceDto, data: OpenaiDto) {
|
||||||
logger.verbose('requested createOpenai from ' + instance.instanceName + ' instance');
|
logger.verbose('requested createOpenai from ' + instance.instanceName + ' instance');
|
||||||
|
|
||||||
if (!data.chave) {
|
if (!data.chave) {
|
||||||
logger.verbose('openai sem chave');
|
logger.verbose('openai sem chave');
|
||||||
data.chave = '';
|
data.chave = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.enabled) {
|
if (!data.enabled) {
|
||||||
logger.verbose('openai disabled');
|
logger.verbose('openai disabled');
|
||||||
data.events = [];
|
data.events = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.events?.length === 0) {
|
if (data.events?.length === 0) {
|
||||||
logger.verbose('openai events empty');
|
logger.verbose('openai events empty');
|
||||||
data.events = [
|
data.events = [
|
||||||
'APPLICATION_STARTUP',
|
'APPLICATION_STARTUP',
|
||||||
'QRCODE_UPDATED',
|
'QRCODE_UPDATED',
|
||||||
'MESSAGES_SET',
|
'MESSAGES_SET',
|
||||||
'MESSAGES_UPSERT',
|
'MESSAGES_UPSERT',
|
||||||
'MESSAGES_UPDATE',
|
'MESSAGES_UPDATE',
|
||||||
'MESSAGES_DELETE',
|
'MESSAGES_DELETE',
|
||||||
'SEND_MESSAGE',
|
'SEND_MESSAGE',
|
||||||
'CONTACTS_SET',
|
'CONTACTS_SET',
|
||||||
'CONTACTS_UPSERT',
|
'CONTACTS_UPSERT',
|
||||||
'CONTACTS_UPDATE',
|
'CONTACTS_UPDATE',
|
||||||
'PRESENCE_UPDATE',
|
'PRESENCE_UPDATE',
|
||||||
'CHATS_SET',
|
'CHATS_SET',
|
||||||
'CHATS_UPSERT',
|
'CHATS_UPSERT',
|
||||||
'CHATS_UPDATE',
|
'CHATS_UPDATE',
|
||||||
'CHATS_DELETE',
|
'CHATS_DELETE',
|
||||||
'GROUPS_UPSERT',
|
'GROUPS_UPSERT',
|
||||||
'GROUP_UPDATE',
|
'GROUP_UPDATE',
|
||||||
'GROUP_PARTICIPANTS_UPDATE',
|
'GROUP_PARTICIPANTS_UPDATE',
|
||||||
'CONNECTION_UPDATE',
|
'CONNECTION_UPDATE',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
'NEW_JWT_TOKEN',
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
'CHAMA_AI_ACTION',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.openaiService.create(instance, data);
|
return this.openaiService.create(instance, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findOpenai(instance: InstanceDto) {
|
public async findOpenai(instance: InstanceDto) {
|
||||||
logger.verbose('requested findOpenai from ' + instance.instanceName + ' instance');
|
logger.verbose('requested findOpenai from ' + instance.instanceName + ' instance');
|
||||||
return this.openaiService.find(instance);
|
return this.openaiService.find(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createContactOpenai(instance: InstanceDto, data: ContactOpenaiDto) {
|
public async createContactOpenai(instance: InstanceDto, data: ContactOpenaiDto) {
|
||||||
logger.verbose('requested createOpenai from ' + instance.instanceName + ' instance');
|
logger.verbose('requested createOpenai from ' + instance.instanceName + ' instance');
|
||||||
|
|
||||||
if (!data.contact) {
|
if (!data.contact) {
|
||||||
logger.verbose('openai sem chave');
|
logger.verbose('openai sem chave');
|
||||||
data.contact = '';
|
data.contact = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.enabled) {
|
if (!data.enabled) {
|
||||||
logger.verbose('openai disabled');
|
logger.verbose('openai disabled');
|
||||||
data.enabled = false;
|
data.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.owner = instance.instanceName;
|
data.owner = instance.instanceName;
|
||||||
|
|
||||||
return this.openaiService.createContact(instance, data);
|
return this.openaiService.createContact(instance, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findContactOpenai(instance: InstanceDto) {
|
public async findContactOpenai(instance: InstanceDto) {
|
||||||
logger.verbose('requested findOpenai from ' + instance.instanceName + ' instance');
|
logger.verbose('requested findOpenai from ' + instance.instanceName + ' instance');
|
||||||
return this.openaiService.findContact(instance);
|
return this.openaiService.findContact(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
110
src/whatsapp/controllers/sqs.controller.ts
Executable file → Normal file
110
src/whatsapp/controllers/sqs.controller.ts
Executable file → Normal file
@ -1,56 +1,56 @@
|
|||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { SqsDto } from '../dto/sqs.dto';
|
import { SqsDto } from '../dto/sqs.dto';
|
||||||
import { SqsService } from '../services/sqs.service';
|
import { SqsService } from '../services/sqs.service';
|
||||||
|
|
||||||
const logger = new Logger('SqsController');
|
const logger = new Logger('SqsController');
|
||||||
|
|
||||||
export class SqsController {
|
export class SqsController {
|
||||||
constructor(private readonly sqsService: SqsService) { }
|
constructor(private readonly sqsService: SqsService) { }
|
||||||
|
|
||||||
public async createSqs(instance: InstanceDto, data: SqsDto) {
|
public async createSqs(instance: InstanceDto, data: SqsDto) {
|
||||||
logger.verbose('requested createSqs from ' + instance.instanceName + ' instance');
|
logger.verbose('requested createSqs from ' + instance.instanceName + ' instance');
|
||||||
|
|
||||||
if (!data.enabled) {
|
if (!data.enabled) {
|
||||||
logger.verbose('sqs disabled');
|
logger.verbose('sqs disabled');
|
||||||
data.events = [];
|
data.events = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.events.length === 0) {
|
if (data.events.length === 0) {
|
||||||
logger.verbose('sqs events empty');
|
logger.verbose('sqs events empty');
|
||||||
data.events = [
|
data.events = [
|
||||||
'APPLICATION_STARTUP',
|
'APPLICATION_STARTUP',
|
||||||
'QRCODE_UPDATED',
|
'QRCODE_UPDATED',
|
||||||
'MESSAGES_SET',
|
'MESSAGES_SET',
|
||||||
'MESSAGES_UPSERT',
|
'MESSAGES_UPSERT',
|
||||||
'MESSAGES_UPDATE',
|
'MESSAGES_UPDATE',
|
||||||
'MESSAGES_DELETE',
|
'MESSAGES_DELETE',
|
||||||
'SEND_MESSAGE',
|
'SEND_MESSAGE',
|
||||||
'CONTACTS_SET',
|
'CONTACTS_SET',
|
||||||
'CONTACTS_UPSERT',
|
'CONTACTS_UPSERT',
|
||||||
'CONTACTS_UPDATE',
|
'CONTACTS_UPDATE',
|
||||||
'PRESENCE_UPDATE',
|
'PRESENCE_UPDATE',
|
||||||
'CHATS_SET',
|
'CHATS_SET',
|
||||||
'CHATS_UPSERT',
|
'CHATS_UPSERT',
|
||||||
'CHATS_UPDATE',
|
'CHATS_UPDATE',
|
||||||
'CHATS_DELETE',
|
'CHATS_DELETE',
|
||||||
'GROUPS_UPSERT',
|
'GROUPS_UPSERT',
|
||||||
'GROUP_UPDATE',
|
'GROUP_UPDATE',
|
||||||
'GROUP_PARTICIPANTS_UPDATE',
|
'GROUP_PARTICIPANTS_UPDATE',
|
||||||
'CONNECTION_UPDATE',
|
'CONNECTION_UPDATE',
|
||||||
'CALL',
|
'CALL',
|
||||||
'NEW_JWT_TOKEN',
|
'NEW_JWT_TOKEN',
|
||||||
'TYPEBOT_START',
|
'TYPEBOT_START',
|
||||||
'TYPEBOT_CHANGE_STATUS',
|
'TYPEBOT_CHANGE_STATUS',
|
||||||
'CHAMA_AI_ACTION',
|
'CHAMA_AI_ACTION',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.sqsService.create(instance, data);
|
return this.sqsService.create(instance, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findSqs(instance: InstanceDto) {
|
public async findSqs(instance: InstanceDto) {
|
||||||
logger.verbose('requested findSqs from ' + instance.instanceName + ' instance');
|
logger.verbose('requested findSqs from ' + instance.instanceName + ' instance');
|
||||||
return this.sqsService.find(instance);
|
return this.sqsService.find(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
10
src/whatsapp/dto/contactopenai.dto.ts
Executable file → Normal file
10
src/whatsapp/dto/contactopenai.dto.ts
Executable file → Normal file
@ -1,5 +1,5 @@
|
|||||||
export class ContactOpenaiDto {
|
export class ContactOpenaiDto {
|
||||||
contact?: string;
|
contact?: string;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
owner: string;
|
owner: string;
|
||||||
}
|
}
|
||||||
|
88
src/whatsapp/dto/instance.dto.ts
Executable file → Normal file
88
src/whatsapp/dto/instance.dto.ts
Executable file → Normal file
@ -1,44 +1,44 @@
|
|||||||
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;
|
||||||
webhook_base64?: boolean;
|
webhook_base64?: 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;
|
||||||
websocket_enabled?: boolean;
|
websocket_enabled?: boolean;
|
||||||
websocket_events?: string[];
|
websocket_events?: string[];
|
||||||
rabbitmq_enabled?: boolean;
|
rabbitmq_enabled?: boolean;
|
||||||
rabbitmq_events?: string[];
|
rabbitmq_events?: string[];
|
||||||
|
|
||||||
openai_chave?: boolean;
|
openai_chave?: boolean;
|
||||||
openai_prompts?: string;
|
openai_prompts?: string;
|
||||||
openai_enabled?: boolean;
|
openai_enabled?: boolean;
|
||||||
openai_events?: string[];
|
openai_events?: string[];
|
||||||
|
|
||||||
sqs_enabled?: boolean;
|
sqs_enabled?: boolean;
|
||||||
sqs_events?: string[];
|
sqs_events?: string[];
|
||||||
|
|
||||||
typebot_url?: string;
|
typebot_url?: string;
|
||||||
typebot?: string;
|
typebot?: string;
|
||||||
typebot_expire?: number;
|
typebot_expire?: number;
|
||||||
typebot_keyword_finish?: string;
|
typebot_keyword_finish?: string;
|
||||||
typebot_delay_message?: number;
|
typebot_delay_message?: number;
|
||||||
typebot_unknown_message?: string;
|
typebot_unknown_message?: string;
|
||||||
typebot_listening_from_me?: boolean;
|
typebot_listening_from_me?: boolean;
|
||||||
proxy_enabled?: boolean;
|
proxy_enabled?: boolean;
|
||||||
proxy?: string;
|
proxy?: string;
|
||||||
}
|
}
|
||||||
|
12
src/whatsapp/dto/openai.dto.ts
Executable file → Normal file
12
src/whatsapp/dto/openai.dto.ts
Executable file → Normal file
@ -1,6 +1,6 @@
|
|||||||
export class OpenaiDto {
|
export class OpenaiDto {
|
||||||
chave?: string;
|
chave?: string;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
prompts?: string;
|
prompts?: string;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
}
|
}
|
||||||
|
6
src/whatsapp/dto/sqs.dto.ts
Executable file → Normal file
6
src/whatsapp/dto/sqs.dto.ts
Executable file → Normal file
@ -1,4 +1,4 @@
|
|||||||
export class SqsDto {
|
export class SqsDto {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
}
|
}
|
152
src/whatsapp/guards/instance.guard.ts
Executable file → Normal file
152
src/whatsapp/guards/instance.guard.ts
Executable file → Normal file
@ -1,76 +1,76 @@
|
|||||||
import { NextFunction, Request, Response } from 'express';
|
import { NextFunction, Request, Response } from 'express';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { configService, Database, Redis } from '../../config/env.config';
|
import { configService, Database, Redis } from '../../config/env.config';
|
||||||
import { INSTANCE_DIR } from '../../config/path.config';
|
import { INSTANCE_DIR } from '../../config/path.config';
|
||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
ForbiddenException,
|
ForbiddenException,
|
||||||
InternalServerErrorException,
|
InternalServerErrorException,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
} from '../../exceptions';
|
} from '../../exceptions';
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { dbserver } from '../../libs/db.connect';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
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) {
|
||||||
try {
|
try {
|
||||||
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(
|
||||||
db.CONNECTION.DB_PREFIX_NAME +
|
db.CONNECTION.DB_PREFIX_NAME +
|
||||||
db.CONNECTION.DB_PREFIX_FINAL_NAME)
|
db.CONNECTION.DB_PREFIX_FINAL_NAME)
|
||||||
.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));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new InternalServerErrorException(error?.toString());
|
throw new InternalServerErrorException(error?.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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]) {
|
if (waMonitor.waInstances[instance.instanceName]) {
|
||||||
waMonitor.waInstances[instance.instanceName]?.removeRabbitmqQueues();
|
waMonitor.waInstances[instance.instanceName]?.removeRabbitmqQueues();
|
||||||
delete waMonitor.waInstances[instance.instanceName];
|
delete waMonitor.waInstances[instance.instanceName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
40
src/whatsapp/models/contactOpenai.model.ts
Executable file → Normal file
40
src/whatsapp/models/contactOpenai.model.ts
Executable file → Normal file
@ -1,20 +1,20 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { dbserver } from '../../libs/db.connect';
|
||||||
|
|
||||||
export class ContactOpenaiRaw {
|
export class ContactOpenaiRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
contact?: string;
|
contact?: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
owner: string;
|
owner: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const contactOpenaiSchema = new Schema<ContactOpenaiRaw>({
|
const contactOpenaiSchema = new Schema<ContactOpenaiRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
contact: { type: String, required: true, minlength: 1 },
|
contact: { type: String, required: true, minlength: 1 },
|
||||||
enabled: { type: Boolean, required: true },
|
enabled: { type: Boolean, required: true },
|
||||||
owner: { type: String, required: true, minlength: 1 },
|
owner: { type: String, required: true, minlength: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ContactOpenaiModel = dbserver?.model(ContactOpenaiRaw.name, contactOpenaiSchema, 'openai_contacts');
|
export const ContactOpenaiModel = dbserver?.model(ContactOpenaiRaw.name, contactOpenaiSchema, 'openai_contacts');
|
||||||
export type IContactOpenaiModel = typeof ContactOpenaiModel;
|
export type IContactOpenaiModel = typeof ContactOpenaiModel;
|
||||||
|
30
src/whatsapp/models/index.ts
Executable file → Normal file
30
src/whatsapp/models/index.ts
Executable file → Normal file
@ -1,15 +1,15 @@
|
|||||||
export * from './auth.model';
|
export * from './auth.model';
|
||||||
export * from './chamaai.model';
|
export * from './chamaai.model';
|
||||||
export * from './chat.model';
|
export * from './chat.model';
|
||||||
export * from './chatwoot.model';
|
export * from './chatwoot.model';
|
||||||
export * from './contact.model';
|
export * from './contact.model';
|
||||||
export * from './message.model';
|
export * from './message.model';
|
||||||
export * from './proxy.model';
|
export * from './proxy.model';
|
||||||
export * from './rabbitmq.model';
|
export * from './rabbitmq.model';
|
||||||
export * from './settings.model';
|
export * from './settings.model';
|
||||||
export * from './sqs.model';
|
export * from './sqs.model';
|
||||||
export * from './typebot.model';
|
export * from './typebot.model';
|
||||||
export * from './webhook.model';
|
export * from './webhook.model';
|
||||||
export * from './websocket.model';
|
export * from './websocket.model';
|
||||||
export * from './openai.model';
|
export * from './openai.model';
|
||||||
export * from './contactOpenai.model';
|
export * from './contactOpenai.model';
|
||||||
|
44
src/whatsapp/models/openai.model.ts
Executable file → Normal file
44
src/whatsapp/models/openai.model.ts
Executable file → Normal file
@ -1,22 +1,22 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { dbserver } from '../../libs/db.connect';
|
||||||
|
|
||||||
export class OpenaiRaw {
|
export class OpenaiRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
chave?: string;
|
chave?: string;
|
||||||
prompts?: string;
|
prompts?: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const openaiSchema = new Schema<OpenaiRaw>({
|
const openaiSchema = new Schema<OpenaiRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
chave: { type: String, required: true },
|
chave: { type: String, required: true },
|
||||||
prompts: { type: String, required: false },
|
prompts: { type: String, required: false },
|
||||||
enabled: { type: Boolean, required: true },
|
enabled: { type: Boolean, required: true },
|
||||||
events: { type: [String], required: true },
|
events: { type: [String], required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const OpenaiModel = dbserver?.model(OpenaiRaw.name, openaiSchema, 'openai');
|
export const OpenaiModel = dbserver?.model(OpenaiRaw.name, openaiSchema, 'openai');
|
||||||
export type IOpenaiModel = typeof OpenaiModel;
|
export type IOpenaiModel = typeof OpenaiModel;
|
||||||
|
34
src/whatsapp/models/sqs.model.ts
Executable file → Normal file
34
src/whatsapp/models/sqs.model.ts
Executable file → Normal file
@ -1,18 +1,18 @@
|
|||||||
import { Schema } from 'mongoose';
|
import { Schema } from 'mongoose';
|
||||||
|
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { dbserver } from '../../libs/db.connect';
|
||||||
|
|
||||||
export class SqsRaw {
|
export class SqsRaw {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const sqsSchema = new Schema<SqsRaw>({
|
const sqsSchema = new Schema<SqsRaw>({
|
||||||
_id: { type: String, _id: true },
|
_id: { type: String, _id: true },
|
||||||
enabled: { type: Boolean, required: true },
|
enabled: { type: Boolean, required: true },
|
||||||
events: { type: [String], required: true },
|
events: { type: [String], required: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const SqsModel = dbserver?.model(SqsRaw.name, sqsSchema, 'sqs');
|
export const SqsModel = dbserver?.model(SqsRaw.name, sqsSchema, 'sqs');
|
||||||
export type ISqsModel = typeof SqsModel;
|
export type ISqsModel = typeof SqsModel;
|
306
src/whatsapp/repository/openai.repository.ts
Executable file → Normal file
306
src/whatsapp/repository/openai.repository.ts
Executable file → Normal file
@ -1,153 +1,153 @@
|
|||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService } from '../../config/env.config';
|
import { ConfigService } from '../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../abstract/abstract.repository';
|
||||||
import { IContactOpenaiModel, ContactOpenaiRaw, IOpenaiModel, OpenaiRaw } from '../models';
|
import { IContactOpenaiModel, ContactOpenaiRaw, IOpenaiModel, OpenaiRaw } from '../models';
|
||||||
|
|
||||||
export class OpenaiRepository extends Repository {
|
export class OpenaiRepository extends Repository {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly openaiModel: IOpenaiModel,
|
private readonly openaiModel: IOpenaiModel,
|
||||||
private readonly contactopenaiModel: IContactOpenaiModel,
|
private readonly contactopenaiModel: IContactOpenaiModel,
|
||||||
private readonly configService: ConfigService
|
private readonly configService: ConfigService
|
||||||
) {
|
) {
|
||||||
super(configService);
|
super(configService);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('OpenaiRepository');
|
private readonly logger = new Logger('OpenaiRepository');
|
||||||
|
|
||||||
public async create(data: OpenaiRaw, instance: string): Promise<IInsert> {
|
public async create(data: OpenaiRaw, instance: string): Promise<IInsert> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('creating openai');
|
this.logger.verbose('creating openai');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('saving openai to db');
|
this.logger.verbose('saving openai to db');
|
||||||
const insert = await this.openaiModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
const insert = await this.openaiModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||||
|
|
||||||
this.logger.verbose('openai saved to db: ' + insert.modifiedCount + ' openai');
|
this.logger.verbose('openai saved to db: ' + insert.modifiedCount + ' openai');
|
||||||
return { insertCount: insert.modifiedCount };
|
return { insertCount: insert.modifiedCount };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('saving openai to store');
|
this.logger.verbose('saving openai to store');
|
||||||
|
|
||||||
this.writeStore<OpenaiRaw>({
|
this.writeStore<OpenaiRaw>({
|
||||||
path: join(this.storePath, 'openai'),
|
path: join(this.storePath, 'openai'),
|
||||||
fileName: instance,
|
fileName: instance,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.logger.verbose('openai saved to store in path: ' + join(this.storePath, 'openai') + '/' + instance);
|
this.logger.verbose('openai saved to store in path: ' + join(this.storePath, 'openai') + '/' + instance);
|
||||||
|
|
||||||
this.logger.verbose('openai created');
|
this.logger.verbose('openai created');
|
||||||
return { insertCount: 1 };
|
return { insertCount: 1 };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async createContact(data: ContactOpenaiRaw, instance: string): Promise<IInsert> {
|
public async createContact(data: ContactOpenaiRaw, instance: string): Promise<IInsert> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('creating contact openai');
|
this.logger.verbose('creating contact openai');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('saving openai to db');
|
this.logger.verbose('saving openai to db');
|
||||||
var resultado = await this.openaiModel.findOne({ owner: instance, contact: data.contact });
|
var resultado = await this.openaiModel.findOne({ owner: instance, contact: data.contact });
|
||||||
if(!resultado){
|
if(!resultado){
|
||||||
const insert = await this.contactopenaiModel.insertMany({ ...data });
|
const insert = await this.contactopenaiModel.insertMany({ ...data });
|
||||||
|
|
||||||
this.logger.verbose('openai saved to db: ' + insert.length + ' openai_contacts');
|
this.logger.verbose('openai saved to db: ' + insert.length + ' openai_contacts');
|
||||||
return { insertCount: insert.length };
|
return { insertCount: insert.length };
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
const contacts = []
|
const contacts = []
|
||||||
contacts[0] = {
|
contacts[0] = {
|
||||||
updateOne: {
|
updateOne: {
|
||||||
filter: { owner: data.owner, contact: data.contact },
|
filter: { owner: data.owner, contact: data.contact },
|
||||||
update: { ...data },
|
update: { ...data },
|
||||||
upsert: true,
|
upsert: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const { nModified } = await this.contactopenaiModel.bulkWrite(contacts);
|
const { nModified } = await this.contactopenaiModel.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('saving openai to store');
|
this.logger.verbose('saving openai to store');
|
||||||
|
|
||||||
this.writeStore<OpenaiRaw>({
|
this.writeStore<OpenaiRaw>({
|
||||||
path: join(this.storePath, 'openai_contact'),
|
path: join(this.storePath, 'openai_contact'),
|
||||||
fileName: instance,
|
fileName: instance,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.logger.verbose('openai contact saved to store in path: ' + join(this.storePath, 'openai_contact') + '/' + instance);
|
this.logger.verbose('openai contact saved to store in path: ' + join(this.storePath, 'openai_contact') + '/' + instance);
|
||||||
|
|
||||||
this.logger.verbose('openai contact created');
|
this.logger.verbose('openai contact created');
|
||||||
return { insertCount: 1 };
|
return { insertCount: 1 };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async find(instance: string): Promise<OpenaiRaw> {
|
public async find(instance: string): Promise<OpenaiRaw> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('finding openai');
|
this.logger.verbose('finding openai');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('finding openai in db');
|
this.logger.verbose('finding openai in db');
|
||||||
return await this.openaiModel.findOne({ _id: instance });
|
return await this.openaiModel.findOne({ _id: instance });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('finding openai in store');
|
this.logger.verbose('finding openai in store');
|
||||||
return JSON.parse(
|
return JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'openai', instance + '.json'), {
|
readFileSync(join(this.storePath, 'openai', instance + '.json'), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
) as OpenaiRaw;
|
) as OpenaiRaw;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findContact(instance: string, contact: string): Promise<ContactOpenaiRaw> {
|
public async findContact(instance: string, contact: string): Promise<ContactOpenaiRaw> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('finding openai');
|
this.logger.verbose('finding openai');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('finding openai in db');
|
this.logger.verbose('finding openai in db');
|
||||||
|
|
||||||
return await this.contactopenaiModel.findOne({ owner: instance,contact: contact});
|
return await this.contactopenaiModel.findOne({ owner: instance,contact: contact});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('finding openai in store');
|
this.logger.verbose('finding openai in store');
|
||||||
return JSON.parse(
|
return JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'openai_contact', instance + '.json'), {
|
readFileSync(join(this.storePath, 'openai_contact', instance + '.json'), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
) as ContactOpenaiRaw;
|
) as ContactOpenaiRaw;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findContactAll(instance: string): Promise<any> {
|
public async findContactAll(instance: string): Promise<any> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('finding openai');
|
this.logger.verbose('finding openai');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('finding openai in db');
|
this.logger.verbose('finding openai in db');
|
||||||
return await this.contactopenaiModel.find({ owner: instance });
|
return await this.contactopenaiModel.find({ owner: instance });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('finding openai in store');
|
this.logger.verbose('finding openai in store');
|
||||||
return JSON.parse(
|
return JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'openai_contact', instance + '.json'), {
|
readFileSync(join(this.storePath, 'openai_contact', instance + '.json'), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
) as ContactOpenaiRaw;
|
) as ContactOpenaiRaw;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
338
src/whatsapp/repository/repository.manager.ts
Executable file → Normal file
338
src/whatsapp/repository/repository.manager.ts
Executable file → Normal file
@ -1,169 +1,169 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { MongoClient } from 'mongodb';
|
import { MongoClient } from 'mongodb';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { Auth, ConfigService, Database } from '../../config/env.config';
|
import { Auth, ConfigService, Database } from '../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { AuthRepository } from './auth.repository';
|
import { AuthRepository } from './auth.repository';
|
||||||
import { ChamaaiRepository } from './chamaai.repository';
|
import { ChamaaiRepository } from './chamaai.repository';
|
||||||
import { ChatRepository } from './chat.repository';
|
import { ChatRepository } from './chat.repository';
|
||||||
import { ChatwootRepository } from './chatwoot.repository';
|
import { ChatwootRepository } from './chatwoot.repository';
|
||||||
import { ContactRepository } from './contact.repository';
|
import { ContactRepository } from './contact.repository';
|
||||||
import { MessageRepository } from './message.repository';
|
import { MessageRepository } from './message.repository';
|
||||||
import { MessageUpRepository } from './messageUp.repository';
|
import { MessageUpRepository } from './messageUp.repository';
|
||||||
import { ProxyRepository } from './proxy.repository';
|
import { ProxyRepository } from './proxy.repository';
|
||||||
import { RabbitmqRepository } from './rabbitmq.repository';
|
import { RabbitmqRepository } from './rabbitmq.repository';
|
||||||
import { OpenaiRepository } from './openai.repository';
|
import { OpenaiRepository } from './openai.repository';
|
||||||
import { SettingsRepository } from './settings.repository';
|
import { SettingsRepository } from './settings.repository';
|
||||||
import { SqsRepository } from './sqs.repository';
|
import { SqsRepository } from './sqs.repository';
|
||||||
import { TypebotRepository } from './typebot.repository';
|
import { TypebotRepository } from './typebot.repository';
|
||||||
import { WebhookRepository } from './webhook.repository';
|
import { WebhookRepository } from './webhook.repository';
|
||||||
import { WebsocketRepository } from './websocket.repository';
|
import { WebsocketRepository } from './websocket.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 websocket: WebsocketRepository,
|
public readonly websocket: WebsocketRepository,
|
||||||
public readonly rabbitmq: RabbitmqRepository,
|
public readonly rabbitmq: RabbitmqRepository,
|
||||||
public readonly openai: OpenaiRepository,
|
public readonly openai: OpenaiRepository,
|
||||||
public readonly openai_contact: OpenaiRepository,
|
public readonly openai_contact: OpenaiRepository,
|
||||||
public readonly sqs: SqsRepository,
|
public readonly sqs: SqsRepository,
|
||||||
public readonly typebot: TypebotRepository,
|
public readonly typebot: TypebotRepository,
|
||||||
public readonly proxy: ProxyRepository,
|
public readonly proxy: ProxyRepository,
|
||||||
public readonly chamaai: ChamaaiRepository,
|
public readonly chamaai: ChamaaiRepository,
|
||||||
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 sqsDir = join(storePath, 'sqs');
|
const sqsDir = join(storePath, 'sqs');
|
||||||
const websocketDir = join(storePath, 'websocket');
|
const websocketDir = join(storePath, 'websocket');
|
||||||
const rabbitmqDir = join(storePath, 'rabbitmq');
|
const rabbitmqDir = join(storePath, 'rabbitmq');
|
||||||
const openaiDir = join(storePath, 'openai');
|
const openaiDir = join(storePath, 'openai');
|
||||||
const typebotDir = join(storePath, 'typebot');
|
const typebotDir = join(storePath, 'typebot');
|
||||||
const proxyDir = join(storePath, 'proxy');
|
const proxyDir = join(storePath, 'proxy');
|
||||||
const chamaaiDir = join(storePath, 'chamaai');
|
const chamaaiDir = join(storePath, 'chamaai');
|
||||||
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)) {
|
if (!fs.existsSync(chatsDir)) {
|
||||||
this.logger.verbose('creating chats dir: ' + chatsDir);
|
this.logger.verbose('creating chats dir: ' + chatsDir);
|
||||||
fs.mkdirSync(chatsDir, { recursive: true });
|
fs.mkdirSync(chatsDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(contactsDir)) {
|
if (!fs.existsSync(contactsDir)) {
|
||||||
this.logger.verbose('creating contacts dir: ' + contactsDir);
|
this.logger.verbose('creating contacts dir: ' + contactsDir);
|
||||||
fs.mkdirSync(contactsDir, { recursive: true });
|
fs.mkdirSync(contactsDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(messagesDir)) {
|
if (!fs.existsSync(messagesDir)) {
|
||||||
this.logger.verbose('creating messages dir: ' + messagesDir);
|
this.logger.verbose('creating messages dir: ' + messagesDir);
|
||||||
fs.mkdirSync(messagesDir, { recursive: true });
|
fs.mkdirSync(messagesDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(messageUpDir)) {
|
if (!fs.existsSync(messageUpDir)) {
|
||||||
this.logger.verbose('creating message-up dir: ' + messageUpDir);
|
this.logger.verbose('creating message-up dir: ' + messageUpDir);
|
||||||
fs.mkdirSync(messageUpDir, { recursive: true });
|
fs.mkdirSync(messageUpDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(webhookDir)) {
|
if (!fs.existsSync(webhookDir)) {
|
||||||
this.logger.verbose('creating webhook dir: ' + webhookDir);
|
this.logger.verbose('creating webhook dir: ' + webhookDir);
|
||||||
fs.mkdirSync(webhookDir, { recursive: true });
|
fs.mkdirSync(webhookDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(chatwootDir)) {
|
if (!fs.existsSync(chatwootDir)) {
|
||||||
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
||||||
fs.mkdirSync(chatwootDir, { recursive: true });
|
fs.mkdirSync(chatwootDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(settingsDir)) {
|
if (!fs.existsSync(settingsDir)) {
|
||||||
this.logger.verbose('creating settings dir: ' + settingsDir);
|
this.logger.verbose('creating settings dir: ' + settingsDir);
|
||||||
fs.mkdirSync(settingsDir, { recursive: true });
|
fs.mkdirSync(settingsDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(sqsDir)) {
|
if (!fs.existsSync(sqsDir)) {
|
||||||
this.logger.verbose('creating sqs dir: ' + sqsDir);
|
this.logger.verbose('creating sqs dir: ' + sqsDir);
|
||||||
fs.mkdirSync(sqsDir, { recursive: true });
|
fs.mkdirSync(sqsDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(websocketDir)) {
|
if (!fs.existsSync(websocketDir)) {
|
||||||
this.logger.verbose('creating websocket dir: ' + websocketDir);
|
this.logger.verbose('creating websocket dir: ' + websocketDir);
|
||||||
fs.mkdirSync(websocketDir, { recursive: true });
|
fs.mkdirSync(websocketDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(rabbitmqDir)) {
|
if (!fs.existsSync(rabbitmqDir)) {
|
||||||
this.logger.verbose('creating rabbitmq dir: ' + rabbitmqDir);
|
this.logger.verbose('creating rabbitmq dir: ' + rabbitmqDir);
|
||||||
fs.mkdirSync(rabbitmqDir, { recursive: true });
|
fs.mkdirSync(rabbitmqDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(openaiDir)) {
|
if (!fs.existsSync(openaiDir)) {
|
||||||
this.logger.verbose('creating openai dir: ' + openaiDir);
|
this.logger.verbose('creating openai dir: ' + openaiDir);
|
||||||
fs.mkdirSync(openaiDir, { recursive: true });
|
fs.mkdirSync(openaiDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(typebotDir)) {
|
if (!fs.existsSync(typebotDir)) {
|
||||||
this.logger.verbose('creating typebot dir: ' + typebotDir);
|
this.logger.verbose('creating typebot dir: ' + typebotDir);
|
||||||
fs.mkdirSync(typebotDir, { recursive: true });
|
fs.mkdirSync(typebotDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(proxyDir)) {
|
if (!fs.existsSync(proxyDir)) {
|
||||||
this.logger.verbose('creating proxy dir: ' + proxyDir);
|
this.logger.verbose('creating proxy dir: ' + proxyDir);
|
||||||
fs.mkdirSync(proxyDir, { recursive: true });
|
fs.mkdirSync(proxyDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(chamaaiDir)) {
|
if (!fs.existsSync(chamaaiDir)) {
|
||||||
this.logger.verbose('creating chamaai dir: ' + chamaaiDir);
|
this.logger.verbose('creating chamaai dir: ' + chamaaiDir);
|
||||||
fs.mkdirSync(chamaaiDir, { recursive: true });
|
fs.mkdirSync(chamaaiDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(tempDir)) {
|
if (!fs.existsSync(tempDir)) {
|
||||||
this.logger.verbose('creating temp dir: ' + tempDir);
|
this.logger.verbose('creating temp dir: ' + tempDir);
|
||||||
fs.mkdirSync(tempDir, { recursive: true });
|
fs.mkdirSync(tempDir, { recursive: true });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
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);
|
||||||
|
|
||||||
const tempDir = join(storePath, 'temp');
|
const tempDir = join(storePath, 'temp');
|
||||||
const chatwootDir = join(storePath, 'chatwoot');
|
const chatwootDir = join(storePath, 'chatwoot');
|
||||||
|
|
||||||
if (!fs.existsSync(chatwootDir)) {
|
if (!fs.existsSync(chatwootDir)) {
|
||||||
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
this.logger.verbose('creating chatwoot dir: ' + chatwootDir);
|
||||||
fs.mkdirSync(chatwootDir, { recursive: true });
|
fs.mkdirSync(chatwootDir, { recursive: true });
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(tempDir)) {
|
if (!fs.existsSync(tempDir)) {
|
||||||
this.logger.verbose('creating temp dir: ' + tempDir);
|
this.logger.verbose('creating temp dir: ' + tempDir);
|
||||||
fs.mkdirSync(tempDir, { recursive: true });
|
fs.mkdirSync(tempDir, { recursive: true });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
122
src/whatsapp/repository/sqs.repository.ts
Executable file → Normal file
122
src/whatsapp/repository/sqs.repository.ts
Executable file → Normal file
@ -1,62 +1,62 @@
|
|||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { ConfigService } from '../../config/env.config';
|
import { ConfigService } from '../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { IInsert, Repository } from '../abstract/abstract.repository';
|
import { IInsert, Repository } from '../abstract/abstract.repository';
|
||||||
import { ISqsModel, SqsRaw } from '../models';
|
import { ISqsModel, SqsRaw } from '../models';
|
||||||
|
|
||||||
export class SqsRepository extends Repository {
|
export class SqsRepository extends Repository {
|
||||||
constructor(private readonly sqsModel: ISqsModel, private readonly configService: ConfigService) {
|
constructor(private readonly sqsModel: ISqsModel, private readonly configService: ConfigService) {
|
||||||
super(configService);
|
super(configService);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly logger = new Logger('SqsRepository');
|
private readonly logger = new Logger('SqsRepository');
|
||||||
|
|
||||||
public async create(data: SqsRaw, instance: string): Promise<IInsert> {
|
public async create(data: SqsRaw, instance: string): Promise<IInsert> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('creating sqs');
|
this.logger.verbose('creating sqs');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('saving sqs to db');
|
this.logger.verbose('saving sqs to db');
|
||||||
const insert = await this.sqsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
const insert = await this.sqsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||||
|
|
||||||
this.logger.verbose('sqs saved to db: ' + insert.modifiedCount + ' sqs');
|
this.logger.verbose('sqs saved to db: ' + insert.modifiedCount + ' sqs');
|
||||||
return { insertCount: insert.modifiedCount };
|
return { insertCount: insert.modifiedCount };
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('saving sqs to store');
|
this.logger.verbose('saving sqs to store');
|
||||||
|
|
||||||
this.writeStore<SqsRaw>({
|
this.writeStore<SqsRaw>({
|
||||||
path: join(this.storePath, 'sqs'),
|
path: join(this.storePath, 'sqs'),
|
||||||
fileName: instance,
|
fileName: instance,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.logger.verbose('sqs saved to store in path: ' + join(this.storePath, 'sqs') + '/' + instance);
|
this.logger.verbose('sqs saved to store in path: ' + join(this.storePath, 'sqs') + '/' + instance);
|
||||||
|
|
||||||
this.logger.verbose('sqs created');
|
this.logger.verbose('sqs created');
|
||||||
return { insertCount: 1 };
|
return { insertCount: 1 };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async find(instance: string): Promise<SqsRaw> {
|
public async find(instance: string): Promise<SqsRaw> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('finding sqs');
|
this.logger.verbose('finding sqs');
|
||||||
if (this.dbSettings.ENABLED) {
|
if (this.dbSettings.ENABLED) {
|
||||||
this.logger.verbose('finding sqs in db');
|
this.logger.verbose('finding sqs in db');
|
||||||
return await this.sqsModel.findOne({ _id: instance });
|
return await this.sqsModel.findOne({ _id: instance });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('finding sqs in store');
|
this.logger.verbose('finding sqs in store');
|
||||||
return JSON.parse(
|
return JSON.parse(
|
||||||
readFileSync(join(this.storePath, 'sqs', instance + '.json'), {
|
readFileSync(join(this.storePath, 'sqs', instance + '.json'), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
}),
|
}),
|
||||||
) as SqsRaw;
|
) as SqsRaw;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
126
src/whatsapp/routers/index.router.ts
Executable file → Normal file
126
src/whatsapp/routers/index.router.ts
Executable file → Normal file
@ -1,63 +1,63 @@
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
import { Auth, configService } from '../../config/env.config';
|
import { Auth, configService } from '../../config/env.config';
|
||||||
import { authGuard } from '../guards/auth.guard';
|
import { authGuard } from '../guards/auth.guard';
|
||||||
import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard';
|
import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard';
|
||||||
import { ChamaaiRouter } from './chamaai.router';
|
import { ChamaaiRouter } from './chamaai.router';
|
||||||
import { ChatRouter } from './chat.router';
|
import { ChatRouter } from './chat.router';
|
||||||
import { ChatwootRouter } from './chatwoot.router';
|
import { ChatwootRouter } from './chatwoot.router';
|
||||||
import { GroupRouter } from './group.router';
|
import { GroupRouter } from './group.router';
|
||||||
import { InstanceRouter } from './instance.router';
|
import { InstanceRouter } from './instance.router';
|
||||||
import { ProxyRouter } from './proxy.router';
|
import { ProxyRouter } from './proxy.router';
|
||||||
import { RabbitmqRouter } from './rabbitmq.router';
|
import { RabbitmqRouter } from './rabbitmq.router';
|
||||||
import { OpenaiRouter } from './openai.router';
|
import { OpenaiRouter } from './openai.router';
|
||||||
import { MessageRouter } from './sendMessage.router';
|
import { MessageRouter } from './sendMessage.router';
|
||||||
import { SettingsRouter } from './settings.router';
|
import { SettingsRouter } from './settings.router';
|
||||||
import { SqsRouter } from './sqs.router';
|
import { SqsRouter } from './sqs.router';
|
||||||
import { TypebotRouter } from './typebot.router';
|
import { TypebotRouter } from './typebot.router';
|
||||||
import { ViewsRouter } from './view.router';
|
import { ViewsRouter } from './view.router';
|
||||||
import { WebhookRouter } from './webhook.router';
|
import { WebhookRouter } from './webhook.router';
|
||||||
import { WebsocketRouter } from './websocket.router';
|
import { WebsocketRouter } from './websocket.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();
|
||||||
const authType = configService.get<Auth>('AUTHENTICATION').TYPE;
|
const authType = configService.get<Auth>('AUTHENTICATION').TYPE;
|
||||||
const guards = [instanceExistsGuard, instanceLoggedGuard, authGuard[authType]];
|
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: 'Api',
|
message: 'Api',
|
||||||
// version: packageJson.version,
|
// version: packageJson.version,
|
||||||
// documentation: `${req.protocol}://${req.get('host')}/docs`,
|
// documentation: `${req.protocol}://${req.get('host')}/docs`,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.use('/instance', new InstanceRouter(configService, ...guards).router)
|
.use('/instance', new InstanceRouter(configService, ...guards).router)
|
||||||
.use('/manager', new ViewsRouter().router)
|
.use('/manager', new ViewsRouter().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)
|
||||||
.use('/websocket', new WebsocketRouter(...guards).router)
|
.use('/websocket', new WebsocketRouter(...guards).router)
|
||||||
.use('/rabbitmq', new RabbitmqRouter(...guards).router)
|
.use('/rabbitmq', new RabbitmqRouter(...guards).router)
|
||||||
.use('/openai', new OpenaiRouter(...guards).router)
|
.use('/openai', new OpenaiRouter(...guards).router)
|
||||||
.use('/typebot', new TypebotRouter(...guards).router)
|
.use('/typebot', new TypebotRouter(...guards).router)
|
||||||
.use('/proxy', new ProxyRouter(...guards).router)
|
.use('/proxy', new ProxyRouter(...guards).router)
|
||||||
.use('/chamaai', new ChamaaiRouter(...guards).router);
|
.use('/chamaai', new ChamaaiRouter(...guards).router);
|
||||||
|
|
||||||
export { HttpStatus, router };
|
export { HttpStatus, router };
|
||||||
|
402
src/whatsapp/routers/instance.router.ts
Executable file → Normal file
402
src/whatsapp/routers/instance.router.ts
Executable file → Normal file
@ -1,201 +1,201 @@
|
|||||||
import { RequestHandler, Router } from 'express';
|
import { RequestHandler, Router } from 'express';
|
||||||
|
|
||||||
import { Auth, ConfigService, Database } from '../../config/env.config';
|
import { Auth, ConfigService, Database } from '../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { dbserver } from '../../libs/db.connect';
|
||||||
import { instanceNameSchema, oldTokenSchema } from '../../validate/validate.schema';
|
import { instanceNameSchema, oldTokenSchema } from '../../validate/validate.schema';
|
||||||
import { RouterBroker } from '../abstract/abstract.router';
|
import { RouterBroker } from '../abstract/abstract.router';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { OldToken } from '../services/auth.service';
|
import { OldToken } from '../services/auth.service';
|
||||||
import { instanceController } from '../whatsapp.module';
|
import { instanceController } from '../whatsapp.module';
|
||||||
import { HttpStatus } from './index.router';
|
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),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (req.query['qrcode']) {
|
if (req.query['qrcode']) {
|
||||||
return res.status(HttpStatus.OK).render('qrcode', {
|
return res.status(HttpStatus.OK).render('qrcode', {
|
||||||
qrcode: response.qrcode.base64,
|
qrcode: response.qrcode.base64,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
}
|
}
|
||||||
//return res.status(HttpStatus.CREATED).json(response);
|
//return res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
.put(this.routerPath('restart'), ...guards, async (req, res) => {
|
.put(this.routerPath('restart'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in restartInstance');
|
logger.verbose('request received in restartInstance');
|
||||||
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.restartInstance(instance),
|
execute: (instance) => instanceController.restartInstance(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('qr'), ...guards, async (req, res) => {
|
.get(this.routerPath('qr'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in get qrCode');
|
logger.verbose('request received in get qrCode');
|
||||||
|
|
||||||
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.qrInstance(instance),
|
execute: (instance) => instanceController.qrInstance(instance),
|
||||||
});
|
});
|
||||||
return res.status(HttpStatus.OK).render('qrcode', {
|
return res.status(HttpStatus.OK).render('qrcode', {
|
||||||
qrcode: response,
|
qrcode: response,
|
||||||
});
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
.get(this.routerPath('connect'), ...guards, async (req, res) => {
|
.get(this.routerPath('connect'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in connectInstance');
|
logger.verbose('request received in connectInstance');
|
||||||
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.connectToWhatsapp(instance),
|
execute: (instance) => instanceController.connectToWhatsapp(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('connectionState'), ...guards, async (req, res) => {
|
.get(this.routerPath('connectionState'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in connectionState');
|
logger.verbose('request received in connectionState');
|
||||||
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.connectionState(instance),
|
execute: (instance) => instanceController.connectionState(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => {
|
.get(this.routerPath('fetchInstances', false), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in fetchInstances');
|
logger.verbose('request received in fetchInstances');
|
||||||
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) => instanceController.fetchInstances(instance),
|
execute: (instance) => instanceController.fetchInstances(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.delete(this.routerPath('logout'), ...guards, async (req, res) => {
|
.delete(this.routerPath('logout'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in logoutInstances');
|
logger.verbose('request received in logoutInstances');
|
||||||
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.logout(instance),
|
execute: (instance) => instanceController.logout(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.delete(this.routerPath('delete'), ...guards, async (req, res) => {
|
.delete(this.routerPath('delete'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in deleteInstances');
|
logger.verbose('request received in deleteInstances');
|
||||||
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.deleteInstance(instance),
|
execute: (instance) => instanceController.deleteInstance(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.OK).json(response);
|
return res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (auth.TYPE === 'jwt') {
|
if (auth.TYPE === 'jwt') {
|
||||||
this.router.put('/refreshToken', async (req, res) => {
|
this.router.put('/refreshToken', async (req, res) => {
|
||||||
logger.verbose('request received in refreshToken');
|
logger.verbose('request received in refreshToken');
|
||||||
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<OldToken>({
|
const response = await this.dataValidate<OldToken>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: oldTokenSchema,
|
schema: oldTokenSchema,
|
||||||
ClassRef: OldToken,
|
ClassRef: OldToken,
|
||||||
execute: (_, data) => instanceController.refreshToken(_, data),
|
execute: (_, data) => instanceController.refreshToken(_, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(HttpStatus.CREATED).json(response);
|
return res.status(HttpStatus.CREATED).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.router.delete('/deleteDatabase', async (req, res) => {
|
this.router.delete('/deleteDatabase', async (req, res) => {
|
||||||
logger.verbose('request received in deleteDatabase');
|
logger.verbose('request received in deleteDatabase');
|
||||||
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 db = this.configService.get<Database>('DATABASE');
|
const db = this.configService.get<Database>('DATABASE');
|
||||||
if (db.ENABLED) {
|
if (db.ENABLED) {
|
||||||
try {
|
try {
|
||||||
await dbserver.dropDatabase();
|
await dbserver.dropDatabase();
|
||||||
return res
|
return res
|
||||||
.status(HttpStatus.CREATED)
|
.status(HttpStatus.CREATED)
|
||||||
.json({ status: 'SUCCESS', error: false, response: { message: 'database deleted' } });
|
.json({ status: 'SUCCESS', error: false, response: { message: 'database deleted' } });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: error.message });
|
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: error.message });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: 'Database is not enabled' });
|
return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: true, message: 'Database is not enabled' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
172
src/whatsapp/routers/openai.router.ts
Executable file → Normal file
172
src/whatsapp/routers/openai.router.ts
Executable file → Normal file
@ -1,86 +1,86 @@
|
|||||||
import { RequestHandler, Router } from 'express';
|
import { RequestHandler, Router } from 'express';
|
||||||
|
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { instanceNameSchema, openaiSchema } from '../../validate/validate.schema';
|
import { instanceNameSchema, openaiSchema } from '../../validate/validate.schema';
|
||||||
import { RouterBroker } from '../abstract/abstract.router';
|
import { RouterBroker } from '../abstract/abstract.router';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { OpenaiDto } from '../dto/openai.dto';
|
import { OpenaiDto } from '../dto/openai.dto';
|
||||||
import { ContactOpenaiDto } from '../dto/contactopenai.dto';
|
import { ContactOpenaiDto } from '../dto/contactopenai.dto';
|
||||||
import { openaiController } from '../whatsapp.module';
|
import { openaiController } from '../whatsapp.module';
|
||||||
import { HttpStatus } from './index.router';
|
import { HttpStatus } from './index.router';
|
||||||
|
|
||||||
const logger = new Logger('OpenaiRouter');
|
const logger = new Logger('OpenaiRouter');
|
||||||
|
|
||||||
export class OpenaiRouter extends RouterBroker {
|
export class OpenaiRouter 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 setOpenai');
|
logger.verbose('request received in setOpenai');
|
||||||
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<OpenaiDto>({
|
const response = await this.dataValidate<OpenaiDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: openaiSchema,
|
schema: openaiSchema,
|
||||||
ClassRef: OpenaiDto,
|
ClassRef: OpenaiDto,
|
||||||
execute: (instance, data) => openaiController.createOpenai(instance, data),
|
execute: (instance, data) => openaiController.createOpenai(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 findOpenai');
|
logger.verbose('request received in findOpenai');
|
||||||
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) => openaiController.findOpenai(instance),
|
execute: (instance) => openaiController.findOpenai(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
})
|
||||||
.post(this.routerPath('contact'), ...guards, async (req, res) => {
|
.post(this.routerPath('contact'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in setOpenai');
|
logger.verbose('request received in setOpenai');
|
||||||
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<ContactOpenaiDto>({
|
const response = await this.dataValidate<ContactOpenaiDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: openaiSchema,
|
schema: openaiSchema,
|
||||||
ClassRef: ContactOpenaiDto,
|
ClassRef: ContactOpenaiDto,
|
||||||
execute: (instance, data) => openaiController.createContactOpenai(instance, data),
|
execute: (instance, data) => openaiController.createContactOpenai(instance, data),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.CREATED).json(response);
|
res.status(HttpStatus.CREATED).json(response);
|
||||||
})
|
})
|
||||||
|
|
||||||
.get(this.routerPath('findcontact'), ...guards, async (req, res) => {
|
.get(this.routerPath('findcontact'), ...guards, async (req, res) => {
|
||||||
logger.verbose('request received in findOpenai');
|
logger.verbose('request received in findOpenai');
|
||||||
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) => openaiController.findContactOpenai(instance),
|
execute: (instance) => openaiController.findContactOpenai(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
||||||
|
102
src/whatsapp/routers/sqs.router.ts
Executable file → Normal file
102
src/whatsapp/routers/sqs.router.ts
Executable file → Normal file
@ -1,52 +1,52 @@
|
|||||||
import { RequestHandler, Router } from 'express';
|
import { RequestHandler, Router } from 'express';
|
||||||
|
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { instanceNameSchema, sqsSchema } from '../../validate/validate.schema';
|
import { instanceNameSchema, sqsSchema } from '../../validate/validate.schema';
|
||||||
import { RouterBroker } from '../abstract/abstract.router';
|
import { RouterBroker } from '../abstract/abstract.router';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { SqsDto } from '../dto/sqs.dto';
|
import { SqsDto } from '../dto/sqs.dto';
|
||||||
import { sqsController } from '../whatsapp.module';
|
import { sqsController } from '../whatsapp.module';
|
||||||
import { HttpStatus } from './index.router';
|
import { HttpStatus } from './index.router';
|
||||||
|
|
||||||
const logger = new Logger('SqsRouter');
|
const logger = new Logger('SqsRouter');
|
||||||
|
|
||||||
export class SqsRouter extends RouterBroker {
|
export class SqsRouter 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 setSqs');
|
logger.verbose('request received in setSqs');
|
||||||
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<SqsDto>({
|
const response = await this.dataValidate<SqsDto>({
|
||||||
request: req,
|
request: req,
|
||||||
schema: sqsSchema,
|
schema: sqsSchema,
|
||||||
ClassRef: SqsDto,
|
ClassRef: SqsDto,
|
||||||
execute: (instance, data) => sqsController.createSqs(instance, data),
|
execute: (instance, data) => sqsController.createSqs(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 findSqs');
|
logger.verbose('request received in findSqs');
|
||||||
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) => sqsController.findSqs(instance),
|
execute: (instance) => sqsController.findSqs(instance),
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly router = Router();
|
public readonly router = Router();
|
||||||
}
|
}
|
BIN
src/whatsapp/services/._whatsapp.service.ts
Normal file
BIN
src/whatsapp/services/._whatsapp.service.ts
Normal file
Binary file not shown.
3316
src/whatsapp/services/chatwoot.service.ts
Executable file → Normal file
3316
src/whatsapp/services/chatwoot.service.ts
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
796
src/whatsapp/services/monitor.service.ts
Executable file → Normal file
796
src/whatsapp/services/monitor.service.ts
Executable file → Normal file
@ -1,398 +1,398 @@
|
|||||||
import { execSync } from 'child_process';
|
import { execSync } from 'child_process';
|
||||||
import EventEmitter2 from 'eventemitter2';
|
import EventEmitter2 from 'eventemitter2';
|
||||||
import { opendirSync, readdirSync, rmSync } from 'fs';
|
import { opendirSync, readdirSync, rmSync } from 'fs';
|
||||||
import { Db } from 'mongodb';
|
import { Db } from 'mongodb';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { Auth, ConfigService, Database, DelInstance, HttpServer, Redis } from '../../config/env.config';
|
import { Auth, ConfigService, Database, DelInstance, HttpServer, Redis } from '../../config/env.config';
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config';
|
import { INSTANCE_DIR, STORE_DIR } from '../../config/path.config';
|
||||||
import { NotFoundException } from '../../exceptions';
|
import { NotFoundException } from '../../exceptions';
|
||||||
import { dbserver } from '../../libs/db.connect';
|
import { dbserver } from '../../libs/db.connect';
|
||||||
import { RedisCache } from '../../libs/redis.client';
|
import { RedisCache } from '../../libs/redis.client';
|
||||||
import {
|
import {
|
||||||
AuthModel,
|
AuthModel,
|
||||||
ChamaaiModel,
|
ChamaaiModel,
|
||||||
ChatModel,
|
ChatModel,
|
||||||
ChatwootModel,
|
ChatwootModel,
|
||||||
ContactModel,
|
ContactModel,
|
||||||
MessageModel,
|
MessageModel,
|
||||||
MessageUpModel,
|
MessageUpModel,
|
||||||
ProxyModel,
|
ProxyModel,
|
||||||
RabbitmqModel,
|
RabbitmqModel,
|
||||||
SettingsModel,
|
SettingsModel,
|
||||||
TypebotModel,
|
TypebotModel,
|
||||||
WebhookModel,
|
WebhookModel,
|
||||||
WebsocketModel,
|
WebsocketModel,
|
||||||
|
|
||||||
} 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.repository.dbServer?.db(
|
||||||
this.db.CONNECTION.DB_PREFIX_NAME +
|
this.db.CONNECTION.DB_PREFIX_NAME +
|
||||||
this.db.CONNECTION.DB_PREFIX_FINAL_NAME
|
this.db.CONNECTION.DB_PREFIX_FINAL_NAME
|
||||||
)
|
)
|
||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly db: Partial<Database> = {};
|
private readonly db: Partial<Database> = {};
|
||||||
private readonly redis: Partial<Redis> = {};
|
private readonly redis: Partial<Redis> = {};
|
||||||
|
|
||||||
private dbInstance: Db;
|
private dbInstance: Db;
|
||||||
|
|
||||||
private dbStore = dbserver;
|
private dbStore = dbserver;
|
||||||
|
|
||||||
private readonly logger = new Logger(WAMonitoringService.name);
|
private readonly logger = new Logger(WAMonitoringService.name);
|
||||||
public readonly waInstances: Record<string, WAStartupService> = {};
|
public readonly waInstances: Record<string, WAStartupService> = {};
|
||||||
|
|
||||||
public delInstanceTime(instance: string) {
|
public delInstanceTime(instance: string) {
|
||||||
const time = this.configService.get<DelInstance>('DEL_INSTANCE');
|
const time = this.configService.get<DelInstance>('DEL_INSTANCE');
|
||||||
if (typeof time === 'number' && time > 0) {
|
if (typeof time === 'number' && time > 0) {
|
||||||
this.logger.verbose(`Instance "${instance}" don't have connection, will be removed in ${time} minutes`);
|
this.logger.verbose(`Instance "${instance}" don't have connection, will be removed in ${time} minutes`);
|
||||||
|
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
if (this.waInstances[instance]?.connectionStatus?.state !== 'open') {
|
if (this.waInstances[instance]?.connectionStatus?.state !== 'open') {
|
||||||
if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') {
|
if (this.waInstances[instance]?.connectionStatus?.state === 'connecting') {
|
||||||
await this.waInstances[instance]?.client?.logout('Log out instance: ' + instance);
|
await this.waInstances[instance]?.client?.logout('Log out instance: ' + instance);
|
||||||
this.waInstances[instance]?.client?.ws?.close();
|
this.waInstances[instance]?.client?.ws?.close();
|
||||||
this.waInstances[instance]?.client?.end(undefined);
|
this.waInstances[instance]?.client?.end(undefined);
|
||||||
this.waInstances[instance]?.removeRabbitmqQueues();
|
this.waInstances[instance]?.removeRabbitmqQueues();
|
||||||
delete this.waInstances[instance];
|
delete this.waInstances[instance];
|
||||||
} else {
|
} else {
|
||||||
this.waInstances[instance]?.removeRabbitmqQueues();
|
this.waInstances[instance]?.removeRabbitmqQueues();
|
||||||
delete this.waInstances[instance];
|
delete this.waInstances[instance];
|
||||||
this.eventEmitter.emit('remove.instance', instance, 'inner');
|
this.eventEmitter.emit('remove.instance', instance, 'inner');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 1000 * 60 * time);
|
}, 1000 * 60 * time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async instanceInfo(instanceName?: string) {
|
public async instanceInfo(instanceName?: string) {
|
||||||
this.logger.verbose('get instance info');
|
this.logger.verbose('get instance info');
|
||||||
if (instanceName && !this.waInstances[instanceName]) {
|
if (instanceName && !this.waInstances[instanceName]) {
|
||||||
throw new NotFoundException(`Instance "${instanceName}" not found`);
|
throw new NotFoundException(`Instance "${instanceName}" not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const instances: any[] = [];
|
const instances: any[] = [];
|
||||||
|
|
||||||
for await (const [key, value] of Object.entries(this.waInstances)) {
|
for await (const [key, value] of Object.entries(this.waInstances)) {
|
||||||
if (value) {
|
if (value) {
|
||||||
this.logger.verbose('get instance info: ' + key);
|
this.logger.verbose('get instance info: ' + key);
|
||||||
let chatwoot: any;
|
let chatwoot: any;
|
||||||
|
|
||||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
const findChatwoot = await this.waInstances[key].findChatwoot();
|
const findChatwoot = await this.waInstances[key].findChatwoot();
|
||||||
|
|
||||||
if (findChatwoot && findChatwoot.enabled) {
|
if (findChatwoot && findChatwoot.enabled) {
|
||||||
chatwoot = {
|
chatwoot = {
|
||||||
...findChatwoot,
|
...findChatwoot,
|
||||||
webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(key)}`,
|
webhook_url: `${urlServer}/chatwoot/webhook/${encodeURIComponent(key)}`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.connectionStatus.state === 'open') {
|
if (value.connectionStatus.state === 'open') {
|
||||||
this.logger.verbose('instance: ' + key + ' - connectionStatus: open');
|
this.logger.verbose('instance: ' + key + ' - connectionStatus: open');
|
||||||
|
|
||||||
const instanceData = {
|
const instanceData = {
|
||||||
instance: {
|
instance: {
|
||||||
instanceName: key,
|
instanceName: key,
|
||||||
owner: value.wuid,
|
owner: value.wuid,
|
||||||
profileName: (await value.getProfileName()) || 'not loaded',
|
profileName: (await value.getProfileName()) || 'not loaded',
|
||||||
profilePictureUrl: value.profilePictureUrl,
|
profilePictureUrl: value.profilePictureUrl,
|
||||||
profileStatus: (await value.getProfileStatus()) || '',
|
profileStatus: (await value.getProfileStatus()) || '',
|
||||||
status: value.connectionStatus.state,
|
status: value.connectionStatus.state,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
|
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
|
||||||
|
|
||||||
instanceData.instance['chatwoot'] = chatwoot;
|
instanceData.instance['chatwoot'] = chatwoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
instances.push(instanceData);
|
instances.push(instanceData);
|
||||||
} else {
|
} else {
|
||||||
this.logger.verbose('instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state);
|
this.logger.verbose('instance: ' + key + ' - connectionStatus: ' + value.connectionStatus.state);
|
||||||
|
|
||||||
const instanceData = {
|
const instanceData = {
|
||||||
instance: {
|
instance: {
|
||||||
instanceName: key,
|
instanceName: key,
|
||||||
status: value.connectionStatus.state,
|
status: value.connectionStatus.state,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
|
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
|
||||||
|
|
||||||
instanceData.instance['chatwoot'] = chatwoot;
|
instanceData.instance['chatwoot'] = chatwoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
instances.push(instanceData);
|
instances.push(instanceData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('return instance info: ' + instances.length);
|
this.logger.verbose('return instance info: ' + instances.length);
|
||||||
|
|
||||||
return instances.find((i) => i.instance.instanceName === instanceName) ?? instances;
|
return instances.find((i) => i.instance.instanceName === instanceName) ?? instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
private delInstanceFiles() {
|
private delInstanceFiles() {
|
||||||
this.logger.verbose('cron to delete instance files started');
|
this.logger.verbose('cron to delete instance files started');
|
||||||
setInterval(async () => {
|
setInterval(async () => {
|
||||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
const collections = await this.dbInstance.collections();
|
const collections = await this.dbInstance.collections();
|
||||||
collections.forEach(async (collection) => {
|
collections.forEach(async (collection) => {
|
||||||
const name = collection.namespace.replace(/^[\w-]+./, '');
|
const name = collection.namespace.replace(/^[\w-]+./, '');
|
||||||
await this.dbInstance.collection(name).deleteMany({
|
await this.dbInstance.collection(name).deleteMany({
|
||||||
$or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }],
|
$or: [{ _id: { $regex: /^app.state.*/ } }, { _id: { $regex: /^session-.*/ } }],
|
||||||
});
|
});
|
||||||
this.logger.verbose('instance files deleted: ' + name);
|
this.logger.verbose('instance files deleted: ' + name);
|
||||||
});
|
});
|
||||||
} else if (!this.redis.ENABLED) {
|
} else if (!this.redis.ENABLED) {
|
||||||
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
||||||
for await (const dirent of dir) {
|
for await (const dirent of dir) {
|
||||||
if (dirent.isDirectory()) {
|
if (dirent.isDirectory()) {
|
||||||
const files = readdirSync(join(INSTANCE_DIR, dirent.name), {
|
const files = readdirSync(join(INSTANCE_DIR, dirent.name), {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
});
|
});
|
||||||
files.forEach(async (file) => {
|
files.forEach(async (file) => {
|
||||||
if (file.match(/^app.state.*/) || file.match(/^session-.*/)) {
|
if (file.match(/^app.state.*/) || file.match(/^session-.*/)) {
|
||||||
rmSync(join(INSTANCE_DIR, dirent.name, file), {
|
rmSync(join(INSTANCE_DIR, dirent.name, file), {
|
||||||
recursive: true,
|
recursive: true,
|
||||||
force: true,
|
force: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.logger.verbose('instance files deleted: ' + dirent.name);
|
this.logger.verbose('instance files deleted: ' + dirent.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 3600 * 1000 * 2);
|
}, 3600 * 1000 * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async cleaningUp(instanceName: string) {
|
public async cleaningUp(instanceName: string) {
|
||||||
this.logger.verbose('cleaning up instance: ' + instanceName);
|
this.logger.verbose('cleaning up instance: ' + instanceName);
|
||||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
this.logger.verbose('cleaning up instance in database: ' + instanceName);
|
this.logger.verbose('cleaning up instance in database: ' + instanceName);
|
||||||
await this.repository.dbServer.connect();
|
await this.repository.dbServer.connect();
|
||||||
const collections: any[] = await this.dbInstance.collections();
|
const collections: any[] = await this.dbInstance.collections();
|
||||||
if (collections.length > 0) {
|
if (collections.length > 0) {
|
||||||
await this.dbInstance.dropCollection(instanceName);
|
await this.dbInstance.dropCollection(instanceName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.redis.ENABLED) {
|
if (this.redis.ENABLED) {
|
||||||
this.logger.verbose('cleaning up instance in redis: ' + instanceName);
|
this.logger.verbose('cleaning up instance in redis: ' + instanceName);
|
||||||
this.cache.reference = instanceName;
|
this.cache.reference = instanceName;
|
||||||
await this.cache.delAll();
|
await this.cache.delAll();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('cleaning up instance in files: ' + instanceName);
|
this.logger.verbose('cleaning up instance in files: ' + instanceName);
|
||||||
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
public async cleaningStoreFiles(instanceName: string) {
|
public async cleaningStoreFiles(instanceName: string) {
|
||||||
if (!this.db.ENABLED) {
|
if (!this.db.ENABLED) {
|
||||||
this.logger.verbose('cleaning store files instance: ' + instanceName);
|
this.logger.verbose('cleaning store files instance: ' + instanceName);
|
||||||
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
||||||
|
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'contacts', instanceName)}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'message-up', instanceName)}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'messages', instanceName)}`);
|
||||||
|
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'webhook', 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, 'chatwoot', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'chamaai', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'chamaai', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'proxy', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'proxy', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'rabbitmq', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'rabbitmq', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'typebot', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'typebot', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'websocket', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'websocket', instanceName + '*')}`);
|
||||||
execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`);
|
execSync(`rm -rf ${join(STORE_DIR, 'settings', instanceName + '*')}`);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('cleaning store database instance: ' + instanceName);
|
this.logger.verbose('cleaning store database instance: ' + instanceName);
|
||||||
|
|
||||||
await AuthModel.deleteMany({ owner: instanceName });
|
await AuthModel.deleteMany({ owner: instanceName });
|
||||||
await ChatModel.deleteMany({ owner: instanceName });
|
await ChatModel.deleteMany({ owner: instanceName });
|
||||||
await ContactModel.deleteMany({ owner: instanceName });
|
await ContactModel.deleteMany({ owner: instanceName });
|
||||||
await MessageModel.deleteMany({ owner: instanceName });
|
await MessageModel.deleteMany({ owner: instanceName });
|
||||||
|
|
||||||
await MessageUpModel.deleteMany({ owner: instanceName });
|
await MessageUpModel.deleteMany({ owner: instanceName });
|
||||||
await WebhookModel.deleteMany({ _id: instanceName });
|
await WebhookModel.deleteMany({ _id: instanceName });
|
||||||
await ChatwootModel.deleteMany({ _id: instanceName });
|
await ChatwootModel.deleteMany({ _id: instanceName });
|
||||||
|
|
||||||
await ChamaaiModel.deleteMany({ _id: instanceName });
|
await ChamaaiModel.deleteMany({ _id: instanceName });
|
||||||
await ProxyModel.deleteMany({ _id: instanceName });
|
await ProxyModel.deleteMany({ _id: instanceName });
|
||||||
await RabbitmqModel.deleteMany({ _id: instanceName });
|
await RabbitmqModel.deleteMany({ _id: instanceName });
|
||||||
await TypebotModel.deleteMany({ _id: instanceName });
|
await TypebotModel.deleteMany({ _id: instanceName });
|
||||||
await WebsocketModel.deleteMany({ _id: instanceName });
|
await WebsocketModel.deleteMany({ _id: instanceName });
|
||||||
|
|
||||||
await SettingsModel.deleteMany({ _id: instanceName });
|
await SettingsModel.deleteMany({ _id: instanceName });
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadInstance() {
|
public async loadInstance() {
|
||||||
this.logger.verbose('Loading instances');
|
this.logger.verbose('Loading instances');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.redis.ENABLED) {
|
if (this.redis.ENABLED) {
|
||||||
await this.loadInstancesFromRedis();
|
await this.loadInstancesFromRedis();
|
||||||
} else if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
} else if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||||
await this.loadInstancesFromDatabase();
|
await this.loadInstancesFromDatabase();
|
||||||
} else {
|
} else {
|
||||||
await this.loadInstancesFromFiles();
|
await this.loadInstancesFromFiles();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setInstance(name: string) {
|
private async setInstance(name: string) {
|
||||||
const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache);
|
const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache);
|
||||||
instance.instanceName = name;
|
instance.instanceName = name;
|
||||||
this.logger.verbose('Instance loaded: ' + name);
|
this.logger.verbose('Instance loaded: ' + name);
|
||||||
|
|
||||||
await instance.connectToWhatsapp();
|
await instance.connectToWhatsapp();
|
||||||
this.logger.verbose('connectToWhatsapp: ' + name);
|
this.logger.verbose('connectToWhatsapp: ' + name);
|
||||||
|
|
||||||
this.waInstances[name] = instance;
|
this.waInstances[name] = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadInstancesFromRedis() {
|
private async loadInstancesFromRedis() {
|
||||||
this.logger.verbose('Redis enabled');
|
this.logger.verbose('Redis enabled');
|
||||||
await this.cache.connect(this.redis as Redis);
|
await this.cache.connect(this.redis as Redis);
|
||||||
const keys = await this.cache.instanceKeys();
|
const keys = await this.cache.instanceKeys();
|
||||||
|
|
||||||
if (keys?.length > 0) {
|
if (keys?.length > 0) {
|
||||||
this.logger.verbose('Reading instance keys and setting instances');
|
this.logger.verbose('Reading instance keys and setting instances');
|
||||||
await Promise.all(keys.map((k) => this.setInstance(k.split(':')[1])));
|
await Promise.all(keys.map((k) => this.setInstance(k.split(':')[1])));
|
||||||
} else {
|
} else {
|
||||||
this.logger.verbose('No instance keys found');
|
this.logger.verbose('No instance keys found');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadInstancesFromDatabase() {
|
private async loadInstancesFromDatabase() {
|
||||||
this.logger.verbose('Database enabled');
|
this.logger.verbose('Database enabled');
|
||||||
await this.repository.dbServer.connect();
|
await this.repository.dbServer.connect();
|
||||||
const collections: any[] = await this.dbInstance.collections();
|
const collections: any[] = await this.dbInstance.collections();
|
||||||
|
|
||||||
if (collections.length > 0) {
|
if (collections.length > 0) {
|
||||||
this.logger.verbose('Reading collections and setting instances');
|
this.logger.verbose('Reading collections and setting instances');
|
||||||
await Promise.all(collections.map((coll) => this.setInstance(coll.namespace.replace(/^[\w-]+\./, ''))));
|
await Promise.all(collections.map((coll) => this.setInstance(coll.namespace.replace(/^[\w-]+\./, ''))));
|
||||||
} else {
|
} else {
|
||||||
this.logger.verbose('No collections found');
|
this.logger.verbose('No collections found');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadInstancesFromFiles() {
|
private async loadInstancesFromFiles() {
|
||||||
this.logger.verbose('Store in files enabled');
|
this.logger.verbose('Store in files enabled');
|
||||||
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
||||||
const instanceDirs = [];
|
const instanceDirs = [];
|
||||||
|
|
||||||
for await (const dirent of dir) {
|
for await (const dirent of dir) {
|
||||||
if (dirent.isDirectory()) {
|
if (dirent.isDirectory()) {
|
||||||
instanceDirs.push(dirent.name);
|
instanceDirs.push(dirent.name);
|
||||||
} else {
|
} else {
|
||||||
this.logger.verbose('No instance files found');
|
this.logger.verbose('No instance files found');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
instanceDirs.map(async (instanceName) => {
|
instanceDirs.map(async (instanceName) => {
|
||||||
this.logger.verbose('Reading instance files and setting instances: ' + instanceName);
|
this.logger.verbose('Reading instance files and setting instances: ' + instanceName);
|
||||||
const files = readdirSync(join(INSTANCE_DIR, instanceName), { encoding: 'utf-8' });
|
const files = readdirSync(join(INSTANCE_DIR, instanceName), { encoding: 'utf-8' });
|
||||||
|
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
|
||||||
} else {
|
} else {
|
||||||
await this.setInstance(instanceName);
|
await this.setInstance(instanceName);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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.eventEmitter.on('logout.instance', async (instanceName: string) => {
|
||||||
this.logger.verbose('logout instance: ' + instanceName);
|
this.logger.verbose('logout instance: ' + instanceName);
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
||||||
this.cleaningUp(instanceName);
|
this.cleaningUp(instanceName);
|
||||||
} finally {
|
} finally {
|
||||||
this.logger.warn(`Instance "${instanceName}" - LOGOUT`);
|
this.logger.warn(`Instance "${instanceName}" - LOGOUT`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private noConnection() {
|
private noConnection() {
|
||||||
this.logger.verbose('checking instances without connection');
|
this.logger.verbose('checking instances without connection');
|
||||||
this.eventEmitter.on('no.connection', async (instanceName) => {
|
this.eventEmitter.on('no.connection', async (instanceName) => {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('logging out instance: ' + instanceName);
|
this.logger.verbose('logging out instance: ' + instanceName);
|
||||||
await this.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName);
|
await this.waInstances[instanceName]?.client?.logout('Log out instance: ' + instanceName);
|
||||||
|
|
||||||
this.logger.verbose('close connection instance: ' + instanceName);
|
this.logger.verbose('close connection instance: ' + instanceName);
|
||||||
this.waInstances[instanceName]?.client?.ws?.close();
|
this.waInstances[instanceName]?.client?.ws?.close();
|
||||||
|
|
||||||
this.waInstances[instanceName].instance.qrcode = { count: 0 };
|
this.waInstances[instanceName].instance.qrcode = { count: 0 };
|
||||||
this.waInstances[instanceName].stateConnection.state = 'close';
|
this.waInstances[instanceName].stateConnection.state = 'close';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error({
|
this.logger.error({
|
||||||
localError: 'noConnection',
|
localError: 'noConnection',
|
||||||
warn: 'Error deleting instance from memory.',
|
warn: 'Error deleting instance from memory.',
|
||||||
error,
|
error,
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
this.logger.warn(`Instance "${instanceName}" - NOT CONNECTION`);
|
this.logger.warn(`Instance "${instanceName}" - NOT CONNECTION`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
114
src/whatsapp/services/openai.service.ts
Executable file → Normal file
114
src/whatsapp/services/openai.service.ts
Executable file → Normal file
@ -1,57 +1,57 @@
|
|||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { initQueues } from '../../libs/amqp.server';
|
import { initQueues } from '../../libs/amqp.server';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { OpenaiDto } from '../dto/openai.dto';
|
import { OpenaiDto } from '../dto/openai.dto';
|
||||||
import { ContactOpenaiDto } from '../dto/contactopenai.dto';
|
import { ContactOpenaiDto } from '../dto/contactopenai.dto';
|
||||||
import { OpenaiRaw } from '../models';
|
import { OpenaiRaw } from '../models';
|
||||||
import { WAMonitoringService } from './monitor.service';
|
import { WAMonitoringService } from './monitor.service';
|
||||||
|
|
||||||
export class OpenaiService {
|
export class OpenaiService {
|
||||||
constructor(private readonly waMonitor: WAMonitoringService) {}
|
constructor(private readonly waMonitor: WAMonitoringService) {}
|
||||||
|
|
||||||
private readonly logger = new Logger(OpenaiService.name);
|
private readonly logger = new Logger(OpenaiService.name);
|
||||||
|
|
||||||
public create(instance: InstanceDto, data: OpenaiDto) {
|
public create(instance: InstanceDto, data: OpenaiDto) {
|
||||||
this.logger.verbose('create openai: ' + instance.instanceName);
|
this.logger.verbose('create openai: ' + instance.instanceName);
|
||||||
this.waMonitor.waInstances[instance.instanceName].setOpenai(data);
|
this.waMonitor.waInstances[instance.instanceName].setOpenai(data);
|
||||||
return { openai: { ...instance, openai: data } };
|
return { openai: { ...instance, openai: data } };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async find(instance: InstanceDto): Promise<OpenaiRaw> {
|
public async find(instance: InstanceDto): Promise<OpenaiRaw> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('find openai: ' + instance.instanceName);
|
this.logger.verbose('find openai: ' + instance.instanceName);
|
||||||
const result = await this.waMonitor.waInstances[instance.instanceName].findOpenai();
|
const result = await this.waMonitor.waInstances[instance.instanceName].findOpenai();
|
||||||
|
|
||||||
if (Object.keys(result).length === 0) {
|
if (Object.keys(result).length === 0) {
|
||||||
throw new Error('openai not found');
|
throw new Error('openai not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { chave: '', enabled: false, events: [] };
|
return { chave: '', enabled: false, events: [] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public createContact(instance: InstanceDto, data: ContactOpenaiDto) {
|
public createContact(instance: InstanceDto, data: ContactOpenaiDto) {
|
||||||
this.logger.verbose('create openai: ' + instance.instanceName);
|
this.logger.verbose('create openai: ' + instance.instanceName);
|
||||||
this.waMonitor.waInstances[instance.instanceName].setContactOpenai(data);
|
this.waMonitor.waInstances[instance.instanceName].setContactOpenai(data);
|
||||||
return { openai: { ...instance, openai: data } };
|
return { openai: { ...instance, openai: data } };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async findContact(instance: InstanceDto): Promise<OpenaiRaw> {
|
public async findContact(instance: InstanceDto): Promise<OpenaiRaw> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('find openai: ' + instance.instanceName);
|
this.logger.verbose('find openai: ' + instance.instanceName);
|
||||||
const result = await this.waMonitor.waInstances[instance.instanceName].findContactOpenai();
|
const result = await this.waMonitor.waInstances[instance.instanceName].findContactOpenai();
|
||||||
|
|
||||||
if (Object.keys(result).length === 0) {
|
if (Object.keys(result).length === 0) {
|
||||||
throw new Error('openai not found');
|
throw new Error('openai not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { chave: '', enabled: false, events: [] };
|
return { chave: '', enabled: false, events: [] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
68
src/whatsapp/services/sqs.service.ts
Executable file → Normal file
68
src/whatsapp/services/sqs.service.ts
Executable file → Normal file
@ -1,35 +1,35 @@
|
|||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { initQueues } from '../../libs/sqs.server';
|
import { initQueues } from '../../libs/sqs.server';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { SqsDto } from '../dto/sqs.dto';
|
import { SqsDto } from '../dto/sqs.dto';
|
||||||
import { SqsRaw } from '../models';
|
import { SqsRaw } from '../models';
|
||||||
import { WAMonitoringService } from './monitor.service';
|
import { WAMonitoringService } from './monitor.service';
|
||||||
|
|
||||||
export class SqsService {
|
export class SqsService {
|
||||||
constructor(private readonly waMonitor: WAMonitoringService) { }
|
constructor(private readonly waMonitor: WAMonitoringService) { }
|
||||||
|
|
||||||
private readonly logger = new Logger(SqsService.name);
|
private readonly logger = new Logger(SqsService.name);
|
||||||
|
|
||||||
public create(instance: InstanceDto, data: SqsDto) {
|
public create(instance: InstanceDto, data: SqsDto) {
|
||||||
this.logger.verbose('create sqs: ' + instance.instanceName);
|
this.logger.verbose('create sqs: ' + instance.instanceName);
|
||||||
this.waMonitor.waInstances[instance.instanceName].setSqs(data);
|
this.waMonitor.waInstances[instance.instanceName].setSqs(data);
|
||||||
|
|
||||||
initQueues(instance.instanceName, data.events);
|
initQueues(instance.instanceName, data.events);
|
||||||
return { sqs: { ...instance, sqs: data } };
|
return { sqs: { ...instance, sqs: data } };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async find(instance: InstanceDto): Promise<SqsRaw> {
|
public async find(instance: InstanceDto): Promise<SqsRaw> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('find sqs: ' + instance.instanceName);
|
this.logger.verbose('find sqs: ' + instance.instanceName);
|
||||||
const result = await this.waMonitor.waInstances[instance.instanceName].findSqs();
|
const result = await this.waMonitor.waInstances[instance.instanceName].findSqs();
|
||||||
|
|
||||||
if (Object.keys(result).length === 0) {
|
if (Object.keys(result).length === 0) {
|
||||||
throw new Error('Sqs not found');
|
throw new Error('Sqs not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { enabled: false, events: [] };
|
return { enabled: false, events: [] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
2020
src/whatsapp/services/typebot.service.ts
Executable file → Normal file
2020
src/whatsapp/services/typebot.service.ts
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
7682
src/whatsapp/services/whatsapp.service.ts
Executable file → Normal file
7682
src/whatsapp/services/whatsapp.service.ts
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
290
src/whatsapp/types/wa.types.ts
Executable file → Normal file
290
src/whatsapp/types/wa.types.ts
Executable file → Normal file
@ -1,145 +1,145 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-namespace */
|
/* eslint-disable @typescript-eslint/no-namespace */
|
||||||
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',
|
||||||
TYPEBOT_START = 'typebot.start',
|
TYPEBOT_START = 'typebot.start',
|
||||||
TYPEBOT_CHANGE_STATUS = 'typebot.change-status',
|
TYPEBOT_CHANGE_STATUS = 'typebot.change-status',
|
||||||
CHAMA_AI_ACTION = 'chama-ai.action',
|
CHAMA_AI_ACTION = 'chama-ai.action',
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
webhook_base64?: boolean;
|
webhook_base64?: 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 LocalWebsocket = {
|
export type LocalWebsocket = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalRabbitmq = {
|
export type LocalRabbitmq = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalSqs = {
|
export type LocalSqs = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalOpenai = {
|
export type LocalOpenai = {
|
||||||
chave?: string;
|
chave?: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
events?: string[];
|
events?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type Session = {
|
type Session = {
|
||||||
remoteJid?: string;
|
remoteJid?: string;
|
||||||
sessionId?: string;
|
sessionId?: string;
|
||||||
createdAt?: number;
|
createdAt?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalTypebot = {
|
export type LocalTypebot = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
url?: string;
|
url?: string;
|
||||||
typebot?: string;
|
typebot?: string;
|
||||||
expire?: number;
|
expire?: number;
|
||||||
keyword_finish?: string;
|
keyword_finish?: string;
|
||||||
delay_message?: number;
|
delay_message?: number;
|
||||||
unknown_message?: string;
|
unknown_message?: string;
|
||||||
listening_from_me?: boolean;
|
listening_from_me?: boolean;
|
||||||
sessions?: Session[];
|
sessions?: Session[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalProxy = {
|
export type LocalProxy = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
proxy?: string;
|
proxy?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LocalChamaai = {
|
export type LocalChamaai = {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
url?: string;
|
url?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
waNumber?: string;
|
waNumber?: string;
|
||||||
answerByAudio?: boolean;
|
answerByAudio?: 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',
|
||||||
];
|
];
|
||||||
|
350
src/whatsapp/whatsapp.module.ts
Executable file → Normal file
350
src/whatsapp/whatsapp.module.ts
Executable file → Normal file
@ -1,175 +1,175 @@
|
|||||||
import { configService } from '../config/env.config';
|
import { configService } from '../config/env.config';
|
||||||
import { eventEmitter } from '../config/event.config';
|
import { eventEmitter } from '../config/event.config';
|
||||||
import { Logger } from '../config/logger.config';
|
import { Logger } from '../config/logger.config';
|
||||||
import { dbserver } from '../libs/db.connect';
|
import { dbserver } from '../libs/db.connect';
|
||||||
import { RedisCache } from '../libs/redis.client';
|
import { RedisCache } from '../libs/redis.client';
|
||||||
import { ChamaaiController } from './controllers/chamaai.controller';
|
import { ChamaaiController } from './controllers/chamaai.controller';
|
||||||
import { ChatController } from './controllers/chat.controller';
|
import { ChatController } from './controllers/chat.controller';
|
||||||
import { ChatwootController } from './controllers/chatwoot.controller';
|
import { ChatwootController } from './controllers/chatwoot.controller';
|
||||||
import { GroupController } from './controllers/group.controller';
|
import { GroupController } from './controllers/group.controller';
|
||||||
import { InstanceController } from './controllers/instance.controller';
|
import { InstanceController } from './controllers/instance.controller';
|
||||||
import { ProxyController } from './controllers/proxy.controller';
|
import { ProxyController } from './controllers/proxy.controller';
|
||||||
import { RabbitmqController } from './controllers/rabbitmq.controller';
|
import { RabbitmqController } from './controllers/rabbitmq.controller';
|
||||||
import { OpenaiController } from './controllers/openai.controller';
|
import { OpenaiController } from './controllers/openai.controller';
|
||||||
import { SendMessageController } from './controllers/sendMessage.controller';
|
import { SendMessageController } from './controllers/sendMessage.controller';
|
||||||
import { SettingsController } from './controllers/settings.controller';
|
import { SettingsController } from './controllers/settings.controller';
|
||||||
import { SqsController } from './controllers/sqs.controller';
|
import { SqsController } from './controllers/sqs.controller';
|
||||||
import { TypebotController } from './controllers/typebot.controller';
|
import { TypebotController } from './controllers/typebot.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 { WebsocketController } from './controllers/websocket.controller';
|
import { WebsocketController } from './controllers/websocket.controller';
|
||||||
import {
|
import {
|
||||||
AuthModel,
|
AuthModel,
|
||||||
ChamaaiModel,
|
ChamaaiModel,
|
||||||
ChatModel,
|
ChatModel,
|
||||||
ChatwootModel,
|
ChatwootModel,
|
||||||
ContactModel,
|
ContactModel,
|
||||||
MessageModel,
|
MessageModel,
|
||||||
MessageUpModel,
|
MessageUpModel,
|
||||||
ProxyModel,
|
ProxyModel,
|
||||||
RabbitmqModel,
|
RabbitmqModel,
|
||||||
OpenaiModel,
|
OpenaiModel,
|
||||||
ContactOpenaiModel,
|
ContactOpenaiModel,
|
||||||
SettingsModel,
|
SettingsModel,
|
||||||
SqsModel,
|
SqsModel,
|
||||||
TypebotModel,
|
TypebotModel,
|
||||||
WebhookModel,
|
WebhookModel,
|
||||||
WebsocketModel,
|
WebsocketModel,
|
||||||
} from './models';
|
} from './models';
|
||||||
import { AuthRepository } from './repository/auth.repository';
|
import { AuthRepository } from './repository/auth.repository';
|
||||||
import { ChamaaiRepository } from './repository/chamaai.repository';
|
import { ChamaaiRepository } from './repository/chamaai.repository';
|
||||||
import { ChatRepository } from './repository/chat.repository';
|
import { ChatRepository } from './repository/chat.repository';
|
||||||
import { ChatwootRepository } from './repository/chatwoot.repository';
|
import { ChatwootRepository } from './repository/chatwoot.repository';
|
||||||
import { ContactRepository } from './repository/contact.repository';
|
import { ContactRepository } from './repository/contact.repository';
|
||||||
import { MessageRepository } from './repository/message.repository';
|
import { MessageRepository } from './repository/message.repository';
|
||||||
import { MessageUpRepository } from './repository/messageUp.repository';
|
import { MessageUpRepository } from './repository/messageUp.repository';
|
||||||
import { ProxyRepository } from './repository/proxy.repository';
|
import { ProxyRepository } from './repository/proxy.repository';
|
||||||
import { RabbitmqRepository } from './repository/rabbitmq.repository';
|
import { RabbitmqRepository } from './repository/rabbitmq.repository';
|
||||||
import { OpenaiRepository } from './repository/openai.repository';
|
import { OpenaiRepository } from './repository/openai.repository';
|
||||||
import { RepositoryBroker } from './repository/repository.manager';
|
import { RepositoryBroker } from './repository/repository.manager';
|
||||||
import { SettingsRepository } from './repository/settings.repository';
|
import { SettingsRepository } from './repository/settings.repository';
|
||||||
import { SqsRepository } from './repository/sqs.repository';
|
import { SqsRepository } from './repository/sqs.repository';
|
||||||
import { TypebotRepository } from './repository/typebot.repository';
|
import { TypebotRepository } from './repository/typebot.repository';
|
||||||
import { WebhookRepository } from './repository/webhook.repository';
|
import { WebhookRepository } from './repository/webhook.repository';
|
||||||
import { WebsocketRepository } from './repository/websocket.repository';
|
import { WebsocketRepository } from './repository/websocket.repository';
|
||||||
import { AuthService } from './services/auth.service';
|
import { AuthService } from './services/auth.service';
|
||||||
import { ChamaaiService } from './services/chamaai.service';
|
import { ChamaaiService } from './services/chamaai.service';
|
||||||
import { ChatwootService } from './services/chatwoot.service';
|
import { ChatwootService } from './services/chatwoot.service';
|
||||||
import { WAMonitoringService } from './services/monitor.service';
|
import { WAMonitoringService } from './services/monitor.service';
|
||||||
import { ProxyService } from './services/proxy.service';
|
import { ProxyService } from './services/proxy.service';
|
||||||
import { RabbitmqService } from './services/rabbitmq.service';
|
import { RabbitmqService } from './services/rabbitmq.service';
|
||||||
import { OpenaiService } from './services/openai.service';
|
import { OpenaiService } from './services/openai.service';
|
||||||
import { SettingsService } from './services/settings.service';
|
import { SettingsService } from './services/settings.service';
|
||||||
import { SqsService } from './services/sqs.service';
|
import { SqsService } from './services/sqs.service';
|
||||||
import { TypebotService } from './services/typebot.service';
|
import { TypebotService } from './services/typebot.service';
|
||||||
import { WebhookService } from './services/webhook.service';
|
import { WebhookService } from './services/webhook.service';
|
||||||
import { WebsocketService } from './services/websocket.service';
|
import { WebsocketService } from './services/websocket.service';
|
||||||
|
|
||||||
const logger = new Logger('WA MODULE');
|
const logger = new Logger('WA MODULE');
|
||||||
|
|
||||||
const messageRepository = new MessageRepository(MessageModel, configService);
|
const messageRepository = new MessageRepository(MessageModel, configService);
|
||||||
const chatRepository = new ChatRepository(ChatModel, configService);
|
const chatRepository = new ChatRepository(ChatModel, configService);
|
||||||
const contactRepository = new ContactRepository(ContactModel, configService);
|
const contactRepository = new ContactRepository(ContactModel, configService);
|
||||||
const messageUpdateRepository = new MessageUpRepository(MessageUpModel, configService);
|
const messageUpdateRepository = new MessageUpRepository(MessageUpModel, configService);
|
||||||
const typebotRepository = new TypebotRepository(TypebotModel, configService);
|
const typebotRepository = new TypebotRepository(TypebotModel, configService);
|
||||||
const webhookRepository = new WebhookRepository(WebhookModel, configService);
|
const webhookRepository = new WebhookRepository(WebhookModel, configService);
|
||||||
const websocketRepository = new WebsocketRepository(WebsocketModel, configService);
|
const websocketRepository = new WebsocketRepository(WebsocketModel, configService);
|
||||||
const proxyRepository = new ProxyRepository(ProxyModel, configService);
|
const proxyRepository = new ProxyRepository(ProxyModel, configService);
|
||||||
const chamaaiRepository = new ChamaaiRepository(ChamaaiModel, configService);
|
const chamaaiRepository = new ChamaaiRepository(ChamaaiModel, configService);
|
||||||
const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService);
|
const rabbitmqRepository = new RabbitmqRepository(RabbitmqModel, configService);
|
||||||
const openaiRepository = new OpenaiRepository(OpenaiModel,ContactOpenaiModel, configService);
|
const openaiRepository = new OpenaiRepository(OpenaiModel,ContactOpenaiModel, configService);
|
||||||
const chatwootRepository = new ChatwootRepository(ChatwootModel, configService);
|
const chatwootRepository = new ChatwootRepository(ChatwootModel, configService);
|
||||||
const settingsRepository = new SettingsRepository(SettingsModel, configService);
|
const settingsRepository = new SettingsRepository(SettingsModel, configService);
|
||||||
const sqsRepository = new SqsRepository(SqsModel, configService);
|
const sqsRepository = new SqsRepository(SqsModel, 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,
|
||||||
websocketRepository,
|
websocketRepository,
|
||||||
rabbitmqRepository,
|
rabbitmqRepository,
|
||||||
openaiRepository,
|
openaiRepository,
|
||||||
openaiRepository,
|
openaiRepository,
|
||||||
sqsRepository,
|
sqsRepository,
|
||||||
typebotRepository,
|
typebotRepository,
|
||||||
proxyRepository,
|
proxyRepository,
|
||||||
chamaaiRepository,
|
chamaaiRepository,
|
||||||
authRepository,
|
authRepository,
|
||||||
configService,
|
configService,
|
||||||
dbserver?.getClient(),
|
dbserver?.getClient(),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const cache = new RedisCache();
|
export const cache = new RedisCache();
|
||||||
|
|
||||||
export const waMonitor = new WAMonitoringService(eventEmitter, configService, repository, cache);
|
export const waMonitor = new WAMonitoringService(eventEmitter, configService, repository, cache);
|
||||||
|
|
||||||
const authService = new AuthService(configService, waMonitor, repository);
|
const authService = new AuthService(configService, waMonitor, repository);
|
||||||
|
|
||||||
const typebotService = new TypebotService(waMonitor, configService);
|
const typebotService = new TypebotService(waMonitor, configService);
|
||||||
|
|
||||||
export const typebotController = new TypebotController(typebotService);
|
export const typebotController = new TypebotController(typebotService);
|
||||||
|
|
||||||
const webhookService = new WebhookService(waMonitor);
|
const webhookService = new WebhookService(waMonitor);
|
||||||
|
|
||||||
export const webhookController = new WebhookController(webhookService);
|
export const webhookController = new WebhookController(webhookService);
|
||||||
|
|
||||||
const websocketService = new WebsocketService(waMonitor);
|
const websocketService = new WebsocketService(waMonitor);
|
||||||
|
|
||||||
export const websocketController = new WebsocketController(websocketService);
|
export const websocketController = new WebsocketController(websocketService);
|
||||||
|
|
||||||
const proxyService = new ProxyService(waMonitor);
|
const proxyService = new ProxyService(waMonitor);
|
||||||
|
|
||||||
export const proxyController = new ProxyController(proxyService);
|
export const proxyController = new ProxyController(proxyService);
|
||||||
|
|
||||||
const chamaaiService = new ChamaaiService(waMonitor, configService);
|
const chamaaiService = new ChamaaiService(waMonitor, configService);
|
||||||
|
|
||||||
export const chamaaiController = new ChamaaiController(chamaaiService);
|
export const chamaaiController = new ChamaaiController(chamaaiService);
|
||||||
|
|
||||||
const rabbitmqService = new RabbitmqService(waMonitor);
|
const rabbitmqService = new RabbitmqService(waMonitor);
|
||||||
|
|
||||||
export const rabbitmqController = new RabbitmqController(rabbitmqService);
|
export const rabbitmqController = new RabbitmqController(rabbitmqService);
|
||||||
|
|
||||||
const sqsService = new SqsService(waMonitor);
|
const sqsService = new SqsService(waMonitor);
|
||||||
|
|
||||||
export const sqsController = new SqsController(sqsService);
|
export const sqsController = new SqsController(sqsService);
|
||||||
|
|
||||||
const openaiService = new OpenaiService(waMonitor);
|
const openaiService = new OpenaiService(waMonitor);
|
||||||
|
|
||||||
export const openaiController = new OpenaiController(openaiService);
|
export const openaiController = new OpenaiController(openaiService);
|
||||||
|
|
||||||
const chatwootService = new ChatwootService(waMonitor, configService);
|
const chatwootService = new ChatwootService(waMonitor, configService);
|
||||||
|
|
||||||
export const chatwootController = new ChatwootController(chatwootService, configService);
|
export const chatwootController = new ChatwootController(chatwootService, configService);
|
||||||
|
|
||||||
const settingsService = new SettingsService(waMonitor);
|
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,
|
||||||
websocketService,
|
websocketService,
|
||||||
rabbitmqService,
|
rabbitmqService,
|
||||||
openaiService,
|
openaiService,
|
||||||
proxyService,
|
proxyService,
|
||||||
sqsService,
|
sqsService,
|
||||||
typebotService,
|
typebotService,
|
||||||
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);
|
||||||
export const chatController = new ChatController(waMonitor);
|
export const chatController = new ChatController(waMonitor);
|
||||||
export const groupController = new GroupController(waMonitor);
|
export const groupController = new GroupController(waMonitor);
|
||||||
|
|
||||||
logger.info('Module - ON');
|
logger.info('Module - ON');
|
||||||
|
Loading…
Reference in New Issue
Block a user