Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/stupid-rats-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rocket.chat/apps-engine': minor
'@rocket.chat/meteor': minor
---

Adds a filter option to include or exclude threads in the Apps Engine room read/unread messages bridge, enhancing flexibility in message retrieval.
21 changes: 16 additions & 5 deletions apps/meteor/app/apps/server/bridges/rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,15 @@ export class AppRoomBridge extends RoomBridge {
protected async getMessages(roomId: string, options: GetMessagesOptions, appId: string): Promise<IMessageRaw[]> {
this.orch.debugLog(`The App ${appId} is getting the messages of the room: "${roomId}" with options:`, options);

const { limit, skip = 0, sort: _sort } = options;
const { limit, skip = 0, sort: _sort, showThreadMessages } = options;

const messageConverter = this.orch.getConverters()?.get('messages');
if (!messageConverter) {
throw new Error('Message converter not found');
}

const threadFilterQuery = showThreadMessages ? {} : { tmid: { $exists: false } };

// We support only one field for now
const sort: Sort | undefined = _sort?.createdAt ? { ts: _sort.createdAt } : undefined;

Expand All @@ -128,6 +130,7 @@ export class AppRoomBridge extends RoomBridge {
rid: roomId,
_hidden: { $ne: true },
t: { $exists: false },
...threadFilterQuery,
};

const cursor = Messages.find(query, messageQueryOptions);
Expand Down Expand Up @@ -268,10 +271,18 @@ export class AppRoomBridge extends RoomBridge {

const sort: Sort = options.sort?.createdAt ? { ts: options.sort.createdAt } : { ts: 1 };

const cursor = Messages.findVisibleByRoomIdBetweenTimestampsNotContainingTypes(roomId, lastSeen, new Date(), [], {
...options,
sort,
});
const cursor = Messages.findVisibleByRoomIdBetweenTimestampsNotContainingTypes(
roomId,
lastSeen,
new Date(),
[],
{
limit: options.limit,
skip: options.skip,
sort,
},
options.showThreadMessages,
);

const messages = await cursor.toArray();
return Promise.all(messages.map((msg) => messageConverter.convertMessageRaw(msg)));
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/app/apps/server/converters/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export class AppMessagesConverter {
editor: 'editedBy',
attachments: getAttachments,
sender: 'u',
threadMsgCount: 'tcount',
};

return transformMappedData(message, map);
Expand Down
2 changes: 2 additions & 0 deletions packages/apps-engine/src/definition/accessors/IRoomRead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface IRoomRead {
* - limit: The maximum number of messages to retrieve. Maximum 100
* - skip: The number of messages to skip (for pagination).
* - sort: An object defining the sorting order of the messages. Each key is a field to sort by, and the value is either "asc" for ascending order or "desc" for descending order.
* - showThreadMessages: Whether to include thread messages in the results. Defaults to true.
* @returns A Promise that resolves to an array of IMessage objects representing the messages in the room.
*/
getMessages(roomId: string, options?: Partial<GetMessagesOptions>): Promise<Array<IMessageRaw>>;
Expand Down Expand Up @@ -100,6 +101,7 @@ export interface IRoomRead {
* - limit: The maximum number of messages to retrieve. If more than 100 is passed, it defaults to 100.
* - skip: The number of messages to skip (for pagination).
* - sort: An object defining the sorting order of the messages. Each key is a field to sort by, and the value is either 'asc' for ascending order or 'desc' for descending order.
* - showThreadMessages: Whether to include thread messages in the results. Defaults to true.
* @returns A Promise that resolves to an array of IMessage objects representing the unread messages for the specified user in the specified room.
*/
getUnreadByUser(roomId: string, uid: string, options?: Partial<GetMessagesOptions>): Promise<IMessageRaw[]>;
Expand Down
5 changes: 3 additions & 2 deletions packages/apps-engine/src/server/accessors/RoomRead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class RoomRead implements IRoomRead {
}

options.limit ??= 100;
options.showThreadMessages ??= true;

if (options.sort) {
this.validateSort(options.sort);
Expand Down Expand Up @@ -62,7 +63,7 @@ export class RoomRead implements IRoomRead {
}

public async getUnreadByUser(roomId: string, uid: string, options: Partial<GetMessagesOptions> = {}): Promise<IMessageRaw[]> {
const { limit = 100, sort = { createdAt: 'asc' }, skip = 0 } = options;
const { limit = 100, sort = { createdAt: 'asc' }, skip = 0, showThreadMessages = true } = options;

if (typeof roomId !== 'string' || roomId.trim().length === 0) {
throw new Error('Invalid roomId: must be a non-empty string');
Expand All @@ -74,7 +75,7 @@ export class RoomRead implements IRoomRead {

this.validateSort(sort);

const completeOptions: GetMessagesOptions = { limit, sort, skip };
const completeOptions: GetMessagesOptions = { limit, sort, skip, showThreadMessages };

return this.roomBridge.doGetUnreadByUser(roomId, uid, completeOptions, this.appId);
}
Expand Down
1 change: 1 addition & 0 deletions packages/apps-engine/src/server/bridges/RoomBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type GetMessagesOptions = {
limit: number;
skip: number;
sort: Record<(typeof GetMessagesSortableFields)[number], 'asc' | 'desc'>;
showThreadMessages: boolean;
};

export abstract class RoomBridge extends BaseBridge {
Expand Down
Loading