Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d85e2498fd | ||
|
|
507382b6d2 | ||
|
|
f343cf8549 | ||
|
|
832d5baf35 | ||
|
|
0253f32574 | ||
|
|
6173180272 | ||
|
|
2d21931fb1 | ||
|
|
bdaa7187fd | ||
|
|
e7ad6e06ec | ||
|
|
7c14483852 | ||
|
|
8b4b1f934e | ||
|
|
713eb3f169 | ||
|
|
48297c80d1 | ||
|
|
315ffdac92 | ||
|
|
7ddc17e6e5 | ||
|
|
e3b8073c82 | ||
|
|
80517e416c | ||
|
|
4b71aade9d | ||
|
|
1b52698c54 | ||
|
|
b8f372d83f | ||
|
|
7bc5f55fb2 |
No files matched your search
@@ -1,3 +1,4 @@
|
||||
*.heapsnapshot
|
||||
.yarn
|
||||
example.ts
|
||||
.*sessions
|
||||
|
||||
+4
-2
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# Build
|
||||
#
|
||||
ARG NODE_VERSION=20.12.2-bullseye
|
||||
ARG NODE_VERSION=22.8-bullseye
|
||||
FROM node:${NODE_VERSION} as build
|
||||
ENV PUPPETEER_SKIP_DOWNLOAD=True
|
||||
|
||||
@@ -9,6 +9,8 @@ ENV PUPPETEER_SKIP_DOWNLOAD=True
|
||||
WORKDIR /src
|
||||
COPY package.json .
|
||||
COPY yarn.lock .
|
||||
ENV YARN_CHECKSUM_BEHAVIOR=update
|
||||
RUN npm install -g corepack && corepack enable
|
||||
RUN yarn set version 3.6.3
|
||||
RUN yarn install
|
||||
|
||||
@@ -24,7 +26,7 @@ RUN yarn build && find ./dist -name "*.d.ts" -delete
|
||||
FROM node:${NODE_VERSION} as dashboard
|
||||
|
||||
# Download WAHA Dashboard
|
||||
ENV WAHA_DASHBOARD_SHA c1a91f879a35f0ae32d46ddb2e061ac1819a3d4f
|
||||
ENV WAHA_DASHBOARD_SHA 9afbd7b68618ea67be01bdefa978cf98a6336611
|
||||
RUN \
|
||||
wget https://github.com/devlikeapro/dashboard/archive/${WAHA_DASHBOARD_SHA}.zip \
|
||||
&& unzip ${WAHA_DASHBOARD_SHA}.zip -d /tmp/dashboard \
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
services:
|
||||
waha:
|
||||
restart: always
|
||||
container_name: waha
|
||||
# image: devlikeapro/waha:latest
|
||||
image: devlikeapro/waha-plus:latest
|
||||
ports:
|
||||
- '3000:3000/tcp'
|
||||
volumes:
|
||||
- './.sessions:/app/.sessions'
|
||||
- './.media:/app/.media'
|
||||
environment:
|
||||
- WHATSAPP_API_KEY=321
|
||||
- WAHA_DASHBOARD_USERNAME=waha
|
||||
- WAHA_DASHBOARD_PASSWORD=waha
|
||||
- WHATSAPP_DEFAULT_ENGINE=WEBJS
|
||||
- WHATSAPP_RESTART_ALL_SESSIONS=True
|
||||
- WAHA_PRINT_QR=False
|
||||
- WAHA_MEDIA_STORAGE=LOCAL
|
||||
- WHATSAPP_FILES_LIFETIME=0
|
||||
- WHATSAPP_FILES_FOLDER=/app/.media
|
||||
|
||||
n8n:
|
||||
image: docker.n8n.io/n8nio/n8n
|
||||
container_name: n8n
|
||||
restart: always
|
||||
environment:
|
||||
- WEBHOOK_URL=http://n8n:5678
|
||||
ports:
|
||||
- '5678:5678'
|
||||
volumes:
|
||||
- n8n_data:/home/node/.n8n
|
||||
|
||||
volumes:
|
||||
n8n_data: {}
|
||||
+2
-2
@@ -85,10 +85,10 @@ services:
|
||||
# Logging
|
||||
# https://waha.devlike.pro/docs/how-to/observability/#logging
|
||||
#
|
||||
- WAHA_LOG_FORMAT=PRETTY
|
||||
# Set log format to JSON if you consume logs with log management systems
|
||||
#- WAHA_LOG_FORMAT=JSON
|
||||
- WAHA_LOG_FORMAT=JSON
|
||||
- WAHA_LOG_LEVEL=info
|
||||
# - WAHA_LOG_FORMAT=PRETTY
|
||||
# If you want to see more logs, you can set the log level to debug
|
||||
#- WAHA_LOG_LEVEL=debug
|
||||
# DEBUG=1 # shortcut for setting log level to debug
|
||||
|
||||
+1
-1
@@ -8,4 +8,4 @@ uv_threadpool_size=$(($cpus * 2))
|
||||
export UV_THREADPOOL_SIZE="${UV_THREADPOOL_SIZE:-$uv_threadpool_size}"
|
||||
|
||||
# Start your application using yarn
|
||||
yarn start:prod
|
||||
node dist/main
|
||||
+1
-2
@@ -43,7 +43,7 @@
|
||||
"@types/ws": "^8.5.4",
|
||||
"adm-zip": "0.5.10",
|
||||
"async-lock": "^1.4.1",
|
||||
"better-sqlite3": "9.6.0",
|
||||
"better-sqlite3": "11.3.0",
|
||||
"check-disk-space": "^3.4.0",
|
||||
"chokidar": "^3.6.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
@@ -77,7 +77,6 @@
|
||||
"rxjs": "^7.1.0",
|
||||
"sharp": "^0.33.4",
|
||||
"swagger-ui-express": "^4.1.4",
|
||||
"venom-bot": "5.0.1",
|
||||
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-webpack-exodus-channels"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ docker run -d \
|
||||
--env WHATSAPP_API_KEY=321 \
|
||||
--env WAHA_DASHBOARD_USERNAME=waha \
|
||||
--env WAHA_DASHBOARD_PASSWORD=waha \
|
||||
--env WAHA_LOG_FORMAT=PRETTY \
|
||||
--env WAHA_LOG_FORMAT=JSON \
|
||||
--env WAHA_LOG_LEVEL=info \
|
||||
--env WHATSAPP_DEFAULT_ENGINE=WEBJS \
|
||||
--env WHATSAPP_RESTART_ALL_SESSIONS=True \
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
import * as process from 'node:process';
|
||||
import * as v8 from 'node:v8';
|
||||
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Logger,
|
||||
NotFoundException,
|
||||
Post,
|
||||
Query,
|
||||
Res,
|
||||
StreamableFile,
|
||||
UseInterceptors,
|
||||
UsePipes,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
||||
import { WhatsappConfigService } from '@waha/config.service';
|
||||
import { getApp } from '@waha/main';
|
||||
import { WAHAValidationPipe } from '@waha/nestjs/pipes/WAHAValidationPipe';
|
||||
import { WAHAEnvironment } from '@waha/structures/environment.dto';
|
||||
@@ -105,3 +111,34 @@ export class ServerController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ApiSecurity('api_key')
|
||||
@Controller('api/server/debug')
|
||||
@ApiTags('🔍 Observability')
|
||||
export class ServerDebugController {
|
||||
private logger: Logger;
|
||||
private readonly enabled: boolean;
|
||||
|
||||
constructor(protected config: WhatsappConfigService) {
|
||||
this.logger = new Logger('ServerDebugController');
|
||||
this.enabled = this.config.debugModeEnabled;
|
||||
}
|
||||
|
||||
@Get('heapsnapshot')
|
||||
@ApiOperation({
|
||||
summary: 'Return a heapsnapshot',
|
||||
description: "Return a heapsnapshot of the server's memory",
|
||||
})
|
||||
async heapsnapshot() {
|
||||
if (!this.enabled) {
|
||||
throw new NotFoundException('WAHA_DEBUG_MODE is disabled');
|
||||
}
|
||||
this.logger.log('Creating a heap snapshot...');
|
||||
const heap = v8.getHeapSnapshot();
|
||||
const fileName = `${Date.now()}.heapsnapshot`;
|
||||
return new StreamableFile(heap, {
|
||||
type: 'application/octet-stream',
|
||||
disposition: `attachment; filename=${fileName}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -136,4 +136,9 @@ export class WhatsappConfigService {
|
||||
3000,
|
||||
);
|
||||
}
|
||||
|
||||
get debugModeEnabled(): boolean {
|
||||
const value = this.configService.get('WAHA_DEBUG_MODE', 'false');
|
||||
return parseBool(value);
|
||||
}
|
||||
}
|
||||
@@ -170,6 +170,7 @@ export abstract class WhatsappSession {
|
||||
'--disable-offline-load-stale-cache',
|
||||
'--disable-popup-blocking',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-site-isolation-trials', // https://superuser.com/questions/654565/how-to-run-google-chrome-in-a-single-process
|
||||
'--disable-speech-api',
|
||||
'--disable-sync',
|
||||
'--disable-translate',
|
||||
@@ -178,6 +179,7 @@ export abstract class WhatsappSession {
|
||||
'--hide-scrollbars',
|
||||
'--ignore-certificate-errors',
|
||||
'--ignore-ssl-errors',
|
||||
'--in-process-gpu', // https://superuser.com/questions/654565/how-to-run-google-chrome-in-a-single-process
|
||||
'--metrics-recording-only',
|
||||
'--mute-audio',
|
||||
'--no-default-browser-check',
|
||||
@@ -186,6 +188,7 @@ export abstract class WhatsappSession {
|
||||
'--no-sandbox',
|
||||
'--no-zygote',
|
||||
'--password-store=basic',
|
||||
'--renderer-process-limit=2', // https://superuser.com/questions/654565/how-to-run-google-chrome-in-a-single-process
|
||||
'--safebrowsing-disable-auto-update',
|
||||
'--single-process',
|
||||
'--use-mock-keychain',
|
||||
|
||||
@@ -5,7 +5,10 @@ import { PassportModule } from '@nestjs/passport';
|
||||
import { ServeStaticModule } from '@nestjs/serve-static';
|
||||
import { TerminusModule } from '@nestjs/terminus';
|
||||
import { ChannelsController } from '@waha/api/channels.controller';
|
||||
import { ServerController } from '@waha/api/server.controller';
|
||||
import {
|
||||
ServerController,
|
||||
ServerDebugController,
|
||||
} from '@waha/api/server.controller';
|
||||
import { WebsocketGatewayCore } from '@waha/core/api/websocket.gateway.core';
|
||||
import { MediaLocalStorageConfig } from '@waha/core/media/local/MediaLocalStorageConfig';
|
||||
import { BufferJsonReplacerInterceptor } from '@waha/nestjs/BufferJsonReplacerInterceptor';
|
||||
@@ -112,6 +115,7 @@ export const CONTROLLERS = [
|
||||
PingController,
|
||||
HealthController,
|
||||
ServerController,
|
||||
ServerDebugController,
|
||||
VersionController,
|
||||
];
|
||||
const PROVIDERS = [
|
||||
|
||||
@@ -284,6 +284,8 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
}
|
||||
|
||||
async buildClient() {
|
||||
// @ts-ignore
|
||||
this.sock?.ev?.removeAllListeners();
|
||||
this.sock = await this.makeSocket();
|
||||
this.issueMessageUpdateOnEdits();
|
||||
this.issuePresenceUpdateOnMessageUpsert();
|
||||
@@ -645,11 +647,13 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
}
|
||||
|
||||
async startTyping(request: ChatRequest) {
|
||||
return this.sock.sendPresenceUpdate('composing', request.chatId);
|
||||
const chatId = toJID(this.ensureSuffix(request.chatId));
|
||||
return this.sock.sendPresenceUpdate('composing', chatId);
|
||||
}
|
||||
|
||||
async stopTyping(request: ChatRequest) {
|
||||
return this.sock.sendPresenceUpdate('paused', request.chatId);
|
||||
const chatId = toJID(this.ensureSuffix(request.chatId));
|
||||
return this.sock.sendPresenceUpdate('paused', chatId);
|
||||
}
|
||||
|
||||
async getMessages(query: GetMessageQuery) {
|
||||
@@ -887,6 +891,9 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
`NOWEB engine doesn't support '${presence}' presence.`,
|
||||
);
|
||||
}
|
||||
if (chatId) {
|
||||
chatId = toJID(this.ensureSuffix(chatId));
|
||||
}
|
||||
await this.sock.sendPresenceUpdate(enginePresence, chatId);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
import { UnprocessableEntityException } from '@nestjs/common/exceptions/unprocessable-entity.exception';
|
||||
import { IMediaEngineProcessor } from '@waha/core/media/IMediaEngineProcessor';
|
||||
import * as Buffer from 'buffer';
|
||||
import { create, CreateConfig, Message, Whatsapp } from 'venom-bot';
|
||||
|
||||
import {
|
||||
ChatRequest,
|
||||
CheckNumberStatusQuery,
|
||||
GetMessageQuery,
|
||||
MessageFileRequest,
|
||||
MessageImageRequest,
|
||||
MessageLinkPreviewRequest,
|
||||
MessageLocationRequest,
|
||||
MessageReactionRequest,
|
||||
MessageReplyRequest,
|
||||
MessageTextRequest,
|
||||
WANumberExistResult,
|
||||
} from '../../../structures/chatting.dto';
|
||||
import {
|
||||
WAHAEngine,
|
||||
WAHAEvents,
|
||||
WAHASessionStatus,
|
||||
} from '../../../structures/enums.dto';
|
||||
import { WAMessage } from '../../../structures/responses.dto';
|
||||
import { WAHAInternalEvent, WhatsappSession } from '../../abc/session.abc';
|
||||
import { NotImplementedByEngineError } from '../../exceptions';
|
||||
import { QR } from '../../QR';
|
||||
|
||||
export class WhatsappSessionVenomCore extends WhatsappSession {
|
||||
engine = WAHAEngine.VENOM;
|
||||
|
||||
whatsapp: Whatsapp;
|
||||
private qr: QR;
|
||||
|
||||
public constructor(config) {
|
||||
super(config);
|
||||
this.qr = new QR();
|
||||
}
|
||||
|
||||
protected buildClient() {
|
||||
const venomOptions: CreateConfig = {
|
||||
headless: true,
|
||||
devtools: false,
|
||||
debug: false,
|
||||
logQR: true,
|
||||
browserArgs: this.getBrowserArgsForPuppeteer(),
|
||||
autoClose: 60000,
|
||||
puppeteerOptions: {},
|
||||
};
|
||||
this.addProxyConfig(venomOptions);
|
||||
return create(this.name, this.getCatchQR(), undefined, venomOptions);
|
||||
}
|
||||
|
||||
protected addProxyConfig(venomOptions: CreateConfig) {
|
||||
if (this.proxyConfig?.server !== undefined) {
|
||||
venomOptions.addProxy = [this.proxyConfig?.server];
|
||||
}
|
||||
if (
|
||||
this.proxyConfig?.username !== undefined &&
|
||||
this.proxyConfig?.password !== undefined
|
||||
) {
|
||||
venomOptions.userProxy = this.proxyConfig?.username;
|
||||
venomOptions.userPass = this.proxyConfig?.password;
|
||||
}
|
||||
}
|
||||
|
||||
protected getCatchQR() {
|
||||
return (base64Qrimg, asciiQR, attempts, urlCode) => {
|
||||
this.qr.save(base64Qrimg, urlCode);
|
||||
this.printQR(this.qr);
|
||||
this.status = WAHASessionStatus.SCAN_QR_CODE;
|
||||
this.logger.debug('Number of attempts to read the qrcode: ', attempts);
|
||||
};
|
||||
}
|
||||
|
||||
async start() {
|
||||
this.status = WAHASessionStatus.STARTING;
|
||||
try {
|
||||
this.whatsapp = await this.buildClient();
|
||||
} catch (error) {
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.logger.error(error);
|
||||
this.qr.save('');
|
||||
return;
|
||||
}
|
||||
|
||||
this.status = WAHASessionStatus.WORKING;
|
||||
this.events.emit(WAHAInternalEvent.ENGINE_START);
|
||||
return this;
|
||||
}
|
||||
|
||||
async stop() {
|
||||
this.status = WAHASessionStatus.STOPPED;
|
||||
this.events.removeAllListeners();
|
||||
await this.whatsapp.close();
|
||||
}
|
||||
|
||||
subscribeEngineEvent(event: WAHAEvents | string, handler: (message) => void) {
|
||||
switch (event) {
|
||||
case WAHAEvents.MESSAGE:
|
||||
this.whatsapp.onMessage((message: Message) =>
|
||||
this.processIncomingMessage(message).then(handler),
|
||||
);
|
||||
return true;
|
||||
case WAHAEvents.MESSAGE_ANY:
|
||||
this.whatsapp.onAnyMessage((message: Message) =>
|
||||
this.processIncomingMessage(message).then(handler),
|
||||
);
|
||||
return true;
|
||||
case WAHAEvents.STATE_CHANGE:
|
||||
this.whatsapp.onStateChange(handler);
|
||||
return true;
|
||||
case WAHAEvents.MESSAGE_ACK:
|
||||
this.whatsapp.onAck(handler);
|
||||
return true;
|
||||
case WAHAEvents.GROUP_JOIN:
|
||||
this.whatsapp.onAddedToGroup(handler);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* START - Methods for API
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auth methods
|
||||
*/
|
||||
public getQR(): QR {
|
||||
return this.qr;
|
||||
}
|
||||
|
||||
getScreenshot(): Promise<Buffer> {
|
||||
if (this.status === WAHASessionStatus.STARTING) {
|
||||
throw new UnprocessableEntityException(
|
||||
`The session is starting, please try again after few seconds`,
|
||||
);
|
||||
} else if (this.status === WAHASessionStatus.SCAN_QR_CODE) {
|
||||
return Promise.resolve(this.qr.get());
|
||||
} else if (this.status === WAHASessionStatus.WORKING) {
|
||||
return this.whatsapp.page.screenshot();
|
||||
} else {
|
||||
throw new UnprocessableEntityException(`Unknown status - ${this.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
async checkNumberStatus(
|
||||
request: CheckNumberStatusQuery,
|
||||
): Promise<WANumberExistResult> {
|
||||
try {
|
||||
return await this.whatsapp.checkNumberStatus(
|
||||
this.ensureSuffix(request.phone),
|
||||
);
|
||||
} catch (error) {
|
||||
// Catch number doesn't exist error and return it as is
|
||||
if (error.status === 404 && !error.numberExists) {
|
||||
return error;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
sendText(request: MessageTextRequest) {
|
||||
return this.whatsapp.sendText(
|
||||
this.ensureSuffix(request.chatId),
|
||||
request.text,
|
||||
);
|
||||
}
|
||||
|
||||
reply(request: MessageReplyRequest) {
|
||||
return this.whatsapp.reply(request.chatId, request.text, request.reply_to);
|
||||
}
|
||||
|
||||
sendFile(request: MessageFileRequest) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
sendImage(request: MessageImageRequest) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
async sendVoice(request) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
sendLinkPreview(request: MessageLinkPreviewRequest) {
|
||||
return this.whatsapp.sendLinkPreview(
|
||||
request.chatId,
|
||||
request.url,
|
||||
request.title,
|
||||
);
|
||||
}
|
||||
|
||||
sendLocation(request: MessageLocationRequest) {
|
||||
return this.whatsapp.sendLocation(
|
||||
request.chatId,
|
||||
String(request.latitude),
|
||||
String(request.longitude),
|
||||
request.title,
|
||||
);
|
||||
}
|
||||
|
||||
sendSeen(chat: ChatRequest) {
|
||||
return this.whatsapp.markMarkSeenMessage(chat.chatId);
|
||||
}
|
||||
|
||||
startTyping(chat: ChatRequest) {
|
||||
return this.whatsapp.startTyping(chat.chatId, false);
|
||||
}
|
||||
|
||||
stopTyping(chat: ChatRequest) {
|
||||
return;
|
||||
// The method is not available yet in new venom-bot
|
||||
// return this.whatsapp.stopTyping(chat.chatId);
|
||||
}
|
||||
|
||||
async getChatMessages(chatId: string, limit: number) {
|
||||
const messages = await this.whatsapp.getAllMessagesInChat(
|
||||
chatId,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
// Go over messages, download media, and convert to right format.
|
||||
const result = [];
|
||||
for (const [count, message] of messages.entries()) {
|
||||
if (count > limit) {
|
||||
// Have enough in the list, stop processing
|
||||
break;
|
||||
}
|
||||
result.push(await this.processIncomingMessage(message));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async getMessages(query: GetMessageQuery) {
|
||||
return this.getChatMessages(query.chatId, query.limit);
|
||||
}
|
||||
|
||||
setReaction(request: MessageReactionRequest) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
/**
|
||||
* END - Methods for API
|
||||
*/
|
||||
|
||||
protected downloadMedia(message: Message) {
|
||||
const processor = new EngineMediaProcessor(this);
|
||||
return this.mediaManager.processMedia(processor, message, this.name);
|
||||
}
|
||||
|
||||
private processIncomingMessage(message: Message) {
|
||||
return this.downloadMedia(message).then(this.toWAMessage);
|
||||
}
|
||||
|
||||
protected toWAMessage(message: Message): Promise<WAMessage> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve({
|
||||
id: message.id,
|
||||
timestamp: message.timestamp,
|
||||
from: message.from,
|
||||
fromMe: message.fromMe,
|
||||
to: message.to,
|
||||
body: message.body,
|
||||
// Media
|
||||
// @ts-ignore
|
||||
hasMedia: Boolean(message.media),
|
||||
// @ts-ignore
|
||||
media: message.media,
|
||||
// @ts-ignore
|
||||
mediaUrl: message.media?.url,
|
||||
// @ts-ignore
|
||||
ack: message.ack,
|
||||
location: undefined,
|
||||
vCards: undefined,
|
||||
_data: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class EngineMediaProcessor implements IMediaEngineProcessor<Message> {
|
||||
constructor(public session: WhatsappSessionVenomCore) {}
|
||||
|
||||
hasMedia(message: any): boolean {
|
||||
if (!message.isMMS || !message.isMedia) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
getMessageId(message: any): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
getMimetype(message: any): string {
|
||||
return '';
|
||||
}
|
||||
|
||||
getMediaBuffer(message: any): Promise<Buffer | null> {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
getFilename(message: Message): string | null {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -235,6 +235,8 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
private async end() {
|
||||
try {
|
||||
this.whatsapp?.removeAllListeners();
|
||||
this.whatsapp?.pupBrowser?.removeAllListeners();
|
||||
this.whatsapp?.pupPage?.removeAllListeners();
|
||||
this.startDelayedJob.cancel();
|
||||
// It's possible that browser yet starting
|
||||
await waitUntil(
|
||||
|
||||
+23
-24
@@ -27,7 +27,6 @@ import { SessionManager } from './abc/manager.abc';
|
||||
import { SessionParams, WhatsappSession } from './abc/session.abc';
|
||||
import { EngineConfigService } from './config/EngineConfigService';
|
||||
import { WhatsappSessionNoWebCore } from './engines/noweb/session.noweb.core';
|
||||
import { WhatsappSessionVenomCore } from './engines/venom/session.venom.core';
|
||||
import { WhatsappSessionWebJSCore } from './engines/webjs/session.webjs.core';
|
||||
import { DOCS_URL } from './exceptions';
|
||||
import { getProxyConfig } from './helpers.proxy';
|
||||
@@ -43,6 +42,10 @@ export class OnlyDefaultSessionIsAllowed extends UnprocessableEntityException {
|
||||
);
|
||||
}
|
||||
}
|
||||
enum DefaultSessionStatus {
|
||||
REMOVED = undefined,
|
||||
STOPPED = null,
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionManagerCore extends SessionManager {
|
||||
@@ -51,7 +54,7 @@ export class SessionManagerCore extends SessionManager {
|
||||
// session - exists and running (or failed or smth)
|
||||
// null - stopped
|
||||
// undefined - removed
|
||||
private session: WhatsappSession | undefined | null;
|
||||
private session: WhatsappSession | DefaultSessionStatus;
|
||||
private sessionConfig?: SessionConfig;
|
||||
DEFAULT = 'default';
|
||||
|
||||
@@ -66,7 +69,7 @@ export class SessionManagerCore extends SessionManager {
|
||||
) {
|
||||
super();
|
||||
this.events = new EventEmitter();
|
||||
this.session = null;
|
||||
this.session = DefaultSessionStatus.STOPPED;
|
||||
this.sessionConfig = null;
|
||||
this.log.setContext(SessionManagerCore.name);
|
||||
const engineName = this.engineConfigService.getDefaultEngineName();
|
||||
@@ -86,8 +89,6 @@ export class SessionManagerCore extends SessionManager {
|
||||
protected getEngine(engine: WAHAEngine): typeof WhatsappSession {
|
||||
if (engine === WAHAEngine.WEBJS) {
|
||||
return WhatsappSessionWebJSCore;
|
||||
} else if (engine === WAHAEngine.VENOM) {
|
||||
return WhatsappSessionVenomCore;
|
||||
} else if (engine === WAHAEngine.NOWEB) {
|
||||
return WhatsappSessionNoWebCore;
|
||||
} else {
|
||||
@@ -113,7 +114,7 @@ export class SessionManagerCore extends SessionManager {
|
||||
//
|
||||
async exists(name: string): Promise<boolean> {
|
||||
this.onlyDefault(name);
|
||||
return this.session !== undefined;
|
||||
return this.session !== DefaultSessionStatus.REMOVED;
|
||||
}
|
||||
|
||||
isRunning(name: string): boolean {
|
||||
@@ -138,10 +139,7 @@ export class SessionManagerCore extends SessionManager {
|
||||
new MediaNoopStorage(),
|
||||
this.config.mimetypes,
|
||||
);
|
||||
const logger = this.log.logger.child({
|
||||
session: name,
|
||||
sessionRunTimestamp: Date.now(),
|
||||
});
|
||||
const logger = this.log.logger.child({ session: name });
|
||||
logger.level = getPinoLogLevel(this.sessionConfig?.debug);
|
||||
const loggerBuilder: LoggerBuilder = logger;
|
||||
|
||||
@@ -199,7 +197,7 @@ export class SessionManagerCore extends SessionManager {
|
||||
}
|
||||
}
|
||||
this.log.info(`Session has been stopped.`, { session: name });
|
||||
this.session = null;
|
||||
this.session = DefaultSessionStatus.STOPPED;
|
||||
await sleep(this.SESSION_STOP_TIMEOUT);
|
||||
}
|
||||
|
||||
@@ -210,7 +208,7 @@ export class SessionManagerCore extends SessionManager {
|
||||
|
||||
async delete(name: string): Promise<void> {
|
||||
this.onlyDefault(name);
|
||||
this.session = undefined;
|
||||
this.session = DefaultSessionStatus.REMOVED;
|
||||
this.sessionConfig = undefined;
|
||||
}
|
||||
|
||||
@@ -239,20 +237,20 @@ export class SessionManagerCore extends SessionManager {
|
||||
if (!this.session) {
|
||||
return undefined;
|
||||
}
|
||||
const sessions = { [this.DEFAULT]: this.session };
|
||||
const sessions = { [this.DEFAULT]: this.session as WhatsappSession };
|
||||
return getProxyConfig(this.config, sessions, this.DEFAULT);
|
||||
}
|
||||
|
||||
getSession(name: string): WhatsappSession {
|
||||
this.onlyDefault(name);
|
||||
const session = this.session;
|
||||
if (session === undefined) {
|
||||
if (!session) {
|
||||
throw new NotFoundException(
|
||||
`We didn't find a session with name '${name}'.
|
||||
Please start it first by using POST /sessions/${name}/start request`,
|
||||
`We didn't find a session with name '${name}'.\n` +
|
||||
`Please start it first by using POST /sessions/${name}/start request`,
|
||||
);
|
||||
}
|
||||
return session;
|
||||
return session as WhatsappSession;
|
||||
}
|
||||
|
||||
async getSessions(all: boolean): Promise<SessionInfo[]> {
|
||||
@@ -270,12 +268,13 @@ export class SessionManagerCore extends SessionManager {
|
||||
return [];
|
||||
}
|
||||
|
||||
const me = this.session.getSessionMeInfo();
|
||||
const session = this.session as WhatsappSession;
|
||||
const me = session.getSessionMeInfo();
|
||||
// Get engine info
|
||||
let engineInfo = {};
|
||||
if (this.session) {
|
||||
if (session) {
|
||||
try {
|
||||
engineInfo = await promiseTimeout(10, this.session.getEngineInfo());
|
||||
engineInfo = await promiseTimeout(10, session.getEngineInfo());
|
||||
} catch (e) {
|
||||
this.log.warn(
|
||||
{ session: this.session },
|
||||
@@ -284,14 +283,14 @@ export class SessionManagerCore extends SessionManager {
|
||||
}
|
||||
}
|
||||
const engine = {
|
||||
engine: this.session?.engine,
|
||||
engine: session?.engine,
|
||||
...engineInfo,
|
||||
};
|
||||
return [
|
||||
{
|
||||
name: this.session.name,
|
||||
status: this.session.status,
|
||||
config: this.session.sessionConfig,
|
||||
name: session.name,
|
||||
status: session.status,
|
||||
config: session.sessionConfig,
|
||||
me: me,
|
||||
engine: engine,
|
||||
},
|
||||
|
||||
@@ -98,5 +98,7 @@ async function bootstrap() {
|
||||
|
||||
bootstrap().catch((error) => {
|
||||
logger.error(error, `Failed to start WAHA: ${error}`);
|
||||
// @ts-ignore
|
||||
logger.error(error.stack);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -32,7 +32,6 @@ export enum WAHASessionStatus {
|
||||
}
|
||||
|
||||
export enum WAHAEngine {
|
||||
VENOM = 'VENOM',
|
||||
WEBJS = 'WEBJS',
|
||||
NOWEB = 'NOWEB',
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ export class SingleDelayedJobRunner {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.logger.debug(`Running job...`);
|
||||
fn().finally(() => {
|
||||
this.logger.debug(`Job finished`);
|
||||
this.timeout = null;
|
||||
this.logger.debug(`Job finished`);
|
||||
});
|
||||
}, this.timeoutMs);
|
||||
this.logger.info(`Job scheduled with timeout ${this.timeoutMs} ms`);
|
||||
@@ -42,6 +42,7 @@ export class SingleDelayedJobRunner {
|
||||
|
||||
cancel() {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
this.logger.info(`Job cancelled`);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ export class SinglePeriodicJobRunner {
|
||||
|
||||
stop() {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
this.logger.info(`Job stopped`);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ export function getEngineName(): string {
|
||||
}
|
||||
|
||||
export const VERSION: WAHAEnvironment = {
|
||||
version: '2024.9.4',
|
||||
version: '2024.9.5',
|
||||
engine: getEngineName(),
|
||||
tier: getWAHAVersion(),
|
||||
browser: getBrowserExecutablePath(),
|
||||
|
||||
Reference in new issue
Block a user