Compare commits

...
19 Commits
Author SHA1 Message Date
devlikepro 76ae3e0f6b [core] 2025.9.5
Release / WEBJS - chrome - amd64 - chrome (push) Canceled after 0s
Release / WEBJS - chromium - amd64 - latest (push) Canceled after 0s
Release / WEBJS - chromium - linux/arm64 - arm (push) Canceled after 0s
Release / NOWEB - none - linux/arm64 - noweb-arm (push) Canceled after 0s
Release / GOWS - none - amd64 - gows (push) Canceled after 0s
Release / GOWS - none - linux/arm64 - gows-arm (push) Canceled after 0s
Release / NOWEB - none - amd64 - noweb (push) Canceled after 0s
2025-09-23 15:51:01 +07:00
devlikepro f37b6edaa6 [core] Up Dashboard 2025-09-23 15:51:00 +07:00
devlikepro 7095f77f93 [core] GOWS - v1.0.15 2025-09-23 15:51:00 +07:00
devlikepro 5853b778f2 [core] GOWS - fix "typing" after message
fix #1364
2025-09-23 15:51:00 +07:00
devlikepro 6405725ce6 [core] WEBJS - send vcard
fix #1341
2025-09-23 15:50:59 +07:00
devlikepro 111d6141aa [core] WEBJS - fix login via code on new version 2025-09-23 15:50:58 +07:00
devlikepro 5560b3c8e6 [core] NOWEB - login via phone
fix #1385
2025-09-23 15:50:58 +07:00
devlikepro d528d541ea [core] NOWEB - fix fromMe in group messages
fix #1350
2025-09-23 15:50:57 +07:00
devlikepro ab6b51cc1f [core] NOWEB - normalized lid 2025-09-23 15:50:57 +07:00
devlikepro 35aa4f2658 [core] WEBJS - fix status messages 2025-09-23 15:50:56 +07:00
devlikepro 36db3c37e8 [core] WEBJS - fix channel role 2025-09-23 15:50:55 +07:00
devlikepro b0c9232153 [core] Update WEBJS 2025-09-23 15:50:55 +07:00
devlikepro 0070fb9e5c [core] Update NOWEB, use ESM wrapper 2025-09-23 15:50:53 +07:00
devlikepro aa33ac4b1d [core] NOWEB - handle lid-mapping.update 2025-09-23 15:50:52 +07:00
devlikepro 1c2bc5b395 [core] NOWEB - no clean storage on history sync 2025-09-23 15:50:51 +07:00
devlikepro f2fe18a4c5 [core] NOWEB Handle lottie stickers using .zip 2025-09-23 15:50:51 +07:00
devlikepro 87fdcbebf6 [core] NOWEB Use directPath for newsletters 2025-09-23 15:50:51 +07:00
devlikepro 68a4f651ea [core] pin postgres:17.6
fix #1380
2025-09-23 15:50:50 +07:00
devlikepro 243caa9626 [core] ChatWoot - group participant at the bottom
fix #1369
2025-09-23 15:50:50 +07:00
70 changed files with 552 additions and 316 deletions

No files matched your search

+2 -2
View File
@@ -35,13 +35,13 @@ for-swagger:
WHATSAPP_SWAGGER_CONFIG_ADVANCED=true . ${NVM_DIR}/nvm.sh && nvm exec yarn start
up-noweb:
. ${NVM_DIR}/nvm.sh && nvm exec yarn up @adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-07-04
. ${NVM_DIR}/nvm.sh && nvm exec yarn up @adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-09-21
up-noweb-libsignal:
. ${NVM_DIR}/nvm.sh && nvm exec yarn up libsignal@github:devlikeapro/libsignal-node#fork-master
up-webjs:
. ${NVM_DIR}/nvm.sh && nvm exec yarn up whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09
. ${NVM_DIR}/nvm.sh && nvm exec yarn up whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-09-10
start-proxy:
docker run --rm -d --name squid-container -e TZ=UTC -p 3128:3128 ubuntu/squid:5.2-22.04_beta
+1 -1
View File
@@ -36,7 +36,7 @@ services:
# NOTE: Only if you're using PostgreSQL to save sessions
# https://waha.devlike.pro/docs/how-to/storages/#media---postgresql
# postgres:
# image: postgres:17
# image: postgres:17.6
# restart: always
# environment:
# POSTGRES_USER: postgres
+2 -2
View File
@@ -26,7 +26,7 @@
"gows:proto": "yarn gows:proto:fetch && yarn gows:proto:build"
},
"dependencies": {
"@adiwajshing/baileys": "github:devlikeapro/Baileys#fork-master-2025-07-04",
"@adiwajshing/baileys": "github:devlikeapro/Baileys#fork-master-2025-09-21",
"@adiwajshing/keyed-db": "^0.2.4",
"@aws-sdk/client-s3": "^3.633.0",
"@aws-sdk/s3-request-presigner": "^3.633.0",
@@ -101,7 +101,7 @@
"sqlite3": "^5.1.7",
"swagger-ui-express": "^4.1.4",
"ulid": "^2.3.0",
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09",
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-main-2025-09-10",
"write-file-atomic": "^6.0.0",
"yaml": "^2.7.1"
},
-1
View File
@@ -1,4 +1,3 @@
import { isJidGroup } from '@adiwajshing/baileys';
import {
Body,
Controller,
+1 -1
View File
@@ -1,4 +1,3 @@
import { isLidUser } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import {
Controller,
Get,
@@ -22,6 +21,7 @@ import {
import { PaginationParams, SortOrder } from '@waha/structures/pagination.dto';
import { SessionManager } from '../core/abc/manager.abc';
import { isLidUser } from '@waha/core/utils/jids';
@ApiSecurity('api_key')
@Controller('api/:session/lids')
+1 -1
View File
@@ -1,7 +1,7 @@
import { isLidUser } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import { AttributeKey } from '@waha/apps/chatwoot/const';
import { WhatsAppMessage } from '@waha/apps/chatwoot/storage';
import { buildMessageId } from '@waha/core/engines/noweb/session.noweb.core';
import { isLidUser } from '@waha/core/utils/jids';
export function GetJID(contact: any): string | null {
return contact?.custom_attributes?.[AttributeKey.WA_JID];
+1 -3
View File
@@ -1,4 +1,3 @@
import { isJidGroup, isJidStatusBroadcast } from '@adiwajshing/baileys';
import { conversation_message_create } from '@figuro/chatwoot-sdk';
import type { generic_id } from '@figuro/chatwoot-sdk/dist/models/generic_id';
import type { message } from '@figuro/chatwoot-sdk/dist/models/message';
@@ -22,7 +21,6 @@ import {
WhatsAppMessage,
} from '@waha/apps/chatwoot/storage';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { toCusFormat } from '@waha/core/engines/noweb/session.noweb.core';
import { parseMessageIdSerialized } from '@waha/core/utils/ids';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { WAHAEvents } from '@waha/structures/enums.dto';
@@ -36,7 +34,7 @@ import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import { isJidBroadcast } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import { isJidBroadcast, isJidGroup, toCusFormat } from '@waha/core/utils/jids';
export function ListenEventsForChatWoot() {
return [
@@ -1,3 +1,4 @@
import type { proto } from '@adiwajshing/baileys';
import { Processor } from '@nestjs/bullmq';
import { JOB_CONCURRENCY } from '@waha/apps/app_sdk/constants';
import { SendAttachment } from '@waha/apps/chatwoot/client/types';
@@ -21,7 +22,6 @@ import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import { JobLink } from '@waha/apps/app_sdk/JobUtils';
import { proto } from '@adiwajshing/baileys';
import * as lodash from 'lodash';
import { parseVCardV3, SimpleVCardInfo } from '@waha/core/vcard';
@@ -16,13 +16,13 @@ import {
MessageMappingService,
} from '@waha/apps/chatwoot/storage';
import { SessionManager } from '@waha/core/abc/manager.abc';
import { toCusFormat } from '@waha/core/engines/noweb/session.noweb.core';
import { RMutexService } from '@waha/modules/rmutex/rmutex.service';
import { WAHAEvents } from '@waha/structures/enums.dto';
import { WAHAWebhookMessageRevoked } from '@waha/structures/webhooks.dto';
import { Job } from 'bullmq';
import { PinoLogger } from 'nestjs-pino';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import { toCusFormat } from '@waha/core/utils/jids';
@Processor(QueueName.WAHA_MESSAGE_REVOKED, { concurrency: JOB_CONCURRENCY })
export class WAHAMessageRevokedConsumer extends ChatWootWAHABaseConsumer {
@@ -1,16 +1,4 @@
import {
isJidGroup,
isJidNewsletter,
isJidStatusBroadcast,
} from '@adiwajshing/baileys';
import {
isJidBroadcast,
isLidUser,
} from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import {
public_contact_create_update_payload,
public_contact_create_update_payload as Contact,
} from '@figuro/chatwoot-sdk';
import { public_contact_create_update_payload as Contact } from '@figuro/chatwoot-sdk';
import { ContactInfo } from '@waha/apps/chatwoot/client/ContactConversationService';
import { AttributeKey } from '@waha/apps/chatwoot/const';
import { Locale } from '@waha/apps/chatwoot/i18n/locale';
@@ -18,6 +6,13 @@ import { WAHASessionAPI } from '@waha/apps/chatwoot/session/WAHASelf';
import { Channel } from '@waha/structures/channels.dto';
import { CacheAsync } from '@waha/utils/Cache';
import { TKey } from '@waha/apps/chatwoot/i18n/templates';
import {
isJidBroadcast,
isJidGroup,
isJidNewsletter,
isJidStatusBroadcast,
isLidUser,
} from '@waha/core/utils/jids';
/**
* Base WhatsApp contact info class
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *تم تعديلها في واتساب*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*تفاعل* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *হোয়াটসঅ্যাপে সম্পাদিত*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*প্রতিক্রিয়া দিয়েছেন* {{{emoji}}}
+2 -2
View File
@@ -52,10 +52,10 @@ message.edited.in.whatsapp: |-
✏️ *In WhatsApp bearbeitet*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Reagiert mit* {{{emoji}}}
+2 -2
View File
@@ -50,10 +50,10 @@ message.edited.in.whatsapp: |-
✏️ *Edited in WhatsApp*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Reacted* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *Editado en WhatsApp*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Reaccionó con* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *ویرایش شده در واتساپ*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*واکنش* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *Modifié dans WhatsApp*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*A réagi avec* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *נערך בוואטסאפ*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*הגיב* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *व्हाट्सएप में संपादित*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*प्रतिक्रिया दी* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *Diedit di WhatsApp*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Bereaksi* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *ਵਟਸਐਪ ਵਿੱਚ ਸੰਪਾਦਿਤ ਕੀਤਾ ਗਿਆ*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*ਪ੍ਰਤੀਕਿਰਿਆ ਕੀਤੀ* {{{emoji}}}
+2 -2
View File
@@ -52,10 +52,10 @@ message.edited.in.whatsapp: |-
✏️ *Editado no WhatsApp*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Reagiu com* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *Отредактировано в WhatsApp*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Реакция* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *WhatsApp'ta düzenlendi*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Tepki verdi* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *Відредаговано у WhatsApp*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*Реакція* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *واٹس ایپ میں ترمیم کی گئی*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*ردعمل دیا* {{{emoji}}}
+2 -2
View File
@@ -49,10 +49,10 @@ message.edited.in.whatsapp: |-
✏️ *已在 WhatsApp 中编辑*
whatsapp.group.message: |-
{{{text}}}
👥 *{{{participant}}}*
{{{text}}}
whatsapp.reaction.added: |-
*已反应* {{{emoji}}}
+1 -1
View File
@@ -1,6 +1,6 @@
import type { proto } from '@adiwajshing/baileys';
import { ChatWootCommandsConfig } from '@waha/apps/chatwoot/dto/config.dto';
import { WAMessage } from '@waha/structures/responses.dto';
import { proto } from '@adiwajshing/baileys';
import { SimpleVCardInfo } from '@waha/core/vcard';
export enum TKey {
+1 -1
View File
@@ -1,8 +1,8 @@
import { WhatsAppMessage } from '@waha/apps/chatwoot/storage';
import { toCusFormat } from '@waha/core/engines/noweb/session.noweb.core';
import { WAHAEngine } from '@waha/structures/enums.dto';
import { getEngineName } from '@waha/version';
import { Message as MessageInstance } from 'whatsapp-web.js/src/structures';
import { toCusFormat } from '@waha/core/utils/jids';
interface IEngineHelper {
WhatsAppMessageKeys(message: any): WhatsAppMessage;
+1 -1
View File
@@ -1,4 +1,3 @@
import { isJidBroadcast } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import {
CoreMediaConverter,
IMediaConverter,
@@ -7,6 +6,7 @@ import { MessagesForRead } from '@waha/core/utils/convertors';
import {
IgnoreJidConfig,
isJidNewsletter,
isJidBroadcast,
JidFilter,
} from '@waha/core/utils/jids';
import {
+1 -1
View File
@@ -1,7 +1,7 @@
import { toCusFormat } from '@waha/core/engines/noweb/session.noweb.core';
import { Label, LabelChatAssociation } from '@waha/structures/labels.dto';
import * as gows from './types';
import { toCusFormat } from '@waha/core/utils/jids';
/**
* Converts a GOWS LabelEdit event to a Label DTO
+71 -28
View File
@@ -1,14 +1,4 @@
import {
aggregateMessageKeysNotFromMe,
getContentType,
getUrlFromDirectPath,
isJidGroup,
jidNormalizedUser,
normalizeMessageContent,
proto,
WAMessageKey,
} from '@adiwajshing/baileys';
import { isJidBroadcast } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import type { proto, WAMessageKey } from '@adiwajshing/baileys';
import * as grpc from '@grpc/grpc-js';
import { connectivityState } from '@grpc/grpc-js';
import { UnprocessableEntityException } from '@nestjs/common';
@@ -37,7 +27,6 @@ import { GowsAuthFactoryCore } from '@waha/core/engines/gows/store/GowsAuthFacto
import {
extractBody,
getDestination,
toCusFormat,
} from '@waha/core/engines/noweb/session.noweb.core';
import { extractMediaContent } from '@waha/core/engines/noweb/utils';
import {
@@ -48,7 +37,12 @@ import { IMediaEngineProcessor } from '@waha/core/media/IMediaEngineProcessor';
import { QR } from '@waha/core/QR';
import { ExtractMessageKeysForRead } from '@waha/core/utils/convertors';
import { parseMessageIdSerialized } from '@waha/core/utils/ids';
import { toJID } from '@waha/core/utils/jids';
import {
isJidBroadcast,
isJidGroup,
toCusFormat,
toJID,
} from '@waha/core/utils/jids';
import {
Channel,
ChannelListResult,
@@ -148,6 +142,7 @@ import {
retry,
share,
} from 'rxjs';
import { Subject } from 'rxjs';
import { map } from 'rxjs/operators';
import { promisify } from 'util';
@@ -170,7 +165,7 @@ import {
isLabelChatAddedEvent,
isLabelUpsertEvent,
} from './labels.gows';
import IMessageKey = proto.IMessageKey;
import esm from '@waha/vendor/esm';
enum WhatsMeowEvent {
CONNECTED = 'gows.ConnectedEventData',
@@ -218,6 +213,8 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
public session: messages.Session;
protected presences: any;
private local$ = new Subject<EnginePayload>();
public constructor(config) {
super(config);
this.qr = new QR();
@@ -304,7 +301,11 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
);
// Retry on error with delay
this.all$ = this.stream$.pipe(retry({ delay: 2_000 }), share());
// Accept locally re-issued events as well
this.all$ = merge(this.stream$, this.local$).pipe(
retry({ delay: 2_000 }),
share(),
);
}
subscribeEvents() {
@@ -314,9 +315,9 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
events.on(WhatsMeowEvent.CONNECTED, (data) => {
this.status = WAHASessionStatus.WORKING;
this.me = {
id: toCusFormat(jidNormalizedUser(data.ID)),
id: toCusFormat(esm.b.jidNormalizedUser(data.ID)),
pushName: data.PushName,
lid: jidNormalizedUser(data.LID),
lid: esm.b.jidNormalizedUser(data.LID),
};
// @ts-ignore
this.me.jid = data.ID;
@@ -390,6 +391,48 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
// add new value
this.presences.set(Chat, [...filtered, event]);
});
//
// Fix for "typing" after sending a message
// Re-issue a synthetic ChatPresence(PAUSED) to cancel COMPOSING state
// Works for both DM and Group chats
//
events.on(WhatsMeowEvent.MESSAGE, (message: any) => {
const chat = message?.Info?.Chat;
if (!this.jids.include(chat)) {
return;
}
if (message?.Info?.IsFromMe) {
return;
}
const sender = message?.Info?.Sender || chat;
if (!chat || !sender) {
return;
}
const stored: Array<gows.Presence | gows.ChatPresence> =
this.presences.get(chat) || [];
const composing = stored.find(
(presence: any) =>
(presence?.Sender === sender || presence?.From === sender) &&
presence?.State === gows.ChatPresenceState.COMPOSING,
) as gows.ChatPresence | undefined;
if (!composing) {
return;
}
const presence: gows.ChatPresence = {
Chat: chat,
Sender: sender,
IsFromMe: false,
IsGroup: !!isJidGroup(chat),
State: gows.ChatPresenceState.PAUSED,
Media: (composing as any)?.Media ?? gows.ChatPresenceMedia.TEXT,
} as any;
this.local$.next({
event: WhatsMeowEvent.CHAT_PRESENCE,
data: presence,
} as any);
});
events.start();
}
@@ -961,7 +1004,7 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
if (keys.length === 0) {
return;
}
const receipts = aggregateMessageKeysNotFromMe(keys);
const receipts = esm.b.aggregateMessageKeysNotFromMe(keys);
for (const receipt of receipts) {
if (receipt.messageIds.length === 0) {
return;
@@ -1403,11 +1446,11 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
(newsletter.role?.toUpperCase() as ChannelRole) || ChannelRole.GUEST;
let picture = newsletter.picture;
if (picture.startsWith('/')) {
picture = getUrlFromDirectPath(picture);
picture = esm.b.getUrlFromDirectPath(picture);
}
let preview = newsletter.preview;
if (preview.startsWith('/')) {
preview = getUrlFromDirectPath(preview);
preview = esm.b.getUrlFromDirectPath(preview);
}
return {
id: newsletter.id,
@@ -1913,8 +1956,8 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
// Ignore protocol messages
if (message.Message.protocolMessage) return;
const normalizedContent = normalizeMessageContent(message.Message);
const contentType = getContentType(normalizedContent);
const normalizedContent = esm.b.normalizeMessageContent(message.Message);
const contentType = esm.b.getContentType(normalizedContent);
// Ignore device sent message
if (contentType == 'deviceSentMessage') {
return;
@@ -2001,13 +2044,13 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
private toPollVotePayload(event: any): PollVotePayload {
// Extract event creation message key from the message
const creationKey = event.Message?.pollUpdateMessage.pollCreationMessageKey;
const pollKey: IMessageKey = {
const pollKey: proto.IMessageKey = {
remoteJid: creationKey.remoteJID,
fromMe: creationKey.fromMe,
id: creationKey.ID,
participant: creationKey.participant,
};
const voteKey: IMessageKey = {
const voteKey: proto.IMessageKey = {
id: event.Info.ID,
remoteJid: event.Info.Chat,
participant: event.IsGroup ? event.Info.Sender : null,
@@ -2074,7 +2117,7 @@ export class WhatsappSessionGoWSCore extends WhatsappSession {
}
protected extractReplyTo(message): ReplyToMessage | null {
const msgType = getContentType(message);
const msgType = esm.b.getContentType(message);
const contextInfo = message[msgType]?.contextInfo;
if (!contextInfo) {
return null;
@@ -2334,10 +2377,10 @@ export function getMessageIdFromSerialized(serialized: string): string | null {
*/
function fixPollCreationKey(
vote: IMessageKey,
poll: IMessageKey,
vote: proto.IMessageKey,
poll: proto.IMessageKey,
me: MeInfo,
): IMessageKey {
): proto.IMessageKey {
// If the vote is from me, the pollCreationKey is already in my perspective
if (vote?.fromMe) {
return poll;
+5 -4
View File
@@ -1,11 +1,10 @@
import { GroupMetadata, jidNormalizedUser } from '@adiwajshing/baileys';
import type { GroupMetadata } from '@adiwajshing/baileys';
import type { Contact } from '@adiwajshing/baileys/lib/Types/Contact';
import {
import type {
GroupParticipant as NOWEBGroupParticipant,
ParticipantAction,
} from '@adiwajshing/baileys/lib/Types/GroupMetadata';
import { getGroupInviteLink } from '@waha/core/abc/session.abc';
import { toCusFormat } from '@waha/core/engines/noweb/session.noweb.core';
import {
GroupInfo,
GroupParticipant,
@@ -18,6 +17,8 @@ import {
GroupV2ParticipantsEvent,
GroupV2UpdateEvent,
} from '@waha/structures/groups.events.dto';
import { toCusFormat } from '@waha/core/utils/jids';
import esm from '@waha/vendor/esm';
export function ToGroupInfo(group: Partial<GroupMetadata>): GroupInfo {
let participants: GroupParticipant[] = undefined;
@@ -128,7 +129,7 @@ export function ToGroupV2LeaveEvent(
if (!me) {
return null;
}
const meId = jidNormalizedUser(me.id);
const meId = esm.b.jidNormalizedUser(me.id);
if (!update.participants.includes(meId)) {
return null;
}
@@ -0,0 +1,4 @@
export enum LabelAssociationType {
Chat = 'label_jid',
Message = 'label_message',
}
+3 -3
View File
@@ -1,5 +1,5 @@
import { generateWAMessageFromContent, proto } from '@adiwajshing/baileys';
import { Button, ButtonType } from '@waha/structures/chatting.buttons.dto';
import esm from '@waha/vendor/esm';
function toName(type: ButtonType) {
switch (type) {
@@ -96,8 +96,8 @@ export async function sendButtonMessage(
};
}
const msg = proto.Message.fromObject(data);
const fullMessage = generateWAMessageFromContent(chatId, msg, {
const msg = esm.b.proto.Message.create(data);
const fullMessage = esm.b.generateWAMessageFromContent(chatId, msg, {
userJid: sock?.user?.id,
});
await sock.relayMessage(chatId, fullMessage.message, {
+23 -16
View File
@@ -11,7 +11,7 @@ import makeWASocket, {
getContentType,
getKeyAuthor,
isJidGroup,
isJidUser,
isPnUser,
isRealMessage,
jidNormalizedUser,
makeCacheableSignalKeyStore,
@@ -24,6 +24,7 @@ import makeWASocket, {
WAMessageKey,
WAMessageUpdate,
} from '@adiwajshing/baileys';
import type { WABrowserDescription } from '@adiwajshing/baileys';
import { WACallEvent } from '@adiwajshing/baileys/lib/Types/Call';
import { BaileysEventMap } from '@adiwajshing/baileys/lib/Types/Events';
import { GroupMetadata } from '@adiwajshing/baileys/lib/Types/GroupMetadata';
@@ -308,9 +309,7 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
getSocketConfig(agent, state): Partial<SocketConfig> {
const fullSyncEnabled = this.sessionConfig?.noweb?.store?.fullSync || false;
const browser = fullSyncEnabled
? Browsers.ubuntu('Desktop')
: Browsers.ubuntu('Chrome');
const browser = ['Ubuntu', 'Chrome', '20.0.04'] as WABrowserDescription;
let markOnlineOnConnect = this.sessionConfig?.noweb?.markOnline;
if (markOnlineOnConnect == undefined) {
markOnlineOnConnect = true;
@@ -410,9 +409,9 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
await this.ensureStore();
this.sock = await this.makeSocket();
this.fixMessages();
this.issueMessageUpdateOnEdits();
this.issueMessageUpdateOnPoll();
this.fixMessageUpsertStatus();
this.issuePresenceUpdateOnMessageUpsert();
if (this.isDebugEnabled()) {
this.listenEngineEventsInDebugMode();
@@ -439,7 +438,7 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
key: WAMessageKey,
): Promise<WAMessageContent | undefined> {
if (!this.store) {
return proto.Message.fromObject({});
return proto.Message.create({});
}
const msg = await this.store.loadMessage(key.remoteJid, key.id);
return msg?.message || undefined;
@@ -586,12 +585,16 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
await this.store?.close();
}
private fixMessageUpsertStatus() {
// If no status - set it to WAMessageAck.DEVICE
private fixMessages() {
this.sock.ev.on('messages.upsert', ({ messages }) => {
for (const message of messages) {
if (message.status == null) {
message.status = AckToStatus(WAMessageAck.DEVICE);
// If no status - set it to WAMessageAck.DEVICE
message.status = message.status ?? AckToStatus(WAMessageAck.DEVICE);
// Fix fromMe in @lid addressed groups
// https://github.com/devlikeapro/waha/issues/1350
if (message.key.participant === this.getSessionMeInfo()?.lid) {
message.key.fromMe = true;
}
}
});
@@ -737,7 +740,7 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
return {
id: toCusFormat(meId),
pushName: me.name,
lid: me.lid,
lid: jidNormalizedUser(me.lid),
};
}
@@ -2141,7 +2144,7 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
this.logger.debug({ jid: update.id }, 'Profile picture updated');
const url = await this.refreshProfilePicture(update.id);
if (isJidUser(update.id)) {
if (isPnUser(update.id) || isLidUser(update.id)) {
// update 123@c.us and 123 profiles as well
const cus = toCusFormat(update.id);
this.profilePictures.set(cus, url);
@@ -2577,11 +2580,16 @@ export class NOWEBEngineMediaProcessor implements IMediaEngineProcessor<any> {
async getMediaBuffer(message: any): Promise<Buffer | null> {
const content = extractMediaContent(message.message);
const url = content.url;
// Fix Stickers
// https://github.com/devlikeapro/waha/issues/504
const url = content.url;
// Set it to null so the engine handles it right
if (!hasPath(url)) {
// Set it to null so the engine handles it right
content.url = null;
}
// Fix Newsletter
// directPath has the unencrypted path
if (isJidNewsletter(message.key.remoteJid) && content.directPath) {
content.url = null;
}
@@ -2594,8 +2602,7 @@ export class NOWEBEngineMediaProcessor implements IMediaEngineProcessor<any> {
reuploadRequest: this.session.sock.updateMediaMessage,
},
).finally(() => {
// Fix Stickers - set url back, just to have it in the response
// https://github.com/devlikeapro/waha/issues/504
// Set url back in case we removed it
content.url = url;
})) as Buffer;
}
@@ -1,4 +1,4 @@
import { Chat } from '@adiwajshing/baileys';
import type { Chat } from '@adiwajshing/baileys';
import { OverviewFilter } from '@waha/structures/chats.dto';
import { PaginationParams } from '@waha/structures/pagination.dto';
@@ -1,4 +1,4 @@
import { Contact } from '@adiwajshing/baileys';
import type { Contact } from '@adiwajshing/baileys';
import { PaginationParams } from '@waha/structures/pagination.dto';
export interface IContactRepository {
@@ -1,4 +1,4 @@
import { GroupMetadata } from '@adiwajshing/baileys';
import type { GroupMetadata } from '@adiwajshing/baileys';
import { PaginationParams } from '@waha/structures/pagination.dto';
export interface IGroupRepository {
@@ -1,4 +1,4 @@
import {
import type {
LabelAssociation,
LabelAssociationType,
} from '@adiwajshing/baileys/lib/Types/LabelAssociation';
@@ -1,5 +1,4 @@
import { Contact } from '@adiwajshing/baileys';
import { Label } from '@adiwajshing/baileys/lib/Types/Label';
import type { Label } from '@adiwajshing/baileys/lib/Types/Label';
export interface ILabelsRepository {
getById(id: string): Promise<Label | null>;
+3 -3
View File
@@ -1,11 +1,11 @@
import {
import type {
BaileysEventEmitter,
Chat,
Contact,
proto,
} from '@adiwajshing/baileys';
import { GroupMetadata } from '@adiwajshing/baileys/lib/Types/GroupMetadata';
import { Label } from '@adiwajshing/baileys/lib/Types/Label';
import type { GroupMetadata } from '@adiwajshing/baileys/lib/Types/GroupMetadata';
import type { Label } from '@adiwajshing/baileys/lib/Types/Label';
import {
GetChatMessagesFilter,
OverviewFilter,
@@ -1,10 +1,6 @@
import makeWASocket, {
Chat,
Contact,
GroupMetadata,
proto,
} from '@adiwajshing/baileys';
import { Label } from '@adiwajshing/baileys/lib/Types/Label';
import type { Chat, Contact, GroupMetadata, proto } from '@adiwajshing/baileys';
import type makeWASocket from '@adiwajshing/baileys';
import type { Label } from '@adiwajshing/baileys/lib/Types/Label';
import { BadRequestException } from '@nestjs/common';
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
import { LidToPhoneNumber } from '@waha/structures/lids.dto';
@@ -1,31 +1,25 @@
import makeWASocket, {
areJidsSameUser,
import type makeWASocket from '@adiwajshing/baileys';
import type {
BaileysEventEmitter,
Chat,
ChatUpdate,
Contact,
GroupParticipant,
isJidUser,
isRealMessage,
jidNormalizedUser,
Contact,
ParticipantAction,
proto,
updateMessageWithReaction,
updateMessageWithReceipt,
WAMessage,
} from '@adiwajshing/baileys';
import { WACallEvent } from '@adiwajshing/baileys/lib/Types/Call';
import { GroupMetadata } from '@adiwajshing/baileys/lib/Types/GroupMetadata';
import { Label } from '@adiwajshing/baileys/lib/Types/Label';
import {
LabelAssociation,
LabelAssociationType,
} from '@adiwajshing/baileys/lib/Types/LabelAssociation';
import { isLidUser } from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import type { GroupMetadata } from '@adiwajshing/baileys/lib/Types/GroupMetadata';
import type { Label } from '@adiwajshing/baileys/lib/Types/Label';
import type { LabelAssociation } from '@adiwajshing/baileys/lib/Types/LabelAssociation';
import { IGroupRepository } from '@waha/core/engines/noweb/store/IGroupRepository';
import { ILabelAssociationRepository } from '@waha/core/engines/noweb/store/ILabelAssociationsRepository';
import { ILabelsRepository } from '@waha/core/engines/noweb/store/ILabelsRepository';
import { JidFilter } from '@waha/core/utils/jids';
import {
isLidUser,
isPnUser,
JidFilter,
jidsFromKey,
} from '@waha/core/utils/jids';
import {
GetChatMessagesFilter,
OverviewFilter,
@@ -41,7 +35,6 @@ import { waitUntil } from '@waha/utils/promiseTimeout';
import * as lodash from 'lodash';
import { toNumber } from 'lodash';
import { Logger } from 'pino';
import { filter } from 'rxjs';
import { IChatRepository } from './IChatRepository';
import { IContactRepository } from './IContactRepository';
@@ -49,6 +42,8 @@ import { IMessagesRepository } from './IMessagesRepository';
import { INowebLidPNRepository, LidToPN } from './INowebLidPNRepository';
import { INowebStorage } from './INowebStorage';
import { INowebStore } from './INowebStore';
import { LabelAssociationType } from '../labels/LabelAssociationType';
import esm from '@waha/vendor/esm';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const AsyncLock = require('async-lock');
@@ -118,18 +113,20 @@ export class NowebPersistentStore implements INowebStore {
if (!message.key) {
return null;
}
// Phone
let pn = message.key.senderPn || message.key.participantPn;
const jids = jidsFromKey(message.key);
if (!jids) {
return null;
}
let { lid, pn } = jids;
// 123 => 123@s.whatsapp.net
if (pn && !pn.includes('@')) {
pn = `${pn}@s.whatsapp.net`;
}
// 123@c.us => 123@s.whatsapp.net
if (pn && !isJidUser(pn)) {
pn = jidNormalizedUser(pn);
if (pn && !isPnUser(pn)) {
pn = esm.b.jidNormalizedUser(pn);
}
// 999@lid
const lid = message.key.senderLid || message.key.participantLid;
return {
id: message.key.remoteJid,
lid: lid,
@@ -185,6 +182,16 @@ export class NowebPersistentStore implements INowebStore {
),
);
// Lids
ev.on('lid-mapping.update', (data) => {
this.withLock('lids', async () => {
const lids = await this.handleLidPNUpdates([data]);
this.logger.debug(
`lid-mapping.update - '${lids.length}' synced lid to pn mapping`,
);
});
});
// Contacts
ev.on('contacts.upsert', (data) => {
this.withLock('contacts', () => this.onContactsUpsert(data));
@@ -221,17 +228,7 @@ export class NowebPersistentStore implements INowebStore {
}
private async onMessagingHistorySet(history) {
const { contacts, chats, messages, isLatest } = history;
if (isLatest) {
this.logger.debug(
'history sync - clearing all entities, got latest history',
);
await Promise.all([
this.withLock('contacts', () => this.contactRepo.deleteAll()),
this.withLock('chats', () => this.chatRepo.deleteAll()),
this.withLock('messages', () => this.messagesRepo.deleteAll()),
]);
}
const { contacts, chats, messages } = history;
await Promise.all([
this.withLock('contacts', async () => {
@@ -250,7 +247,7 @@ export class NowebPersistentStore implements INowebStore {
}
private async syncMessagesHistory(messages) {
const realMessages = messages.filter(isRealMessage);
const realMessages = messages.filter(esm.b.isRealMessage);
messages = messages.filter((msg) => this.jids.include(msg.key.remoteJid));
await this.messagesRepo.upsert(realMessages);
this.logger.info(
@@ -266,7 +263,7 @@ export class NowebPersistentStore implements INowebStore {
}
let messages = update.messages;
messages = messages.filter((msg) => this.jids.include(msg.key.remoteJid));
const realMessages = messages.filter(isRealMessage);
const realMessages = messages.filter(esm.b.isRealMessage);
await this.messagesRepo.upsert(realMessages);
this.logger.debug(
`messages.upsert - ${messages.length} got messages, ${realMessages.length} real messages`,
@@ -276,7 +273,7 @@ export class NowebPersistentStore implements INowebStore {
private async onMessageUpdate(updates) {
for (const update of updates) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const jid = jidNormalizedUser(update.key.remoteJid!);
const jid = esm.b.jidNormalizedUser(update.key.remoteJid!);
if (!this.jids.include(jid)) {
continue;
}
@@ -319,7 +316,8 @@ export class NowebPersistentStore implements INowebStore {
// In case of revoked messages - remove it
// TODO: May be we should save the flag instead of completely removing the message
const isYetRealMessage =
isRealMessage(message, this.socket?.authState?.creds?.me?.id) || false;
esm.b.isRealMessage(message, this.socket?.authState?.creds?.me?.id) ||
false;
if (isYetRealMessage) {
await this.messagesRepo.upsertOne(message);
} else {
@@ -333,7 +331,7 @@ export class NowebPersistentStore implements INowebStore {
await this.messagesRepo.deleteAllByJid(item.jid);
return;
}
const jid = jidNormalizedUser(item.keys[0].remoteJid);
const jid = esm.b.jidNormalizedUser(item.keys[0].remoteJid);
const ids = item.keys.map((key) => key.id);
await this.messagesRepo.deleteByJidByIds(jid, ids);
}
@@ -383,7 +381,7 @@ export class NowebPersistentStore implements INowebStore {
// Remove the group if the current user is removed
const myJid = this.socket?.authState?.creds?.me?.id;
const participantsIncludesMe = lodash.find(participants, (p) =>
areJidsSameUser(p, myJid),
esm.b.areJidsSameUser(p, myJid),
);
if (participantsIncludesMe) {
await this.groupRepo.deleteById(id);
@@ -534,7 +532,7 @@ export class NowebPersistentStore implements INowebStore {
);
continue;
}
updateMessageWithReaction(msg, reaction);
esm.b.updateMessageWithReaction(msg, reaction);
await this.messagesRepo.upsertOne(msg);
}
}
@@ -553,7 +551,7 @@ export class NowebPersistentStore implements INowebStore {
);
continue;
}
updateMessageWithReceipt(msg, receipt);
esm.b.updateMessageWithReceipt(msg, receipt);
await this.messagesRepo.upsertOne(msg);
}
}
@@ -596,7 +594,7 @@ export class NowebPersistentStore implements INowebStore {
if (!data) {
return null;
}
return proto.WebMessageInfo.fromObject(data);
return esm.b.proto.WebMessageInfo.create(data);
}
getMessagesByJid(
@@ -702,23 +700,23 @@ export class NowebPersistentStore implements INowebStore {
let lids: LidToPN[] = [];
for (const contact of contacts) {
// contact.id = pn, contact.lid = lid
if (isJidUser(contact.id) && isLidUser(contact.lid)) {
if (isPnUser(contact.id) && isLidUser(contact.lid)) {
lids.push({
pn: contact.id,
id: contact.lid,
});
}
// contact.pn = pn, contact.lid = lid
else if (isJidUser(contact.jid) && isLidUser(contact.lid)) {
// contact.phoneNumber = pn, contact.lid = lid
else if (isPnUser(contact.phoneNumber) && isLidUser(contact.lid)) {
lids.push({
pn: contact.jid,
pn: contact.phoneNumber,
id: contact.lid,
});
}
// contact.pn = pn, contact.id = lid
else if (isJidUser(contact.jid) && isLidUser(contact.id)) {
// contact.phoneNumber = pn, contact.id = lid
else if (isPnUser(contact.phoneNumber) && isLidUser(contact.id)) {
lids.push({
pn: contact.jid,
pn: contact.phoneNumber,
id: contact.id,
});
}
@@ -11,28 +11,19 @@ import type {
WAMessageCursor,
WAMessageKey,
} from '@adiwajshing/baileys/lib/Types';
import { Label } from '@adiwajshing/baileys/lib/Types/Label';
import {
import type { Label } from '@adiwajshing/baileys/lib/Types/Label';
import * as lodash from 'lodash';
import type {
LabelAssociation,
LabelAssociationType,
MessageLabelAssociation,
} from '@adiwajshing/baileys/lib/Types/LabelAssociation';
import {
md5,
toNumber,
updateMessageWithReaction,
updateMessageWithReceipt,
} from '@adiwajshing/baileys/lib/Utils';
import {
jidDecode,
jidNormalizedUser,
} from '@adiwajshing/baileys/lib/WABinary';
import { proto } from '@adiwajshing/baileys/WAProto';
import type { Comparable } from '@adiwajshing/keyed-db/lib/Types';
import type { Logger } from 'pino';
import makeOrderedDictionary from './make-ordered-dictionary';
import { ObjectRepository } from './object-repository';
import { LabelAssociationType } from '@waha/core/engines/noweb/labels/LabelAssociationType';
import esm from '@waha/vendor/esm';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const KeyedDB = require('@adiwajshing/keyed-db').default;
@@ -137,7 +128,7 @@ export default (config: BaileysInMemoryStoreConfig) => {
isLatest,
syncType,
}) => {
if (syncType === proto.HistorySync.HistorySyncType.ON_DEMAND) {
if (syncType === esm.b.proto.HistorySync.HistorySyncType.ON_DEMAND) {
return; // FOR NOW,
//TODO: HANDLE
}
@@ -187,10 +178,11 @@ export default (config: BaileysInMemoryStoreConfig) => {
} else {
const contactHashes = await Promise.all(
Object.keys(contacts).map(async (contactId) => {
const { user } = jidDecode(contactId)!;
const { user } = esm.b.jidDecode(contactId)!;
return [
contactId,
(await md5(Buffer.from(user + 'WA_ADD_NOTIF', 'utf8')))
esm.b
.md5(Buffer.from(user + 'WA_ADD_NOTIF', 'utf8'))
.toString('base64')
.slice(0, 3),
];
@@ -279,7 +271,7 @@ export default (config: BaileysInMemoryStoreConfig) => {
case 'append':
case 'notify':
for (const msg of newMessages) {
const jid = jidNormalizedUser(msg.key.remoteJid!);
const jid = esm.b.jidNormalizedUser(msg.key.remoteJid!);
const list = assertMessageList(jid);
list.upsert(msg, 'append');
@@ -287,7 +279,9 @@ export default (config: BaileysInMemoryStoreConfig) => {
ev.emit('chats.upsert', [
{
id: jid,
conversationTimestamp: toNumber(msg.messageTimestamp as any),
conversationTimestamp: lodash.toNumber(
msg.messageTimestamp as any,
),
unreadCount: 1,
},
]);
@@ -299,7 +293,7 @@ export default (config: BaileysInMemoryStoreConfig) => {
});
ev.on('messages.update', (updates) => {
for (const { update, key } of updates) {
const list = assertMessageList(jidNormalizedUser(key.remoteJid!));
const list = assertMessageList(esm.b.jidNormalizedUser(key.remoteJid!));
if (update?.status) {
const listStatus = list.get(key.id!)?.status;
if (listStatus && update?.status <= listStatus) {
@@ -382,7 +376,7 @@ export default (config: BaileysInMemoryStoreConfig) => {
const obj = messages[key.remoteJid!];
const msg = obj?.get(key.id!);
if (msg) {
updateMessageWithReceipt(msg, receipt);
esm.b.updateMessageWithReceipt(msg, receipt);
}
}
});
@@ -392,7 +386,7 @@ export default (config: BaileysInMemoryStoreConfig) => {
const obj = messages[key.remoteJid!];
const msg = obj?.get(key.id!);
if (msg) {
updateMessageWithReaction(msg, reaction);
esm.b.updateMessageWithReaction(msg, reaction);
}
}
});
@@ -420,7 +414,7 @@ export default (config: BaileysInMemoryStoreConfig) => {
for (const jid in json.messages) {
const list = assertMessageList(jid);
for (const msg of json.messages[jid]) {
list.upsert(proto.WebMessageInfo.fromObject(msg), 'append');
list.upsert(esm.b.proto.WebMessageInfo.create(msg), 'append');
}
}
};
+2 -2
View File
@@ -1,5 +1,5 @@
import { WAMessage } from '@adiwajshing/baileys';
import { LabelAssociation } from '@adiwajshing/baileys/lib/Types/LabelAssociation';
import type { WAMessage } from '@adiwajshing/baileys';
import type { LabelAssociation } from '@adiwajshing/baileys/lib/Types/LabelAssociation';
export const NowebMessagesMetadata = new Map()
.set('jid', (msg: WAMessage) => msg.key.remoteJid)
@@ -1,4 +1,4 @@
import { Chat } from '@adiwajshing/baileys';
import type { Chat } from '@adiwajshing/baileys';
import { SqlKVRepository } from '@waha/core/storage/sql/SqlKVRepository';
import { OverviewFilter } from '@waha/structures/chats.dto';
import { PaginationParams } from '@waha/structures/pagination.dto';
@@ -1,8 +1,6 @@
import {
LabelAssociation,
LabelAssociationType,
} from '@adiwajshing/baileys/lib/Types/LabelAssociation';
import type { LabelAssociation } from '@adiwajshing/baileys/lib/Types/LabelAssociation';
import { SqlKVRepository } from '@waha/core/storage/sql/SqlKVRepository';
import { LabelAssociationType } from '@waha/core/engines/noweb/labels/LabelAssociationType';
export class SqlLabelAssociationsMethods {
constructor(private repository: SqlKVRepository<any>) {}
@@ -1,9 +1,9 @@
import { BufferJSON } from '@adiwajshing/baileys/lib/Utils';
import {
convertProtobufToPlainObject,
replaceLongsWithNumber,
} from '@waha/core/engines/noweb/utils';
import { Sqlite3KVRepository } from '@waha/core/storage/sqlite3/Sqlite3KVRepository';
import esm from '@waha/vendor/esm';
/**
* Key value repository with extra metadata
@@ -13,11 +13,11 @@ export class NOWEBSqlite3KVRepository<
Entity,
> extends Sqlite3KVRepository<Entity> {
protected stringify(data: any): string {
return JSON.stringify(data, BufferJSON.replacer);
return JSON.stringify(data, esm.b.BufferJSON.replacer);
}
protected parse(row: any): any {
return JSON.parse(row.data, BufferJSON.reviver);
return JSON.parse(row.data, esm.b.BufferJSON.reviver);
}
protected dump(entity: Entity) {
@@ -1,4 +1,4 @@
import { Chat } from '@adiwajshing/baileys';
import type { Chat } from '@adiwajshing/baileys';
import { NowebChatSchema } from '@waha/core/engines/noweb/store/schemas';
import { SqlChatMethods } from '@waha/core/engines/noweb/store/sql/SqlChatMethods';
import { OverviewFilter } from '@waha/structures/chats.dto';
@@ -1,4 +1,4 @@
import { Contact } from '@adiwajshing/baileys';
import type { Contact } from '@adiwajshing/baileys';
import { NowebContactSchema } from '@waha/core/engines/noweb/store/schemas';
import { KnexPaginator } from '@waha/utils/Paginator';
@@ -1,4 +1,4 @@
import { GroupMetadata } from '@adiwajshing/baileys/lib/Types/GroupMetadata';
import type { GroupMetadata } from '@adiwajshing/baileys/lib/Types/GroupMetadata';
import { IGroupRepository } from '@waha/core/engines/noweb/store/IGroupRepository';
import { NowebGroupsSchema } from '@waha/core/engines/noweb/store/schemas';
import { KnexPaginator } from '@waha/utils/Paginator';
@@ -1,4 +1,4 @@
import {
import type {
LabelAssociation,
LabelAssociationType,
} from '@adiwajshing/baileys/lib/Types/LabelAssociation';
@@ -1,4 +1,4 @@
import { Label } from '@adiwajshing/baileys/lib/Types/Label';
import type { Label } from '@adiwajshing/baileys/lib/Types/Label';
import { ILabelsRepository } from '@waha/core/engines/noweb/store/ILabelsRepository';
import { NowebLabelsSchema } from '@waha/core/engines/noweb/store/schemas';
@@ -1,11 +1,10 @@
import {
import type {
AuthenticationCreds,
AuthenticationState,
proto,
} from '@adiwajshing/baileys';
import { BufferJSON, initAuthCreds } from '@adiwajshing/baileys/lib/Utils';
import { mkdir, readFile, stat, unlink } from 'fs/promises';
import { join } from 'path';
import esm from '@waha/vendor/esm';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const writeFileAtomic = require('write-file-atomic');
@@ -43,7 +42,7 @@ export const useMultiFileAuthState = async (
return fileLock.acquire(filePath, () =>
writeFileAtomic(
join(filePath),
JSON.stringify(data, BufferJSON.replacer),
JSON.stringify(data, esm.b.BufferJSON.replacer),
),
);
};
@@ -54,7 +53,7 @@ export const useMultiFileAuthState = async (
const data = await fileLock.acquire(filePath, () =>
readFile(filePath, { encoding: 'utf-8' }),
);
return JSON.parse(data, BufferJSON.reviver);
return JSON.parse(data, esm.b.BufferJSON.reviver);
} catch (error) {
return null;
}
@@ -84,7 +83,7 @@ export const useMultiFileAuthState = async (
file?.replace(/\//g, '__')?.replace(/:/g, '-') || '';
const creds: AuthenticationCreds =
(await readData('creds.json')) || initAuthCreds();
(await readData('creds.json')) || esm.b.initAuthCreds();
return {
state: {
@@ -96,7 +95,7 @@ export const useMultiFileAuthState = async (
ids.map(async (id) => {
let value = await readData(`${type}-${id}.json`);
if (type === 'app-state-sync-key' && value) {
value = proto.Message.AppStateSyncKeyData.fromObject(value);
value = esm.b.proto.Message.AppStateSyncKeyData.create(value);
}
data[id] = value;
+3 -2
View File
@@ -1,9 +1,10 @@
import { extractMessageContent, proto } from '@adiwajshing/baileys';
import type { proto } from '@adiwajshing/baileys';
import esm from '@waha/vendor/esm';
export function extractMediaContent(
content: any | proto.IMessage | null | undefined,
) {
content = extractMessageContent(content);
content = esm.b.extractMessageContent(content);
const mediaContent =
content?.documentMessage ||
content?.imageMessage ||
+1 -1
View File
@@ -223,7 +223,7 @@ export class WebjsClientCore extends Client {
// @ts-ignore
await window.Store.SendStatus.sendStatusTextMsgAction(status);
// @ts-ignore
const meUser = window.Store.User.getMeUser();
const meUser = window.Store.User.getMaybeMePnUser();
// @ts-ignore
const myStatus = window.Store.Status.getModelsArray().findLast(
(x) => x.id == meUser,
+14 -21
View File
@@ -1,14 +1,7 @@
import {
areJidsSameUser,
BinaryNode,
getBinaryNodeChildren,
getStatusFromReceiptType,
isJidGroup,
isJidStatusBroadcast,
jidEncode,
jidNormalizedUser,
proto,
} from '@adiwajshing/baileys';
import type { proto } from '@adiwajshing/baileys';
import type { BinaryNode } from '@adiwajshing/baileys';
import { isJidGroup, isJidStatusBroadcast } from '@waha/core/utils/jids';
import esm from '@waha/vendor/esm';
export interface ReceiptEvent {
key: proto.IMessageKey;
@@ -39,7 +32,7 @@ export function jid(field: any) {
? 's.whatsapp.net'
: 'lid';
}
return jidEncode(data.user, server, data.device);
return esm.b.jidEncode(data.user, server, data.device);
}
export function TagReceiptNodeToReceiptEvent(
@@ -47,17 +40,17 @@ export function TagReceiptNodeToReceiptEvent(
me: Me,
): ReceiptEvent[] {
const { attrs, content } = node;
const status = getStatusFromReceiptType(attrs.type);
const status = esm.b.getStatusFromReceiptType(attrs.type);
if (status == null) {
return [];
}
const from = jidNormalizedUser(jid(attrs.from));
const participant = jidNormalizedUser(jid(attrs.participant));
const recipient = jidNormalizedUser(jid(attrs.recipient));
const from = esm.b.jidNormalizedUser(jid(attrs.from));
const participant = esm.b.jidNormalizedUser(jid(attrs.participant));
const recipient = esm.b.jidNormalizedUser(jid(attrs.recipient));
const isLid = from.includes('lid');
const isNodeFromMe = areJidsSameUser(
const isNodeFromMe = esm.b.areJidsSameUser(
participant || from,
isLid ? me?.lid : me?.id,
);
@@ -66,7 +59,7 @@ export function TagReceiptNodeToReceiptEvent(
// basically, we only want to know when a message from us has been delivered to/read by the other person
// or another device of ours has read some messages
if (status < proto.WebMessageInfo.Status.SERVER_ACK && isNodeFromMe) {
if (status < esm.b.proto.WebMessageInfo.Status.SERVER_ACK && isNodeFromMe) {
return [];
}
@@ -78,7 +71,7 @@ export function TagReceiptNodeToReceiptEvent(
const ids = [attrs.id];
if (Array.isArray(content)) {
const items = getBinaryNodeChildren(content[0], 'item');
const items = esm.b.getBinaryNodeChildren(content[0], 'item');
ids.push(...items.map((i) => i.attrs.id));
}
@@ -134,12 +127,12 @@ function handleGroupedReceipts(
const participantKey = participants.attrs?.key;
if (!participantKey) continue;
const users = getBinaryNodeChildren(participants, 'user');
const users = esm.b.getBinaryNodeChildren(participants, 'user');
for (const user of users) {
const userAttrs = user.attrs;
if (!userAttrs) continue;
const userJid = jidNormalizedUser(jid(userAttrs.jid));
const userJid = esm.b.jidNormalizedUser(jid(userAttrs.jid));
if (!userJid) continue;
key.participant = fromMe ? (isLid ? me.lid : me.id) : userJid;
+2 -2
View File
@@ -1,9 +1,9 @@
import { BinaryNode, WAPresence } from '@adiwajshing/baileys';
import { toCusFormat } from '@waha/core/engines/noweb/session.noweb.core';
import type { BinaryNode, WAPresence } from '@adiwajshing/baileys';
import { WAHAPresenceStatus } from '@waha/structures/enums.dto';
import { WAHAChatPresences } from '@waha/structures/presence.dto';
import { jid } from './ack.webjs';
import { toCusFormat } from '@waha/core/utils/jids';
export function TagPresenceToPresence(node: BinaryNode): WAHAChatPresences {
const { attrs } = node;
+33 -6
View File
@@ -1,13 +1,9 @@
import { isJidGroup, isJidStatusBroadcast } from '@adiwajshing/baileys';
import { UnprocessableEntityException } from '@nestjs/common';
import {
getChannelInviteLink,
WhatsappSession,
} from '@waha/core/abc/session.abc';
import {
getFromToParticipant,
toCusFormat,
} from '@waha/core/engines/noweb/session.noweb.core';
import { getFromToParticipant } from '@waha/core/engines/noweb/session.noweb.core';
import {
ReceiptEvent,
TagReceiptNodeToReceiptEvent,
@@ -68,6 +64,7 @@ import {
CheckNumberStatusQuery,
EditMessageRequest,
MessageButtonReply,
MessageContactVcardRequest,
MessageFileRequest,
MessageForwardRequest,
MessageImageRequest,
@@ -80,6 +77,7 @@ import {
SendSeenRequest,
WANumberExistResult,
} from '@waha/structures/chatting.dto';
import { toVcardV3 } from '@waha/core/vcard';
import {
ContactQuery,
ContactRequest,
@@ -149,6 +147,11 @@ import {
import { Message as MessageInstance } from 'whatsapp-web.js/src/structures';
import { WAJSPresenceChatStateType, WebJSPresence } from './types';
import {
isJidGroup,
isJidStatusBroadcast,
toCusFormat,
} from '@waha/core/utils/jids';
export interface WebJSConfig {
webVersion?: string;
@@ -662,6 +665,28 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
return message.edit(request.text, options);
}
async sendContactVCard(request: MessageContactVcardRequest) {
const chatId = this.ensureSuffix(request.chatId);
const vcards = request.contacts.map((el) => toVcardV3(el as any));
const options = this.getMessageOptions(request);
// Single vCard: pass raw vcard text as a message body.
// WEBJS will detect BEGIN:VCARD when parseVCards=true and send as a contact card.
if (vcards.length <= 1) {
const vcard = vcards[0] || '';
return this.whatsapp.sendMessage(chatId, vcard, options);
}
// Multiple vCards: send as a single multi_vcard message using extra options.
const extra = {
type: 'multi_vcard',
vcardList: vcards.map((v) => ({ vcard: v })),
body: null,
} as any;
return this.whatsapp.sendMessage(chatId, '', { ...options, extra });
}
reply(request: MessageReplyRequest) {
const options = this.getMessageOptions(request);
return this.whatsapp.sendMessage(
@@ -1239,9 +1264,11 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
}
protected ChannelMetadataToChannel(metadata: any): Channel {
let role = metadata.membershipType.toUpperCase();
let role = metadata.membershipType?.toUpperCase();
if (role === 'VIEWER') {
role = ChannelRole.GUEST;
} else if (!role) {
role = ChannelRole.GUEST;
}
return {
id: metadata.id,
+4 -2
View File
@@ -62,7 +62,10 @@ export class MediaManager implements IMediaManager {
return null;
}
const extension = mime.extension(mimetype);
let extension = mime.extension(mimetype);
if (mimetype == 'application/was' && !extension) {
extension = 'zip';
}
const mediaData: MediaData = {
session: session,
message: {
@@ -125,7 +128,6 @@ export class MediaManager implements IMediaManager {
try {
media.filename = processor.getFilename(message);
media.mimetype = processor.getMimetype(message);
media.filename = processor.getFilename(message);
const data = await this.processMediaInternal(processor, message, session);
media = { ...media, ...data };
} catch (err) {
+2 -2
View File
@@ -1,6 +1,6 @@
import { isJidGroup, WAMessageKey } from '@adiwajshing/baileys';
import type { WAMessageKey } from '@adiwajshing/baileys';
import { parseMessageIdSerialized } from '@waha/core/utils/ids';
import { toJID } from '@waha/core/utils/jids';
import { isJidGroup, toJID } from '@waha/core/utils/jids';
import {
GetChatMessagesFilter,
GetChatMessagesQuery,
+1 -1
View File
@@ -1,4 +1,4 @@
import { WAMessageKey } from '@adiwajshing/baileys';
import type { WAMessageKey } from '@adiwajshing/baileys';
import { toJID } from '@waha/core/utils/jids';
/**
+94 -10
View File
@@ -1,12 +1,5 @@
import {
isJidGroup,
isJidMetaIa,
isJidStatusBroadcast,
} from '@adiwajshing/baileys';
import {
isJidBroadcast,
isLidUser,
} from '@adiwajshing/baileys/lib/WABinary/jid-utils';
import type { WAMessageKey } from '@adiwajshing/baileys';
import { ensureSuffix } from '@waha/core/abc/session.abc';
export function isJidNewsletter(jid: string) {
return jid?.endsWith('@newsletter');
@@ -16,6 +9,33 @@ export function isJidCus(jid: string) {
return jid?.endsWith('@c.us');
}
export function isJidGroup(jid: string) {
return typeof jid === 'string' && jid.endsWith('@g.us');
}
export function isJidStatusBroadcast(jid: string) {
return jid === 'status@broadcast';
}
export function isJidBroadcast(jid: string) {
return typeof jid === 'string' && jid.endsWith('@broadcast');
}
export function isJidMetaAI(jid: string) {
return typeof jid === 'string' && jid.endsWith('@meta.ai');
}
export function isLidUser(jid: string) {
return typeof jid === 'string' && jid.endsWith('@lid');
}
export function isPnUser(jid: string) {
return (
typeof jid === 'string' &&
(jid.endsWith('@s.whatsapp.net') || jid.endsWith('@c.us'))
);
}
/**
* Convert from 11111111111@c.us to 11111111111@s.whatsapp.net
* @param chatId
@@ -33,7 +53,7 @@ export function toJID(chatId) {
if (isLidUser(chatId)) {
return chatId;
}
if (isJidMetaIa(chatId)) {
if (isJidMetaAI(chatId)) {
return chatId;
}
const number = chatId.split('@')[0];
@@ -67,3 +87,67 @@ export class JidFilter {
return true;
}
}
export interface Jids {
lid?: string;
pn?: string;
}
export function jidsFromKey(key: WAMessageKey): Jids | null {
// DM
if (isLidUser(key.remoteJid)) {
return {
lid: key.remoteJid,
pn: key.remoteJidAlt,
};
} else if (isPnUser(key.remoteJid)) {
return {
lid: key.remoteJidAlt,
pn: key.remoteJid,
};
}
// Groups
else if (isLidUser(key.participant)) {
return {
lid: key.participant,
pn: key.participantAlt,
};
} else if (isPnUser(key.participant)) {
return {
lid: key.remoteJid,
pn: key.participantAlt,
};
}
return null;
}
/**
* Convert from 11111111111@s.whatsapp.net to 11111111111@c.us
*/
export function toCusFormat(remoteJid) {
if (!remoteJid) {
return remoteJid;
}
if (isJidGroup(remoteJid)) {
return remoteJid;
}
if (isJidBroadcast(remoteJid)) {
return remoteJid;
}
if (isLidUser(remoteJid)) {
return remoteJid;
}
if (isJidNewsletter(remoteJid)) {
return remoteJid;
}
if (!remoteJid) {
return;
}
if (remoteJid == 'me') {
return remoteJid;
}
let number = remoteJid.split('@')[0];
// remove :{device} part
number = number.split(':')[0];
return ensureSuffix(number);
}
+3 -1
View File
@@ -17,6 +17,7 @@ import { AppModuleCore } from './core/app.module.core';
import { SwaggerConfiguratorCore } from './core/SwaggerConfiguratorCore';
import { AllExceptionsFilter } from './nestjs/AllExceptionsFilter';
import { getWAHAVersion, VERSION, WAHAVersion } from './version';
import { loadESMModules } from '@waha/vendor/esm';
const logger: Logger = pino({
level: getPinoLogLevel(),
@@ -48,8 +49,9 @@ process.on('SIGTERM', () => {
});
async function loadModules(): Promise<typeof AppModuleCore> {
const version = getWAHAVersion();
await loadESMModules();
const version = getWAHAVersion();
if (version === WAHAVersion.CORE) {
const { AppModuleCore } = await import('./core/app.module.core');
return AppModuleCore;
+2 -2
View File
@@ -1,4 +1,3 @@
import { BufferJSON } from '@adiwajshing/baileys/lib/Utils';
import {
CallHandler,
ExecutionContext,
@@ -8,6 +7,7 @@ import {
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import esm from '@waha/vendor/esm';
@Injectable()
export class BufferJsonReplacerInterceptor implements NestInterceptor {
@@ -27,7 +27,7 @@ export class BufferJsonReplacerInterceptor implements NestInterceptor {
return data;
}
return JSON.parse(JSON.stringify(data, BufferJSON.replacer));
return JSON.parse(JSON.stringify(data, esm.b.BufferJSON.replacer));
}),
);
}
+29
View File
@@ -0,0 +1,29 @@
/**
* NestJS is not yet supporting ESM and work in CommonJS mode
* We create a single place where we'll load all ESM modules and export it
*
* Centralized dynamic loader for ESM-only Baileys from CommonJS/TS code
*/
type Baileys = typeof import('@adiwajshing/baileys');
const esm: { b: Baileys } = {
b: null,
};
const modules = {
b: '@adiwajshing/baileys',
};
async function loadESMModules(): Promise<void> {
for (const [key, value] of Object.entries(modules)) {
if (esm[key]) {
// Make sure we call it ONCE on setup
throw new Error(`Module '${key}' is already loaded`);
}
esm[key] = await import(value);
}
}
export { loadESMModules };
export default esm;
+1 -1
View File
@@ -30,7 +30,7 @@ export function getWAHAVersion(): WAHAVersion {
}
export const VERSION: WAHAEnvironment = {
version: '2025.9.4',
version: '2025.9.5',
engine: getEngineName(),
tier: getWAHAVersion(),
browser:
+2 -2
View File
@@ -2,11 +2,11 @@
"waha": {
"gows": {
"repo": "devlikeapro/gows",
"ref": "v1.0.14"
"ref": "v1.0.15"
},
"dashboard": {
"repo": "devlikeapro/dashboard",
"ref": "042f5bd9cc14440fde062d313bdb8e1bdc511a50"
"ref": "f3e0934f496f7557bdda67f38efa197df44ceabe"
}
}
}
+103 -36
View File
@@ -5,25 +5,25 @@ __metadata:
version: 6
cacheKey: 8
"@adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-07-04":
version: 6.7.18
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=4633d3145f768231c8a45bfb023a2c13094d818c"
"@adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-2025-09-21":
version: 7.0.0-rc.3
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=7198ccbb5f571dd3f7420f112379996bc41fa659"
dependencies:
"@cacheable/node-cache": ^1.4.0
"@hapi/boom": ^9.1.3
async-mutex: ^0.5.0
axios: ^1.6.0
libsignal: "github:WhiskeySockets/libsignal-node"
lodash: ^4.17.21
music-metadata: ^7.12.3
libsignal: "git+https://github.com/whiskeysockets/libsignal-node"
lru-cache: ^11.1.0
music-metadata: ^11.7.0
pino: ^9.6
protobufjs: ^7.2.4
ws: ^8.13.0
peerDependencies:
audio-decode: ^2.1.3
jimp: ^0.16.1
jimp: ^1.6.0
link-preview-js: ^3.0.0
sharp: ^0.32.6
sharp: "*"
peerDependenciesMeta:
audio-decode:
optional: true
@@ -31,9 +31,7 @@ __metadata:
optional: true
link-preview-js:
optional: true
sharp:
optional: true
checksum: 7dfd2e5029c507ba1298253bad83e6cde5c5a27f2cf88c80723a0a00db7c9fe1c7a1877b2a32bbb7527640b282e5e728f8e8b139d51f5586abb68be3599035f7
checksum: bb8f5d9dac5faca5034d829507f70f4d3b71d821bec4ebeab645d774811b12962c4e0a5625d2cb6040e32cc653879acc8911188e9a558b03bd6d696eaefc68ae
languageName: node
linkType: hard
@@ -1173,6 +1171,20 @@ __metadata:
languageName: node
linkType: hard
"@borewit/text-codec@npm:^0.1.0":
version: 0.1.1
resolution: "@borewit/text-codec@npm:0.1.1"
checksum: 94c1fef259292d77c98ad1c2ffa66e366d752153962d37a7999489ada9632a9d36d3fe291759791705b1f501e33cd7b65128d193e0ca8a955107fe5cd8fde548
languageName: node
linkType: hard
"@borewit/text-codec@npm:^0.2.0":
version: 0.2.0
resolution: "@borewit/text-codec@npm:0.2.0"
checksum: 64f073206e96c7c5bef416d23ba185b67e9470b3dda3de42ec1b7cfa901071d9519f89ed49a452575b6148532a7ac6d0c57592e7acca346ca6b4d6895ba8ecdc
languageName: node
linkType: hard
"@bull-board/api@npm:6.11.0, @bull-board/api@npm:^6.9.1":
version: 6.11.0
resolution: "@bull-board/api@npm:6.11.0"
@@ -4603,7 +4615,14 @@ __metadata:
languageName: node
linkType: hard
"async@npm:>=0.2.9, async@npm:^3.2.3, async@npm:^3.2.4":
"async@npm:^0.2.9":
version: 0.2.10
resolution: "async@npm:0.2.10"
checksum: 9ea83419ba67dc4ecf42d4eb0d93ce0ac80a67cabb612f160ed096aef5d001e3184ec9e9be5d4dc39b2c51a34e2ae16f9b21d737068b0f615fccb4eea16d0138
languageName: node
linkType: hard
"async@npm:^3.2.3, async@npm:^3.2.4":
version: 3.2.6
resolution: "async@npm:3.2.6"
checksum: ee6eb8cd8a0ab1b58bd2a3ed6c415e93e773573a91d31df9d5ef559baafa9dab37d3b096fa7993e84585cac3697b2af6ddb9086f45d3ac8cae821bb2aab65682
@@ -5931,6 +5950,18 @@ __metadata:
languageName: node
linkType: hard
"debug@npm:^4.4.3":
version: 4.4.3
resolution: "debug@npm:4.4.3"
dependencies:
ms: ^2.1.3
peerDependenciesMeta:
supports-color:
optional: true
checksum: 4805abd570e601acdca85b6aa3757186084a45cff9b2fa6eee1f3b173caa776b45f478b2a71a572d616d2010cea9211d0ac4a02a610e4c18ac4324bde3760834
languageName: node
linkType: hard
"decamelize@npm:^1.2.0":
version: 1.2.0
resolution: "decamelize@npm:1.2.0"
@@ -6725,7 +6756,7 @@ __metadata:
languageName: node
linkType: hard
"file-type@npm:16.5.4, file-type@npm:^16.5.4":
"file-type@npm:16.5.4":
version: 16.5.4
resolution: "file-type@npm:16.5.4"
dependencies:
@@ -6736,7 +6767,7 @@ __metadata:
languageName: node
linkType: hard
"file-type@npm:21.0.0":
"file-type@npm:21.0.0, file-type@npm:^21.0.0":
version: 21.0.0
resolution: "file-type@npm:21.0.0"
dependencies:
@@ -6797,13 +6828,13 @@ __metadata:
languageName: node
linkType: hard
"fluent-ffmpeg@npm:2.1.2":
version: 2.1.2
resolution: "fluent-ffmpeg@npm:2.1.2"
"fluent-ffmpeg@npm:2.1.3":
version: 2.1.3
resolution: "fluent-ffmpeg@npm:2.1.3"
dependencies:
async: ">=0.2.9"
async: ^0.2.9
which: ^1.1.1
checksum: ab7ed909486298f33b991af051c38e40410ae5b03b0b6d33d0855636a0b56330ffe9efed6c7eedb00f1c6c713c795cbdb283f6f2216db925ae5e737a22c6a97f
checksum: 89d548527c3bb1746acb4c4fa8dc3f660397fcdf598ce455f5a6ec0df2df402ed977f329279e695c549df52822590e3f38c815e8efd740a47c00e9e0f685f083
languageName: node
linkType: hard
@@ -8667,6 +8698,13 @@ __metadata:
languageName: node
linkType: hard
"lru-cache@npm:^11.1.0":
version: 11.2.1
resolution: "lru-cache@npm:11.2.1"
checksum: d54584b6f03e6de64c9e9f01e48abce5a9bc04318874d5204cee9e4275719544624d51eea6a167672576794af8bba3a7cfc23455d28b270a278cc387d1965131
languageName: node
linkType: hard
"lru-cache@npm:^5.1.1":
version: 5.1.1
resolution: "lru-cache@npm:5.1.1"
@@ -9278,18 +9316,20 @@ __metadata:
languageName: node
linkType: hard
"music-metadata@npm:^7.12.3":
version: 7.14.0
resolution: "music-metadata@npm:7.14.0"
"music-metadata@npm:^11.7.0":
version: 11.9.0
resolution: "music-metadata@npm:11.9.0"
dependencies:
"@borewit/text-codec": ^0.2.0
"@tokenizer/token": ^0.3.0
content-type: ^1.0.5
debug: ^4.3.4
file-type: ^16.5.4
debug: ^4.4.3
file-type: ^21.0.0
media-typer: ^1.1.0
strtok3: ^6.3.0
token-types: ^4.2.1
checksum: e1583c3d6519ea3ce1f451e2dfb37ad7a614cd9a8cdb7acfc7d2a2243f7490d209772fb4735b8d8f118f5e1fff27a81096a75839af72e8269516756a658edc3e
strtok3: ^10.3.4
token-types: ^6.1.1
uint8array-extras: ^1.5.0
checksum: e123ae50b502f528cdf0f7b4bcf6ad21ff029e59b18a6a9cabd0900649da83f611b334d6de3e86a704fce27e137b57dbb3596f3f671abdf92934f935d9e0da49
languageName: node
linkType: hard
@@ -11588,7 +11628,16 @@ __metadata:
languageName: node
linkType: hard
"strtok3@npm:^6.2.4, strtok3@npm:^6.3.0":
"strtok3@npm:^10.3.4":
version: 10.3.4
resolution: "strtok3@npm:10.3.4"
dependencies:
"@tokenizer/token": ^0.3.0
checksum: 7faf008cdf7f96c3d066d349116affbd5e5a49da0f03520299a9a04ad55d57b338d368231d469a64d358a86a03c2a0a3b67d61aa124000c941f65093ada9ae98
languageName: node
linkType: hard
"strtok3@npm:^6.2.4":
version: 6.3.0
resolution: "strtok3@npm:6.3.0"
dependencies:
@@ -11910,7 +11959,7 @@ __metadata:
languageName: node
linkType: hard
"token-types@npm:^4.1.1, token-types@npm:^4.2.1":
"token-types@npm:^4.1.1":
version: 4.2.1
resolution: "token-types@npm:4.2.1"
dependencies:
@@ -11930,6 +11979,17 @@ __metadata:
languageName: node
linkType: hard
"token-types@npm:^6.1.1":
version: 6.1.1
resolution: "token-types@npm:6.1.1"
dependencies:
"@borewit/text-codec": ^0.1.0
"@tokenizer/token": ^0.3.0
ieee754: ^1.2.1
checksum: a4d79dfa5bdfe546d28d8ba1374b7e77ceb2da7b44ce13c643d5af06e37aac26e0e6ec59a7d4b1ecfbfc78c13baca00f36fc6f1bb8e8a1f050465340f61d2df7
languageName: node
linkType: hard
"tr46@npm:^4.1.1":
version: 4.1.1
resolution: "tr46@npm:4.1.1"
@@ -12213,6 +12273,13 @@ __metadata:
languageName: node
linkType: hard
"uint8array-extras@npm:^1.5.0":
version: 1.5.0
resolution: "uint8array-extras@npm:1.5.0"
checksum: e7fb42b57e73a5891fe3d5358ca6ac2e2db8e8666b1621220319e2dd0523965cd35562a8171c3e9b2ff26693cc658dc5bc1256e6f4935e4e4c13070d779bf76e
languageName: node
linkType: hard
"ulid@npm:^2.3.0":
version: 2.4.0
resolution: "ulid@npm:2.4.0"
@@ -12403,7 +12470,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "waha@workspace:."
dependencies:
"@adiwajshing/baileys": "github:devlikeapro/Baileys#fork-master-2025-07-04"
"@adiwajshing/baileys": "github:devlikeapro/Baileys#fork-master-2025-09-21"
"@adiwajshing/keyed-db": ^0.2.4
"@aws-sdk/client-s3": ^3.633.0
"@aws-sdk/s3-request-presigner": ^3.633.0
@@ -12501,7 +12568,7 @@ __metadata:
tsconfig-paths: ^4.1.0
typescript: 5.9.2
ulid: ^2.3.0
whatsapp-web.js: "github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09"
whatsapp-web.js: "github:devlikeapro/whatsapp-web.js#fork-main-2025-09-10"
write-file-atomic: ^6.0.0
yaml: ^2.7.1
yargs: ^17.7.2
@@ -12603,13 +12670,13 @@ __metadata:
languageName: node
linkType: hard
"whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-06-09":
version: 1.30.1-alpha.2
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=d3c1b36c643ea671b64a1d369b6526de7ffa705a"
"whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-2025-09-10":
version: 1.34.1
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=67ed942bfa5b9bc4464d004d1691b7437ead989f"
dependencies:
"@pedroslopez/moduleraid": ^5.0.2
archiver: ^5.3.1
fluent-ffmpeg: 2.1.2
fluent-ffmpeg: 2.1.3
fs-extra: ^10.1.0
mime: ^3.0.0
node-fetch: ^2.6.9
@@ -12623,7 +12690,7 @@ __metadata:
optional: true
unzipper:
optional: true
checksum: 98e574d1e443d11c8b237392d6e66b75451061d0a489cc66bf776f52bf702c94dad9ff4d65912b69bb871e471372b8a3565b26a1d9e736aeef69c5dcba14b0db
checksum: a0852af6f93d776438db5cf8138933b241cd44a6d4a93c245e74cd587d005c08a007d73f9925d1bca8f89991a8567a3dde603d094312b82e620a7f8133c2183e
languageName: node
linkType: hard