ac-node-hipchat
Version:
A common module plugin for building Atlassian Connect add-ons for HipChat
454 lines (407 loc) • 17.4 kB
JavaScript
var _ = require('lodash');
var rsvp = require('rsvp');
var Promise = rsvp.Promise;
var check = require('check-types');
var verify = check.verify;
var param = encodeURIComponent;
function TenantClient(restClient, tenant, cache, scopes) {
verify.object(restClient);
verify.object(tenant);
verify.object(cache);
verify.maybe.array(scopes);
this._client = restClient;
this._tenant = tenant;
this._cache = cache;
this._scopes = scopes || [];
}
TenantClient.prototype.getEmoticons = function (options) {
var self = this;
var resourceUrl = this._tenant.links.api + '/emoticon';
return self.getToken('view_group').then(function (token) {
return self._client.getEmoticons(resourceUrl, token, options);
});
};
TenantClient.prototype.getEmoticon = function (emoticonIdOrShortcut, options) {
var self = this;
exports.verifyNumberOrString('emoticonIdOrShortcut', emoticonIdOrShortcut);
var resourceUrl = this._tenant.links.api + '/emoticon/' + param(emoticonIdOrShortcut);
return self.getToken('view_group').then(function (token) {
return self._client.getEmoticon(resourceUrl, token, options);
});
};
TenantClient.prototype.deleteSession = function (sessionId) {
var self = this;
verify.string(sessionId);
var resourceUrl = this._tenant.links.api + '/oauth/token/' + param(sessionId);
return self._client.deleteSession(resourceUrl, sessionId);
};
TenantClient.prototype.getSession = function (sessionId) {
var self = this;
verify.string(sessionId);
var resourceUrl = this._tenant.links.api + '/oauth/token/' + param(sessionId);
return self._client.getSession(resourceUrl, sessionId);
};
TenantClient.prototype.getToken = function () {
var self = this;
var scopes = [].slice.call(arguments);
if (scopes.length === 0) {
throw new Error('At least one scope is required when generating a token');
}
self._ensureScopes(scopes);
var cacheKey = (scopes || []).join('|');
return self._cache.get(cacheKey).then(function (tokenData) {
if (tokenData) return tokenData;
var tokenUrl = self._tenant.links.token;
var username = self._tenant.id;
var password = self._tenant.secret;
return self._client.generateToken(tokenUrl, username, password, scopes).then(function (freshTokenData) {
return self._cache.set(cacheKey, freshTokenData, freshTokenData.expires_in - 60).then(function () {
return freshTokenData;
});
});
}).then(function (tokenData) {
return tokenData.access_token;
});
};
TenantClient.prototype.getRoomMessage = function (roomIdOrName, messageId, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
verify.string(messageId);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/history/' + param(messageId);
return self.getToken('view_messages').then(function (token) {
return self._client.getRoomMessage(resourceUrl, token, options);
});
};
// TODO: share file with room
TenantClient.prototype.createRoom = function (room, options) {
var self = this;
verify.object(room);
var resourceUrl = this._tenant.links.api + '/room';
return self.getToken('manage_rooms').then(function (token) {
return self._client.createRoom(resourceUrl, token, room);
});
};
TenantClient.prototype.getRooms = function (options) {
var self = this;
var resourceUrl = this._tenant.links.api + '/room';
return self.getToken('view_group').then(function (token) {
return self._client.getRooms(resourceUrl, token, options);
});
};
TenantClient.prototype.getRecentRoomHistory = function (roomIdOrName, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/history/latest';
return self.getToken('view_messages').then(function (token) {
return self._client.getRecentRoomHistory(resourceUrl, token, options);
});
};
TenantClient.prototype.sendNotification = function (roomIdOrName, message, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
verify.string(message);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/notification';
return self.getToken('send_notification').then(function (token) {
return self._client.sendNotification(resourceUrl, token, message, options);
});
};
TenantClient.prototype.updateRoom = function (roomIdOrName, room) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
verify.object(room);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName);
return self.getToken('admin_room').then(function (token) {
return self._client.updateRoom(resourceUrl, token, room);
});
};
TenantClient.prototype.getRoom = function (roomIdOrName, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName);
return self.getToken('view_group').then(function (token) {
return self._client.getRoom(resourceUrl, token, options);
});
};
TenantClient.prototype.deleteRoom = function (roomIdOrName) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName);
return self.getToken('manage_rooms').then(function (token) {
return self._client.deleteRoom(resourceUrl, token);
});
};
TenantClient.prototype.createRoomWebhook = TenantClient.prototype.createWebhook = function (roomIdOrName, webhook) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
verify.object(webhook);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/webhook';
return self.getToken('admin_room').then(function (token) {
return self._client.createRoomWebhook(resourceUrl, token, webhook);
});
};
TenantClient.prototype.getRoomWebhooks = TenantClient.prototype.getWebhooks = function (roomIdOrName, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/webhook';
return self.getToken('admin_room').then(function (token) {
return self._client.getRoomWebhooks(resourceUrl, token, options);
});
};
TenantClient.prototype.getRoomStatistics = function (roomIdOrName, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/statistics';
return self.getToken('view_group').then(function (token) {
return self._client.getRoomStatistics(resourceUrl, token, options);
});
};
TenantClient.prototype.replyToMessage = function (roomIdOrName, parentMessageId, message) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/reply';
return self.getToken('send_message').then(function (token) {
return self._client.replyToMessage(resourceUrl, token, parentMessageId, message);
});
};
TenantClient.prototype.getRoomMembers = function (roomIdOrName, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/member';
return self.getToken('view_room').then(function (token) {
return self._client.getRoomMembers(resourceUrl, token, options);
});
};
TenantClient.prototype.setRoomTopic = function (roomIdOrName, topic) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/topic';
return self.getToken('admin_room').then(function (token) {
return self._client.setRoomTopic(resourceUrl, token, topic);
});
};
TenantClient.prototype.shareLinkWithRoom = function (roomIdOrName, link, message) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/share/link';
return self.getToken('send_message').then(function (token) {
return self._client.shareLinkWithRoom(resourceUrl, token, link, message);
});
};
TenantClient.prototype.addRoomMember = function (roomIdOrName, userIdOrEmail) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/member/' + param(userIdOrEmail);
return self.getToken('admin_room').then(function (token) {
return self._client.addRoomMember(resourceUrl, token);
});
};
TenantClient.prototype.removeRoomMember = function (roomIdOrName, userIdOrEmail) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/member/' + param(userIdOrEmail);
return self.getToken('admin_room').then(function (token) {
return self._client.removeRoomMember(resourceUrl, token);
});
};
TenantClient.prototype.deleteRoomWebhook = TenantClient.prototype.deleteWebhook = function (roomIdOrName, webhookId) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
verify.number(webhookId);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/webhook/' + param(webhookId);
return self.getToken('admin_room').then(function (token) {
return self._client.deleteRoomWebhook(resourceUrl, token);
});
};
TenantClient.prototype.getRoomWebhook = TenantClient.prototype.getWebhook = function (roomIdOrName, webhookId, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
verify.number(webhookId);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/webhook/' + param(webhookId);
return self.getToken('admin_room').then(function (token) {
return self._client.getRoomWebhook(resourceUrl, token);
});
};
TenantClient.prototype.getRoomHistory = function (roomIdOrName, options) {
var self = this;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var resourceUrl = this._tenant.links.api + '/room/' + param(roomIdOrName) + '/history';
return self.getToken('view_messages').then(function (token) {
return self._client.getRoomHistory(resourceUrl, token, options);
});
};
TenantClient.prototype.getPrivateChatMessage = function (userIdOrEmail, messageId, options) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
verify.string(messageId);
var resourceUrl = this._tenant.links.api + '/user/' + param(userIdOrEmail) + '/history/' + param(messageId);
return self.getToken('view_messages').then(function (token) {
return self._client.getPrivateChatMessage(resourceUrl, token, options);
});
};
TenantClient.prototype.getRecentPrivateChatHistory = function (userIdOrEmail, options) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/user/' + param(userIdOrEmail) + '/history/latest';
return self.getToken('view_messages').then(function (token) {
return self._client.getRecentPrivateChatHistory(resourceUrl, token, options);
});
};
TenantClient.prototype.updateUserPhoto = function (userIdOrEmail, photo) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/user/' + param(userIdOrEmail) + '/photo';
return self.getToken('admin_group').then(function (token) {
return self._client.updateUserPhoto(resourceUrl, token, photo);
});
};
TenantClient.prototype.deleteUserPhoto = function (userIdOrEmail) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/user/' + param(userIdOrEmail) + '/photo';
return self.getToken('admin_group').then(function (token) {
return self._client.deleteUserPhoto(resourceUrl, token);
});
};
TenantClient.prototype.updateUser = function (userIdOrEmail, user) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/user/' + param(userIdOrEmail);
return self.getToken('admin_group').then(function (token) {
return self._client.updateUser(resourceUrl, token, user);
});
};
TenantClient.prototype.deleteUser = function (userIdOrEmail) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/user/' + param(userIdOrEmail);
return self.getToken('admin_group').then(function (token) {
return self._client.deleteUser(resourceUrl, token);
});
};
TenantClient.prototype.getUser = function (userIdOrEmail, options) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/user/' + param(userIdOrEmail);
return self.getToken('view_group').then(function (token) {
return self._client.getUser(resourceUrl, token, options);
});
};
TenantClient.prototype.createUser = function (user) {
var self = this;
verify.object(user);
var resourceUrl = this._tenant.links.api + '/user';
return self.getToken('admin_group').then(function (token) {
return self._client.createUser(resourceUrl, token, user);
});
};
TenantClient.prototype.getUsers = function (options) {
var self = this;
var resourceUrl = this._tenant.links.api + '/user';
return self.getToken('view_group').then(function (token) {
return self._client.getUsers(resourceUrl, token, options);
});
};
TenantClient.prototype.shareLinkWithUser = function (userIdOrEmail, link, message) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var resourceUrl = this._tenant.links.api + '/user/' + param(userIdOrEmail) + '/share/link';
return self.getToken('send_message').then(function (token) {
return self._client.shareLinkWithUser(resourceUrl, token, link, message);
});
};
TenantClient.prototype.glancePushUser = function (userId, options) {
var self = this;
exports.verifyNumberOrString('userId', userId);
var resourceUrl = this._tenant.links.api + '/addon/ui/user/' + param(userId);
return self.getToken('view_group').then(function (token) {
return self._client.glancePushUser(resourceUrl, token, options);
});
};
TenantClient.prototype.glancePushRoom = function (roomId, options) {
var self = this;
exports.verifyNumberOrString('roomId', roomId);
var resourceUrl = this._tenant.links.api + '/addon/ui/room/' + param(roomId);
return self.getToken('view_room').then(function (token) {
return self._client.glancePushRoom(resourceUrl, token, options);
});
};
TenantClient.prototype.glancePushGroup = function (options) {
var self = this;
var resourceUrl = this._tenant.links.api + '/addon/ui';
return self.getToken('view_group').then(function (token) {
return self._client.glancePushGroup(resourceUrl, token, options);
});
};
// TODO: share file with user
TenantClient.prototype.forRoom = function (roomIdOrName) {
var self = this;
roomIdOrName = roomIdOrName || self._tenant.room;
exports.verifyNumberOrString('roomIdOrName', roomIdOrName);
var roomMethods = [
'getRoomMessage',
'getRecentRoomHistory',
'sendNotification',
'updateRoom',
'getRoom',
'roomIdOrName',
'deleteRoom',
'createRoomWebhook',
'createWebhook',
'getRoomWebhooks',
'getWebhooks',
'getRoomStatistics',
'replyToMessage',
'getRoomMembers',
'setRoomTopic',
'shareLinkWithRoom',
'addRoomMember',
'removeRoomMember',
'deleteRoomWebhook',
'getRoomWebhook',
'getRoomHistory'
];
return _.object(roomMethods.map(function (method) {
return [method, function () {
var args = [roomIdOrName].concat([].slice.call(arguments));
return self[method].apply(self, args);
}];
}));
};
TenantClient.prototype.forUser = function (userIdOrEmail) {
var self = this;
exports.verifyNumberOrString('userIdOrEmail', userIdOrEmail);
var userMethods = [
'getPrivateChatMessage',
'getRecentPrivateChatHistory',
'updateUserPhoto',
'deleteUserPhoto',
'updateUser',
'deleteUser',
'getUser',
'shareLinkWithUser'
];
return _.object(userMethods.map(function (method) {
return [method, function () {
var args = [userIdOrEmail].concat([].slice.call(arguments));
return self[method].apply(self, args);
}];
}));
};
TenantClient.prototype._ensureScopes = function () {
var scopes = arguments.length > 0 ? [].slice.call(arguments) : defaultScopes;
scopes.forEach(function (scope) {
if (scopes.indexOf(scope) === -1) {
throw new Error('Scope ' + scope + ' not in allowable tenant scopes: [' + scopes.join(', ') + ']');
}
});
};
exports.verifyNumberOrString = function (name, val) {
if (!check.number(val) && !check.string(val)) {
throw new Error('Argument ' + name + ' must be a number or string');
}
}
module.exports = function (client, tenant, cache, scopes) {
return new TenantClient(client, tenant, cache, scopes);
};