evolution-api/src/api/integrations/event/pusher/pusher.controller.ts
2024-10-11 07:01:38 -03:00

210 lines
6.8 KiB
TypeScript

import { EventDto } from '@api/integrations/event/event.dto';
import { PrismaRepository } from '@api/repository/repository.service';
import { WAMonitoringService } from '@api/services/monitor.service';
import { wa } from '@api/types/wa.types';
import { configService, Log, Pusher as ConfigPusher } from '@config/env.config';
import { Logger } from '@config/logger.config';
import Pusher from 'pusher';
import { EmitData, EventController, EventControllerInterface } from '../event.controller';
export class PusherController extends EventController implements EventControllerInterface {
private readonly logger = new Logger('PusherController');
private pusherClients: { [instanceName: string]: Pusher } = {};
private globalPusherClient: Pusher | null = null;
private pusherConfig: ConfigPusher = configService.get<ConfigPusher>('PUSHER');
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
super(prismaRepository, waMonitor, configService.get<ConfigPusher>('PUSHER')?.ENABLED, 'pusher');
this.init();
}
public async init(): Promise<void> {
if (!this.status) {
return;
}
if (this.pusherConfig.GLOBAL?.ENABLED) {
const { APP_ID, KEY, SECRET, CLUSTER, USE_TLS } = this.pusherConfig.GLOBAL;
if (APP_ID && KEY && SECRET && CLUSTER) {
this.globalPusherClient = new Pusher({
appId: APP_ID,
key: KEY,
secret: SECRET,
cluster: CLUSTER,
useTLS: USE_TLS,
});
this.logger.info('Pusher global client initialized');
}
}
const instances = await this.prismaRepository.instance.findMany({
where: {
Pusher: {
isNot: null,
},
},
include: {
Pusher: true,
},
});
instances.forEach((instance) => {
if (
instance.Pusher.enabled &&
instance.Pusher.appId &&
instance.Pusher.key &&
instance.Pusher.secret &&
instance.Pusher.cluster
) {
this.pusherClients[instance.name] = new Pusher({
appId: instance.Pusher.appId,
key: instance.Pusher.key,
secret: instance.Pusher.secret,
cluster: instance.Pusher.cluster,
useTLS: instance.Pusher.useTLS,
});
this.logger.info(`Pusher client initialized for instance ${instance.name}`);
} else {
delete this.pusherClients[instance.name];
this.logger.warn(`Pusher client disabled or misconfigured for instance ${instance.name}`);
}
});
}
override async set(instanceName: string, data: EventDto): Promise<wa.LocalPusher> {
if (!data.pusher?.enabled) {
data.pusher.events = [];
} else if (data.pusher.events.length === 0) {
data.pusher.events = EventController.events;
}
const instance = await this.prisma.pusher.upsert({
where: {
instanceId: this.monitor.waInstances[instanceName].instanceId,
},
update: {
enabled: data.pusher.enabled,
events: data.pusher.events,
appId: data.pusher.appId,
key: data.pusher.key,
secret: data.pusher.secret,
cluster: data.pusher.cluster,
useTLS: data.pusher.useTLS,
},
create: {
enabled: data.pusher.enabled,
events: data.pusher.events,
instanceId: this.monitor.waInstances[instanceName].instanceId,
appId: data.pusher.appId,
key: data.pusher.key,
secret: data.pusher.secret,
cluster: data.pusher.cluster,
useTLS: data.pusher.useTLS,
},
});
if (instance.enabled && instance.appId && instance.key && instance.secret && instance.cluster) {
this.pusherClients[instanceName] = new Pusher({
appId: instance.appId,
key: instance.key,
secret: instance.secret,
cluster: instance.cluster,
useTLS: instance.useTLS,
});
this.logger.info(`Pusher client initialized for instance ${instanceName}`);
} else {
delete this.pusherClients[instanceName];
this.logger.warn(`Pusher client disabled or misconfigured for instance ${instanceName}`);
}
return instance;
}
public async emit({
instanceName,
origin,
event,
data,
serverUrl,
dateTime,
sender,
apiKey,
local,
}: EmitData): Promise<void> {
if (!this.status) {
return;
}
const instance = (await this.get(instanceName)) as wa.LocalPusher;
const we = event.replace(/[.-]/gm, '_').toUpperCase();
const enabledLog = configService.get<Log>('LOG').LEVEL.includes('WEBHOOKS');
const eventName = event.replace(/_/g, '.').toLowerCase();
const pusherData = {
event,
instance: instanceName,
data,
destination: instance?.appId || this.pusherConfig.GLOBAL?.APP_ID,
date_time: dateTime,
sender,
server_url: serverUrl,
apikey: apiKey,
};
if (event == 'qrcode.updated') {
delete pusherData.data.qrcode.base64;
}
const payload = JSON.stringify(pusherData);
const payloadSize = Buffer.byteLength(payload, 'utf8');
const MAX_SIZE = 10240;
if (payloadSize > MAX_SIZE) {
this.logger.error({
local: `${origin}.sendData-Pusher`,
message: 'Payload size exceeds Pusher limit',
event,
instanceName,
payloadSize,
});
return;
}
if (local && instance && instance.enabled) {
const pusherLocalEvents = instance.events;
if (Array.isArray(pusherLocalEvents) && pusherLocalEvents.includes(we)) {
if (enabledLog) {
this.logger.log({
local: `${origin}.sendData-Pusher`,
appId: instance.appId,
...pusherData,
});
}
try {
const pusher = this.pusherClients[instanceName];
if (pusher) {
pusher.trigger(instanceName, eventName, pusherData);
} else {
this.logger.error(`Pusher client not found for instance ${instanceName}`);
}
} catch (error) {
this.logger.error({
local: `${origin}.sendData-Pusher`,
message: error?.message,
error,
});
}
}
}
if (this.pusherConfig.GLOBAL?.ENABLED) {
const globalEvents = this.pusherConfig.EVENTS;
if (globalEvents[we]) {
if (enabledLog) {
this.logger.log({
local: `${origin}.sendData-Pusher-Global`,
appId: this.pusherConfig.GLOBAL?.APP_ID,
...pusherData,
});
}
try {
if (this.globalPusherClient) {
this.globalPusherClient.trigger(instanceName, eventName, pusherData);
} else {
this.logger.error('Global Pusher client not initialized');
}
} catch (error) {
this.logger.error({
local: `${origin}.sendData-Pusher-Global`,
message: error?.message,
error,
});
}
}
}
}
}