diff --git a/src/api/controllers/chat.controller.ts b/src/api/controllers/chat.controller.ts index 1c16260d..9d22a8f0 100644 --- a/src/api/controllers/chat.controller.ts +++ b/src/api/controllers/chat.controller.ts @@ -4,6 +4,7 @@ import { BlockUserDto, DeleteMessage, getBase64FromMediaMessageDto, + MarkChatUnreadDto, NumberDto, PrivacySettingDto, ProfileNameDto, @@ -40,6 +41,11 @@ export class ChatController { return await this.waMonitor.waInstances[instanceName].archiveChat(data); } + public async markChatUnread({ instanceName }: InstanceDto, data: MarkChatUnreadDto) { + logger.verbose('requested markChatUnread from ' + instanceName + ' instance'); + return await this.waMonitor.waInstances[instanceName].markChatUnread(data); + } + public async deleteMessage({ instanceName }: InstanceDto, data: DeleteMessage) { logger.verbose('requested deleteMessage from ' + instanceName + ' instance'); return await this.waMonitor.waInstances[instanceName].deleteMessage(data); diff --git a/src/api/dto/chat.dto.ts b/src/api/dto/chat.dto.ts index 0178de2a..7952ddc6 100644 --- a/src/api/dto/chat.dto.ts +++ b/src/api/dto/chat.dto.ts @@ -73,6 +73,11 @@ export class ArchiveChatDto { archive: boolean; } +export class MarkChatUnreadDto { + lastMessage?: LastMessage; + chat?: string; +} + class PrivacySetting { readreceipts: WAReadReceiptsValue; profile: WAPrivacyValue; diff --git a/src/api/routes/chat.router.ts b/src/api/routes/chat.router.ts index e8c82a16..4debf3d1 100644 --- a/src/api/routes/chat.router.ts +++ b/src/api/routes/chat.router.ts @@ -6,6 +6,7 @@ import { blockUserSchema, contactValidateSchema, deleteMessageSchema, + markChatUnreadSchema, messageUpSchema, messageValidateSchema, presenceSchema, @@ -24,6 +25,7 @@ import { BlockUserDto, DeleteMessage, getBase64FromMediaMessageDto, + MarkChatUnreadDto, NumberDto, PrivacySettingDto, ProfileNameDto, @@ -98,6 +100,23 @@ export class ChatRouter extends RouterBroker { return res.status(HttpStatus.CREATED).json(response); }) + .put(this.routerPath('markChatUnread'), ...guards, async (req, res) => { + logger.verbose('request received in markChatUnread'); + logger.verbose('request body: '); + logger.verbose(req.body); + + logger.verbose('request query: '); + logger.verbose(req.query); + + const response = await this.dataValidate({ + request: req, + schema: markChatUnreadSchema, + ClassRef: MarkChatUnreadDto, + execute: (instance, data) => chatController.markChatUnread(instance, data), + }); + + return res.status(HttpStatus.CREATED).json(response); + }) .delete(this.routerPath('deleteMessageForEveryone'), ...guards, async (req, res) => { logger.verbose('request received in deleteMessageForEveryone'); logger.verbose('request body: '); diff --git a/src/api/services/channels/whatsapp.baileys.service.ts b/src/api/services/channels/whatsapp.baileys.service.ts index 7e2f8d88..ebf6d740 100644 --- a/src/api/services/channels/whatsapp.baileys.service.ts +++ b/src/api/services/channels/whatsapp.baileys.service.ts @@ -68,6 +68,7 @@ import { DeleteMessage, getBase64FromMediaMessageDto, LastMessage, + MarkChatUnreadDto, NumberBusiness, OnWhatsAppDto, PrivacySettingDto, @@ -2714,6 +2715,45 @@ export class BaileysStartupService extends ChannelStartupService { } } + public async markChatUnread(data: MarkChatUnreadDto) { + this.logger.verbose('Marking chat as unread'); + + try { + let last_message = data.lastMessage; + let number = data.chat; + + if (!last_message && number) { + last_message = await this.getLastMessage(number); + } else { + last_message = data.lastMessage; + last_message.messageTimestamp = last_message?.messageTimestamp ?? Date.now(); + number = last_message?.key?.remoteJid; + } + + if (!last_message || Object.keys(last_message).length === 0) { + throw new NotFoundException('Last message not found'); + } + + await this.client.chatModify( + { + markRead: false, + lastMessages: [last_message], + }, + this.createJid(number), + ); + + return { + chatId: number, + markedChatUnread: true, + }; + } catch (error) { + throw new InternalServerErrorException({ + markedChatUnread: false, + message: ['An error occurred while marked unread the chat. Open a calling.', error.toString()], + }); + } + } + public async deleteMessage(del: DeleteMessage) { this.logger.verbose('Deleting message'); try { diff --git a/src/api/services/channels/whatsapp.business.service.ts b/src/api/services/channels/whatsapp.business.service.ts index d55f72e8..09ddd2a0 100644 --- a/src/api/services/channels/whatsapp.business.service.ts +++ b/src/api/services/channels/whatsapp.business.service.ts @@ -1258,6 +1258,9 @@ export class BusinessStartupService extends ChannelStartupService { public async archiveChat() { throw new BadRequestException('Method not available on WhatsApp Business API'); } + public async markChatUnread() { + throw new BadRequestException('Method not available on WhatsApp Business API'); + } public async fetchProfile() { throw new BadRequestException('Method not available on WhatsApp Business API'); } diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 9013ca39..8f7cb1a0 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -597,6 +597,33 @@ export const archiveChatSchema: JSONSchema7 = { required: ['archive'], }; +export const markChatUnreadSchema: JSONSchema7 = { + $id: v4(), + type: 'object', + properties: { + chat: { type: 'string' }, + lastMessage: { + type: 'object', + properties: { + key: { + type: 'object', + properties: { + id: { type: 'string' }, + remoteJid: { type: 'string' }, + fromMe: { type: 'boolean', enum: [true, false] }, + }, + required: ['id', 'fromMe', 'remoteJid'], + ...isNotEmpty('id', 'remoteJid'), + }, + messageTimestamp: { type: 'integer', minLength: 1 }, + }, + required: ['key'], + ...isNotEmpty('messageTimestamp'), + }, + }, + required: ['lastMessage'], +}; + export const deleteMessageSchema: JSONSchema7 = { $id: v4(), type: 'object',