Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f867e0b5d | ||
|
|
d4f6ec18fd | ||
|
|
ac05dd83e9 | ||
|
|
17c22f0cd4 | ||
|
|
971979c13f | ||
|
|
845e203637 | ||
|
|
7a2e1cd731 | ||
|
|
84ba011a4c | ||
|
|
50399f1192 | ||
|
|
a2517b248d | ||
|
|
f02d95331a | ||
|
|
cb1faff88c | ||
|
|
3ff1c06eea | ||
|
|
c91d2c59eb | ||
|
|
4cf5a74d23 |
No files matched your search
@@ -146,6 +146,17 @@ export class WAHASelf {
|
||||
.then((response) => response.data);
|
||||
}
|
||||
|
||||
async getGroupParticipants(
|
||||
session: string,
|
||||
groupId: string,
|
||||
opts?: RequestOptions,
|
||||
) {
|
||||
const url = `/api/${session}/groups/${groupId}/participants/v2`;
|
||||
return await this.client
|
||||
.get(url, { signal: opts?.signal })
|
||||
.then((response) => response.data);
|
||||
}
|
||||
|
||||
async getChannel(
|
||||
session: string,
|
||||
channelId: string,
|
||||
@@ -371,6 +382,10 @@ export class WAHASessionAPI {
|
||||
return this.api.getGroup(this.session, groupId, opts);
|
||||
}
|
||||
|
||||
getGroupParticipants(groupId: string, opts?: RequestOptions): Promise<any> {
|
||||
return this.api.getGroupParticipants(this.session, groupId, opts);
|
||||
}
|
||||
|
||||
getChannel(channelId: string, opts?: RequestOptions): Promise<Channel> {
|
||||
return this.api.getChannel(this.session, channelId, opts);
|
||||
}
|
||||
@@ -459,4 +474,8 @@ export class WAHASessionAPI {
|
||||
findLIDByPN(pn: string, opts?: RequestOptions) {
|
||||
return this.api.findLIDByPN(this.session, pn, opts);
|
||||
}
|
||||
|
||||
getSessionInfo(opts?: RequestOptions) {
|
||||
return this.api.get(this.session, opts);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { InboxData } from '@waha/apps/chatwoot/consumers/types';
|
||||
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
|
||||
import {
|
||||
ChatIDNotFoundForContactError,
|
||||
ChatWootAppNotFoundError,
|
||||
PhoneNumberNotFoundInWhatsAppError,
|
||||
} from '@waha/apps/chatwoot/errors';
|
||||
import { WAHASessionAPI } from '@waha/apps/app_sdk/waha/WAHASelf';
|
||||
@@ -43,7 +44,11 @@ export abstract class ChatWootInboxMessageConsumer extends AppConsumer {
|
||||
const knex = this.manager.store.getWAHADatabase();
|
||||
this.appRepository = new AppRepository(knex);
|
||||
const logger = new JobLoggerWrapper(job, this.logger);
|
||||
const app = await this.appRepository.getById(appId);
|
||||
const app = await this.appRepository.findEnabledAppById(appId);
|
||||
if (!app) {
|
||||
logger.warn(`Chatwoot app not found or disabled: ${appId}`);
|
||||
throw new ChatWootAppNotFoundError(appId);
|
||||
}
|
||||
return new DIContainer(app.pk, app.config, logger, knex);
|
||||
}
|
||||
|
||||
@@ -86,6 +91,10 @@ export abstract class ChatWootInboxMessageConsumer extends AppConsumer {
|
||||
await this.ReportErrorRecovered(job, body);
|
||||
return result;
|
||||
} catch (err) {
|
||||
if (err instanceof ChatWootAppNotFoundError) {
|
||||
this.logger.warn(err.message);
|
||||
throw err;
|
||||
}
|
||||
await this.ReportErrorForMessage(job, err, body);
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
MessageMappingService,
|
||||
} from '@waha/apps/chatwoot/storage';
|
||||
import { MarkdownToWhatsApp } from '@waha/apps/chatwoot/messages/to/whatsapp/markdown';
|
||||
import { parseMentionsFromText } from '@waha/apps/chatwoot/messages/to/whatsapp/mentions';
|
||||
import { SessionManager } from '@waha/core/abc/manager.abc';
|
||||
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
|
||||
import {
|
||||
@@ -36,6 +37,7 @@ import {
|
||||
LinkPreview,
|
||||
} from '@waha/apps/chatwoot/dto/config.dto';
|
||||
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
|
||||
import { isJidGroup } from '@waha/core/utils/jids';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const mime = require('mime-types');
|
||||
@@ -90,7 +92,16 @@ export class MessageHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
const content = MarkdownToWhatsApp(message.content);
|
||||
let content: string = message.content;
|
||||
let mentions: null | string[] = null;
|
||||
if (isJidGroup(chatId)) {
|
||||
// Parse any mention in the text and get a new clean text if required
|
||||
const parsed = parseMentionsFromText(message.content);
|
||||
content = parsed.text;
|
||||
mentions = parsed.mentions;
|
||||
}
|
||||
|
||||
content = MarkdownToWhatsApp(content);
|
||||
const results = [];
|
||||
let part = 0; // Start from 0 and increment before each send/check
|
||||
const replyTo = await this.getReplyTo(message).catch((err) => {
|
||||
@@ -116,7 +127,7 @@ export class MessageHandler {
|
||||
content: content,
|
||||
chatwoot: body,
|
||||
});
|
||||
const msg = await this.sendTextMessage(chatId, text, replyTo);
|
||||
const msg = await this.sendTextMessage(chatId, text, replyTo, mentions);
|
||||
results.push(msg);
|
||||
await this.saveMapping(message, msg, part);
|
||||
this.logger.info(`Text message sent: ${msg.id}`);
|
||||
@@ -139,7 +150,7 @@ export class MessageHandler {
|
||||
chatwoot: body,
|
||||
singleAttachment: attachments.length == 1,
|
||||
});
|
||||
const msg = await this.sendFile(chatId, caption, file, replyTo);
|
||||
const msg = await this.sendFile(chatId, caption, replyTo, mentions, file);
|
||||
this.logger.info(
|
||||
`File message sent: ${msg.id} - ${file.data_url} - ${file.file_type}`,
|
||||
);
|
||||
@@ -196,6 +207,7 @@ export class MessageHandler {
|
||||
chatId: string,
|
||||
content: string,
|
||||
replyTo: string,
|
||||
mentions: string[] | null,
|
||||
) {
|
||||
const request: MessageTextRequest = {
|
||||
session: '',
|
||||
@@ -206,6 +218,7 @@ export class MessageHandler {
|
||||
this.config.linkPreview,
|
||||
),
|
||||
linkPreviewHighQuality: this.config.linkPreview == LinkPreview.HQ,
|
||||
mentions: mentions,
|
||||
};
|
||||
const session = this.session;
|
||||
await session.readMessages(chatId);
|
||||
@@ -219,8 +232,9 @@ export class MessageHandler {
|
||||
private async sendFile(
|
||||
chatId: string,
|
||||
content: string,
|
||||
file: MessageAttachment,
|
||||
replyTo: string,
|
||||
mentions: string[] | null,
|
||||
file: MessageAttachment,
|
||||
) {
|
||||
const url = file.data_url;
|
||||
let filename = url.split('/').pop();
|
||||
@@ -245,6 +259,7 @@ export class MessageHandler {
|
||||
url: url,
|
||||
mimetype: mimetype,
|
||||
},
|
||||
mentions: mentions,
|
||||
};
|
||||
return session.sendImage(imageRequest);
|
||||
case 'video':
|
||||
@@ -262,6 +277,7 @@ export class MessageHandler {
|
||||
filename: filename,
|
||||
},
|
||||
convert: true,
|
||||
mentions: mentions,
|
||||
};
|
||||
return session.sendVideo(videoRequest);
|
||||
case 'audio':
|
||||
@@ -288,6 +304,7 @@ export class MessageHandler {
|
||||
url: url,
|
||||
mimetype: mimetype,
|
||||
},
|
||||
mentions: mentions,
|
||||
};
|
||||
return session.sendFile(fileRequest);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { PinoLogger } from 'nestjs-pino';
|
||||
|
||||
import { AppRepository } from '../../storage';
|
||||
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
|
||||
import { ChatWootAppNotFoundError } from '@waha/apps/chatwoot/errors';
|
||||
|
||||
/**
|
||||
* Base class for ChatWoot scheduled consumers
|
||||
@@ -35,7 +36,11 @@ export abstract class ChatWootScheduledConsumer extends AppConsumer {
|
||||
const knex = this.manager.store.getWAHADatabase();
|
||||
this.appRepository = new AppRepository(knex);
|
||||
const logger = new JobLoggerWrapper(job, this.logger);
|
||||
const app = await this.appRepository.getById(appId);
|
||||
const app = await this.appRepository.findEnabledAppById(appId);
|
||||
if (!app) {
|
||||
logger.warn(`Chatwoot app not found or disabled: ${appId}`);
|
||||
throw new ChatWootAppNotFoundError(appId);
|
||||
}
|
||||
return new DIContainer(app.pk, app.config, logger, knex);
|
||||
}
|
||||
|
||||
@@ -62,6 +67,10 @@ export abstract class ChatWootScheduledConsumer extends AppConsumer {
|
||||
await this.ReportErrorRecovered(job);
|
||||
return result;
|
||||
} catch (err) {
|
||||
if (err instanceof ChatWootAppNotFoundError) {
|
||||
this.logger.warn(err.message);
|
||||
throw err;
|
||||
}
|
||||
await this.ReportErrorForJob(job, err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import { AppRepository } from '../../storage';
|
||||
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
|
||||
import { SignalRace } from '@waha/utils/abortable';
|
||||
import { IsCommandsChat } from '@waha/apps/chatwoot/client/ids';
|
||||
import { ChatWootAppNotFoundError } from '@waha/apps/chatwoot/errors';
|
||||
|
||||
/**
|
||||
* Base class for ChatWoot background task consumers
|
||||
@@ -36,7 +37,11 @@ export abstract class ChatWootTaskConsumer extends AppConsumer {
|
||||
const knex = this.manager.store.getWAHADatabase();
|
||||
this.appRepository = new AppRepository(knex);
|
||||
const logger = new JobLoggerWrapper(job, this.logger);
|
||||
const app = await this.appRepository.getById(appId);
|
||||
const app = await this.appRepository.findEnabledAppById(appId);
|
||||
if (!app) {
|
||||
logger.warn(`Chatwoot app not found or disabled: ${appId}`);
|
||||
throw new ChatWootAppNotFoundError(appId);
|
||||
}
|
||||
return new DIContainer(app.pk, app.config, logger, knex);
|
||||
}
|
||||
|
||||
@@ -68,6 +73,10 @@ export abstract class ChatWootTaskConsumer extends AppConsumer {
|
||||
await this.ReportErrorRecovered(job);
|
||||
return result;
|
||||
} catch (err) {
|
||||
if (err instanceof ChatWootAppNotFoundError) {
|
||||
this.logger.warn(err.message);
|
||||
throw err;
|
||||
}
|
||||
this.ReportErrorForJob(job, err).catch((exc) =>
|
||||
this.logger.error(`Failed to report error for job ${job.id}: ${exc}`),
|
||||
);
|
||||
|
||||
@@ -12,6 +12,7 @@ import { WhatsAppChatIdKey } from '@waha/apps/chatwoot/consumers/mutex';
|
||||
import { EventData } from '@waha/apps/chatwoot/consumers/types';
|
||||
import { WhatsAppContactInfo } from '@waha/apps/chatwoot/contacts/WhatsAppContactInfo';
|
||||
import { DIContainer } from '@waha/apps/chatwoot/di/DIContainer';
|
||||
import { ChatWootAppNotFoundError } from '@waha/apps/chatwoot/errors';
|
||||
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
|
||||
import { WAHASelf, WAHASessionAPI } from '@waha/apps/app_sdk/waha/WAHASelf';
|
||||
import {
|
||||
@@ -83,6 +84,10 @@ export abstract class ChatWootWAHABaseConsumer extends AppConsumer {
|
||||
await this.ReportErrorRecovered(errorReportInfo, job);
|
||||
return result;
|
||||
} catch (err) {
|
||||
if (err instanceof ChatWootAppNotFoundError) {
|
||||
this.logger.warn(err.message);
|
||||
throw err;
|
||||
}
|
||||
await this.ReportErrorForMessage(errorReportInfo, job, err);
|
||||
throw err;
|
||||
}
|
||||
@@ -95,7 +100,11 @@ export abstract class ChatWootWAHABaseConsumer extends AppConsumer {
|
||||
const knex = this.manager.store.getWAHADatabase();
|
||||
this.appRepository = new AppRepository(knex);
|
||||
const logger = new JobLoggerWrapper(job, this.logger);
|
||||
const app = await this.appRepository.getById(appId);
|
||||
const app = await this.appRepository.findEnabledAppById(appId);
|
||||
if (!app) {
|
||||
logger.warn(`Chatwoot app not found or disabled: ${appId}`);
|
||||
throw new ChatWootAppNotFoundError(appId);
|
||||
}
|
||||
return new DIContainer(app.pk, app.config, logger, knex);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,12 @@ export class ChatWootErrorReporter {
|
||||
// There's retries more left - ignore it for now
|
||||
return;
|
||||
}
|
||||
if (!conversation) {
|
||||
this.logger.error(
|
||||
'Chatwoot error report skipped: conversation not ready',
|
||||
);
|
||||
return;
|
||||
}
|
||||
const attempts = {
|
||||
current: this.job.attemptsMade + 1,
|
||||
max: this.job.opts?.attempts || 1,
|
||||
@@ -87,6 +93,12 @@ export class ChatWootErrorReporter {
|
||||
// https://github.com/devlikeapro/waha/issues/1395
|
||||
return null;
|
||||
|
||||
if (!conversation) {
|
||||
this.logger.warn(
|
||||
'Chatwoot success report skipped: conversation not ready',
|
||||
);
|
||||
return;
|
||||
}
|
||||
const template = this.l.key(TKey.JOB_REPORT_SUCCEEDED);
|
||||
const attempts = {
|
||||
current: this.job.attemptsMade + 1,
|
||||
|
||||
@@ -15,3 +15,9 @@ export class UnknownJIDFormat extends Error {
|
||||
super(`WhatsApp Chat ID is not recognized: ${jid}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class ChatWootAppNotFoundError extends Error {
|
||||
constructor(public appId: string) {
|
||||
super(`Chatwoot app not found or disabled: ${appId}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import { parseMentionsFromText } from './mentions';
|
||||
|
||||
describe('parseMentionsFromText', () => {
|
||||
it('returns null mentions when none exist', () => {
|
||||
const input = 'Hello there';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Hello there',
|
||||
mentions: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('parses @all and removes it from the text', () => {
|
||||
const input = 'Hello @all';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Hello',
|
||||
mentions: ['all'],
|
||||
});
|
||||
});
|
||||
|
||||
it('parses @ALL case-insensitively', () => {
|
||||
const input = 'Hello @ALL';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Hello',
|
||||
mentions: ['all'],
|
||||
});
|
||||
});
|
||||
|
||||
it('uses a fallback text when only @all is present', () => {
|
||||
const input = '@all';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: ' ',
|
||||
mentions: ['all'],
|
||||
});
|
||||
});
|
||||
|
||||
it('parses phone number mentions with a suffix', () => {
|
||||
const input = 'Ping @558591203123';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Ping @558591203123',
|
||||
mentions: ['558591203123@c.us'],
|
||||
});
|
||||
});
|
||||
|
||||
it('deduplicates phone number mentions', () => {
|
||||
const input = 'Hi @1111111 and @1111111';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Hi @1111111 and @1111111',
|
||||
mentions: ['1111111@c.us'],
|
||||
});
|
||||
});
|
||||
|
||||
it('handles @all alongside phone mentions', () => {
|
||||
const input = '@all Hi @558591203123';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Hi @558591203123',
|
||||
mentions: ['all', '558591203123@c.us'],
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores quoted @all text', () => {
|
||||
const input = "You can send '@all' to chat";
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: "You can send '@all' to chat",
|
||||
mentions: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores email-like mentions', () => {
|
||||
const input = 'Reach us at email@12341domain.com';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Reach us at email@12341domain.com',
|
||||
mentions: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores @all when followed by letters', () => {
|
||||
const input = 'Please ping @allx';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Please ping @allx',
|
||||
mentions: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores phone mentions followed by letters', () => {
|
||||
const input = 'Call @1234567abc';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Call @1234567abc',
|
||||
mentions: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores @all inside email-like text', () => {
|
||||
const input = 'Contact email@alldomain.com for details';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Contact email@alldomain.com for details',
|
||||
mentions: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts phone mentions with trailing punctuation', () => {
|
||||
const input = 'Ping @1231234, then @5555555.';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Ping @1231234, then @5555555.',
|
||||
mentions: ['1231234@c.us', '5555555@c.us'],
|
||||
});
|
||||
});
|
||||
|
||||
it('parses @lid mentions without c.us suffix', () => {
|
||||
const input = 'Notify @123123@lid now';
|
||||
expect(parseMentionsFromText(input)).toEqual({
|
||||
text: 'Notify @123123@lid now',
|
||||
mentions: ['123123@lid'],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,79 @@
|
||||
import { ensureSuffix } from '@waha/core/abc/session.abc';
|
||||
import { isJidGroup } from '@waha/core/utils/jids';
|
||||
|
||||
export interface ParsedMentions {
|
||||
text: string;
|
||||
mentions?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse mentions from text message
|
||||
* Supports:
|
||||
* - @all - mentions all group participants
|
||||
* - @558591203123 - mentions specific phone number
|
||||
*
|
||||
* @param text - The message text
|
||||
* @returns Parsed mentions with cleaned text
|
||||
*/
|
||||
export function parseMentionsFromText(text: string): ParsedMentions {
|
||||
const mentions: string[] = [];
|
||||
let content = text;
|
||||
|
||||
// Regex to match @all (case-insensitive, word boundary)
|
||||
// Use separate regex instances to avoid lastIndex issues with global flag
|
||||
const allRegexTest = /(^|\s)@all\b/gi;
|
||||
if (allRegexTest.test(text)) {
|
||||
mentions.push('all');
|
||||
// Remove @all from text - WAHA endpoint doesn't display it, only mentions all participants
|
||||
// Create a new regex instance for replace to avoid lastIndex issues
|
||||
const allRegexReplace = /(^|\s)@all\b/gi;
|
||||
content = content.replace(allRegexReplace, '$1').trim();
|
||||
}
|
||||
|
||||
const lidRegex = /(^|\s)@(\d{6,15})@lid\b/g;
|
||||
const lidMatches = text.matchAll(lidRegex);
|
||||
|
||||
for (const match of lidMatches) {
|
||||
const lidNumber = match[2];
|
||||
const formattedLid = `${lidNumber}@lid`;
|
||||
if (!mentions.includes(formattedLid)) {
|
||||
mentions.push(formattedLid);
|
||||
}
|
||||
}
|
||||
|
||||
// Regex to match @ followed by phone number
|
||||
// Matches: @558591203123, @5585991203123, etc.
|
||||
// Phone numbers: 7-15 digits (international format)
|
||||
const phoneRegex = /(^|\s)@(\d{7,15})(?!@lid)\b/g;
|
||||
const phoneMatches = text.matchAll(phoneRegex);
|
||||
|
||||
for (const match of phoneMatches) {
|
||||
const phoneNumber = match[2];
|
||||
// Format phone number to @c.us format
|
||||
const formattedJid = ensureSuffix(phoneNumber);
|
||||
if (!mentions.includes(formattedJid)) {
|
||||
mentions.push(formattedJid);
|
||||
}
|
||||
}
|
||||
|
||||
if (mentions.length == 0) {
|
||||
// Nothing found
|
||||
return {
|
||||
text: text,
|
||||
mentions: null,
|
||||
};
|
||||
}
|
||||
|
||||
// Ensure text is not empty when there are mentions
|
||||
// If text becomes empty after removing mentions, use a default message
|
||||
content = content.trim();
|
||||
if (content === '') {
|
||||
// When only mentions are present, use a minimal text to satisfy DTO requirements
|
||||
// The mentions array will handle the actual mentions
|
||||
content = ' ';
|
||||
}
|
||||
return {
|
||||
text: content,
|
||||
mentions: mentions,
|
||||
};
|
||||
}
|
||||
@@ -50,7 +50,6 @@ import * as lodash from 'lodash';
|
||||
import * as NodeCache from 'node-cache';
|
||||
import { Logger } from 'pino';
|
||||
import {
|
||||
BehaviorSubject,
|
||||
catchError,
|
||||
delay,
|
||||
filter,
|
||||
@@ -228,7 +227,8 @@ export abstract class WhatsappSession {
|
||||
engineConfig,
|
||||
ignore,
|
||||
}: SessionParams) {
|
||||
this.status$ = new BehaviorSubject(WAHASessionStatus.STOPPED);
|
||||
this._status = WAHASessionStatus.STOPPED;
|
||||
this.status$ = new Subject<WAHASessionStatus>();
|
||||
|
||||
this.name = name;
|
||||
this.proxyConfig = proxyConfig;
|
||||
|
||||
@@ -23,7 +23,8 @@ export namespace messages {
|
||||
IMAGE = 0,
|
||||
AUDIO = 1,
|
||||
VIDEO = 2,
|
||||
DOCUMENT = 3
|
||||
DOCUMENT = 3,
|
||||
PTV = 4
|
||||
}
|
||||
export enum Presence {
|
||||
AVAILABLE = 0,
|
||||
|
||||
@@ -21564,7 +21564,8 @@ proto.messages.MediaType = {
|
||||
IMAGE: 0,
|
||||
AUDIO: 1,
|
||||
VIDEO: 2,
|
||||
DOCUMENT: 3
|
||||
DOCUMENT: 3,
|
||||
PTV: 4
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -288,14 +288,12 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
|
||||
grpc.credentials.createInsecure(),
|
||||
);
|
||||
|
||||
try {
|
||||
await promisify(this.client.StartSession)(request);
|
||||
} catch (err) {
|
||||
promisify(this.client.StartSession)(request).catch((err) => {
|
||||
this.logger.error('Failed to start the client');
|
||||
this.logger.error(err, err.stack);
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected getProxyUrl(config: ProxyConfig): string {
|
||||
@@ -766,15 +764,14 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
|
||||
|
||||
async stop(): Promise<void> {
|
||||
this.cleanupPresenceTimeout();
|
||||
if (this.client) {
|
||||
const response = await promisify(this.client.StopSession)(this.session);
|
||||
response.toObject();
|
||||
}
|
||||
this.status = WAHASessionStatus.STOPPED;
|
||||
this.events?.stop();
|
||||
this.stopEvents();
|
||||
this.client?.close();
|
||||
this.mediaManager.close();
|
||||
if (this.client) {
|
||||
await promisify(this.client.StopSession)(this.session);
|
||||
this.client?.close();
|
||||
}
|
||||
}
|
||||
|
||||
public async requestCode(phoneNumber: string, method: string, params?: any) {
|
||||
|
||||
@@ -2910,6 +2910,12 @@ export function extractBody(message): string | null {
|
||||
// @ts-ignore - AudioMessage doesn't have caption field
|
||||
body = mediaContent?.caption;
|
||||
}
|
||||
if (!body && content.protocolMessage?.editedMessage) {
|
||||
body = extractBody(content.protocolMessage.editedMessage);
|
||||
}
|
||||
if (!body && content.associatedChildMessage?.message) {
|
||||
body = extractBody(content.associatedChildMessage.message);
|
||||
}
|
||||
// Response for buttons
|
||||
if (!body) {
|
||||
body = content.templateButtonReplyMessage?.selectedDisplayText;
|
||||
|
||||
@@ -10,6 +10,7 @@ export function extractMediaContent(
|
||||
content?.imageMessage ||
|
||||
content?.videoMessage ||
|
||||
content?.audioMessage ||
|
||||
content?.ptvMessage ||
|
||||
content?.stickerMessage;
|
||||
if (mediaContent) {
|
||||
return mediaContent;
|
||||
|
||||
@@ -16,9 +16,4 @@ export function validateRequestMentions(request: {
|
||||
`"mentions":["all"] can be used only in group chats, not in '${request.chatId}'`,
|
||||
);
|
||||
}
|
||||
if (request.mentions.length > 1) {
|
||||
throw new UnprocessableEntityException(
|
||||
`"mentions":["all"] cannot be used with other mentions`,
|
||||
);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -40,7 +40,7 @@ function getPlatform() {
|
||||
}
|
||||
|
||||
export const VERSION: WAHAEnvironment = {
|
||||
version: '2026.1.1',
|
||||
version: '2026.1.2',
|
||||
engine: getEngineName(),
|
||||
tier: getWAHAVersion(),
|
||||
browser: getBrowser(),
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"waha": {
|
||||
"gows": {
|
||||
"repo": "devlikeapro/gows",
|
||||
"ref": "v1.0.28"
|
||||
"ref": "v1.0.29"
|
||||
},
|
||||
"dashboard": {
|
||||
"repo": "devlikeapro/dashboard",
|
||||
|
||||
@@ -7,7 +7,7 @@ __metadata:
|
||||
|
||||
"@adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-12-17":
|
||||
version: 7.0.0-rc.9
|
||||
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=425b11f5b2d98c808210fab78afc6257f27f2fe5"
|
||||
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=3d54943ebd83c56f1b5739c4d28da3f9af01020a"
|
||||
dependencies:
|
||||
"@cacheable/node-cache": "npm:^1.4.0"
|
||||
"@hapi/boom": "npm:^9.1.3"
|
||||
@@ -31,7 +31,7 @@ __metadata:
|
||||
optional: true
|
||||
link-preview-js:
|
||||
optional: true
|
||||
checksum: 10/2b58dffc216fe6518e3f72532de60765e7d8c371cdc17221b79c98d74752a5b6c08f5ea2af4543b12bd6c55f1434d1b6b697e4b31f33fea50069b7b4b774feb1
|
||||
checksum: 10/6ec9803fea06e359f1e883c1e050b511350ec272cfb9e3fc3a14c1346ccc8bc18c4bfb3d22f90877d5aaf4f973b02cb8fda9f5a7ab801138d17e766c36b05dfc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -12756,7 +12756,7 @@ __metadata:
|
||||
|
||||
"whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-12-17":
|
||||
version: 1.34.3
|
||||
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=8349fcd26fd2bbede0e6739b0da9b9ce97fe6c14"
|
||||
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=8823818e1db005aeca3cb75cf48622493c5e4cd2"
|
||||
dependencies:
|
||||
"@pedroslopez/moduleraid": "npm:^5.0.2"
|
||||
archiver: "npm:^5.3.1"
|
||||
@@ -12774,7 +12774,7 @@ __metadata:
|
||||
optional: true
|
||||
unzipper:
|
||||
optional: true
|
||||
checksum: 10/b53255dfd1c0336232f4f4683e67779bea2f002242084961ecec59844595414a80f7172859eb4a8983e9dd6c276de6a97bfdec5135c7d4ec6ee5ed638a6e8346
|
||||
checksum: 10/3bcbb476ccf1fc330beccb67b26720b212a37d74d166291c346430feef955a85ffb5948f3802a7f14f9f620fbd7edcd292b049b54e77c80ce9c5f7f2c2474878
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in new issue
Block a user