Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
13de42dbe0 | ||
|
|
f99b86ed18 | ||
|
|
07f6c78372 | ||
|
|
83678553e3 | ||
|
|
9d1bbd780e | ||
|
|
899f9f2e84 | ||
|
|
1d1a083464 | ||
|
|
fabc6753e6 | ||
|
|
a16f3b67fe | ||
|
|
c0c3381a36 | ||
|
|
212a27d9df | ||
|
|
a18c1d82c1 | ||
|
|
67349e4509 | ||
|
|
293267536b |
No files matched your search
@@ -22,6 +22,8 @@ WHATSAPP_SWAGGER_ENABLED=True
|
||||
# WhatsApp engine (WEBJS is default, GOWS or NOWEB for better performance)
|
||||
WHATSAPP_DEFAULT_ENGINE=WEBJS
|
||||
|
||||
# WAHA_CLIENT_DEVICE_NAME=YourApp
|
||||
|
||||
# Base URL for the API (used for webhooks, file URLs, etc.)
|
||||
WAHA_BASE_URL=http://localhost:3000
|
||||
# WAHA_PUBLIC_URL=http://localhost:3000
|
||||
|
||||
@@ -32,6 +32,8 @@ WAHA_PUBLIC_URL=http://localhost:3000
|
||||
# WhatsApp engine (WEBJS is default, GOWS or NOWEB for better performance)
|
||||
WHATSAPP_DEFAULT_ENGINE=GOWS
|
||||
|
||||
# WAHA_CLIENT_DEVICE_NAME=YourApp
|
||||
|
||||
# =================
|
||||
# ===== APPS ======
|
||||
# =================
|
||||
|
||||
@@ -22,7 +22,7 @@ export class GowsEventStreamObservable extends Observable<EnginePayload> {
|
||||
},
|
||||
) {
|
||||
super((subscriber) => {
|
||||
logger.debug('Creating grpc stream...');
|
||||
logger.debug('Creating grpc client and stream...');
|
||||
logger.setBindings({ id: rand() });
|
||||
const { client, stream } = factory();
|
||||
this._client = client;
|
||||
@@ -41,6 +41,13 @@ export class GowsEventStreamObservable extends Observable<EnginePayload> {
|
||||
logger.warn({ err }, 'Failed to cancel gRPC stream');
|
||||
}
|
||||
|
||||
logger.debug({ reason }, 'Closing gRPC client...');
|
||||
try {
|
||||
client.close();
|
||||
} catch (err) {
|
||||
logger.warn({ err }, 'Failed to close gRPC client');
|
||||
}
|
||||
|
||||
await sleep(this.CLIENT_CLOSE_TIMEOUT);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,25 +1,15 @@
|
||||
import * as grpc from '@grpc/grpc-js';
|
||||
import { messages } from '@waha/core/engines/gows/grpc/gows';
|
||||
import { Pool, SizedPool } from '@waha/core/engines/gows/pools';
|
||||
|
||||
let CLIENTS: Pool<messages.MessageServiceClient> | null = null;
|
||||
let STREAM_CLIENTS: Pool<messages.EventStreamClient> | null = null;
|
||||
|
||||
export const GetMessageServiceClient = (
|
||||
session: string,
|
||||
address: string,
|
||||
credentials: grpc.ChannelCredentials,
|
||||
): messages.MessageServiceClient => {
|
||||
if (!CLIENTS) {
|
||||
const factory = () => {
|
||||
return new messages.MessageServiceClient(address, credentials, {
|
||||
'grpc.max_send_message_length': 128 * 1024 * 1024,
|
||||
'grpc.max_receive_message_length': 128 * 1024 * 1024,
|
||||
});
|
||||
};
|
||||
CLIENTS = new SizedPool(16, factory);
|
||||
}
|
||||
return CLIENTS.get(session);
|
||||
return new messages.MessageServiceClient(address, credentials, {
|
||||
'grpc.max_send_message_length': 128 * 1024 * 1024,
|
||||
'grpc.max_receive_message_length': 128 * 1024 * 1024,
|
||||
});
|
||||
};
|
||||
|
||||
export const GetEventStreamClient = (
|
||||
@@ -27,14 +17,8 @@ export const GetEventStreamClient = (
|
||||
address: string,
|
||||
credentials: grpc.ChannelCredentials,
|
||||
): messages.EventStreamClient => {
|
||||
if (!STREAM_CLIENTS) {
|
||||
const factory = () => {
|
||||
return new messages.EventStreamClient(address, credentials, {
|
||||
'grpc.max_send_message_length': 128 * 1024 * 1024,
|
||||
'grpc.max_receive_message_length': 128 * 1024 * 1024,
|
||||
});
|
||||
};
|
||||
STREAM_CLIENTS = new SizedPool(16, factory);
|
||||
}
|
||||
return STREAM_CLIENTS.get(session);
|
||||
return new messages.EventStreamClient(address, credentials, {
|
||||
'grpc.max_send_message_length': 128 * 1024 * 1024,
|
||||
'grpc.max_receive_message_length': 128 * 1024 * 1024,
|
||||
});
|
||||
};
|
||||
@@ -773,6 +773,7 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
|
||||
this.status = WAHASessionStatus.STOPPED;
|
||||
this.events?.stop();
|
||||
this.stopEvents();
|
||||
this.client?.close();
|
||||
this.mediaManager.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { WABrowserDescription } from '@adiwajshing/baileys';
|
||||
import { Browsers, WABrowserDescription } from '@adiwajshing/baileys';
|
||||
import makeWASocket, {
|
||||
Chat,
|
||||
Contact,
|
||||
@@ -205,6 +205,10 @@ import {
|
||||
import { extractWALocation } from '@waha/core/engines/waproto/locaiton';
|
||||
import { extractVCards } from '@waha/core/engines/waproto/vcards';
|
||||
import { Activity } from '@waha/core/abc/activity';
|
||||
import {
|
||||
WAHA_CLIENT_BROWSER_NAME,
|
||||
WAHA_CLIENT_DEVICE_NAME,
|
||||
} from '@waha/core/env';
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const promiseRetry = require('promise-retry');
|
||||
|
||||
@@ -314,8 +318,37 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
}
|
||||
|
||||
getSocketConfig(agents: Agents | undefined, state): Partial<SocketConfig> {
|
||||
// Detect browser
|
||||
let browser = ['Ubuntu', 'Chrome', '22.04.4'] as WABrowserDescription;
|
||||
let deviceName =
|
||||
this.sessionConfig?.client?.deviceName ?? WAHA_CLIENT_DEVICE_NAME;
|
||||
let browserName =
|
||||
this.sessionConfig?.client?.browserName ?? WAHA_CLIENT_BROWSER_NAME;
|
||||
if (browserName && !deviceName) {
|
||||
browser = Browsers.appropriate(browserName);
|
||||
} else if (!browserName && deviceName) {
|
||||
browser = [deviceName, 'Chrome', '22.04.4'];
|
||||
} else if (browserName && deviceName) {
|
||||
switch (deviceName) {
|
||||
case 'Mac OS':
|
||||
case 'MacOS':
|
||||
case 'macos':
|
||||
browser = Browsers.macOS(browserName);
|
||||
break;
|
||||
case 'ubuntu':
|
||||
case 'Ubuntu':
|
||||
browser = Browsers.ubuntu(browserName);
|
||||
break;
|
||||
case 'windows':
|
||||
case 'Windows':
|
||||
browser = Browsers.windows(browserName);
|
||||
break;
|
||||
default:
|
||||
browser = [deviceName, browserName, '22.04.4'];
|
||||
}
|
||||
}
|
||||
|
||||
const fullSyncEnabled = this.sessionConfig?.noweb?.store?.fullSync || false;
|
||||
const browser = ['Ubuntu', 'Chrome', '20.0.04'] as WABrowserDescription;
|
||||
let markOnlineOnConnect = this.sessionConfig?.noweb?.markOnline;
|
||||
if (markOnlineOnConnect == undefined) {
|
||||
markOnlineOnConnect = true;
|
||||
|
||||
@@ -11,7 +11,13 @@ export function extractMediaContent(
|
||||
content?.videoMessage ||
|
||||
content?.audioMessage ||
|
||||
content?.stickerMessage;
|
||||
return mediaContent;
|
||||
if (mediaContent) {
|
||||
return mediaContent;
|
||||
}
|
||||
if (content?.associatedChildMessage?.message) {
|
||||
return extractMediaContent(content.associatedChildMessage.message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
interface Long {
|
||||
|
||||
@@ -121,11 +121,7 @@ import {
|
||||
} from '@waha/structures/responses.dto';
|
||||
import { BrowserTraceQuery } from '@waha/structures/server.debug.dto';
|
||||
import { MeInfo } from '@waha/structures/sessions.dto';
|
||||
import {
|
||||
DeleteStatusRequest,
|
||||
StatusRequest,
|
||||
TextStatus,
|
||||
} from '@waha/structures/status.dto';
|
||||
import { DeleteStatusRequest, TextStatus } from '@waha/structures/status.dto';
|
||||
import {
|
||||
EnginePayload,
|
||||
PollVote as WAHAPollVote,
|
||||
@@ -185,6 +181,10 @@ import {
|
||||
import { Activity } from '@waha/core/abc/activity';
|
||||
import { CallData } from '@waha/structures/calls.dto';
|
||||
import { Jid } from '@waha/core/engines/const';
|
||||
import {
|
||||
WAHA_CLIENT_BROWSER_NAME,
|
||||
WAHA_CLIENT_DEVICE_NAME,
|
||||
} from '@waha/core/env';
|
||||
|
||||
export interface WebJSConfig {
|
||||
webVersion?: string;
|
||||
@@ -246,6 +246,10 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
// add at the start
|
||||
args.unshift(`--a-waha-timestamp=${new Date()}`);
|
||||
args.unshift(`--a-waha-session=${this.name}`);
|
||||
const deviceName =
|
||||
this.sessionConfig?.client?.deviceName ?? WAHA_CLIENT_DEVICE_NAME;
|
||||
const browserName =
|
||||
this.sessionConfig?.client?.browserName ?? WAHA_CLIENT_BROWSER_NAME;
|
||||
return {
|
||||
puppeteer: {
|
||||
protocolTimeout: 300_000,
|
||||
@@ -255,7 +259,9 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
dumpio: this.isDebugEnabled(),
|
||||
},
|
||||
userAgent:
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36',
|
||||
deviceName: deviceName,
|
||||
browserName: browserName,
|
||||
webVersion: webVersion,
|
||||
webVersionCache: {
|
||||
type: cacheType,
|
||||
@@ -521,10 +527,29 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
}
|
||||
});
|
||||
|
||||
this.whatsapp.on(Events.AUTHENTICATED, (args) => {
|
||||
this.whatsapp.on(Events.AUTHENTICATED, async (args) => {
|
||||
this.status = WAHASessionStatus.WORKING;
|
||||
this.qr.save('');
|
||||
this.logger.info({ args: args }, `Session has been authenticated!`);
|
||||
|
||||
// Try to get client info from puppeter if nothing set
|
||||
// Fix https://github.com/devlikeapro/waha/issues/1735
|
||||
await sleep(3_000);
|
||||
if (!this.whatsapp.info) {
|
||||
// try to load client info few times with a delay
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
await this.loadClientInfo().catch((error) =>
|
||||
this.logger.error(
|
||||
error,
|
||||
`Failed to load client info, attempt ${attempt + 1}`,
|
||||
),
|
||||
);
|
||||
if (this.whatsapp.info) {
|
||||
break;
|
||||
}
|
||||
await sleep(3_000);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.whatsapp.on(Events.AUTHENTICATION_FAILURE, (args) => {
|
||||
@@ -585,6 +610,21 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
});
|
||||
}
|
||||
|
||||
private async loadClientInfo() {
|
||||
const data = await this.whatsapp.pupPage.evaluate(() => {
|
||||
return {
|
||||
// @ts-ignore
|
||||
...window.Store.Conn.serialize(),
|
||||
wid:
|
||||
// @ts-ignore
|
||||
window.Store.User.getMaybeMePnUser() ||
|
||||
// @ts-ignore
|
||||
window.Store.User.getMaybeMeLidUser(),
|
||||
};
|
||||
});
|
||||
this.whatsapp.info = data as any;
|
||||
}
|
||||
|
||||
/**
|
||||
* START - Methods for API
|
||||
*/
|
||||
|
||||
@@ -22,3 +22,11 @@ if (KNEX_SQLITE_CLIENT != 'sqlite3' && KNEX_SQLITE_CLIENT != 'better-sqlite3') {
|
||||
KNEX_SQLITE_CLIENT = 'sqlite3';
|
||||
}
|
||||
export { KNEX_SQLITE_CLIENT };
|
||||
|
||||
//
|
||||
// Client config
|
||||
//
|
||||
export const WAHA_CLIENT_DEVICE_NAME =
|
||||
process.env.WAHA_CLIENT_DEVICE_NAME || null;
|
||||
export const WAHA_CLIENT_BROWSER_NAME =
|
||||
process.env.WAHA_CLIENT_BROWSER_NAME || null;
|
||||
@@ -20,4 +20,9 @@ export class WAHAEnvironment {
|
||||
example: '/usr/path/to/bin/google-chrome',
|
||||
})
|
||||
browser: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'linux/x86',
|
||||
})
|
||||
platform: string;
|
||||
}
|
||||
@@ -155,6 +155,16 @@ export class IgnoreConfig {
|
||||
broadcast?: boolean;
|
||||
}
|
||||
|
||||
export class ClientSessionConfig {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
deviceName?: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
browserName?: string;
|
||||
}
|
||||
|
||||
export class SessionConfig {
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => WebhookConfig)
|
||||
@@ -204,6 +214,19 @@ export class SessionConfig {
|
||||
@IsOptional()
|
||||
ignore?: IgnoreConfig;
|
||||
|
||||
@ApiProperty({
|
||||
description:
|
||||
"How connected session renders in device - in format 'Browser (Device)' - Firefox (MacOS)",
|
||||
example: {
|
||||
browserName: 'Firefox',
|
||||
deviceName: 'MacOS',
|
||||
},
|
||||
})
|
||||
@ValidateNested()
|
||||
@Type(() => ClientSessionConfig)
|
||||
@IsOptional()
|
||||
client?: ClientSessionConfig;
|
||||
|
||||
@ApiProperty({
|
||||
example: {
|
||||
store: {
|
||||
|
||||
+13
-3
@@ -29,12 +29,22 @@ export function getWAHAVersion(): WAHAVersion {
|
||||
return WAHAVersion.CORE;
|
||||
}
|
||||
|
||||
function getBrowser() {
|
||||
return getEngineName() === WAHAEngine.WEBJS
|
||||
? getBrowserExecutablePath()
|
||||
: null;
|
||||
}
|
||||
|
||||
function getPlatform() {
|
||||
return `${process.platform}/${process.arch}`;
|
||||
}
|
||||
|
||||
export const VERSION: WAHAEnvironment = {
|
||||
version: '2025.12.2',
|
||||
version: '2026.1.1',
|
||||
engine: getEngineName(),
|
||||
tier: getWAHAVersion(),
|
||||
browser:
|
||||
getEngineName() === WAHAEngine.WEBJS ? getBrowserExecutablePath() : null,
|
||||
browser: getBrowser(),
|
||||
platform: getPlatform(),
|
||||
};
|
||||
|
||||
export const IsChrome = VERSION.browser?.includes('chrome');
|
||||
|
||||
+2
-2
@@ -2,11 +2,11 @@
|
||||
"waha": {
|
||||
"gows": {
|
||||
"repo": "devlikeapro/gows",
|
||||
"ref": "v1.0.26"
|
||||
"ref": "v1.0.28"
|
||||
},
|
||||
"dashboard": {
|
||||
"repo": "devlikeapro/dashboard",
|
||||
"ref": "6d62eda142f95b5a6b40614f83d9c12e52957f85"
|
||||
"ref": "6030cf5e08f2a6e6d09a7a70a1c4194baf0beb55"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user