Skip to content

Commit

Permalink
[NEW] Add REST API endpoints channels.counters, `groups.counters an…
Browse files Browse the repository at this point in the history
…d `im.counters` (#9679)

* Add countVisibleByRoomIdBetweenTimestampsInclusive
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Add channels.counters, groups.counters, im.counters
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Fix spaces
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Fixes
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Small fix
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Small fix #2
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Small fix #3
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Add channels.couters and groups.couters tests
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Fix tests, last message and unread message times
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Fix last message and unread message times for IM
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Add im.counters test
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>

* Fix for msgs=0
Signed-off-by: Eugene Bolshakov <pub@relvarsoft.com>
  • Loading branch information
xbolshe authored and rodrigok committed May 18, 2018
1 parent fbe8c99 commit 9824687
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 2 deletions.
54 changes: 54 additions & 0 deletions packages/rocketchat-api/server/v1/channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,60 @@ RocketChat.API.v1.addRoute('channels.close', { authRequired: true }, {
}
});

RocketChat.API.v1.addRoute('channels.counters', { authRequired: true }, {
get() {
const access = RocketChat.authz.hasPermission(this.userId, 'view-room-administration');
const ruserId = this.requestParams().userId;
let user = this.userId;
let unreads = null;
let userMentions = null;
let unreadsFrom = null;
let joined = false;
let msgs = null;
let latest = null;
let members = null;
let lm = null;

if (ruserId) {
if (!access) {
return RocketChat.API.v1.unauthorized();
}
user = ruserId;
}
const room = findChannelByIdOrName({
params: this.requestParams(),
returnUsernames: true
});
const channel = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(room._id, user);
lm = channel._room.lm ? channel._room.lm : channel._room._updatedAt;

if (typeof channel !== 'undefined' && channel.open) {
if (channel.ls) {
unreads = RocketChat.models.Messages.countVisibleByRoomIdBetweenTimestampsInclusive(channel.rid, channel.ls, lm);
unreadsFrom = channel.ls;
}
userMentions = channel.userMentions;
joined = true;
}

if (access || joined) {
msgs = room.msgs;
latest = lm;
members = room.usernames.length;
}

return RocketChat.API.v1.success({
joined,
members,
unreads,
unreadsFrom,
msgs,
latest,
userMentions
});
}
});

// Channel -> create

function createChannelValidator(params) {
Expand Down
69 changes: 69 additions & 0 deletions packages/rocketchat-api/server/v1/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,75 @@ RocketChat.API.v1.addRoute('groups.close', { authRequired: true }, {
}
});

RocketChat.API.v1.addRoute('groups.counters', { authRequired: true }, {
get() {
const access = RocketChat.authz.hasPermission(this.userId, 'view-room-administration');
const params = this.requestParams();
let user = this.userId;
let room;
let unreads = null;
let userMentions = null;
let unreadsFrom = null;
let joined = false;
let msgs = null;
let latest = null;
let members = null;
let lm = null;

if ((!params.roomId || !params.roomId.trim()) && (!params.roomName || !params.roomName.trim())) {
throw new Meteor.Error('error-room-param-not-provided', 'The parameter "roomId" or "roomName" is required');
}

if (params.roomId) {
room = RocketChat.models.Rooms.findOneById(params.roomId);
} else if (params.roomName) {
room = RocketChat.models.Rooms.findOneByName(params.roomName);
}

if (!room || room.t !== 'p') {
throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any group');
}

if (room.archived) {
throw new Meteor.Error('error-room-archived', `The private group, ${ room.name }, is archived`);
}

if (params.userId) {
if (!access) {
return RocketChat.API.v1.unauthorized();
}
user = params.userId;
}
const group = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(room._id, user);
lm = group._room.lm ? group._room.lm : group._room._updatedAt;

if (typeof group !== 'undefined' && group.open) {
if (group.ls) {
unreads = RocketChat.models.Messages.countVisibleByRoomIdBetweenTimestampsInclusive(group.rid, group.ls, lm);
unreadsFrom = group.ls;
}
userMentions = group.userMentions;
joined = true;
}

if (access || joined) {
msgs = room.msgs;
latest = lm;
members = room.usernames.length;
}

return RocketChat.API.v1.success({
joined,
members,
unreads,
unreadsFrom,
msgs,
latest,
userMentions
});
}
});

//Create Private Group
RocketChat.API.v1.addRoute('groups.create', { authRequired: true }, {
post() {
Expand Down
52 changes: 52 additions & 0 deletions packages/rocketchat-api/server/v1/im.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,58 @@ RocketChat.API.v1.addRoute(['dm.close', 'im.close'], { authRequired: true }, {
}
});

RocketChat.API.v1.addRoute(['dm.counters', 'im.counters'], { authRequired: true }, {
get() {
const access = RocketChat.authz.hasPermission(this.userId, 'view-room-administration');
const ruserId = this.requestParams().userId;
let user = this.userId;
let unreads = null;
let userMentions = null;
let unreadsFrom = null;
let joined = false;
let msgs = null;
let latest = null;
let members = null;
let lm = null;

if (ruserId) {
if (!access) {
return RocketChat.API.v1.unauthorized();
}
user = ruserId;
}
const rs = findDirectMessageRoom(this.requestParams(), {'_id': user});
const room = rs.room;
const dm = rs.subscription;
lm = room.lm ? room.lm : room._updatedAt;

if (typeof dm !== 'undefined' && dm.open) {
if (dm.ls && room.msgs) {
unreads = dm.unread;
unreadsFrom = dm.ls;
}
userMentions = dm.userMentions;
joined = true;
}

if (access || joined) {
msgs = room.msgs;
latest = lm;
members = room.usernames.length;
}

return RocketChat.API.v1.success({
joined,
members,
unreads,
unreadsFrom,
msgs,
latest,
userMentions
});
}
});

RocketChat.API.v1.addRoute(['dm.files', 'im.files'], { authRequired: true }, {
get() {
const findResult = findDirectMessageRoom(this.requestParams(), this.user);
Expand Down
15 changes: 15 additions & 0 deletions packages/rocketchat-lib/server/models/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ RocketChat.models.Messages = new class extends RocketChat.models._Base {
this.tryEnsureIndex({ 'slackBotId': 1, 'slackTs': 1 }, { sparse: 1 });
}

countVisibleByRoomIdBetweenTimestampsInclusive(roomId, afterTimestamp, beforeTimestamp, options) {
const query = {
_hidden: {
$ne: true
},
rid: roomId,
ts: {
$gte: afterTimestamp,
$lte: beforeTimestamp
}
};

return this.find(query, options).count();
}

// FIND
findByMention(username, options) {
const query = {'mentions.username': username};
Expand Down
21 changes: 20 additions & 1 deletion tests/end-to-end/api/02-channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,26 @@ describe('[Channels]', function() {
})
.end(done);
});

it('/channels.counters', (done) => {
request.get(api('channels.counters'))
.set(credentials)
.query({
roomId: channel._id
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('joined', true);
expect(res.body).to.have.property('members');
expect(res.body).to.have.property('unreads');
expect(res.body).to.have.property('unreadsFrom');
expect(res.body).to.have.property('msgs');
expect(res.body).to.have.property('latest');
expect(res.body).to.have.property('userMentions');
})
.end(done);
});
it('/channels.members', (done) => {
request.get(api('channels.members'))
.set(credentials)
Expand Down
23 changes: 22 additions & 1 deletion tests/end-to-end/api/03-groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function getRoomInfo(roomId) {
});
}

describe('groups', function() {
describe('[Groups]', function() {
this.retries(0);

before(done => getCredentials(done));
Expand Down Expand Up @@ -343,6 +343,27 @@ describe('groups', function() {
.end(done);
});

it('/groups.counters', (done) => {
request.get(api('groups.counters'))
.set(credentials)
.query({
roomId: group._id
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('joined', true);
expect(res.body).to.have.property('members');
expect(res.body).to.have.property('unreads');
expect(res.body).to.have.property('unreadsFrom');
expect(res.body).to.have.property('msgs');
expect(res.body).to.have.property('latest');
expect(res.body).to.have.property('userMentions');
})
.end(done);
});

it('/groups.rename', async(done) => {
const roomInfo = await getRoomInfo(group._id);

Expand Down
21 changes: 21 additions & 0 deletions tests/end-to-end/api/04-direct-message.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,27 @@ describe('[Direct Messages]', function() {
.end(done);
});

it('/im.counters', (done) => {
request.get(api('im.counters'))
.set(credentials)
.query({
roomId: directMessage._id
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.property('joined', true);
expect(res.body).to.have.property('members');
expect(res.body).to.have.property('unreads');
expect(res.body).to.have.property('unreadsFrom');
expect(res.body).to.have.property('msgs');
expect(res.body).to.have.property('latest');
expect(res.body).to.have.property('userMentions');
})
.end(done);
});

it('/im.close', (done) => {
request.post(api('im.close'))
.set(credentials)
Expand Down

0 comments on commit 9824687

Please sign in to comment.