Team Ai
Apppublic

oex2003/evolution-api

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
websocket.controller.ts161 linesDownload Raw Back to websocket
1import { PrismaRepository } from '@api/repository/repository.service';2import { WAMonitoringService } from '@api/services/monitor.service';3import { Auth, configService, Cors, Log, Websocket } from '@config/env.config';4import { Logger } from '@config/logger.config';5import { Server } from 'http';6import { Server as SocketIO } from 'socket.io';7 8import { EmitData, EventController, EventControllerInterface } from '../event.controller';9 10export class WebsocketController extends EventController implements EventControllerInterface {11  private io: SocketIO;12  private corsConfig: Array<any>;13  private readonly logger = new Logger('WebsocketController');14 15  constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {16    super(prismaRepository, waMonitor, configService.get<Websocket>('WEBSOCKET')?.ENABLED, 'websocket');17 18    this.cors = configService.get<Cors>('CORS').ORIGIN;19  }20 21  public init(httpServer: Server): void {22    if (!this.status) {23      return;24    }25 26    this.socket = new SocketIO(httpServer, {27      cors: { origin: this.cors },28      allowRequest: async (req, callback) => {29        try {30          const url = new URL(req.url || '', 'http://localhost');31          const params = new URLSearchParams(url.search);32 33          // Permite conexões internas do Socket.IO (EIO=4 é o Engine.IO v4)34          if (params.has('EIO')) {35            return callback(null, true);36          }37 38          const apiKey = params.get('apikey') || (req.headers.apikey as string);39 40          if (!apiKey) {41            this.logger.error('Connection rejected: apiKey not provided');42            return callback('apiKey is required', false);43          }44 45          const instance = await this.prismaRepository.instance.findFirst({ where: { token: apiKey } });46 47          if (!instance) {48            const globalToken = configService.get<Auth>('AUTHENTICATION').API_KEY.KEY;49            if (apiKey !== globalToken) {50              this.logger.error('Connection rejected: invalid global token');51              return callback('Invalid global token', false);52            }53          }54 55          callback(null, true);56        } catch (error) {57          this.logger.error('Authentication error:');58          this.logger.error(error);59          callback('Authentication error', false);60        }61      },62    });63 64    this.socket.on('connection', (socket) => {65      this.logger.info('User connected');66 67      socket.on('disconnect', () => {68        this.logger.info('User disconnected');69      });70 71      socket.on('sendNode', async (data) => {72        try {73          await this.waMonitor.waInstances[data.instanceId].baileysSendNode(data.stanza);74          this.logger.info('Node sent successfully');75        } catch (error) {76          this.logger.error('Error sending node:');77          this.logger.error(error);78        }79      });80    });81 82    this.logger.info('Socket.io initialized');83  }84 85  private set cors(cors: Array<any>) {86    this.corsConfig = cors;87  }88 89  private get cors(): string | Array<any> {90    return this.corsConfig?.includes('*') ? '*' : this.corsConfig;91  }92 93  private set socket(socket: SocketIO) {94    this.io = socket;95  }96 97  public get socket(): SocketIO {98    return this.io;99  }100 101  public async emit({102    instanceName,103    origin,104    event,105    data,106    serverUrl,107    dateTime,108    sender,109    apiKey,110    integration,111  }: EmitData): Promise<void> {112    if (integration && !integration.includes('websocket')) {113      return;114    }115 116    if (!this.status) {117      return;118    }119 120    const configEv = event.replace(/[.-]/gm, '_').toUpperCase();121    const logEnabled = configService.get<Log>('LOG').LEVEL.includes('WEBSOCKET');122    const message = {123      event,124      instance: instanceName,125      data,126      server_url: serverUrl,127      date_time: dateTime,128      sender,129      apikey: apiKey,130    };131 132    if (configService.get<Websocket>('WEBSOCKET')?.GLOBAL_EVENTS) {133      this.socket.emit(event, message);134 135      if (logEnabled) {136        this.logger.log({ local: `${origin}.sendData-WebsocketGlobal`, ...message });137      }138    }139 140    try {141      const instance = await this.get(instanceName);142 143      if (!instance?.enabled) {144        return;145      }146 147      if (Array.isArray(instance?.events) && instance?.events.includes(configEv)) {148        this.socket.of(`/${instanceName}`).emit(event, message);149 150        if (logEnabled) {151          this.logger.log({ local: `${origin}.sendData-Websocket`, ...message });152        }153      }154    } catch (err) {155      if (logEnabled) {156        this.logger.log(err);157      }158    }159  }160}161