Skip to content
Snippets Groups Projects
Unverified Commit 9e2b3615 authored by Marcelo Schmidt's avatar Marcelo Schmidt
Browse files

Allow inputing multiple channels/users in integrations; comma-separated

parent 048a718f
No related branches found
No related tags found
No related merge requests found
......@@ -176,7 +176,7 @@ executeIntegrationRest = ->
try
message = processWebhookMessage @bodyParams, @user, defaultValues
if not message?
if _.isEmpty message
return RocketChat.API.v1.failure 'unknown-error'
return RocketChat.API.v1.success()
......
......@@ -9,8 +9,11 @@ Meteor.methods
if integration.channel.trim() is ''
throw new Meteor.Error 'error-invalid-channel', 'Invalid channel', { method: 'addIncomingIntegration' }
if integration.channel[0] not in ['@', '#']
throw new Meteor.Error 'error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', { method: 'addIncomingIntegration' }
channels = _.map(integration.channel.split(','), (channel) -> s.trim(channel))
for channel in channels
if channel[0] not in ['@', '#']
throw new Meteor.Error 'error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', { method: 'updateIncomingIntegration' }
if not _.isString(integration.username)
throw new Meteor.Error 'error-invalid-username', 'Invalid username', { method: 'addIncomingIntegration' }
......@@ -29,32 +32,33 @@ Meteor.methods
integration.scriptCompiled = undefined
integration.scriptError = _.pick e, 'name', 'message', 'pos', 'loc', 'codeFrame'
record = undefined
channelType = integration.channel[0]
channel = integration.channel.substr(1)
switch channelType
when '#'
record = RocketChat.models.Rooms.findOne
$or: [
{_id: channel}
{name: channel}
]
when '@'
record = RocketChat.models.Users.findOne
$or: [
{_id: channel}
{username: channel}
]
if record is undefined
throw new Meteor.Error 'error-invalid-room', 'Invalid room', { method: 'addIncomingIntegration' }
if record.usernames? and
(not RocketChat.authz.hasPermission @userId, 'manage-integrations') and
(RocketChat.authz.hasPermission @userId, 'manage-own-integrations') and
Meteor.user()?.username not in record.usernames
throw new Meteor.Error 'error-invalid-channel', 'Invalid Channel', { method: 'addIncomingIntegration' }
for channel in channels
record = undefined
channelType = channel[0]
channel = channel.substr(1)
switch channelType
when '#'
record = RocketChat.models.Rooms.findOne
$or: [
{_id: channel}
{name: channel}
]
when '@'
record = RocketChat.models.Users.findOne
$or: [
{_id: channel}
{username: channel}
]
if record is undefined
throw new Meteor.Error 'error-invalid-room', 'Invalid room', { method: 'addIncomingIntegration' }
if record.usernames? and
(not RocketChat.authz.hasPermission @userId, 'manage-integrations') and
(RocketChat.authz.hasPermission @userId, 'manage-own-integrations') and
Meteor.user()?.username not in record.usernames
throw new Meteor.Error 'error-invalid-channel', 'Invalid Channel', { method: 'addIncomingIntegration' }
user = RocketChat.models.Users.findOne({username: integration.username})
......
......@@ -6,8 +6,11 @@ Meteor.methods
if integration.channel.trim() is ''
throw new Meteor.Error 'error-invalid-channel', 'Invalid channel', { method: 'updateIncomingIntegration' }
if integration.channel[0] not in ['@', '#']
throw new Meteor.Error 'error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', { method: 'updateIncomingIntegration' }
channels = _.map(integration.channel.split(','), (channel) -> s.trim(channel))
for channel in channels
if channel[0] not in ['@', '#']
throw new Meteor.Error 'error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', { method: 'updateIncomingIntegration' }
currentIntegration = null
......@@ -32,32 +35,33 @@ Meteor.methods
integration.scriptCompiled = undefined
integration.scriptError = _.pick e, 'name', 'message', 'pos', 'loc', 'codeFrame'
record = undefined
channelType = integration.channel[0]
channel = integration.channel.substr(1)
for channel in channels
record = undefined
channelType = channel[0]
channel = channel.substr(1)
switch channelType
when '#'
record = RocketChat.models.Rooms.findOne
$or: [
{_id: channel}
{name: channel}
]
when '@'
record = RocketChat.models.Users.findOne
$or: [
{_id: channel}
{username: channel}
]
switch channelType
when '#'
record = RocketChat.models.Rooms.findOne
$or: [
{_id: channel}
{name: channel}
]
when '@'
record = RocketChat.models.Users.findOne
$or: [
{_id: channel}
{username: channel}
]
if record is undefined
throw new Meteor.Error 'error-invalid-room', 'Invalid room', { method: 'updateIncomingIntegration' }
if record is undefined
throw new Meteor.Error 'error-invalid-room', 'Invalid room', { method: 'updateIncomingIntegration' }
if record.usernames? and
(not RocketChat.authz.hasPermission @userId, 'manage-integrations') and
(RocketChat.authz.hasPermission @userId, 'manage-own-integrations') and
Meteor.user()?.username not in record.usernames
throw new Meteor.Error 'error-invalid-channel', 'Invalid Channel', { method: 'updateIncomingIntegration' }
if record.usernames? and
(not RocketChat.authz.hasPermission @userId, 'manage-integrations') and
(RocketChat.authz.hasPermission @userId, 'manage-own-integrations') and
Meteor.user()?.username not in record.usernames
throw new Meteor.Error 'error-invalid-channel', 'Invalid Channel', { method: 'updateIncomingIntegration' }
user = RocketChat.models.Users.findOne({username: currentIntegration.username})
RocketChat.models.Roles.addUserRoles user._id, 'bot'
......@@ -69,7 +73,7 @@ Meteor.methods
avatar: integration.avatar
emoji: integration.emoji
alias: integration.alias
channel: integration.channel
channel: channels
script: integration.script
scriptEnabled: integration.scriptEnabled
scriptCompiled: integration.scriptCompiled
......
......@@ -3,7 +3,7 @@ Meteor.methods
if integration.channel?.trim? and integration.channel.trim() is ''
delete integration.channel
if (not RocketChat.authz.hasPermission @userId, 'manage-integrations') and
if (not RocketChat.authz.hasPermission @userId, 'manage-integrations') and
not (RocketChat.authz.hasPermission @userId, 'manage-own-integrations') and
not (RocketChat.authz.hasPermission @userId, 'manage-integrations', 'bot') and
not (RocketChat.authz.hasPermission @userId, 'manage-own-integrations', 'bot')
......@@ -23,8 +23,11 @@ Meteor.methods
if integration.urls.length is 0
throw new Meteor.Error 'error-invalid-urls', 'Invalid URLs', { method: 'addOutgoingIntegration' }
if integration.channel? and integration.channel[0] not in ['@', '#']
throw new Meteor.Error 'error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', { method: 'addOutgoingIntegration' }
channels = _.map(integration.channel.split(','), (channel) -> s.trim(channel))
for channel in channels
if channel[0] not in ['@', '#']
throw new Meteor.Error 'error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', { method: 'updateIncomingIntegration' }
if integration.triggerWords?
if not Match.test integration.triggerWords, [String]
......@@ -47,10 +50,10 @@ Meteor.methods
integration.scriptError = _.pick e, 'name', 'message', 'pos', 'loc', 'codeFrame'
if integration.channel?
for channel in channels
record = undefined
channelType = integration.channel[0]
channel = integration.channel.substr(1)
channelType = channel[0]
channel = channel.substr(1)
switch channelType
when '#'
......
......@@ -20,8 +20,11 @@ Meteor.methods
else
integration.channel = undefined
if integration.channel? and integration.channel[0] not in ['@', '#']
throw new Meteor.Error 'error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', { method: 'updateOutgoingIntegration' }
channels = _.map(integration.channel.split(','), (channel) -> s.trim(channel))
for channel in channels
if channel[0] not in ['@', '#']
throw new Meteor.Error 'error-invalid-channel-start-with-chars', 'Invalid channel. Start with @ or #', { method: 'updateIncomingIntegration' }
if not integration.token? or integration.token?.trim() is ''
throw new Meteor.Error 'error-invalid-token', 'Invalid token', { method: 'updateOutgoingIntegration' }
......@@ -59,10 +62,10 @@ Meteor.methods
integration.scriptError = _.pick e, 'name', 'message', 'pos', 'loc', 'codeFrame'
if integration.channel?
for channel in channels
record = undefined
channelType = integration.channel[0]
channel = integration.channel.substr(1)
channelType = channel[0]
channel = channel.substr(1)
switch channelType
when '#'
......@@ -99,7 +102,7 @@ Meteor.methods
avatar: integration.avatar
emoji: integration.emoji
alias: integration.alias
channel: integration.channel
channel: channels
username: integration.username
userId: user._id
urls: integration.urls
......
this.processWebhookMessage = function(messageObj, user, defaultValues) {
var attachment, channel, channelType, i, len, message, ref, rid, room, roomUser;
var attachment, channel, channels, channelType, i, len, message, ref, rid, room, roomUser, ret;
ret = [];
if (!defaultValues) {
defaultValues = {
......@@ -12,100 +13,101 @@ this.processWebhookMessage = function(messageObj, user, defaultValues) {
channel = messageObj.channel || defaultValues.channel;
channelType = channel[0];
channels = [].concat(channel);
channel = channel.substr(1);
for (channel of channels) {
channelType = channel[0];
switch (channelType) {
case '#':
room = RocketChat.models.Rooms.findOne({
$or: [
{
_id: channel
}, {
name: channel
}
]
});
if (!_.isObject(room)) {
throw new Meteor.Error('invalid-channel');
}
rid = room._id;
if (room.t === 'c') {
Meteor.runAsUser(user._id, function() {
return Meteor.call('joinRoom', room._id);
channel = channel.substr(1);
switch (channelType) {
case '#':
room = RocketChat.models.Rooms.findOne({
$or: [
{
_id: channel
}, {
name: channel
}
]
});
}
break;
case '@':
roomUser = RocketChat.models.Users.findOne({
$or: [
{
_id: channel
}, {
username: channel
}
]
}) || {};
rid = [user._id, roomUser._id].sort().join('');
room = RocketChat.models.Rooms.findOne({
_id: {
$in: [rid, channel]
if (!_.isObject(room)) {
throw new Meteor.Error('invalid-channel');
}
});
if (!_.isObject(roomUser) && !_.isObject(room)) {
throw new Meteor.Error('invalid-channel');
}
if (!room) {
Meteor.runAsUser(user._id, function() {
Meteor.call('createDirectMessage', roomUser.username);
room = RocketChat.models.Rooms.findOne(rid);
rid = room._id;
if (room.t === 'c') {
Meteor.runAsUser(user._id, function() {
return Meteor.call('joinRoom', room._id);
});
}
break;
case '@':
roomUser = RocketChat.models.Users.findOne({
$or: [
{
_id: channel
}, {
username: channel
}
]
}) || {};
rid = [user._id, roomUser._id].sort().join('');
room = RocketChat.models.Rooms.findOne({
_id: {
$in: [rid, channel]
}
});
}
break;
default:
throw new Meteor.Error('invalid-channel-type');
}
if (!_.isObject(roomUser) && !_.isObject(room)) {
throw new Meteor.Error('invalid-channel');
}
if (!room) {
Meteor.runAsUser(user._id, function() {
Meteor.call('createDirectMessage', roomUser.username);
room = RocketChat.models.Rooms.findOne(rid);
});
}
break;
default:
throw new Meteor.Error('invalid-channel-type');
}
if (messageObj.attachments && !_.isArray(messageObj.attachments)) {
console.log('Attachments should be Array, ignoring value'.red, messageObj.attachments);
messageObj.attachments = undefined;
}
if (messageObj.attachments && !_.isArray(messageObj.attachments)) {
console.log('Attachments should be Array, ignoring value'.red, messageObj.attachments);
messageObj.attachments = undefined;
}
message = {
alias: messageObj.username || messageObj.alias || defaultValues.alias,
msg: _.trim(messageObj.text || messageObj.msg || ''),
attachments: messageObj.attachments,
parseUrls: messageObj.parseUrls !== undefined ? messageObj.parseUrls : !messageObj.attachments,
bot: messageObj.bot,
groupable: false
};
message = {
alias: messageObj.username || messageObj.alias || defaultValues.alias,
msg: _.trim(messageObj.text || messageObj.msg || ''),
attachments: messageObj.attachments,
parseUrls: messageObj.parseUrls !== undefined ? messageObj.parseUrls : !messageObj.attachments,
bot: messageObj.bot,
groupable: false
};
if (!_.isEmpty(messageObj.icon_url) || !_.isEmpty(messageObj.avatar)) {
message.avatar = messageObj.icon_url || messageObj.avatar;
} else if (!_.isEmpty(messageObj.icon_emoji) || !_.isEmpty(messageObj.emoji)) {
message.emoji = messageObj.icon_emoji || messageObj.emoji;
} else if (!_.isEmpty(defaultValues.avatar)) {
message.avatar = defaultValues.avatar;
} else if (!_.isEmpty(defaultValues.emoji)) {
message.emoji = defaultValues.emoji;
}
if (!_.isEmpty(messageObj.icon_url) || !_.isEmpty(messageObj.avatar)) {
message.avatar = messageObj.icon_url || messageObj.avatar;
} else if (!_.isEmpty(messageObj.icon_emoji) || !_.isEmpty(messageObj.emoji)) {
message.emoji = messageObj.icon_emoji || messageObj.emoji;
} else if (!_.isEmpty(defaultValues.avatar)) {
message.avatar = defaultValues.avatar;
} else if (!_.isEmpty(defaultValues.emoji)) {
message.emoji = defaultValues.emoji;
}
if (_.isArray(message.attachments)) {
ref = message.attachments;
for (i = 0, len = ref.length; i < len; i++) {
attachment = ref[i];
if (attachment.msg) {
attachment.text = _.trim(attachment.msg);
delete attachment.msg;
if (_.isArray(message.attachments)) {
ref = message.attachments;
for (i = 0, len = ref.length; i < len; i++) {
attachment = ref[i];
if (attachment.msg) {
attachment.text = _.trim(attachment.msg);
delete attachment.msg;
}
}
}
}
var messageReturn = RocketChat.sendMessage(user, message, room, {});
return {
channel: channel,
message: messageReturn
};
var messageReturn = RocketChat.sendMessage(user, message, room, {});
ret.push({ channel: channel, message: messageReturn });
}
return ret;
};
......@@ -94,18 +94,33 @@ executeScript = (integration, method, params) ->
RocketChat.models.Integrations.find({type: 'webhook-outgoing'}).observe
added: (record) ->
channel = record.channel or '__any'
triggers[channel] ?= {}
triggers[channel][record._id] = record
if _.isEmpty(record.channel)
channels = [ '__any' ]
else
channels = [].concat(record.channel)
for channel in channels
triggers[channel] ?= {}
triggers[channel][record._id] = record
changed: (record) ->
channel = record.channel or '__any'
triggers[channel] ?= {}
triggers[channel][record._id] = record
if _.isEmpty(record.channel)
channels = [ '__any' ]
else
channels = [].concat(record.channel)
for channel in channels
triggers[channel] ?= {}
triggers[channel][record._id] = record
removed: (record) ->
channel = record.channel or '__any'
delete triggers[channel][record._id]
if _.isEmpty(record.channel)
channels = [ '__any' ]
else
channels = [].concat(record.channel)
for channel in channels
delete triggers[channel][record._id]
ExecuteTriggerUrl = (url, trigger, message, room, tries=0) ->
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment