fix(NOWEB): archive/unread chat without recent message (closes #2258, fixes #2181)

Co-Authored-By: Poorvaja <poorvaja.s@outlook.com>
This commit is contained in:
devlikeproandPoorvaja committed 2026-09-11 11:27:09 +07:00
1 parent f51a14eaeb
commit 254906cf4c
3 files changed
+60 -2

No files matched your search

@@ -0,0 +1,12 @@
import { UnprocessableEntityException } from '@nestjs/common';
export class NoLastMessageInChatException extends UnprocessableEntityException {
constructor(chatId: string) {
super(
`No recent message found in chat '${chatId}' to modify it. ` +
'Enable NOWEB store with "config.noweb.store.full_sync=True" when starting a new session, ' +
'or wait for a message in the chat and try again. ' +
'Read more: https://waha.devlike.pro/docs/engines/noweb#store',
);
}
}
@@ -67,6 +67,7 @@ import {
} from '@waha/core/engines/noweb/noweb.newsletter';
import { NowebAuthFactoryCore } from '@waha/core/engines/noweb/NowebAuthFactoryCore';
import { NowebInMemoryStore } from '@waha/core/engines/noweb/store/NowebInMemoryStore';
import { NoLastMessageInChatException } from '@waha/core/engines/noweb/noweb.exceptions';
import { NotImplementedByEngineError } from '@waha/core/exceptions';
import { toVcardV3 } from '@waha/core/vcard';
import { createAgentProxy } from '@waha/core/helpers.proxy';
@@ -1863,6 +1864,9 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
): Promise<any> {
const jid = await this.hooks.wid.chat.promise(chatId, 'chatsPutArchive');
const messages = await this.store.getMessagesByJid(jid, {}, { limit: 1 });
if (messages.length === 0) {
throw new NoLastMessageInChatException(chatId);
}
return await this.sock.chatModify(
{ archive: archive, lastMessages: messages },
jid,
@@ -1883,6 +1887,9 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
public async chatsUnreadChat(chatId: string): Promise<any> {
const jid = await this.hooks.wid.chat.promise(chatId, 'chatsUnreadChat');
const messages = await this.store.getMessagesByJid(jid, {}, { limit: 1 });
if (messages.length === 0) {
throw new NoLastMessageInChatException(chatId);
}
return await this.sock.chatModify(
{ markRead: false, lastMessages: messages },
jid,
@@ -2,6 +2,7 @@ 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 { AckToStatus } from '@waha/core/utils/acks';
import {
GetChatMessagesFilter,
OverviewFilter,
@@ -10,8 +11,10 @@ import { LidToPhoneNumber } from '@waha/structures/lids.dto';
import {
LimitOffsetParams,
PaginationParams,
SortOrder,
} from '@waha/structures/pagination.dto';
import { PaginatorInMemory } from '@waha/utils/Paginator';
import * as lodash from 'lodash';
import { INowebStore } from './INowebStore';
import makeInMemoryStore from './memory/make-in-memory-store';
@@ -56,13 +59,49 @@ export class NowebInMemoryStore implements INowebStore {
return this.store.loadMessage(jid, id);
}
getMessagesByJid(
async getMessagesByJid(
chatId: string,
filter: GetChatMessagesFilter,
pagination: PaginationParams,
merge?: boolean,
): Promise<any> {
throw new BadRequestException(this.errorMessage);
let messages = await this.store.loadMessages(
chatId,
Number.MAX_SAFE_INTEGER,
undefined,
);
const lte = filter['filter.timestamp.lte'];
const gte = filter['filter.timestamp.gte'];
const fromMe = filter['filter.fromMe'];
const ack = filter['filter.ack'];
messages = messages.filter((msg) => {
const timestamp = lodash.toNumber(msg.messageTimestamp as any);
if (lte != null && timestamp > lte) {
return false;
}
if (gte != null && timestamp < gte) {
return false;
}
if (fromMe != null && msg.key.fromMe !== fromMe) {
return false;
}
if (ack != null && msg.status !== AckToStatus(ack)) {
return false;
}
return true;
});
// Newest first by default, same as the persistent store
const order = pagination.sortOrder || SortOrder.DESC;
messages = lodash.orderBy(
messages,
[(msg) => lodash.toNumber(msg.messageTimestamp as any)],
[order],
);
const paginator = new PaginatorInMemory({
limit: pagination.limit,
offset: pagination.offset,
});
return paginator.apply(messages);
}
getMessageById(