mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-23 04:22:02 -06:00
perf(chatwoot): create cache for the most used/expensive functions in chatwoot
This commit is contained in:
parent
7373eea842
commit
f376047632
@ -548,6 +548,7 @@ export class InstanceController {
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case 'open':
|
case 'open':
|
||||||
this.logger.verbose('logging out instance: ' + instanceName);
|
this.logger.verbose('logging out instance: ' + instanceName);
|
||||||
|
instance.clearCacheChatwoot();
|
||||||
await instance.reloadConnection();
|
await instance.reloadConnection();
|
||||||
await delay(2000);
|
await delay(2000);
|
||||||
|
|
||||||
@ -613,6 +614,7 @@ export class InstanceController {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.waMonitor.waInstances[instanceName]?.removeRabbitmqQueues();
|
this.waMonitor.waInstances[instanceName]?.removeRabbitmqQueues();
|
||||||
|
this.waMonitor.waInstances[instanceName]?.clearCacheChatwoot();
|
||||||
|
|
||||||
if (instance.state === 'connecting') {
|
if (instance.state === 'connecting') {
|
||||||
this.logger.verbose('logging out instance: ' + instanceName);
|
this.logger.verbose('logging out instance: ' + instanceName);
|
||||||
|
39
src/whatsapp/services/cache.service.ts
Normal file
39
src/whatsapp/services/cache.service.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import NodeCache from 'node-cache';
|
||||||
|
|
||||||
|
import { Logger } from '../../config/logger.config';
|
||||||
|
|
||||||
|
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}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public set(key: string, value) {
|
||||||
|
return CacheService.localCache.set(`${this.module}-${key}`, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public has(key: string) {
|
||||||
|
return CacheService.localCache.has(`${this.module}-${key}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public delete(key: string) {
|
||||||
|
return CacheService.localCache.del(`${this.module}-${key}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteAll() {
|
||||||
|
const keys = CacheService.localCache.keys().filter((key) => key.substring(0, this.module.length) === this.module);
|
||||||
|
|
||||||
|
return CacheService.localCache.del(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public keys() {
|
||||||
|
return CacheService.localCache.keys();
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import ChatwootClient from '@figuro/chatwoot-sdk';
|
import ChatwootClient, { conversation, inbox } from '@figuro/chatwoot-sdk';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
import { createReadStream, unlinkSync, writeFileSync } from 'fs';
|
import { createReadStream, unlinkSync, writeFileSync } from 'fs';
|
||||||
@ -11,15 +11,17 @@ import { Logger } from '../../config/logger.config';
|
|||||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto';
|
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto';
|
||||||
import { MessageRaw } from '../models';
|
import { ChatwootRaw, MessageRaw } from '../models';
|
||||||
import { RepositoryBroker } from '../repository/repository.manager';
|
import { RepositoryBroker } from '../repository/repository.manager';
|
||||||
import { Events } from '../types/wa.types';
|
import { Events } from '../types/wa.types';
|
||||||
|
import { CacheService } from './cache.service';
|
||||||
import { WAMonitoringService } from './monitor.service';
|
import { WAMonitoringService } from './monitor.service';
|
||||||
|
|
||||||
export class ChatwootService {
|
export class ChatwootService {
|
||||||
private readonly logger = new Logger(ChatwootService.name);
|
private readonly logger = new Logger(ChatwootService.name);
|
||||||
|
|
||||||
private provider: any;
|
private provider: any;
|
||||||
|
private cache = new CacheService(ChatwootService.name);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly waMonitor: WAMonitoringService,
|
private readonly waMonitor: WAMonitoringService,
|
||||||
@ -28,6 +30,11 @@ export class ChatwootService {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
private async getProvider(instance: InstanceDto) {
|
private async getProvider(instance: InstanceDto) {
|
||||||
|
const cacheKey = `getProvider-${instance.instanceName}`;
|
||||||
|
if (this.cache.has(cacheKey)) {
|
||||||
|
return this.cache.get(cacheKey) as ChatwootRaw;
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.verbose('get provider to instance: ' + instance.instanceName);
|
this.logger.verbose('get provider to instance: ' + instance.instanceName);
|
||||||
const provider = await this.waMonitor.waInstances[instance.instanceName]?.findChatwoot();
|
const provider = await this.waMonitor.waInstances[instance.instanceName]?.findChatwoot();
|
||||||
|
|
||||||
@ -38,6 +45,8 @@ export class ChatwootService {
|
|||||||
|
|
||||||
this.logger.verbose('provider found');
|
this.logger.verbose('provider found');
|
||||||
|
|
||||||
|
this.cache.set(cacheKey, provider);
|
||||||
|
|
||||||
return provider;
|
return provider;
|
||||||
// try {
|
// try {
|
||||||
// } catch (error) {
|
// } catch (error) {
|
||||||
@ -60,6 +69,11 @@ export class ChatwootService {
|
|||||||
|
|
||||||
this.provider = provider;
|
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);
|
this.logger.verbose('create client to instance: ' + instance.instanceName);
|
||||||
const client = new ChatwootClient({
|
const client = new ChatwootClient({
|
||||||
config: {
|
config: {
|
||||||
@ -72,9 +86,15 @@ export class ChatwootService {
|
|||||||
|
|
||||||
this.logger.verbose('client created');
|
this.logger.verbose('client created');
|
||||||
|
|
||||||
|
this.cache.set(cacheKey, client);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getCache() {
|
||||||
|
return this.cache;
|
||||||
|
}
|
||||||
|
|
||||||
public async create(instance: InstanceDto, data: ChatwootDto) {
|
public async create(instance: InstanceDto, data: ChatwootDto) {
|
||||||
this.logger.verbose('create chatwoot: ' + instance.instanceName);
|
this.logger.verbose('create chatwoot: ' + instance.instanceName);
|
||||||
|
|
||||||
@ -389,6 +409,26 @@ export class ChatwootService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cacheKey = `createConversation-${instance.instanceName}-${body.key.remoteJid}`;
|
||||||
|
if (this.cache.has(cacheKey)) {
|
||||||
|
const conversationId = this.cache.get(cacheKey) as number;
|
||||||
|
let conversationExists: conversation | boolean;
|
||||||
|
try {
|
||||||
|
conversationExists = await client.conversations.get({
|
||||||
|
accountId: this.provider.account_id,
|
||||||
|
conversationId: conversationId,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
conversationExists = false;
|
||||||
|
}
|
||||||
|
if (!conversationExists) {
|
||||||
|
this.cache.delete(cacheKey);
|
||||||
|
return await this.createConversation(instance, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
return conversationId;
|
||||||
|
}
|
||||||
|
|
||||||
const isGroup = body.key.remoteJid.includes('@g.us');
|
const isGroup = body.key.remoteJid.includes('@g.us');
|
||||||
|
|
||||||
this.logger.verbose('is group: ' + isGroup);
|
this.logger.verbose('is group: ' + isGroup);
|
||||||
@ -539,6 +579,7 @@ export class ChatwootService {
|
|||||||
|
|
||||||
if (conversation) {
|
if (conversation) {
|
||||||
this.logger.verbose('conversation found');
|
this.logger.verbose('conversation found');
|
||||||
|
this.cache.set(cacheKey, conversation.id);
|
||||||
return conversation.id;
|
return conversation.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,6 +605,7 @@ export class ChatwootService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('conversation created');
|
this.logger.verbose('conversation created');
|
||||||
|
this.cache.set(cacheKey, conversation.id);
|
||||||
return conversation.id;
|
return conversation.id;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
@ -573,6 +615,11 @@ export class ChatwootService {
|
|||||||
public async getInbox(instance: InstanceDto) {
|
public async getInbox(instance: InstanceDto) {
|
||||||
this.logger.verbose('get inbox to instance: ' + instance.instanceName);
|
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 client = await this.clientCw(instance);
|
const client = await this.clientCw(instance);
|
||||||
|
|
||||||
if (!client) {
|
if (!client) {
|
||||||
@ -599,6 +646,7 @@ export class ChatwootService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('return inbox');
|
this.logger.verbose('return inbox');
|
||||||
|
this.cache.set(cacheKey, findByName);
|
||||||
return findByName;
|
return findByName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +442,7 @@ export class WAMonitoringService {
|
|||||||
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.waInstances[instanceName]?.clearCacheChatwoot();
|
||||||
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
this.logger.verbose('request cleaning up instance: ' + instanceName);
|
||||||
this.cleaningUp(instanceName);
|
this.cleaningUp(instanceName);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -368,6 +368,8 @@ export class WAStartupService {
|
|||||||
|
|
||||||
Object.assign(this.localChatwoot, { ...data, sign_delimiter: data.sign_msg ? data.sign_delimiter : null });
|
Object.assign(this.localChatwoot, { ...data, sign_delimiter: data.sign_msg ? data.sign_delimiter : null });
|
||||||
|
|
||||||
|
this.clearCacheChatwoot();
|
||||||
|
|
||||||
this.logger.verbose('Chatwoot set');
|
this.logger.verbose('Chatwoot set');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,6 +404,14 @@ export class WAStartupService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public clearCacheChatwoot() {
|
||||||
|
this.logger.verbose('Removing cache from chatwoot');
|
||||||
|
|
||||||
|
if (this.localChatwoot.enabled) {
|
||||||
|
this.chatwootService.getCache().deleteAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async loadSettings() {
|
private async loadSettings() {
|
||||||
this.logger.verbose('Loading settings');
|
this.logger.verbose('Loading settings');
|
||||||
const data = await this.repository.settings.find(this.instanceName);
|
const data = await this.repository.settings.find(this.instanceName);
|
||||||
|
Loading…
Reference in New Issue
Block a user