File size: 3,648 Bytes
4327358
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { NestFactory } from '@nestjs/core';
import { WsAdapter } from '@nestjs/platform-ws';
import { WAHA_WEBHOOKS } from '@waha/structures/webhooks';
import {
  getNestJSLogLevels,
  getPinoLogLevel,
  getPinoTransport,
} from '@waha/utils/logging';
import { json, urlencoded } from 'express';
import { Logger as NestJSPinoLogger } from 'nestjs-pino';
import { LoggerErrorInterceptor } from 'nestjs-pino';
import { Logger } from 'pino';
import pino from 'pino';

import { WhatsappConfigService } from './config.service';
import { AppModuleCore } from './core/app.module.core';
import { SwaggerConfiguratorCore } from './core/SwaggerConfiguratorCore';
import { AllExceptionsFilter } from './nestjs/AllExceptionsFilter';
import { getWAHAVersion, VERSION, WAHAVersion } from './version';

const logger: Logger = pino({
  level: getPinoLogLevel(),
  transport: getPinoTransport(),
}).child({ name: 'Bootstrap' });

process.on('uncaughtException', (err) => {
  logger.error('Uncaught Exception:', err);
  if (err instanceof Error) {
    logger.error(err.stack);
  }
});
process.on('unhandledRejection', (reason, promise) => {
  logger.error('Unhandled Rejection at:', promise);
  if (reason instanceof Error) {
    logger.error(reason.stack);
  } else {
    logger.error('Unhandled rejection reason:', reason);
  }
});
logger.info('NODE - Catching unhandled rejections and exceptions enabled');

process.on('SIGINT', () => {
  logger.info('SIGINT received');
});

process.on('SIGTERM', () => {
  logger.info('SIGTERM received');
});

async function loadModules(): Promise<typeof AppModuleCore> {
  const version = getWAHAVersion();

  if (version === WAHAVersion.CORE) {
    const { AppModuleCore } = await import('./core/app.module.core');
    return AppModuleCore;
  }
  // Ignore if it's a core version - there's no plus module
  // @ts-ignore
  const { AppModulePlus } = await import('./plus/app.module.plus');
  // @ts-ignore
  return AppModulePlus;
}

async function bootstrap() {
  const version = getWAHAVersion();
  logger.info(`WAHA (WhatsApp HTTP API) - Running ${version} version...`);
  const AppModule = await loadModules();
  const httpsOptions = AppModule.getHttpsOptions(logger);
  const app = await NestFactory.create(AppModule, {
    logger: getNestJSLogLevels(),
    httpsOptions: httpsOptions,
    bufferLogs: true,
    forceCloseConnections: true,
  });
  app.useLogger(app.get(NestJSPinoLogger));

  // Print the original stack, not pino one
  // https://github.com/iamolegga/nestjs-pino?tab=readme-ov-file#expose-stack-trace-and-error-class-in-err-property
  app.useGlobalInterceptors(new LoggerErrorInterceptor());

  app.useGlobalFilters(new AllExceptionsFilter());
  app.enableCors();
  // Ideally, we should apply it globally.
  // but for now we added it ValidationPipe on Controller or endpoint level
  // app.useGlobalPipes(new ValidationPipe({ transform: true }));

  // Allow sending big body - for images and attachments
  app.use(json({ limit: '50mb' }));
  app.use(urlencoded({ limit: '50mb', extended: false }));
  app.useWebSocketAdapter(new WsAdapter(app));

  // Configure swagger
  const swaggerConfigurator = new SwaggerConfiguratorCore(app);
  swaggerConfigurator.configure(WAHA_WEBHOOKS);

  AppModule.appReady(app, logger);
  app.enableShutdownHooks();
  const config = app.get(WhatsappConfigService);
  await app.listen(config.port);
  logger.info(`WhatsApp HTTP API is running on: ${await app.getUrl()}`);
  logger.info(VERSION, 'Environment');
}

bootstrap().catch((error) => {
  logger.error(error, `Failed to start WAHA: ${error}`);
  // @ts-ignore
  logger.error(error.stack);
  process.exit(1);
});