Merge branch 'release/1.7.2'

This commit is contained in:
Davidson Gomes 2024-04-12 17:32:18 -03:00
commit 71ee5fd148
134 changed files with 1058 additions and 600 deletions

View File

@ -1,3 +1,20 @@
# 1.7.2 (2024-04-12 17:31)
### Feature
* Mobile connection via sms (test)
### Fixed
* Adjusts in redis
* Send global event in websocket
* Adjusts in proxy
* Fix audio encoding
* Fix conversation read on chatwoot version 3.7
* Fix when receiving/sending messages from whatsapp desktop with ephemeral messages enabled
* Changed returned sessions on typebot status change
* Reorganization of files and folders
# 1.7.1 (2024-04-03 10:19)
### Fixed

View File

@ -53,6 +53,7 @@ RABBITMQ_EXCHANGE_NAME=evolution_exchange
RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672
WEBSOCKET_ENABLED=false
WEBSOCKET_GLOBAL_EVENTS=false
WA_BUSINESS_TOKEN_WEBHOOK=evolution
WA_BUSINESS_URL=https://graph.facebook.com

View File

@ -1,6 +1,6 @@
FROM node:20.7.0-alpine AS builder
LABEL version="1.7.1" description="Api to control whatsapp features through http requests."
LABEL version="1.7.2" description="Api to control whatsapp features through http requests."
LABEL maintainer="Davidson Gomes" git="https://github.com/DavidsonGomes"
LABEL contact="contato@agenciadgcode.com"
@ -68,6 +68,7 @@ ENV RABBITMQ_EXCHANGE_NAME=evolution_exchange
ENV RABBITMQ_URI=amqp://guest:guest@rabbitmq:5672
ENV WEBSOCKET_ENABLED=false
ENV WEBSOCKET_GLOBAL_EVENTS=false
ENV WA_BUSINESS_TOKEN_WEBHOOK=evolution
ENV WA_BUSINESS_URL=https://graph.facebook.com

View File

@ -1,6 +1,6 @@
{
"name": "evolution-api",
"version": "1.7.1",
"version": "1.7.2",
"description": "Rest api for communication with WhatsApp",
"main": "./dist/src/main.js",
"scripts": {
@ -46,7 +46,7 @@
"@figuro/chatwoot-sdk": "^1.1.16",
"@hapi/boom": "^10.0.1",
"@sentry/node": "^7.59.2",
"@whiskeysockets/baileys": "6.6.0",
"@whiskeysockets/baileys": "github:AtendAI/Baileys",
"amqplib": "^0.10.3",
"aws-sdk": "^2.1499.0",
"axios": "^1.6.5",
@ -60,6 +60,7 @@
"exiftool-vendored": "^22.0.0",
"express": "^4.18.2",
"express-async-errors": "^3.1.1",
"fluent-ffmpeg": "^2.1.2",
"form-data": "^4.0.0",
"hbs": "^4.2.0",
"https-proxy-agent": "^7.0.2",

View File

@ -8,21 +8,22 @@ import { Logger } from '../../config/logger.config';
import { BadRequestException, InternalServerErrorException } from '../../exceptions';
import { RedisCache } from '../../libs/redis.client';
import { InstanceDto, SetPresenceDto } from '../dto/instance.dto';
import { ChatwootService } from '../integrations/chatwoot/services/chatwoot.service';
import { RabbitmqService } from '../integrations/rabbitmq/services/rabbitmq.service';
import { SqsService } from '../integrations/sqs/services/sqs.service';
import { TypebotService } from '../integrations/typebot/services/typebot.service';
import { WebsocketService } from '../integrations/websocket/services/websocket.service';
import { RepositoryBroker } from '../repository/repository.manager';
import { AuthService, OldToken } from '../services/auth.service';
import { CacheService } from '../services/cache.service';
import { ChatwootService } from '../services/chatwoot.service';
import { IntegrationService } from '../services/integration.service';
import { WAMonitoringService } from '../services/monitor.service';
import { RabbitmqService } from '../services/rabbitmq.service';
import { SettingsService } from '../services/settings.service';
import { SqsService } from '../services/sqs.service';
import { TypebotService } from '../services/typebot.service';
import { WebhookService } from '../services/webhook.service';
import { WebsocketService } from '../services/websocket.service';
import { BaileysStartupService } from '../services/whatsapp.baileys.service';
import { BusinessStartupService } from '../services/whatsapp.business.service';
import { BaileysStartupService } from '../services/whatsapp/whatsapp.baileys.service';
import { BusinessStartupService } from '../services/whatsapp/whatsapp.business.service';
import { Events, Integration, wa } from '../types/wa.types';
import { ProxyController } from './proxy.controller';
export class InstanceController {
constructor(
@ -39,6 +40,7 @@ export class InstanceController {
private readonly sqsService: SqsService,
private readonly typebotService: TypebotService,
private readonly integrationService: IntegrationService,
private readonly proxyService: ProxyController,
private readonly cache: RedisCache,
private readonly chatwootCache: CacheService,
) {}
@ -53,6 +55,7 @@ export class InstanceController {
events,
qrcode,
number,
mobile,
integration,
token,
chatwoot_account_id,
@ -84,6 +87,7 @@ export class InstanceController {
typebot_delay_message,
typebot_unknown_message,
typebot_listening_from_me,
proxy,
}: InstanceDto) {
try {
this.logger.verbose('requested createInstance from ' + instanceName + ' instance');
@ -115,7 +119,7 @@ export class InstanceController {
);
}
await this.waMonitor.saveInstance({ integration, instanceName, token, number });
await this.waMonitor.saveInstance({ integration, instanceName, token, number, mobile });
instance.instanceName = instanceName;
@ -345,6 +349,18 @@ export class InstanceController {
}
}
if (proxy) {
const testProxy = await this.proxyService.testProxy(proxy);
if (!testProxy) {
throw new BadRequestException('Invalid proxy');
}
await this.proxyService.createProxy(instance, {
enabled: true,
proxy,
});
}
if (typebot_url) {
try {
if (!isURL(typebot_url, { require_tld: false })) {
@ -405,7 +421,7 @@ export class InstanceController {
if (qrcode) {
this.logger.verbose('creating qrcode');
await instance.connectToWhatsapp(number);
await instance.connectToWhatsapp(number, mobile);
await delay(5000);
getQrcode = instance.qrCode;
}
@ -569,7 +585,7 @@ export class InstanceController {
}
}
public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) {
public async connectToWhatsapp({ instanceName, number = null, mobile = null }: InstanceDto) {
try {
this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance');
@ -592,7 +608,7 @@ export class InstanceController {
if (state == 'close') {
this.logger.verbose('connecting');
await instance.connectToWhatsapp(number);
await instance.connectToWhatsapp(number, mobile);
await delay(5000);
return instance.qrCode;
@ -633,6 +649,20 @@ export class InstanceController {
}
}
public async registerMobileCode({ instanceName }: InstanceDto, { mobileCode }: any) {
try {
this.logger.verbose('requested registerMobileCode from ' + instanceName + ' instance');
const instance = this.waMonitor.waInstances[instanceName];
console.log('mobileCode', mobileCode);
await instance.receiveMobileCode(mobileCode);
return { status: 'SUCCESS', error: false, response: { message: 'Mobile code registered' } };
} catch (error) {
this.logger.error(error);
}
}
public async connectionState({ instanceName }: InstanceDto) {
this.logger.verbose('requested connectionState from ' + instanceName + ' instance');
return {

View File

@ -46,7 +46,7 @@ export class ProxyController {
return this.proxyService.find(instance);
}
private async testProxy(proxy: ProxyDto['proxy']) {
public async testProxy(proxy: ProxyDto['proxy']) {
logger.verbose('requested testProxy');
try {
const serverIp = await axios.get('https://icanhazip.com/');

View File

@ -1,10 +1,13 @@
import { WAPresence } from "@whiskeysockets/baileys";
import { WAPresence } from '@whiskeysockets/baileys';
import { ProxyDto } from './proxy.dto';
export class InstanceDto {
instanceName: string;
instanceId?: string;
qrcode?: boolean;
number?: string;
mobile?: boolean;
integration?: string;
token?: string;
webhook?: string;
@ -40,7 +43,7 @@ export class InstanceDto {
typebot_delay_message?: number;
typebot_unknown_message?: string;
typebot_listening_from_me?: boolean;
proxy?: string;
proxy?: ProxyDto['proxy'];
}
export class SetPresenceDto {

View File

@ -7,8 +7,8 @@ import { Auth, configService } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { ForbiddenException, UnauthorizedException } from '../../exceptions';
import { InstanceDto } from '../dto/instance.dto';
import { repository } from '../server.module';
import { JwtPayload } from '../services/auth.service';
import { repository } from '../whatsapp.module';
const logger = new Logger('GUARD');

View File

@ -12,7 +12,7 @@ import {
} from '../../exceptions';
import { dbserver } from '../../libs/db.connect';
import { InstanceDto } from '../dto/instance.dto';
import { cache, waMonitor } from '../whatsapp.module';
import { cache, waMonitor } from '../server.module';
async function getInstance(instanceName: string) {
try {

View File

@ -1,6 +1,6 @@
import { Logger } from '../../config/logger.config';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { ChamaaiDto } from '../dto/chamaai.dto';
import { InstanceDto } from '../dto/instance.dto';
import { ChamaaiService } from '../services/chamaai.service';
const logger = new Logger('ChamaaiController');

View File

@ -1,6 +1,6 @@
import { Schema } from 'mongoose';
import { dbserver } from '../../libs/db.connect';
import { dbserver } from '../../../../libs/db.connect';
export class ChamaaiRaw {
_id?: string;

View File

@ -1,10 +1,10 @@
import { readFileSync } from 'fs';
import { join } from 'path';
import { ConfigService } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { IInsert, Repository } from '../abstract/abstract.repository';
import { ChamaaiRaw, IChamaaiModel } from '../models';
import { ConfigService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { IInsert, Repository } from '../../../abstract/abstract.repository';
import { ChamaaiRaw, IChamaaiModel } from '../../../models';
export class ChamaaiRepository extends Repository {
constructor(private readonly chamaaiModel: IChamaaiModel, private readonly configService: ConfigService) {

View File

@ -1,12 +1,12 @@
import { RequestHandler, Router } from 'express';
import { Logger } from '../../config/logger.config';
import { chamaaiSchema, instanceNameSchema } from '../../validate/validate.schema';
import { RouterBroker } from '../abstract/abstract.router';
import { Logger } from '../../../../config/logger.config';
import { chamaaiSchema, instanceNameSchema } from '../../../../validate/validate.schema';
import { RouterBroker } from '../../../abstract/abstract.router';
import { InstanceDto } from '../../../dto/instance.dto';
import { HttpStatus } from '../../../routes/index.router';
import { chamaaiController } from '../../../server.module';
import { ChamaaiDto } from '../dto/chamaai.dto';
import { InstanceDto } from '../dto/instance.dto';
import { chamaaiController } from '../whatsapp.module';
import { HttpStatus } from './index.router';
const logger = new Logger('ChamaaiRouter');

View File

@ -2,13 +2,13 @@ import axios from 'axios';
import { writeFileSync } from 'fs';
import path from 'path';
import { ConfigService, HttpServer } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { ConfigService, HttpServer } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { ChamaaiRaw } from '../../../models';
import { WAMonitoringService } from '../../../services/monitor.service';
import { Events } from '../../../types/wa.types';
import { ChamaaiDto } from '../dto/chamaai.dto';
import { InstanceDto } from '../dto/instance.dto';
import { ChamaaiRaw } from '../models';
import { Events } from '../types/wa.types';
import { WAMonitoringService } from './monitor.service';
export class ChamaaiService {
constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) {}

View File

@ -0,0 +1,35 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
(property) =>
(properties[property] = {
minLength: 1,
description: `The "${property}" cannot be empty`,
}),
);
return {
if: {
propertyNames: {
enum: [...propertyNames],
},
},
then: { properties },
};
};
export const chamaaiSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
enabled: { type: 'boolean', enum: [true, false] },
url: { type: 'string' },
token: { type: 'string' },
waNumber: { type: 'string' },
answerByAudio: { type: 'boolean', enum: [true, false] },
},
required: ['enabled', 'url', 'token', 'waNumber', 'answerByAudio'],
...isNotEmpty('enabled', 'url', 'token', 'waNumber', 'answerByAudio'),
};

View File

@ -1,5 +1,5 @@
import { CacheConf, ConfigService } from '../config/env.config';
import { ICache } from '../whatsapp/abstract/abstract.cache';
import { CacheConf, ConfigService } from '../../../../config/env.config';
import { ICache } from '../../../abstract/abstract.cache';
import { LocalCache } from './localcache';
import { RedisCache } from './rediscache';

View File

@ -1,7 +1,7 @@
import NodeCache from 'node-cache';
import { CacheConf, CacheConfLocal, ConfigService } from '../config/env.config';
import { ICache } from '../whatsapp/abstract/abstract.cache';
import { CacheConf, CacheConfLocal, ConfigService } from '../../../../config/env.config';
import { ICache } from '../../../abstract/abstract.cache';
export class LocalCache implements ICache {
private conf: CacheConfLocal;

View File

@ -1,7 +1,7 @@
import { createClient, RedisClientType } from 'redis';
import { CacheConf, CacheConfRedis, configService } from '../config/env.config';
import { Logger } from '../config/logger.config';
import { CacheConf, CacheConfRedis, configService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
class Redis {
private logger = new Logger(Redis.name);

View File

@ -1,8 +1,8 @@
import { RedisClientType } from 'redis';
import { CacheConf, CacheConfRedis, ConfigService } from '../config/env.config';
import { Logger } from '../config/logger.config';
import { ICache } from '../whatsapp/abstract/abstract.cache';
import { CacheConf, CacheConfRedis, ConfigService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { ICache } from '../../../abstract/abstract.cache';
import { redisClient } from './rediscache.client';
export class RedisCache implements ICache {

View File

@ -1,15 +1,15 @@
import { isURL } from 'class-validator';
import { ConfigService, HttpServer } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { BadRequestException } from '../../exceptions';
import { CacheEngine } from '../../libs/cacheengine';
import { ConfigService, HttpServer } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { BadRequestException } from '../../../../exceptions';
import { InstanceDto } from '../../../dto/instance.dto';
import { RepositoryBroker } from '../../../repository/repository.manager';
import { waMonitor } from '../../../server.module';
import { CacheService } from '../../../services/cache.service';
import { CacheEngine } from '../cache/cacheengine';
import { ChatwootDto } from '../dto/chatwoot.dto';
import { InstanceDto } from '../dto/instance.dto';
import { RepositoryBroker } from '../repository/repository.manager';
import { CacheService } from '../services/cache.service';
import { ChatwootService } from '../services/chatwoot.service';
import { waMonitor } from '../whatsapp.module';
const logger = new Logger('ChatwootController');

View File

@ -1,7 +1,7 @@
import postgresql from 'pg';
import { Chatwoot, configService } from '../config/env.config';
import { Logger } from '../config/logger.config';
import { Chatwoot, configService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
const { Pool } = postgresql;

View File

@ -1,6 +1,6 @@
import { Schema } from 'mongoose';
import { dbserver } from '../../libs/db.connect';
import { dbserver } from '../../../../libs/db.connect';
export class ChatwootRaw {
_id?: string;

View File

@ -1,10 +1,10 @@
import { readFileSync } from 'fs';
import { join } from 'path';
import { ConfigService } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { IInsert, Repository } from '../abstract/abstract.repository';
import { ChatwootRaw, IChatwootModel } from '../models';
import { ConfigService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { IInsert, Repository } from '../../../abstract/abstract.repository';
import { ChatwootRaw, IChatwootModel } from '../../../models';
export class ChatwootRepository extends Repository {
constructor(private readonly chatwootModel: IChatwootModel, private readonly configService: ConfigService) {

View File

@ -1,12 +1,12 @@
import { RequestHandler, Router } from 'express';
import { Logger } from '../../config/logger.config';
import { chatwootSchema, instanceNameSchema } from '../../validate/validate.schema';
import { RouterBroker } from '../abstract/abstract.router';
import { Logger } from '../../../../config/logger.config';
import { chatwootSchema, instanceNameSchema } from '../../../../validate/validate.schema';
import { RouterBroker } from '../../../abstract/abstract.router';
import { InstanceDto } from '../../../dto/instance.dto';
import { HttpStatus } from '../../../routes/index.router';
import { chatwootController } from '../../../server.module';
import { ChatwootDto } from '../dto/chatwoot.dto';
import { InstanceDto } from '../dto/instance.dto';
import { chatwootController } from '../whatsapp.module';
import { HttpStatus } from './index.router';
const logger = new Logger('ChatwootRouter');

View File

@ -1,4 +1,12 @@
import ChatwootClient, { ChatwootAPIConfig, contact, conversation, generic_id, inbox } from '@figuro/chatwoot-sdk';
import ChatwootClient, {
ChatwootAPIConfig,
contact,
contact_inboxes,
conversation,
conversation_show,
generic_id,
inbox,
} from '@figuro/chatwoot-sdk';
import { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request';
import axios from 'axios';
import FormData from 'form-data';
@ -7,18 +15,18 @@ import Jimp from 'jimp';
import mimeTypes from 'mime-types';
import path from 'path';
import { Chatwoot, ConfigService, HttpServer } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { chatwootImport } from '../../utils/chatwoot-import-helper';
import i18next from '../../utils/i18n';
import { ICache } from '../abstract/abstract.cache';
import { Chatwoot, ConfigService, HttpServer } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import i18next from '../../../../utils/i18n';
import { ICache } from '../../../abstract/abstract.cache';
import { InstanceDto } from '../../../dto/instance.dto';
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../../../dto/sendMessage.dto';
import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../models';
import { RepositoryBroker } from '../../../repository/repository.manager';
import { WAMonitoringService } from '../../../services/monitor.service';
import { Events } from '../../../types/wa.types';
import { ChatwootDto } from '../dto/chatwoot.dto';
import { InstanceDto } from '../dto/instance.dto';
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto';
import { ChatwootRaw, ContactRaw, MessageRaw } from '../models';
import { RepositoryBroker } from '../repository/repository.manager';
import { Events } from '../types/wa.types';
import { WAMonitoringService } from './monitor.service';
import { chatwootImport } from '../utils/chatwoot-import-helper';
export class ChatwootService {
private readonly logger = new Logger(ChatwootService.name);
@ -1774,6 +1782,13 @@ export class ChatwootService {
return;
}
// fix when receiving/sending messages from whatsapp desktop with ephemeral messages enabled
if (body.message?.ephemeralMessage?.message) {
body.message = {
...body.message?.ephemeralMessage?.message,
};
}
this.logger.verbose('get conversation message');
// Whatsapp to Chatwoot
@ -2123,12 +2138,13 @@ export class ChatwootService {
};
if (!sourceId && inbox) {
const contact = (await this.findContact(
instance,
this.getNumberFromRemoteJid(body.key.remoteJid),
)) as contact;
const contactInbox = contact?.contact_inboxes?.find((contactInbox) => contactInbox?.inbox?.id === inbox.id);
sourceId = contactInbox?.source_id;
const conversation = (await client.conversations.get({
accountId: this.provider.account_id,
conversationId: conversationId,
})) as conversation_show & {
last_non_activity_message: { conversation: { contact_inbox: contact_inboxes } };
};
sourceId = conversation.last_non_activity_message?.conversation?.contact_inbox?.source_id;
}
if (sourceId && inbox?.inbox_identifier) {

View File

@ -1,12 +1,12 @@
import { inbox } from '@figuro/chatwoot-sdk';
import { proto } from '@whiskeysockets/baileys';
import { Chatwoot, configService } from '../config/env.config';
import { Logger } from '../config/logger.config';
import { InstanceDto } from '../../../../api/dto/instance.dto';
import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../../api/models';
import { Chatwoot, configService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { postgresClient } from '../libs/postgres.client';
import { InstanceDto } from '../whatsapp/dto/instance.dto';
import { ChatwootRaw, ContactRaw, MessageRaw } from '../whatsapp/models';
import { ChatwootService } from '../whatsapp/services/chatwoot.service';
import { ChatwootService } from '../services/chatwoot.service';
type ChatwootUser = {
user_type: string;

View File

@ -0,0 +1,42 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
(property) =>
(properties[property] = {
minLength: 1,
description: `The "${property}" cannot be empty`,
}),
);
return {
if: {
propertyNames: {
enum: [...propertyNames],
},
},
then: { properties },
};
};
export const chatwootSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
enabled: { type: 'boolean', enum: [true, false] },
account_id: { type: 'string' },
token: { type: 'string' },
url: { type: 'string' },
sign_msg: { type: 'boolean', enum: [true, false] },
sign_delimiter: { type: ['string', 'null'] },
reopen_conversation: { type: 'boolean', enum: [true, false] },
conversation_pending: { type: 'boolean', enum: [true, false] },
auto_create: { type: 'boolean', enum: [true, false] },
import_contacts: { type: 'boolean', enum: [true, false] },
import_messages: { type: 'boolean', enum: [true, false] },
days_limit_import_messages: { type: 'number' },
},
required: ['enabled', 'account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'],
...isNotEmpty('account_id', 'token', 'url', 'sign_msg', 'reopen_conversation', 'conversation_pending'),
};

View File

@ -1,5 +1,5 @@
import { Logger } from '../../config/logger.config';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { RabbitmqDto } from '../dto/rabbitmq.dto';
import { RabbitmqService } from '../services/rabbitmq.service';

View File

@ -1,7 +1,7 @@
import * as amqp from 'amqplib/callback_api';
import { configService, Rabbitmq } from '../config/env.config';
import { Logger } from '../config/logger.config';
import { configService, Rabbitmq } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
const logger = new Logger('AMQP');

View File

@ -1,6 +1,6 @@
import { Schema } from 'mongoose';
import { dbserver } from '../../libs/db.connect';
import { dbserver } from '../../../../libs/db.connect';
export class RabbitmqRaw {
_id?: string;

View File

@ -1,10 +1,10 @@
import { readFileSync } from 'fs';
import { join } from 'path';
import { ConfigService } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { IInsert, Repository } from '../abstract/abstract.repository';
import { IRabbitmqModel, RabbitmqRaw } from '../models';
import { ConfigService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { IInsert, Repository } from '../../../abstract/abstract.repository';
import { IRabbitmqModel, RabbitmqRaw } from '../../../models';
export class RabbitmqRepository extends Repository {
constructor(private readonly rabbitmqModel: IRabbitmqModel, private readonly configService: ConfigService) {

View File

@ -1,12 +1,12 @@
import { RequestHandler, Router } from 'express';
import { Logger } from '../../config/logger.config';
import { instanceNameSchema, rabbitmqSchema } from '../../validate/validate.schema';
import { RouterBroker } from '../abstract/abstract.router';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { instanceNameSchema, rabbitmqSchema } from '../../../../validate/validate.schema';
import { RouterBroker } from '../../../abstract/abstract.router';
import { InstanceDto } from '../../../dto/instance.dto';
import { HttpStatus } from '../../../routes/index.router';
import { rabbitmqController } from '../../../server.module';
import { RabbitmqDto } from '../dto/rabbitmq.dto';
import { rabbitmqController } from '../whatsapp.module';
import { HttpStatus } from './index.router';
const logger = new Logger('RabbitmqRouter');

View File

@ -1,9 +1,9 @@
import { Logger } from '../../config/logger.config';
import { initQueues } from '../../libs/amqp.server';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { RabbitmqRaw } from '../../../models';
import { WAMonitoringService } from '../../../services/monitor.service';
import { RabbitmqDto } from '../dto/rabbitmq.dto';
import { RabbitmqRaw } from '../models';
import { WAMonitoringService } from './monitor.service';
import { initQueues } from '../libs/amqp.server';
export class RabbitmqService {
constructor(private readonly waMonitor: WAMonitoringService) {}

View File

@ -0,0 +1,66 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
(property) =>
(properties[property] = {
minLength: 1,
description: `The "${property}" cannot be empty`,
}),
);
return {
if: {
propertyNames: {
enum: [...propertyNames],
},
},
then: { properties },
};
};
export const rabbitmqSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
enabled: { type: 'boolean', enum: [true, false] },
events: {
type: 'array',
minItems: 0,
items: {
type: 'string',
enum: [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'NEW_JWT_TOKEN',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
'CHAMA_AI_ACTION',
],
},
},
},
required: ['enabled'],
...isNotEmpty('enabled'),
};

View File

@ -1,5 +1,5 @@
import { Logger } from '../../config/logger.config';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { SqsDto } from '../dto/sqs.dto';
import { SqsService } from '../services/sqs.service';

View File

@ -1,7 +1,7 @@
import { SQS } from 'aws-sdk';
import { configService, Sqs } from '../config/env.config';
import { Logger } from '../config/logger.config';
import { configService, Sqs } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
const logger = new Logger('SQS');

View File

@ -1,6 +1,6 @@
import { Schema } from 'mongoose';
import { dbserver } from '../../libs/db.connect';
import { dbserver } from '../../../../libs/db.connect';
export class SqsRaw {
_id?: string;

View File

@ -1,10 +1,10 @@
import { readFileSync } from 'fs';
import { join } from 'path';
import { ConfigService } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { IInsert, Repository } from '../abstract/abstract.repository';
import { ISqsModel, SqsRaw } from '../models';
import { ConfigService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { IInsert, Repository } from '../../../abstract/abstract.repository';
import { ISqsModel, SqsRaw } from '../../../models';
export class SqsRepository extends Repository {
constructor(private readonly sqsModel: ISqsModel, private readonly configService: ConfigService) {

View File

@ -1,12 +1,12 @@
import { RequestHandler, Router } from 'express';
import { Logger } from '../../config/logger.config';
import { instanceNameSchema, sqsSchema } from '../../validate/validate.schema';
import { RouterBroker } from '../abstract/abstract.router';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { instanceNameSchema, sqsSchema } from '../../../../validate/validate.schema';
import { RouterBroker } from '../../../abstract/abstract.router';
import { InstanceDto } from '../../../dto/instance.dto';
import { HttpStatus } from '../../../routes/index.router';
import { sqsController } from '../../../server.module';
import { SqsDto } from '../dto/sqs.dto';
import { sqsController } from '../whatsapp.module';
import { HttpStatus } from './index.router';
const logger = new Logger('SqsRouter');

View File

@ -1,9 +1,9 @@
import { Logger } from '../../config/logger.config';
import { initQueues } from '../../libs/sqs.server';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { SqsRaw } from '../../../models';
import { WAMonitoringService } from '../../../services/monitor.service';
import { SqsDto } from '../dto/sqs.dto';
import { SqsRaw } from '../models';
import { WAMonitoringService } from './monitor.service';
import { initQueues } from '../libs/sqs.server';
export class SqsService {
constructor(private readonly waMonitor: WAMonitoringService) {}

View File

@ -0,0 +1,66 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
(property) =>
(properties[property] = {
minLength: 1,
description: `The "${property}" cannot be empty`,
}),
);
return {
if: {
propertyNames: {
enum: [...propertyNames],
},
},
then: { properties },
};
};
export const sqsSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
enabled: { type: 'boolean', enum: [true, false] },
events: {
type: 'array',
minItems: 0,
items: {
type: 'string',
enum: [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'NEW_JWT_TOKEN',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
'CHAMA_AI_ACTION',
],
},
},
},
required: ['enabled'],
...isNotEmpty('enabled'),
};

View File

@ -1,5 +1,5 @@
import { Logger } from '../../config/logger.config';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { TypebotDto } from '../dto/typebot.dto';
import { TypebotService } from '../services/typebot.service';

View File

@ -1,6 +1,6 @@
import { Schema } from 'mongoose';
import { dbserver } from '../../libs/db.connect';
import { dbserver } from '../../../../libs/db.connect';
class Session {
remoteJid?: string;

View File

@ -1,10 +1,10 @@
import { readFileSync } from 'fs';
import { join } from 'path';
import { ConfigService } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { IInsert, Repository } from '../abstract/abstract.repository';
import { ITypebotModel, TypebotRaw } from '../models';
import { ConfigService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { IInsert, Repository } from '../../../abstract/abstract.repository';
import { ITypebotModel, TypebotRaw } from '../../../models';
export class TypebotRepository extends Repository {
constructor(private readonly typebotModel: ITypebotModel, private readonly configService: ConfigService) {

View File

@ -1,17 +1,17 @@
import { RequestHandler, Router } from 'express';
import { Logger } from '../../config/logger.config';
import { Logger } from '../../../../config/logger.config';
import {
instanceNameSchema,
typebotSchema,
typebotStartSchema,
typebotStatusSchema,
} from '../../validate/validate.schema';
import { RouterBroker } from '../abstract/abstract.router';
import { InstanceDto } from '../dto/instance.dto';
} from '../../../../validate/validate.schema';
import { RouterBroker } from '../../../abstract/abstract.router';
import { InstanceDto } from '../../../dto/instance.dto';
import { HttpStatus } from '../../../routes/index.router';
import { typebotController } from '../../../server.module';
import { TypebotDto } from '../dto/typebot.dto';
import { typebotController } from '../whatsapp.module';
import { HttpStatus } from './index.router';
const logger = new Logger('TypebotRouter');

View File

@ -1,13 +1,13 @@
import axios from 'axios';
import EventEmitter2 from 'eventemitter2';
import { ConfigService, Typebot } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { InstanceDto } from '../dto/instance.dto';
import { ConfigService, Typebot } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { MessageRaw } from '../../../models';
import { WAMonitoringService } from '../../../services/monitor.service';
import { Events } from '../../../types/wa.types';
import { Session, TypebotDto } from '../dto/typebot.dto';
import { MessageRaw } from '../models';
import { Events } from '../types/wa.types';
import { WAMonitoringService } from './monitor.service';
export class TypebotService {
constructor(
@ -57,7 +57,7 @@ export class TypebotService {
if (session) {
if (status === 'closed') {
findData.sessions.splice(findData.sessions.indexOf(session), 1);
const found_session: Session[] = findData.sessions.splice(findData.sessions.indexOf(session), 1);
const typebotData = {
enabled: findData.enabled,
@ -68,7 +68,7 @@ export class TypebotService {
delay_message: findData.delay_message,
unknown_message: findData.unknown_message,
listening_from_me: findData.listening_from_me,
sessions: findData.sessions,
sessions: found_session,
};
this.create(instance, typebotData);
@ -106,7 +106,7 @@ export class TypebotService {
delay_message: findData.delay_message,
unknown_message: findData.unknown_message,
listening_from_me: findData.listening_from_me,
sessions: findData.sessions,
sessions: findData.sessions.splice(findData.sessions.indexOf(session), 1),
};
this.create(instance, typebotData);
@ -269,25 +269,28 @@ export class TypebotService {
}
private getTypeMessage(msg: any) {
this.logger.verbose('get type message');
const types = {
conversation: msg.conversation,
extendedTextMessage: msg.extendedTextMessage?.text,
audioMessage: msg.audioMessage?.url,
imageMessage: msg.imageMessage?.url,
videoMessage: msg.videoMessage?.url,
documentMessage: msg.documentMessage?.fileName,
contactMessage: msg.contactMessage?.displayName,
locationMessage: msg.locationMessage?.degreesLatitude,
viewOnceMessageV2: msg.viewOnceMessageV2?.message?.imageMessage?.url || msg.viewOnceMessageV2?.message?.videoMessage?.url || msg.viewOnceMessageV2?.message?.audioMessage?.url,
listResponseMessage: msg.listResponseMessage?.singleSelectReply?.selectedRowId,
responseRowId: msg.listResponseMessage?.singleSelectReply?.selectedRowId,
};
this.logger.verbose('get type message');
const types = {
conversation: msg.conversation,
extendedTextMessage: msg.extendedTextMessage?.text,
audioMessage: msg.audioMessage?.url,
imageMessage: msg.imageMessage?.url,
videoMessage: msg.videoMessage?.url,
documentMessage: msg.documentMessage?.fileName,
contactMessage: msg.contactMessage?.displayName,
locationMessage: msg.locationMessage?.degreesLatitude,
viewOnceMessageV2:
msg.viewOnceMessageV2?.message?.imageMessage?.url ||
msg.viewOnceMessageV2?.message?.videoMessage?.url ||
msg.viewOnceMessageV2?.message?.audioMessage?.url,
listResponseMessage: msg.listResponseMessage?.singleSelectReply?.selectedRowId,
responseRowId: msg.listResponseMessage?.singleSelectReply?.selectedRowId,
};
const messageType = Object.keys(types).find(key => types[key] !== undefined) || 'unknown';
const messageType = Object.keys(types).find((key) => types[key] !== undefined) || 'unknown';
this.logger.verbose('Type message: ' + JSON.stringify(types));
return { ...types, messageType };
this.logger.verbose('Type message: ' + JSON.stringify(types));
return { ...types, messageType };
}
private getMessageContent(types: any) {

View File

@ -0,0 +1,60 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
(property) =>
(properties[property] = {
minLength: 1,
description: `The "${property}" cannot be empty`,
}),
);
return {
if: {
propertyNames: {
enum: [...propertyNames],
},
},
then: { properties },
};
};
export const typebotSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
enabled: { type: 'boolean', enum: [true, false] },
url: { type: 'string' },
typebot: { type: 'string' },
expire: { type: 'integer' },
delay_message: { type: 'integer' },
unknown_message: { type: 'string' },
listening_from_me: { type: 'boolean', enum: [true, false] },
},
required: ['enabled', 'url', 'typebot', 'expire', 'delay_message', 'unknown_message', 'listening_from_me'],
...isNotEmpty('enabled', 'url', 'typebot', 'expire', 'delay_message', 'unknown_message', 'listening_from_me'),
};
export const typebotStatusSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
remoteJid: { type: 'string' },
status: { type: 'string', enum: ['opened', 'closed', 'paused'] },
},
required: ['remoteJid', 'status'],
...isNotEmpty('remoteJid', 'status'),
};
export const typebotStartSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
remoteJid: { type: 'string' },
url: { type: 'string' },
typebot: { type: 'string' },
},
required: ['remoteJid', 'url', 'typebot'],
...isNotEmpty('remoteJid', 'url', 'typebot'),
};

View File

@ -1,5 +1,5 @@
import { Logger } from '../../config/logger.config';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { WebsocketDto } from '../dto/websocket.dto';
import { WebsocketService } from '../services/websocket.service';

View File

@ -1,8 +1,8 @@
import { Server } from 'http';
import { Server as SocketIO } from 'socket.io';
import { configService, Cors, Websocket } from '../config/env.config';
import { Logger } from '../config/logger.config';
import { configService, Cors, Websocket } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
const logger = new Logger('Socket');

View File

@ -1,6 +1,6 @@
import { Schema } from 'mongoose';
import { dbserver } from '../../libs/db.connect';
import { dbserver } from '../../../../libs/db.connect';
export class WebsocketRaw {
_id?: string;

View File

@ -1,10 +1,10 @@
import { readFileSync } from 'fs';
import { join } from 'path';
import { ConfigService } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { IInsert, Repository } from '../abstract/abstract.repository';
import { IWebsocketModel, WebsocketRaw } from '../models';
import { ConfigService } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
import { IInsert, Repository } from '../../../abstract/abstract.repository';
import { IWebsocketModel, WebsocketRaw } from '../../../models';
export class WebsocketRepository extends Repository {
constructor(private readonly websocketModel: IWebsocketModel, private readonly configService: ConfigService) {

View File

@ -1,12 +1,12 @@
import { RequestHandler, Router } from 'express';
import { Logger } from '../../config/logger.config';
import { instanceNameSchema, websocketSchema } from '../../validate/validate.schema';
import { RouterBroker } from '../abstract/abstract.router';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { instanceNameSchema, websocketSchema } from '../../../../validate/validate.schema';
import { RouterBroker } from '../../../abstract/abstract.router';
import { InstanceDto } from '../../../dto/instance.dto';
import { HttpStatus } from '../../../routes/index.router';
import { websocketController } from '../../../server.module';
import { WebsocketDto } from '../dto/websocket.dto';
import { websocketController } from '../whatsapp.module';
import { HttpStatus } from './index.router';
const logger = new Logger('WebsocketRouter');

View File

@ -1,8 +1,8 @@
import { Logger } from '../../config/logger.config';
import { InstanceDto } from '../dto/instance.dto';
import { Logger } from '../../../../config/logger.config';
import { InstanceDto } from '../../../dto/instance.dto';
import { WebsocketRaw } from '../../../models';
import { WAMonitoringService } from '../../../services/monitor.service';
import { WebsocketDto } from '../dto/websocket.dto';
import { WebsocketRaw } from '../models';
import { WAMonitoringService } from './monitor.service';
export class WebsocketService {
constructor(private readonly waMonitor: WAMonitoringService) {}

View File

@ -0,0 +1,66 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
(property) =>
(properties[property] = {
minLength: 1,
description: `The "${property}" cannot be empty`,
}),
);
return {
if: {
propertyNames: {
enum: [...propertyNames],
},
},
then: { properties },
};
};
export const websocketSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
enabled: { type: 'boolean', enum: [true, false] },
events: {
type: 'array',
minItems: 0,
items: {
type: 'string',
enum: [
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'NEW_JWT_TOKEN',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
'CHAMA_AI_ACTION',
],
},
},
},
required: ['enabled'],
...isNotEmpty('enabled'),
};

15
src/api/models/index.ts Normal file
View File

@ -0,0 +1,15 @@
export * from '../integrations/chamaai/models/chamaai.model';
export * from '../integrations/chatwoot/models/chatwoot.model';
export * from '../integrations/rabbitmq/models/rabbitmq.model';
export * from '../integrations/sqs/models/sqs.model';
export * from '../integrations/typebot/models/typebot.model';
export * from '../integrations/websocket/models/websocket.model';
export * from './auth.model';
export * from './chat.model';
export * from './contact.model';
export * from './integration.model';
export * from './label.model';
export * from './message.model';
export * from './proxy.model';
export * from './settings.model';
export * from './webhook.model';

View File

@ -4,22 +4,22 @@ import { join } from 'path';
import { Auth, ConfigService, Database } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
import { ChamaaiRepository } from '../integrations/chamaai/repository/chamaai.repository';
import { ChatwootRepository } from '../integrations/chatwoot/repository/chatwoot.repository';
import { RabbitmqRepository } from '../integrations/rabbitmq/repository/rabbitmq.repository';
import { SqsRepository } from '../integrations/sqs/repository/sqs.repository';
import { TypebotRepository } from '../integrations/typebot/repository/typebot.repository';
import { WebsocketRepository } from '../integrations/websocket/repository/websocket.repository';
import { AuthRepository } from './auth.repository';
import { ChamaaiRepository } from './chamaai.repository';
import { ChatRepository } from './chat.repository';
import { ChatwootRepository } from './chatwoot.repository';
import { ContactRepository } from './contact.repository';
import { IntegrationRepository } from './integration.repository';
import { LabelRepository } from './label.repository';
import { MessageRepository } from './message.repository';
import { MessageUpRepository } from './messageUp.repository';
import { ProxyRepository } from './proxy.repository';
import { RabbitmqRepository } from './rabbitmq.repository';
import { SettingsRepository } from './settings.repository';
import { SqsRepository } from './sqs.repository';
import { TypebotRepository } from './typebot.repository';
import { WebhookRepository } from './webhook.repository';
import { WebsocketRepository } from './websocket.repository';
export class RepositoryBroker {
constructor(
public readonly message: MessageRepository,

View File

@ -9,7 +9,6 @@ import {
messageUpSchema,
messageValidateSchema,
presenceSchema,
presenceOnlySchema,
privacySettingsSchema,
profileNameSchema,
profilePictureSchema,
@ -39,7 +38,7 @@ import { InstanceDto } from '../dto/instance.dto';
import { ContactQuery } from '../repository/contact.repository';
import { MessageQuery } from '../repository/message.repository';
import { MessageUpQuery } from '../repository/messageUp.repository';
import { chatController } from '../whatsapp.module';
import { chatController } from '../server.module';
import { HttpStatus } from './index.router';
const logger = new Logger('ChatRouter');

View File

@ -30,7 +30,7 @@ import {
GroupUpdateParticipantDto,
GroupUpdateSettingDto,
} from '../dto/group.dto';
import { groupController } from '../whatsapp.module';
import { groupController } from '../server.module';
import { HttpStatus } from './index.router';
const logger = new Logger('GroupRouter');

Some files were not shown because too many files have changed in this diff Show More