mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-25 14:47:45 -06:00
feat(cacheservice): add suport to use use redis in cacheservice
This commit is contained in:
13
src/whatsapp/abstract/abstract.cache.ts
Normal file
13
src/whatsapp/abstract/abstract.cache.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface ICache {
|
||||
get(key: string): Promise<any>;
|
||||
|
||||
set(key: string, value: any, ttl?: number): void;
|
||||
|
||||
has(key: string): Promise<boolean>;
|
||||
|
||||
keys(appendCriteria?: string): Promise<string[]>;
|
||||
|
||||
delete(key: string | string[]): Promise<number>;
|
||||
|
||||
deleteAll(appendCriteria?: string): Promise<number>;
|
||||
}
|
||||
@@ -3,9 +3,11 @@ 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 { 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';
|
||||
|
||||
@@ -94,7 +96,9 @@ export class ChatwootController {
|
||||
|
||||
public async receiveWebhook(instance: InstanceDto, data: any) {
|
||||
logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance');
|
||||
const chatwootService = new ChatwootService(waMonitor, this.configService, this.repository);
|
||||
|
||||
const chatwootCache = new CacheService(new CacheEngine(this.configService, ChatwootService.name).getEngine());
|
||||
const chatwootService = new ChatwootService(waMonitor, this.configService, this.repository, chatwootCache);
|
||||
|
||||
return chatwootService.receiveWebhook(instance, data);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { RedisCache } from '../../libs/redis.client';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
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 { WAMonitoringService } from '../services/monitor.service';
|
||||
import { RabbitmqService } from '../services/rabbitmq.service';
|
||||
@@ -36,6 +37,7 @@ export class InstanceController {
|
||||
private readonly sqsService: SqsService,
|
||||
private readonly typebotService: TypebotService,
|
||||
private readonly cache: RedisCache,
|
||||
private readonly chatwootCache: CacheService,
|
||||
) {}
|
||||
|
||||
private readonly logger = new Logger(InstanceController.name);
|
||||
@@ -82,7 +84,13 @@ export class InstanceController {
|
||||
await this.authService.checkDuplicateToken(token);
|
||||
|
||||
this.logger.verbose('creating instance');
|
||||
const instance = new WAStartupService(this.configService, this.eventEmitter, this.repository, this.cache);
|
||||
const instance = new WAStartupService(
|
||||
this.configService,
|
||||
this.eventEmitter,
|
||||
this.repository,
|
||||
this.cache,
|
||||
this.chatwootCache,
|
||||
);
|
||||
instance.instanceName = instanceName;
|
||||
|
||||
const instanceId = v4();
|
||||
|
||||
@@ -1,39 +1,62 @@
|
||||
import NodeCache from 'node-cache';
|
||||
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { ICache } from '../abstract/abstract.cache';
|
||||
|
||||
export class CacheService {
|
||||
private readonly logger = new Logger(CacheService.name);
|
||||
|
||||
constructor(private module: string) {}
|
||||
|
||||
static localCache = new NodeCache({
|
||||
stdTTL: 12 * 60 * 60,
|
||||
});
|
||||
|
||||
public get(key: string) {
|
||||
return CacheService.localCache.get(`${this.module}-${key}`);
|
||||
constructor(private readonly cache: ICache) {
|
||||
if (cache) {
|
||||
this.logger.verbose(`cacheservice created using cache engine: ${cache.constructor?.name}`);
|
||||
} else {
|
||||
this.logger.verbose(`cacheservice disabled`);
|
||||
}
|
||||
}
|
||||
|
||||
public set(key: string, value) {
|
||||
return CacheService.localCache.set(`${this.module}-${key}`, value);
|
||||
async get(key: string): Promise<any> {
|
||||
if (!this.cache) {
|
||||
return;
|
||||
}
|
||||
this.logger.verbose(`cacheservice getting key: ${key}`);
|
||||
return this.cache.get(key);
|
||||
}
|
||||
|
||||
public has(key: string) {
|
||||
return CacheService.localCache.has(`${this.module}-${key}`);
|
||||
async set(key: string, value: any) {
|
||||
if (!this.cache) {
|
||||
return;
|
||||
}
|
||||
this.logger.verbose(`cacheservice setting key: ${key}`);
|
||||
this.cache.set(key, value);
|
||||
}
|
||||
|
||||
public delete(key: string) {
|
||||
return CacheService.localCache.del(`${this.module}-${key}`);
|
||||
async has(key: string) {
|
||||
if (!this.cache) {
|
||||
return;
|
||||
}
|
||||
this.logger.verbose(`cacheservice has key: ${key}`);
|
||||
return this.cache.has(key);
|
||||
}
|
||||
|
||||
public deleteAll() {
|
||||
const keys = CacheService.localCache.keys().filter((key) => key.substring(0, this.module.length) === this.module);
|
||||
|
||||
return CacheService.localCache.del(keys);
|
||||
async delete(key: string) {
|
||||
if (!this.cache) {
|
||||
return;
|
||||
}
|
||||
this.logger.verbose(`cacheservice deleting key: ${key}`);
|
||||
return this.cache.delete(key);
|
||||
}
|
||||
|
||||
public keys() {
|
||||
return CacheService.localCache.keys();
|
||||
async deleteAll(appendCriteria?: string) {
|
||||
if (!this.cache) {
|
||||
return;
|
||||
}
|
||||
this.logger.verbose(`cacheservice deleting all keys`);
|
||||
return this.cache.deleteAll(appendCriteria);
|
||||
}
|
||||
|
||||
async keys(appendCriteria?: string) {
|
||||
if (!this.cache) {
|
||||
return;
|
||||
}
|
||||
this.logger.verbose(`cacheservice getting all keys`);
|
||||
return this.cache.keys(appendCriteria);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,31 +8,31 @@ import path from 'path';
|
||||
|
||||
import { ConfigService, HttpServer } from '../../config/env.config';
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { ICache } from '../abstract/abstract.cache';
|
||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto';
|
||||
import { ChatwootRaw, MessageRaw } from '../models';
|
||||
import { RepositoryBroker } from '../repository/repository.manager';
|
||||
import { Events } from '../types/wa.types';
|
||||
import { CacheService } from './cache.service';
|
||||
import { WAMonitoringService } from './monitor.service';
|
||||
|
||||
export class ChatwootService {
|
||||
private readonly logger = new Logger(ChatwootService.name);
|
||||
|
||||
private provider: any;
|
||||
private cache = new CacheService(ChatwootService.name);
|
||||
|
||||
constructor(
|
||||
private readonly waMonitor: WAMonitoringService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly repository: RepositoryBroker,
|
||||
private readonly cache: ICache,
|
||||
) {}
|
||||
|
||||
private async getProvider(instance: InstanceDto) {
|
||||
const cacheKey = `getProvider-${instance.instanceName}`;
|
||||
if (this.cache.has(cacheKey)) {
|
||||
return this.cache.get(cacheKey) as ChatwootRaw;
|
||||
const cacheKey = `${instance.instanceName}:getProvider`;
|
||||
if (await this.cache.has(cacheKey)) {
|
||||
return (await this.cache.get(cacheKey)) as ChatwootRaw;
|
||||
}
|
||||
|
||||
this.logger.verbose('get provider to instance: ' + instance.instanceName);
|
||||
@@ -69,11 +69,6 @@ export class ChatwootService {
|
||||
|
||||
this.provider = provider;
|
||||
|
||||
const cacheKey = `clientCw-${instance.instanceName}`;
|
||||
if (this.cache.has(cacheKey)) {
|
||||
return this.cache.get(cacheKey) as ChatwootClient;
|
||||
}
|
||||
|
||||
this.logger.verbose('create client to instance: ' + instance.instanceName);
|
||||
const client = new ChatwootClient({
|
||||
config: {
|
||||
@@ -86,8 +81,6 @@ export class ChatwootService {
|
||||
|
||||
this.logger.verbose('client created');
|
||||
|
||||
this.cache.set(cacheKey, client);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -409,9 +402,9 @@ export class ChatwootService {
|
||||
return null;
|
||||
}
|
||||
|
||||
const cacheKey = `createConversation-${instance.instanceName}-${body.key.remoteJid}`;
|
||||
if (this.cache.has(cacheKey)) {
|
||||
const conversationId = this.cache.get(cacheKey) as number;
|
||||
const cacheKey = `${instance.instanceName}:createConversation-${body.key.remoteJid}`;
|
||||
if (await this.cache.has(cacheKey)) {
|
||||
const conversationId = (await this.cache.get(cacheKey)) as number;
|
||||
let conversationExists: conversation | boolean;
|
||||
try {
|
||||
conversationExists = await client.conversations.get({
|
||||
@@ -615,9 +608,9 @@ export class ChatwootService {
|
||||
public async getInbox(instance: InstanceDto) {
|
||||
this.logger.verbose('get inbox to instance: ' + instance.instanceName);
|
||||
|
||||
const cacheKey = `getInbox-${instance.instanceName}`;
|
||||
if (this.cache.has(cacheKey)) {
|
||||
return this.cache.get(cacheKey) as inbox;
|
||||
const cacheKey = `${instance.instanceName}:getInbox`;
|
||||
if (await this.cache.has(cacheKey)) {
|
||||
return (await this.cache.get(cacheKey)) as inbox;
|
||||
}
|
||||
|
||||
const client = await this.clientCw(instance);
|
||||
@@ -1044,7 +1037,7 @@ export class ChatwootService {
|
||||
body.status === 'resolved' &&
|
||||
body.meta?.sender?.identifier
|
||||
) {
|
||||
const keyToDelete = `createConversation-${instance.instanceName}-${body.meta.sender.identifier}`;
|
||||
const keyToDelete = `${instance.instanceName}:createConversation-${body.meta.sender.identifier}`;
|
||||
this.cache.delete(keyToDelete);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
WebsocketModel,
|
||||
} from '../models';
|
||||
import { RepositoryBroker } from '../repository/repository.manager';
|
||||
import { CacheService } from './cache.service';
|
||||
import { WAStartupService } from './whatsapp.service';
|
||||
|
||||
export class WAMonitoringService {
|
||||
@@ -34,6 +35,7 @@ export class WAMonitoringService {
|
||||
private readonly configService: ConfigService,
|
||||
private readonly repository: RepositoryBroker,
|
||||
private readonly cache: RedisCache,
|
||||
private readonly chatwootCache: CacheService,
|
||||
) {
|
||||
this.logger.verbose('instance created');
|
||||
|
||||
@@ -359,7 +361,13 @@ export class WAMonitoringService {
|
||||
}
|
||||
|
||||
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,
|
||||
this.chatwootCache,
|
||||
);
|
||||
instance.instanceName = name;
|
||||
this.logger.verbose('Instance loaded: ' + name);
|
||||
await instance.connectToWhatsapp();
|
||||
|
||||
@@ -131,6 +131,7 @@ import { MessageUpQuery } from '../repository/messageUp.repository';
|
||||
import { RepositoryBroker } from '../repository/repository.manager';
|
||||
import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types';
|
||||
import { waMonitor } from '../whatsapp.module';
|
||||
import { CacheService } from './cache.service';
|
||||
import { ChamaaiService } from './chamaai.service';
|
||||
import { ChatwootService } from './chatwoot.service';
|
||||
import { TypebotService } from './typebot.service';
|
||||
@@ -143,6 +144,7 @@ export class WAStartupService {
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
private readonly repository: RepositoryBroker,
|
||||
private readonly cache: RedisCache,
|
||||
private readonly chatwootCache: CacheService,
|
||||
) {
|
||||
this.logger.verbose('WAStartupService initialized');
|
||||
this.cleanStore();
|
||||
@@ -170,7 +172,7 @@ export class WAStartupService {
|
||||
|
||||
private phoneNumber: string;
|
||||
|
||||
private chatwootService = new ChatwootService(waMonitor, this.configService, this.repository);
|
||||
private chatwootService = new ChatwootService(waMonitor, this.configService, this.repository, this.chatwootCache);
|
||||
|
||||
private typebotService = new TypebotService(waMonitor, this.configService, this.eventEmitter);
|
||||
|
||||
@@ -408,7 +410,7 @@ export class WAStartupService {
|
||||
this.logger.verbose('Removing cache from chatwoot');
|
||||
|
||||
if (this.localChatwoot.enabled) {
|
||||
this.chatwootService.getCache().deleteAll();
|
||||
this.chatwootService.getCache()?.deleteAll(this.instanceName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { configService } from '../config/env.config';
|
||||
import { eventEmitter } from '../config/event.config';
|
||||
import { Logger } from '../config/logger.config';
|
||||
import { CacheEngine } from '../libs/cacheengine';
|
||||
import { dbserver } from '../libs/db.connect';
|
||||
import { RedisCache } from '../libs/redis.client';
|
||||
import { ChamaaiController } from './controllers/chamaai.controller';
|
||||
@@ -48,6 +49,7 @@ import { TypebotRepository } from './repository/typebot.repository';
|
||||
import { WebhookRepository } from './repository/webhook.repository';
|
||||
import { WebsocketRepository } from './repository/websocket.repository';
|
||||
import { AuthService } from './services/auth.service';
|
||||
import { CacheService } from './services/cache.service';
|
||||
import { ChamaaiService } from './services/chamaai.service';
|
||||
import { ChatwootService } from './services/chatwoot.service';
|
||||
import { WAMonitoringService } from './services/monitor.service';
|
||||
@@ -97,7 +99,9 @@ export const repository = new RepositoryBroker(
|
||||
|
||||
export const cache = new RedisCache();
|
||||
|
||||
export const waMonitor = new WAMonitoringService(eventEmitter, configService, repository, cache);
|
||||
const chatwootCache = new CacheService(new CacheEngine(configService, ChatwootService.name).getEngine());
|
||||
|
||||
export const waMonitor = new WAMonitoringService(eventEmitter, configService, repository, cache, chatwootCache);
|
||||
|
||||
const authService = new AuthService(configService, waMonitor, repository);
|
||||
|
||||
@@ -129,7 +133,7 @@ const sqsService = new SqsService(waMonitor);
|
||||
|
||||
export const sqsController = new SqsController(sqsService);
|
||||
|
||||
const chatwootService = new ChatwootService(waMonitor, configService, repository);
|
||||
const chatwootService = new ChatwootService(waMonitor, configService, repository, chatwootCache);
|
||||
|
||||
export const chatwootController = new ChatwootController(chatwootService, configService, repository);
|
||||
|
||||
@@ -151,6 +155,7 @@ export const instanceController = new InstanceController(
|
||||
sqsService,
|
||||
typebotService,
|
||||
cache,
|
||||
chatwootCache,
|
||||
);
|
||||
export const sendMessageController = new SendMessageController(waMonitor);
|
||||
export const chatController = new ChatController(waMonitor);
|
||||
|
||||
Reference in New Issue
Block a user