Skip to content

Commit 6ee1454

Browse files
committed
feat(backend): expose read count to clients
1 parent 58aff13 commit 6ee1454

4 files changed

Lines changed: 81 additions & 0 deletions

File tree

apps/meteor/app/api/server/v1/chat.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
isChatSyncThreadMessagesProps,
3030
isChatGetStarredMessagesProps,
3131
isChatGetDiscussionsProps,
32+
isChatGetMessageReadCountProps,
3233
validateBadRequestErrorResponse,
3334
validateUnauthorizedErrorResponse,
3435
} from '@rocket.chat/rest-typings';
@@ -48,6 +49,7 @@ import { processWebhookMessage } from '../../../lib/server/functions/processWebh
4849
import { getSingleMessage } from '../../../lib/server/methods/getSingleMessage';
4950
import { executeSendMessage } from '../../../lib/server/methods/sendMessage';
5051
import { executeUpdateMessage } from '../../../lib/server/methods/updateMessage';
52+
import { getMessageReadCount as getMessageReadCountHelper } from '../../../read-counter/server/getMessageReadCount';
5153
import { applyAirGappedRestrictionsValidation } from '../../../license/server/airGappedRestrictionsWrapper';
5254
import { pinMessage, unpinMessage } from '../../../message-pin/server/pinMessage';
5355
import { starMessage } from '../../../message-star/server/starMessage';
@@ -174,6 +176,37 @@ API.v1.addRoute(
174176
},
175177
);
176178

179+
API.v1.addRoute(
180+
'chat.getMessageReadCount',
181+
{
182+
authRequired: true,
183+
validateParams: isChatGetMessageReadCountProps,
184+
},
185+
{
186+
async get() {
187+
const { messageId } = this.queryParams;
188+
189+
const message = await Messages.findOneById(messageId, { projection: { rid: 1 } });
190+
191+
if (!message) {
192+
return API.v1.failure('The required "messageId" param is missing or invalid.');
193+
}
194+
195+
if (!(await canAccessRoomIdAsync(message.rid, this.userId))) {
196+
throw new Meteor.Error('error-not-allowed', 'Not allowed');
197+
}
198+
199+
const result = await getMessageReadCountHelper(messageId, this.userId);
200+
201+
if (!result) {
202+
return API.v1.failure();
203+
}
204+
205+
return API.v1.success(result);
206+
},
207+
},
208+
);
209+
177210
type ChatPinMessage = {
178211
messageId: IMessage['_id'];
179212
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { IMessage } from '@rocket.chat/core-typings';
2+
import type { ServerMethods } from '@rocket.chat/ddp-client';
3+
import { check } from 'meteor/check';
4+
import { Meteor } from 'meteor/meteor';
5+
6+
import { getMessageReadCount as getMessageReadCountHelper } from '../../app/read-counter/server/getMessageReadCount';
7+
8+
declare module '@rocket.chat/ddp-client' {
9+
// eslint-disable-next-line @typescript-eslint/naming-convention
10+
interface ServerMethods {
11+
getMessageReadCount(options: { messageId: IMessage['_id'] }): { readCount: number } | null;
12+
}
13+
}
14+
15+
Meteor.methods<ServerMethods>({
16+
async getMessageReadCount({ messageId }) {
17+
check(messageId, String);
18+
19+
const uid = Meteor.userId();
20+
if (!uid) {
21+
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getMessageReadCount' });
22+
}
23+
24+
return getMessageReadCountHelper(messageId, uid);
25+
},
26+
});
27+

apps/meteor/server/methods/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import './createDirectMessage';
1313
import './deleteFileMessage';
1414
import './deleteUser';
1515
import './getAvatarSuggestion';
16+
import './getMessageReadCount';
1617
import './getRoomById';
1718
import './getRoomIdByNameOrId';
1819
import './getRoomNameById';

packages/rest-typings/src/v1/chat.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,23 @@ const ChatGetMessageReadReceiptsSchema = {
574574

575575
export const isChatGetMessageReadReceiptsProps = ajv.compile<ChatGetMessageReadReceipts>(ChatGetMessageReadReceiptsSchema);
576576

577+
type ChatGetMessageReadCount = {
578+
messageId: IMessage['_id'];
579+
};
580+
581+
const ChatGetMessageReadCountSchema = {
582+
type: 'object',
583+
properties: {
584+
messageId: {
585+
type: 'string',
586+
},
587+
},
588+
required: ['messageId'],
589+
additionalProperties: false,
590+
};
591+
592+
export const isChatGetMessageReadCountProps = ajv.compile<ChatGetMessageReadCount>(ChatGetMessageReadCountSchema);
593+
577594
type GetStarredMessages = {
578595
roomId: IRoom['_id'];
579596
count?: number;
@@ -1054,6 +1071,9 @@ export type ChatEndpoints = {
10541071
'/v1/chat.getMessageReadReceipts': {
10551072
GET: (params: ChatGetMessageReadReceipts) => { receipts: IReadReceiptWithUser[] };
10561073
};
1074+
'/v1/chat.getMessageReadCount': {
1075+
GET: (params: ChatGetMessageReadCount) => { readCount: number };
1076+
};
10571077
'/v1/chat.getStarredMessages': {
10581078
GET: (params: GetStarredMessages) => {
10591079
messages: IMessage[];

0 commit comments

Comments
 (0)