Merge branch 'release/1.3.2'

This commit is contained in:
Davidson Gomes 2023-07-21 17:18:40 -03:00
commit 98722e7acf
17 changed files with 315 additions and 447 deletions

2
.gitignore vendored
View File

@ -16,6 +16,8 @@ lerna-debug.log*
/docker-compose-data
/docker-data
docker-compose.yaml
# Package
/yarn.lock
/package-lock.json

View File

@ -1,3 +1,15 @@
# 1.3.2 (homolog)
### Fixed
* Fix in update settings that needed to restart after updated
* Correction in the use of the api with mongodb
* Adjustments to search endpoint for contacts, chats, messages and Status messages
* Now when deleting the instance, the data referring to it in mongodb is also deleted
* It is now validated if the instance name contains uppercase and special characters
* For compatibility reasons, container mode has been removed
* Added docker-compose files example
# 1.3.1 (2023-07-20 07:48)
### Fixed

View File

@ -1,13 +1,13 @@
# Server URL - Set your application url
SERVER_URL='http://localhost:8080'
SERVER_URL=http://localhost:8080
# Cors - * for all or set separate by commas - ex.: 'yourdomain1.com, yourdomain2.com'
CORS_ORIGIN='*'
CORS_METHODS='POST,GET,PUT,DELETE'
CORS_ORIGIN=*
CORS_METHODS=POST,GET,PUT,DELETE
CORS_CREDENTIALS=true
# Determine the logs to be displayed
LOG_LEVEL='ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS'
LOG_LEVEL=ERROR,WARN,DEBUG,INFO,LOG,VERBOSE,DARK,WEBHOOKS
LOG_COLOR=true
# Log Baileys - "fatal" | "error" | "warn" | "info" | "debug" | "trace"
LOG_BAILEYS=error
@ -31,9 +31,9 @@ CLEAN_STORE_CONTACTS=true
CLEAN_STORE_CHATS=true
# Permanent data storage
DATABASE_ENABLED=false
DATABASE_ENABLED=true
DATABASE_CONNECTION_URI=mongodb://root:root@mongodb:27017/?authSource=admin&readPreference=primary&ssl=false&directConnection=true
DATABASE_CONNECTION_DB_PREFIX_NAME=evolution
DATABASE_CONNECTION_DB_PREFIX_NAME=evdocker
# Choose the data you want to save in the application's database or store
DATABASE_SAVE_DATA_INSTANCE=false
@ -42,9 +42,9 @@ DATABASE_SAVE_MESSAGE_UPDATE=false
DATABASE_SAVE_DATA_CONTACTS=false
DATABASE_SAVE_DATA_CHATS=false
REDIS_ENABLED=false
REDIS_ENABLED=true
REDIS_URI=redis://redis:6379
REDIS_PREFIX_KEY=evolution
REDIS_PREFIX_KEY=evdocker
# Global Webhook Settings
# Each instance's Webhook URL and events will be requested at the time it is created
@ -77,7 +77,7 @@ WEBHOOK_EVENTS_CONNECTION_UPDATE=true
WEBHOOK_EVENTS_NEW_JWT_TOKEN=false
# Name that will be displayed on smartphone connection
CONFIG_SESSION_PHONE_CLIENT='Evolution API'
CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI
# Browser Name = chrome | firefox | edge | opera | safari
CONFIG_SESSION_PHONE_NAME=chrome
@ -88,22 +88,12 @@ QRCODE_LIMIT=30
# 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
# jwt or 'apikey'
AUTHENTICATION_TYPE='apikey'
AUTHENTICATION_TYPE=apikey
## Define a global apikey to access all instances.
### OBS: This key must be inserted in the request header to create an instance.
AUTHENTICATION_API_KEY='B6D711FCDE4D4FD5936544120E713976'
AUTHENTICATION_API_KEY=B6D711FCDE4D4FD5936544120E713976
AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=true
## Set the secret key to encrypt and decrypt your token and its expiration time
# seconds - 3600s ===1h | zero (0) - never expires
AUTHENTICATION_JWT_EXPIRIN_IN=0
AUTHENTICATION_JWT_SECRET='L0YWtjb2w554WFqPG'
# Set the instance name and webhook url to create an instance in init the application
# With this option activated, you work with a url per webhook event, respecting the local url and the name of each event
# container or server
AUTHENTICATION_INSTANCE_MODE=server
# if you are using container mode, set the container name and the webhook url to default instance
AUTHENTICATION_INSTANCE_NAME=evolution
AUTHENTICATION_INSTANCE_WEBHOOK_URL=''
AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID=1
AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN=123456
AUTHENTICATION_INSTANCE_CHATWOOT_URL=''
AUTHENTICATION_JWT_SECRET='L=0YWt]b2w[WF>#>:&E`'

View File

@ -12,13 +12,6 @@ services:
- evolution_redis:/data
ports:
- 6379:6379
rebrow:
image: marian/rebrow
ports:
- 5001:5001
links:
- redis
volumes:
evolution_redis:

View File

@ -13,7 +13,7 @@ COPY ./package.json .
ENV DOCKER_ENV=true
ENV SERVER_URL='http://localhost:8080'
ENV SERVER_URL=http://localhost:8080
ENV CORS_ORIGIN=*
ENV CORS_METHODS=POST,GET,PUT,DELETE
@ -77,7 +77,7 @@ ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=true
ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false
ENV CONFIG_SESSION_PHONE_CLIENT='Evolution API'
ENV CONFIG_SESSION_PHONE_CLIENT=EvolutionAPI
ENV CONFIG_SESSION_PHONE_NAME=chrome
ENV QRCODE_LIMIT=30

View File

@ -10,6 +10,8 @@ services:
volumes:
- evolution_instances:/evolution/instances
- evolution_store:/evolution/store
networks:
- evolution-net
env_file:
- ./Docker/.env
command: ['node', './dist/src/main.js']

View File

@ -0,0 +1,79 @@
version: '3.3'
services:
api:
container_name: evolution_api
image: evolution/api:local
restart: always
ports:
- 8080:8080
volumes:
- evolution_instances:/evolution/instances
- evolution_store:/evolution/store
networks:
- evolution-net
env_file:
- ./Docker/.env
command: ['node', './dist/src/main.js']
expose:
- 8080
mongodb:
container_name: mongodb
image: mongo
restart: always
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=root
- PUID=1000
- PGID=1000
volumes:
- evolution_mongodb_data:/data/db
- evolution_mongodb_configdb:/data/configdb
networks:
- evolution-net
expose:
- 27017
mongo-express:
image: mongo-express
networks:
- evolution-net
environment:
ME_CONFIG_BASICAUTH_USERNAME: root
ME_CONFIG_BASICAUTH_PASSWORD: root
ME_CONFIG_MONGODB_SERVER: mongodb
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: root
ports:
- 8081:8081
links:
- mongodb
redis:
image: redis:latest
container_name: redis
command: >
redis-server
--port 6379
--appendonly yes
volumes:
- evolution_redis:/data
networks:
- evolution-net
ports:
- 6379:6379
volumes:
evolution_instances:
evolution_store:
evolution_mongodb_data:
evolution_mongodb_configdb:
evolution_redis:
networks:
evolution-net:
external: true

View File

@ -1,6 +1,6 @@
{
"name": "evolution-api",
"version": "1.3.1",
"version": "1.3.2",
"description": "Rest api for communication with WhatsApp",
"main": "./dist/src/main.js",
"scripts": {

View File

@ -94,20 +94,12 @@ export type EventsWebhook = {
export type ApiKey = { KEY: string };
export type Jwt = { EXPIRIN_IN: number; SECRET: string };
export type Instance = {
NAME: string;
WEBHOOK_URL: string;
MODE: string;
CHATWOOT_ACCOUNT_ID: string;
CHATWOOT_TOKEN: string;
CHATWOOT_URL: string;
};
export type Auth = {
API_KEY: ApiKey;
EXPOSE_IN_FETCH_INSTANCES: boolean;
JWT: Jwt;
TYPE: 'jwt' | 'apikey';
INSTANCE: Instance;
};
export type DelInstance = number | boolean;
@ -276,15 +268,6 @@ export class ConfigService {
: 3600,
SECRET: process.env.AUTHENTICATION_JWT_SECRET,
},
INSTANCE: {
NAME: process.env.AUTHENTICATION_INSTANCE_NAME,
WEBHOOK_URL: process.env.AUTHENTICATION_INSTANCE_WEBHOOK_URL,
MODE: process.env.AUTHENTICATION_INSTANCE_MODE,
CHATWOOT_ACCOUNT_ID:
process.env.AUTHENTICATION_INSTANCE_CHATWOOT_ACCOUNT_ID || '',
CHATWOOT_TOKEN: process.env.AUTHENTICATION_INSTANCE_CHATWOOT_TOKEN || '',
CHATWOOT_URL: process.env.AUTHENTICATION_INSTANCE_CHATWOOT_URL || '',
},
},
};
}

View File

@ -136,14 +136,4 @@ AUTHENTICATION:
# Set the secret key to encrypt and decrypt your token and its expiration time.
JWT:
EXPIRIN_IN: 0 # seconds - 3600s === 1h | zero (0) - never expires
SECRET: L=0YWt]b2w[WF>#>:&E`
# Set the instance name and webhook url to create an instance in init the application
INSTANCE:
# With this option activated, you work with a url per webhook event, respecting the local url and the name of each event
MODE: server # container or server
# if you are using container mode, set the container name and the webhook url to default instance
NAME: evolution
WEBHOOK_URL: <url>
CHATWOOT_ACCOUNT_ID: 1
CHATWOOT_TOKEN: 123456
CHATWOOT_URL: <url>
SECRET: L=0YWt]b2w[WF>#>:&E`

View File

@ -42,273 +42,86 @@ export class InstanceController {
}: InstanceDto) {
this.logger.verbose('requested createInstance from ' + instanceName + ' instance');
const mode = this.configService.get<Auth>('AUTHENTICATION').INSTANCE.MODE;
if (mode === 'container') {
this.logger.verbose('container mode');
if (Object.keys(this.waMonitor.waInstances).length > 0) {
throw new BadRequestException([
'Instance already created',
'Only one instance can be created',
]);
}
this.logger.verbose('checking duplicate token');
await this.authService.checkDuplicateToken(token);
this.logger.verbose('creating instance');
const instance = new WAStartupService(
this.configService,
this.eventEmitter,
this.repository,
this.cache,
if (instanceName !== instanceName.toLowerCase().replace(/[^a-z0-9]/g, '')) {
throw new BadRequestException(
'The instance name must be lowercase and without special characters',
);
instance.instanceName = instanceName
.toLowerCase()
.replace(/[^a-z0-9]/g, '')
.replace(' ', '');
this.logger.verbose('instance: ' + instance.instanceName + ' created');
}
this.waMonitor.waInstances[instance.instanceName] = instance;
this.waMonitor.delInstanceTime(instance.instanceName);
this.logger.verbose('checking duplicate token');
await this.authService.checkDuplicateToken(token);
this.logger.verbose('generating hash');
const hash = await this.authService.generateHash(
{
instanceName: instance.instanceName,
},
token,
);
this.logger.verbose('creating instance');
const instance = new WAStartupService(
this.configService,
this.eventEmitter,
this.repository,
this.cache,
);
instance.instanceName = instanceName
.toLowerCase()
.replace(/[^a-z0-9]/g, '')
.replace(' ', '');
this.logger.verbose('hash: ' + hash + ' generated');
this.logger.verbose('instance: ' + instance.instanceName + ' created');
let getEvents: string[];
this.waMonitor.waInstances[instance.instanceName] = instance;
this.waMonitor.delInstanceTime(instance.instanceName);
if (webhook) {
if (!isURL(webhook, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in webhook');
}
this.logger.verbose('creating webhook');
try {
this.webhookService.create(instance, {
enabled: true,
url: webhook,
events,
webhook_by_events,
});
this.logger.verbose('generating hash');
const hash = await this.authService.generateHash(
{
instanceName: instance.instanceName,
},
token,
);
getEvents = (await this.webhookService.find(instance)).events;
} catch (error) {
this.logger.log(error);
}
this.logger.verbose('hash: ' + hash + ' generated');
let getEvents: string[];
if (webhook) {
if (!isURL(webhook, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in webhook');
}
if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) {
this.logger.verbose('instance created');
this.logger.verbose({
instance: {
instanceName: instance.instanceName,
status: 'created',
},
hash,
webhook,
events: getEvents,
});
return {
instance: {
instanceName: instance.instanceName,
status: 'created',
},
hash,
webhook,
events: getEvents,
};
}
if (!chatwoot_account_id) {
throw new BadRequestException('account_id is required');
}
if (!chatwoot_token) {
throw new BadRequestException('token is required');
}
if (!chatwoot_url) {
throw new BadRequestException('url is required');
}
if (!isURL(chatwoot_url, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in chatwoot');
}
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
this.logger.verbose('creating webhook');
try {
this.chatwootService.create(instance, {
this.webhookService.create(instance, {
enabled: true,
account_id: chatwoot_account_id,
token: chatwoot_token,
url: chatwoot_url,
sign_msg: chatwoot_sign_msg || false,
name_inbox: instance.instanceName,
url: webhook,
events,
webhook_by_events,
});
this.chatwootService.initInstanceChatwoot(
instance,
instance.instanceName,
`${urlServer}/chatwoot/webhook/${instance.instanceName}`,
qrcode,
);
getEvents = (await this.webhookService.find(instance)).events;
} catch (error) {
this.logger.log(error);
}
}
return {
if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) {
let getQrcode: wa.QrCode;
if (qrcode) {
this.logger.verbose('creating qrcode');
await instance.connectToWhatsapp();
await delay(2000);
getQrcode = instance.qrCode;
}
this.logger.verbose('instance created');
this.logger.verbose({
instance: {
instanceName: instance.instanceName,
status: 'created',
},
hash,
chatwoot: {
enabled: true,
account_id: chatwoot_account_id,
token: chatwoot_token,
url: chatwoot_url,
sign_msg: chatwoot_sign_msg || false,
name_inbox: instance.instanceName,
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
},
};
} else {
this.logger.verbose('server mode');
this.logger.verbose('checking duplicate token');
await this.authService.checkDuplicateToken(token);
this.logger.verbose('creating instance');
const instance = new WAStartupService(
this.configService,
this.eventEmitter,
this.repository,
this.cache,
);
instance.instanceName = instanceName
.toLowerCase()
.replace(/[^a-z0-9]/g, '')
.replace(' ', '');
this.logger.verbose('instance: ' + instance.instanceName + ' created');
this.waMonitor.waInstances[instance.instanceName] = instance;
this.waMonitor.delInstanceTime(instance.instanceName);
this.logger.verbose('generating hash');
const hash = await this.authService.generateHash(
{
instanceName: instance.instanceName,
},
token,
);
this.logger.verbose('hash: ' + hash + ' generated');
let getEvents: string[];
if (webhook) {
if (!isURL(webhook, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in webhook');
}
this.logger.verbose('creating webhook');
try {
this.webhookService.create(instance, {
enabled: true,
url: webhook,
events,
webhook_by_events,
});
getEvents = (await this.webhookService.find(instance)).events;
} catch (error) {
this.logger.log(error);
}
}
if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) {
let getQrcode: wa.QrCode;
if (qrcode) {
this.logger.verbose('creating qrcode');
await instance.connectToWhatsapp();
await delay(2000);
getQrcode = instance.qrCode;
}
this.logger.verbose('instance created');
this.logger.verbose({
instance: {
instanceName: instance.instanceName,
status: 'created',
},
hash,
webhook,
webhook_by_events,
events: getEvents,
qrcode: getQrcode,
});
return {
instance: {
instanceName: instance.instanceName,
status: 'created',
},
hash,
webhook,
webhook_by_events,
events: getEvents,
qrcode: getQrcode,
};
}
if (!chatwoot_account_id) {
throw new BadRequestException('account_id is required');
}
if (!chatwoot_token) {
throw new BadRequestException('token is required');
}
if (!chatwoot_url) {
throw new BadRequestException('url is required');
}
if (!isURL(chatwoot_url, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in chatwoot');
}
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
try {
this.chatwootService.create(instance, {
enabled: true,
account_id: chatwoot_account_id,
token: chatwoot_token,
url: chatwoot_url,
sign_msg: chatwoot_sign_msg || false,
name_inbox: instance.instanceName,
});
this.chatwootService.initInstanceChatwoot(
instance,
instance.instanceName,
`${urlServer}/chatwoot/webhook/${instance.instanceName}`,
qrcode,
);
} catch (error) {
this.logger.log(error);
}
webhook,
webhook_by_events,
events: getEvents,
qrcode: getQrcode,
});
return {
instance: {
@ -319,17 +132,67 @@ export class InstanceController {
webhook,
webhook_by_events,
events: getEvents,
chatwoot: {
enabled: true,
account_id: chatwoot_account_id,
token: chatwoot_token,
url: chatwoot_url,
sign_msg: chatwoot_sign_msg || false,
name_inbox: instance.instanceName,
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
},
qrcode: getQrcode,
};
}
if (!chatwoot_account_id) {
throw new BadRequestException('account_id is required');
}
if (!chatwoot_token) {
throw new BadRequestException('token is required');
}
if (!chatwoot_url) {
throw new BadRequestException('url is required');
}
if (!isURL(chatwoot_url, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in chatwoot');
}
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
try {
this.chatwootService.create(instance, {
enabled: true,
account_id: chatwoot_account_id,
token: chatwoot_token,
url: chatwoot_url,
sign_msg: chatwoot_sign_msg || false,
name_inbox: instance.instanceName,
});
this.chatwootService.initInstanceChatwoot(
instance,
instance.instanceName,
`${urlServer}/chatwoot/webhook/${instance.instanceName}`,
qrcode,
);
} catch (error) {
this.logger.log(error);
}
return {
instance: {
instanceName: instance.instanceName,
status: 'created',
},
hash,
webhook,
webhook_by_events,
events: getEvents,
chatwoot: {
enabled: true,
account_id: chatwoot_account_id,
token: chatwoot_token,
url: chatwoot_url,
sign_msg: chatwoot_sign_msg || false,
name_inbox: instance.instanceName,
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
},
};
}
public async connectToWhatsapp({ instanceName }: InstanceDto) {

View File

@ -1,5 +1,5 @@
import { join } from 'path';
import { Auth, ConfigService } from '../../config/env.config';
import { Auth, ConfigService, Database } from '../../config/env.config';
import { IInsert, Repository } from '../abstract/abstract.repository';
import { IAuthModel, AuthRaw } from '../models';
import { readFileSync } from 'fs';

View File

@ -55,7 +55,6 @@ export class RepositoryBroker {
const chatwootDir = join(storePath, 'chatwoot');
const tempDir = join(storePath, 'temp');
// Check if directories exist, create them if not
if (!fs.existsSync(authDir)) {
this.logger.verbose('creating auth dir: ' + authDir);
fs.mkdirSync(authDir, { recursive: true });
@ -91,6 +90,21 @@ export class RepositoryBroker {
} catch (error) {
this.logger.error(error);
}
} else {
const storePath = join(process.cwd(), 'store');
this.logger.verbose('creating store path: ' + storePath);
const tempDir = join(storePath, 'temp');
if (!fs.existsSync(tempDir)) {
this.logger.verbose('creating temp dir: ' + tempDir);
fs.mkdirSync(tempDir, { recursive: true });
}
try {
} catch (error) {
this.logger.error(error);
}
}
}
}

View File

@ -15,9 +15,18 @@ import {
import { RepositoryBroker } from '../repository/repository.manager';
import { NotFoundException } from '../../exceptions';
import { Db } from 'mongodb';
import { initInstance } from '../whatsapp.module';
import { RedisCache } from '../../db/redis.client';
import { execSync } from 'child_process';
import { dbserver } from '../../db/db.connect';
import mongoose from 'mongoose';
import {
AuthModel,
ChatwootModel,
ContactModel,
MessageModel,
MessageUpModel,
WebhookModel,
} from '../models';
export class WAMonitoringService {
constructor(
@ -45,6 +54,8 @@ export class WAMonitoringService {
private dbInstance: Db;
private dbStore = dbserver;
private readonly logger = new Logger(WAMonitoringService.name);
public readonly waInstances: Record<string, WAStartupService> = {};
@ -90,7 +101,7 @@ export class WAMonitoringService {
const findChatwoot = await this.waInstances[key].findChatwoot();
if (findChatwoot.enabled) {
if (findChatwoot && findChatwoot.enabled) {
chatwoot = {
...findChatwoot,
webhook_url: `${urlServer}/chatwoot/webhook/${key}`,
@ -218,11 +229,8 @@ export class WAMonitoringService {
}
public async cleaningStoreFiles(instanceName: string) {
this.logger.verbose('cleaning store files instance: ' + instanceName);
if (!this.db.ENABLED) {
const instance = this.waInstances[instanceName];
this.logger.verbose('cleaning store files instance: ' + instanceName);
rmSync(join(INSTANCE_DIR, instanceName), { recursive: true, force: true });
execSync(`rm -rf ${join(STORE_DIR, 'chats', instanceName)}`);
@ -233,7 +241,21 @@ export class WAMonitoringService {
execSync(`rm -rf ${join(STORE_DIR, 'auth', 'apikey', instanceName + '.json')}`);
execSync(`rm -rf ${join(STORE_DIR, 'webhook', instanceName + '.json')}`);
execSync(`rm -rf ${join(STORE_DIR, 'chatwoot', instanceName + '*')}`);
return;
}
this.logger.verbose('cleaning store database instance: ' + instanceName);
await AuthModel.deleteMany({ owner: instanceName });
await ContactModel.deleteMany({ owner: instanceName });
await MessageModel.deleteMany({ owner: instanceName });
await MessageUpModel.deleteMany({ owner: instanceName });
await AuthModel.deleteMany({ _id: instanceName });
await WebhookModel.deleteMany({ _id: instanceName });
await ChatwootModel.deleteMany({ _id: instanceName });
return;
}
public async loadInstance() {
@ -264,7 +286,6 @@ export class WAMonitoringService {
keys.forEach(async (k) => await set(k.split(':')[1]));
} else {
this.logger.verbose('no instance keys found');
initInstance();
}
return;
}
@ -280,7 +301,6 @@ export class WAMonitoringService {
);
} else {
this.logger.verbose('no collections found');
initInstance();
}
return;
}
@ -301,7 +321,6 @@ export class WAMonitoringService {
await set(dirent.name);
} else {
this.logger.verbose('no instance files found');
initInstance();
}
}
} catch (error) {

View File

@ -328,7 +328,7 @@ export class WAStartupService {
if (!data) {
this.logger.verbose('Chatwoot not found');
throw new NotFoundException('Chatwoot not found');
return null;
}
this.logger.verbose(`Chatwoot account id: ${data.account_id}`);
@ -346,16 +346,15 @@ export class WAStartupService {
const serverUrl = this.configService.get<HttpServer>('SERVER').URL;
const we = event.replace(/[\.-]/gm, '_').toUpperCase();
const transformedWe = we.replace(/_/gm, '-').toLowerCase();
const instance = this.configService.get<Auth>('AUTHENTICATION').INSTANCE;
const expose =
this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES;
const tokenStore = await this.repository.auth.find(this.instanceName);
const instanceApikey = tokenStore.apikey || 'Apikey not found';
const instanceApikey = tokenStore?.apikey || 'Apikey not found';
const globalApiKey = this.configService.get<Auth>('AUTHENTICATION').API_KEY.KEY;
if (local && instance.MODE !== 'container') {
if (local) {
if (Array.isArray(webhookLocal) && webhookLocal.includes(we)) {
this.logger.verbose('Sending data to webhook local');
let baseURL;
@ -432,13 +431,7 @@ export class WAStartupService {
globalURL = globalWebhook.URL;
}
let localUrl;
if (instance.MODE === 'container') {
localUrl = instance.WEBHOOK_URL;
} else {
localUrl = this.localWebhook.url;
}
const localUrl = this.localWebhook.url;
if (this.configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS')) {
const logData = {
@ -1190,6 +1183,22 @@ export class WAStartupService {
this.logger.verbose('Sending data to webhook in event MESSAGE_DELETE');
await this.sendDataWebhook(Events.MESSAGES_DELETE, key);
const message: MessageUpdateRaw = {
...key,
status: 'DELETED',
datetime: Date.now(),
owner: this.instance.name,
};
this.logger.verbose(message);
this.logger.verbose('Inserting message in database');
await this.repository.messageUpdate.insert(
[message],
this.instance.name,
database.SAVE_DATA.MESSAGE_UPDATE,
);
return;
}
@ -1396,8 +1405,6 @@ export class WAStartupService {
}
if (Number(countryCode) === 52 || Number(countryCode) === 54) {
console.log('numero mexicano');
const formattedMXARNumber = this.formatMXOrARNumber(number);
if (formattedMXARNumber !== number) {
@ -2351,6 +2358,9 @@ export class WAStartupService {
this.logger.verbose('Fetching contacts');
if (query?.where) {
query.where.owner = this.instance.name;
if (query.where?.id) {
query.where.id = this.createJid(query.where.id);
}
} else {
query = {
where: {
@ -2364,6 +2374,9 @@ export class WAStartupService {
public async fetchMessages(query: MessageQuery) {
this.logger.verbose('Fetching messages');
if (query?.where) {
if (query.where?.key?.remoteJid) {
query.where.key.remoteJid = this.createJid(query.where.key.remoteJid);
}
query.where.owner = this.instance.name;
} else {
query = {
@ -2379,6 +2392,9 @@ export class WAStartupService {
public async fetchStatusMessage(query: MessageUpQuery) {
this.logger.verbose('Fetching status messages');
if (query?.where) {
if (query.where?.remoteJid) {
query.where.remoteJid = this.createJid(query.where.remoteJid);
}
query.where.owner = this.instance.name;
} else {
query = {
@ -2423,8 +2439,19 @@ export class WAStartupService {
this.logger.verbose('Groups add privacy updated');
// reinicia a instancia
this.client?.ws?.close();
return { update: 'success', data: await this.client.fetchPrivacySettings() };
return {
update: 'success',
data: {
readreceipts: settings.privacySettings.readreceipts,
profile: settings.privacySettings.profile,
status: settings.privacySettings.status,
online: settings.privacySettings.online,
last: settings.privacySettings.last,
groupadd: settings.privacySettings.groupadd,
},
};
} catch (error) {
throw new InternalServerErrorException(
'Error updating privacy settings',

View File

@ -63,6 +63,7 @@ export declare namespace wa {
| 'SERVER_ACK'
| 'DELIVERY_ACK'
| 'READ'
| 'DELETED'
| 'PLAYED';
}

View File

@ -91,111 +91,4 @@ export const sendMessageController = new SendMessageController(waMonitor);
export const chatController = new ChatController(waMonitor);
export const groupController = new GroupController(waMonitor);
export async function initInstance() {
const instance = new WAStartupService(configService, eventEmitter, repository, cache);
const mode = configService.get<Auth>('AUTHENTICATION').INSTANCE.MODE;
logger.verbose('Sending data webhook for event: ' + Events.APPLICATION_STARTUP);
instance.sendDataWebhook(
Events.APPLICATION_STARTUP,
{
message: 'Application startup',
mode,
},
false,
);
if (mode === 'container') {
logger.verbose('Application startup in container mode');
const instanceName = configService.get<Auth>('AUTHENTICATION').INSTANCE.NAME;
logger.verbose('Instance name: ' + instanceName);
const instanceWebhook =
configService.get<Auth>('AUTHENTICATION').INSTANCE.WEBHOOK_URL;
logger.verbose('Instance webhook: ' + instanceWebhook);
// const chatwootAccountId =
// configService.get<Auth>('AUTHENTICATION').INSTANCE.CHATWOOT_ACCOUNT_ID;
// logger.verbose('Chatwoot account id: ' + chatwootAccountId);
// const chatwootToken =
// configService.get<Auth>('AUTHENTICATION').INSTANCE.CHATWOOT_TOKEN;
// logger.verbose('Chatwoot token: ' + chatwootToken);
// const chatwootUrl = configService.get<Auth>('AUTHENTICATION').INSTANCE.CHATWOOT_URL;
// logger.verbose('Chatwoot url: ' + chatwootUrl);
instance.instanceName = instanceName;
waMonitor.waInstances[instance.instanceName] = instance;
waMonitor.delInstanceTime(instance.instanceName);
const hash = await authService.generateHash({
instanceName: instance.instanceName,
token: configService.get<Auth>('AUTHENTICATION').API_KEY.KEY,
});
logger.verbose('Hash generated: ' + hash);
if (instanceWebhook) {
logger.verbose('Creating webhook for instance: ' + instanceName);
try {
webhookService.create(instance, { enabled: true, url: instanceWebhook });
logger.verbose('Webhook created');
} catch (error) {
logger.log(error);
}
}
// if (chatwootUrl && chatwootToken && chatwootAccountId) {
// logger.verbose('Creating chatwoot for instance: ' + instanceName);
// try {
// chatwootService.create(instance, {
// enabled: true,
// url: chatwootUrl,
// token: chatwootToken,
// account_id: chatwootAccountId,
// sign_msg: false,
// });
// logger.verbose('Chatwoot created');
// } catch (error) {
// logger.log(error);
// }
// }
try {
const state = instance.connectionStatus?.state;
switch (state) {
case 'close':
await instance.connectToWhatsapp();
await delay(2000);
return instance.qrCode;
case 'connecting':
return instance.qrCode;
default:
return await this.connectionState({ instanceName });
}
} catch (error) {
logger.log(error);
}
const result = {
instance: {
instanceName: instance.instanceName,
status: 'created',
},
hash,
webhook: instanceWebhook,
};
logger.info(result);
return result;
}
return null;
}
logger.info('Module - ON');