Skip to content
Snippets Groups Projects
unreadMessages.ts 2.31 KiB
Newer Older
import type { IMessage, IRoom } from '@rocket.chat/core-typings';
import { Messages, Subscriptions } from '@rocket.chat/models';
import type { ServerMethods } from '@rocket.chat/ui-contexts';
import { Meteor } from 'meteor/meteor';
import logger from './logger';
declare module '@rocket.chat/ui-contexts' {
	// eslint-disable-next-line @typescript-eslint/naming-convention
	interface ServerMethods {
		unreadMessages(firstUnreadMessage?: IMessage, room?: IRoom['_id']): void;
	}
}

Meteor.methods<ServerMethods>({
	async unreadMessages(firstUnreadMessage, room) {
		const userId = Meteor.userId();
		if (!userId) {
			throw new Meteor.Error('error-invalid-user', 'Invalid user', {
				method: 'unreadMessages',
Diego Sampaio's avatar
Diego Sampaio committed
		if (room && typeof room === 'string') {
			const lastMessage = (
				await Messages.findVisibleByRoomId(room, {
					limit: 1,
					sort: { ts: -1 },
				}).toArray()
			)[0];
				throw new Meteor.Error('error-no-message-for-unread', 'There are no messages to mark unread', {
					method: 'unreadMessages',
					action: 'Unread_messages',
			await Subscriptions.setAsUnreadByRoomIdAndUserId(lastMessage.rid, userId, lastMessage.ts);
			return;
Diego Sampaio's avatar
Diego Sampaio committed
		if (typeof firstUnreadMessage?._id !== 'string') {
			throw new Meteor.Error('error-action-not-allowed', 'Not allowed', {
				method: 'unreadMessages',
				action: 'Unread_messages',
			});
		}

		const originalMessage = await Messages.findOneById(firstUnreadMessage._id, {
			projection: {
		if (!originalMessage || userId === originalMessage.u._id) {
			throw new Meteor.Error('error-action-not-allowed', 'Not allowed', {
				method: 'unreadMessages',
				action: 'Unread_messages',
		const lastSeen = (await Subscriptions.findOneByRoomIdAndUserId(originalMessage.rid, userId))?.ls;
		if (!lastSeen) {
			throw new Meteor.Error('error-subscription-not-found', 'Subscription not found', {
				method: 'unreadMessages',
				action: 'Unread_messages',
			});
		}

		if (firstUnreadMessage.ts >= lastSeen) {
			return logger.debug('Provided message is already marked as unread');
		logger.debug(`Updating unread  message of ${originalMessage.ts} as the first unread`);
		await Subscriptions.setAsUnreadByRoomIdAndUserId(originalMessage.rid, userId, originalMessage.ts);