diff --git a/packages/rocketchat-api/server/v1/chat.js b/packages/rocketchat-api/server/v1/chat.js index e05464877222..5bf1bf084533 100644 --- a/packages/rocketchat-api/server/v1/chat.js +++ b/packages/rocketchat-api/server/v1/chat.js @@ -28,6 +28,31 @@ RocketChat.API.v1.addRoute('chat.delete', { authRequired: true }, { } }); +RocketChat.API.v1.addRoute('chat.syncMessages', { authRequired: true }, { + get() { + const { rid } = this.queryParams; + let lastUpdate = this.queryParams; + lastUpdate = lastUpdate ? new Date(lastUpdate) : lastUpdate; + if (!rid) { + return RocketChat.API.v1.failure('The "rid" query parameter must be provided.'); + } + if (!lastUpdate) { + return RocketChat.API.v1.failure('The "lastUpdate" query parameter must be provided.'); + } + + let result; + Meteor.runAsUser(this.userId, () => { + result = Meteor.call('messages/get', rid, { lastUpdate }); + }); + + if (!result) { + return RocketChat.API.v1.failure(); + } + + return RocketChat.API.v1.success({result}); + } +}); + RocketChat.API.v1.addRoute('chat.getMessage', { authRequired: true }, { get() { if (!this.queryParams.msgId) { diff --git a/packages/rocketchat-lib/server/models/Messages.js b/packages/rocketchat-lib/server/models/Messages.js index db6036bb07dc..f93d03ae64e2 100644 --- a/packages/rocketchat-lib/server/models/Messages.js +++ b/packages/rocketchat-lib/server/models/Messages.js @@ -89,6 +89,19 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base { return this.find(query, options); } + findForUpdates(roomId, timestamp, options) { + const query = { + _hidden: { + $ne: true + }, + rid: roomId, + _updatedAt: { + $gt: timestamp + } + }; + return this.find(query, options); + } + findVisibleByRoomIdBeforeTimestamp(roomId, timestamp, options) { const query = { _hidden: { diff --git a/server/publications/messages.js b/server/publications/messages.js index 66b1029b9f9a..d2f830987b23 100644 --- a/server/publications/messages.js +++ b/server/publications/messages.js @@ -63,3 +63,39 @@ Meteor.publish('messages', function(rid/*, start*/) { return cursorDeleteHandle.stop(); }); }); + +Meteor.methods({ + 'messages/get'(rid, {lastUpdate, latestDate = new Date(), oldestDate, inclusive = false, count = 20, unreads= false}) { + check(rid, String); + + const fromId = Meteor.userId(); + + if (!fromId) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'messages/get' + }); + } + + if (!Meteor.call('canAccessRoom', rid, fromId)) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { + method: 'messages/get' + }); + } + + const options = { + sort: { + ts: -1 + } + }; + + if (lastUpdate instanceof Date) { + return { + updated: RocketChat.models.Messages.findForUpdates(rid, lastUpdate, options).fetch(), + deleted: RocketChat.models.Messages.trashFindDeletedAfter(lastUpdate, {rid}, { ...options, fields: { _id: 1, _deletedAt: 1 }}).fetch() + }; + } + + return Meteor.call('getChannelHistory', { rid, latest: latestDate, oldest: oldestDate, inclusive, count, unreads }); + + } +});