Skip to content

Commit

Permalink
Add a messages endpoint which supports pagination like the other endp…
Browse files Browse the repository at this point in the history
…oints. Rework the direct messages endpoints to support username instead of room id
  • Loading branch information
graywolf336 committed Aug 17, 2017
1 parent 1914d7a commit ae87222
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 45 deletions.
2 changes: 1 addition & 1 deletion packages/rocketchat-api/server/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class API extends Restivus {
endpoints[method] = { action: endpoints[method] };
}

//Add a try/catch for each much
//Add a try/catch for each endpoint
const originalAction = endpoints[method].action;
endpoints[method].action = function() {
this.logger.debug(`${ this.request.method.toUpperCase() }: ${ this.request.url }`);
Expand Down
31 changes: 31 additions & 0 deletions packages/rocketchat-api/server/v1/channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,37 @@ RocketChat.API.v1.addRoute('channels.list.joined', { authRequired: true }, {
}
});

RocketChat.API.v1.addRoute('channels.messages', { authRequired: true }, {
get() {
const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false });
const { offset, count } = this.getPaginationItems();
const { sort, fields, query } = this.parseJsonQuery();

const ourQuery = Object.assign({}, query, { rid: findResult._id });

//Special check for the permissions
if (RocketChat.authz.hasPermission(this.userId, 'view-joined-room') && !findResult.usernames.includes(this.user.username)) {
return RocketChat.API.v1.unauthorized();
} else if (!RocketChat.authz.hasPermission(this.userId, 'view-c-room')) {
return RocketChat.API.v1.unauthorized();
}

const messages = RocketChat.models.Messages.find(ourQuery, {
sort: sort ? sort : { ts: -1 },
skip: offset,
limit: count,
fields: Object.assign({}, fields, RocketChat.API.v1.defaultFieldsToExclude)
}).fetch();

return RocketChat.API.v1.success({
messages,
count: messages.length,
offset,
total: RocketChat.models.Messages.find(ourQuery).count()
});
}
});

RocketChat.API.v1.addRoute('channels.online', { authRequired: true }, {
get() {
const { query } = this.parseJsonQuery();
Expand Down
24 changes: 24 additions & 0 deletions packages/rocketchat-api/server/v1/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,30 @@ RocketChat.API.v1.addRoute('groups.list', { authRequired: true }, {
}
});

RocketChat.API.v1.addRoute('groups.messages', { authRequired: true }, {
get() {
const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId });
const { offset, count } = this.getPaginationItems();
const { sort, fields, query } = this.parseJsonQuery();

const ourQuery = Object.assign({}, query, { rid: findResult.rid });

const messages = RocketChat.models.Messages.find(ourQuery, {
sort: sort ? sort : { ts: -1 },
skip: offset,
limit: count,
fields: Object.assign({}, fields, RocketChat.API.v1.defaultFieldsToExclude)
}).fetch();

return RocketChat.API.v1.success({
messages,
count: messages.length,
offset,
total: RocketChat.models.Messages.find(ourQuery).count()
});
}
});

RocketChat.API.v1.addRoute('groups.online', { authRequired: true }, {
get() {
const { query } = this.parseJsonQuery();
Expand Down
115 changes: 71 additions & 44 deletions packages/rocketchat-api/server/v1/im.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,46 @@
function findDirectMessageRoomById(roomId, userId) {
if (!roomId || !roomId.trim()) {
return RocketChat.API.v1.failure('Body param "roomId" is required');
function findDirectMessageRoom(params, user) {
if ((!params.roomId || !params.roomId.trim()) && (!params.username || !params.username.trim())) {
throw new Meteor.Error('error-room-param-not-provided', 'Body param "roomId" or "username" is required');
}

const roomSub = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(roomId, userId);
const room = RocketChat.getRoomByNameOrIdWithOptionToJoin({
currentUserId: user._id,
nameOrId: params.username || params.roomId,
type: 'd'
});

if (!roomSub || roomSub.t !== 'd') {
return RocketChat.API.v1.failure(`No direct message room found by the id of: ${ roomId }`);
if (!room || room.t !== 'd') {
throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "username" param provided does not match any dirct message');
}

return roomSub;
const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(room._id, user._id);

return {
room,
subscription
};
}

RocketChat.API.v1.addRoute(['dm.close', 'im.close'], { authRequired: true }, {
RocketChat.API.v1.addRoute(['dm.create', 'im.create'], { authRequired: true }, {
post() {
const findResult = findDirectMessageRoomById(this.bodyParams.roomId, this.userId);
const findResult = findDirectMessageRoom(this.requestParams(), this.user);

//The find method returns either with the dm or the failure
if (findResult.statusCode) {
return findResult;
}
return RocketChat.API.v1.success({
room: findResult.room
});
}
});

RocketChat.API.v1.addRoute(['dm.close', 'im.close'], { authRequired: true }, {
post() {
const findResult = findDirectMessageRoom(this.requestParams(), this.user);

if (!findResult.open) {
if (!findResult.subscription.open) {
return RocketChat.API.v1.failure(`The direct message room, ${ this.bodyParams.name }, is already closed to the sender`);
}

Meteor.runAsUser(this.userId, () => {
Meteor.call('hideRoom', findResult.rid);
Meteor.call('hideRoom', findResult.room._id);
});

return RocketChat.API.v1.success();
Expand All @@ -35,17 +49,12 @@ RocketChat.API.v1.addRoute(['dm.close', 'im.close'], { authRequired: true }, {

RocketChat.API.v1.addRoute(['dm.files', 'im.files'], { authRequired: true }, {
get() {
const findResult = findDirectMessageRoomById(this.bodyParams.roomId, this.userId);

//The find method returns either with the dm or the failure
if (findResult.statusCode) {
return findResult;
}
const findResult = findDirectMessageRoom(this.requestParams(), this.user);

const { offset, count } = this.getPaginationItems();
const { sort, fields, query } = this.parseJsonQuery();

const ourQuery = Object.assign({}, query, { rid: findResult._id });
const ourQuery = Object.assign({}, query, { rid: findResult.room._id });

const files = RocketChat.models.Uploads.find(ourQuery, {
sort: sort ? sort : { name: 1 },
Expand All @@ -65,12 +74,7 @@ RocketChat.API.v1.addRoute(['dm.files', 'im.files'], { authRequired: true }, {

RocketChat.API.v1.addRoute(['dm.history', 'im.history'], { authRequired: true }, {
get() {
const findResult = findDirectMessageRoomById(this.queryParams.roomId, this.userId);

//The find method returns either with the group or the failure
if (findResult.statusCode) {
return findResult;
}
const findResult = findDirectMessageRoom(this.requestParams(), this.user);

let latestDate = new Date();
if (this.queryParams.latest) {
Expand Down Expand Up @@ -99,7 +103,14 @@ RocketChat.API.v1.addRoute(['dm.history', 'im.history'], { authRequired: true },

let result;
Meteor.runAsUser(this.userId, () => {
result = Meteor.call('getChannelHistory', { rid: findResult.rid, latest: latestDate, oldest: oldestDate, inclusive, count, unreads });
result = Meteor.call('getChannelHistory', {
rid: findResult.room._id,
latest: latestDate,
oldest: oldestDate,
inclusive,
count,
unreads
});
});

return RocketChat.API.v1.success({
Expand All @@ -108,6 +119,32 @@ RocketChat.API.v1.addRoute(['dm.history', 'im.history'], { authRequired: true },
}
});

RocketChat.API.v1.addRoute(['dm.messages', 'im.messages'], { authRequired: true }, {
get() {
const findResult = findDirectMessageRoom(this.requestParams(), this.user);

const { offset, count } = this.getPaginationItems();
const { sort, fields, query } = this.parseJsonQuery();

console.log(findResult);
const ourQuery = Object.assign({}, query, { rid: findResult.room._id });

const messages = RocketChat.models.Messages.find(ourQuery, {
sort: sort ? sort : { ts: -1 },
skip: offset,
limit: count,
fields: Object.assign({}, fields, RocketChat.API.v1.defaultFieldsToExclude)
}).fetch();

return RocketChat.API.v1.success({
messages,
count: messages.length,
offset,
total: RocketChat.models.Messages.find(ourQuery).count()
});
}
});

RocketChat.API.v1.addRoute(['dm.messages.others', 'im.messages.others'], { authRequired: true }, {
get() {
if (RocketChat.settings.get('API_Enable_Direct_Message_History_EndPoint') !== true) {
Expand Down Expand Up @@ -200,19 +237,14 @@ RocketChat.API.v1.addRoute(['dm.list.everyone', 'im.list.everyone'], { authRequi

RocketChat.API.v1.addRoute(['dm.open', 'im.open'], { authRequired: true }, {
post() {
const findResult = findDirectMessageRoomById(this.bodyParams.roomId, this.userId);
const findResult = findDirectMessageRoom(this.requestParams(), this.user);

//The find method returns either with the group or the failure
if (findResult.statusCode) {
return findResult;
}

if (findResult.open) {
if (findResult.subscription.open) {
return RocketChat.API.v1.failure(`The direct message room, ${ this.bodyParams.name }, is already open for the sender`);
}

Meteor.runAsUser(this.userId, () => {
Meteor.call('openRoom', findResult.rid);
Meteor.call('openRoom', findResult.room._id);
});

return RocketChat.API.v1.success();
Expand All @@ -225,15 +257,10 @@ RocketChat.API.v1.addRoute(['dm.setTopic', 'im.setTopic'], { authRequired: true
return RocketChat.API.v1.failure('The bodyParam "topic" is required');
}

const findResult = findDirectMessageRoomById(this.bodyParams.roomId, this.userId);

//The find method returns either with the group or the failure
if (findResult.statusCode) {
return findResult;
}
const findResult = findDirectMessageRoom(this.requestParams(), this.user);

Meteor.runAsUser(this.userId, () => {
Meteor.call('saveRoomSettings', findResult.rid, 'roomTopic', this.bodyParams.topic);
Meteor.call('saveRoomSettings', findResult.room._id, 'roomTopic', this.bodyParams.topic);
});

return RocketChat.API.v1.success({
Expand Down

0 comments on commit ae87222

Please sign in to comment.