Rocket models in webhooks (#6420)

* Allow access to the models within integrations and fix a few issues with incoming webhooks

* Update the history file to reflect the changes to the integrations
pull/6430/head^2
Bradley Hilton 9 years ago committed by Rodrigo Nascimento
parent 2ffad6d4e3
commit a2c853c5e9
  1. 3
      HISTORY.md
  2. 72
      packages/rocketchat-integrations/server/api/api.coffee
  3. 49
      packages/rocketchat-integrations/server/lib/triggerHandler.js

@ -2,6 +2,9 @@
## NEXT
- [NEW] Integrations, both incoming and outgoing, now have access to the models. Example: `Users.findOneById(id)` (#6336)
- [FIX] Incoming integrations would break when trying to use the `Store` feature.
## 0.54.1 - 2017-Mar-23
- [FIX] Images on attachments were not loading except for uploaded files.

@ -1,18 +1,14 @@
vm = Npm.require('vm')
moment = require('moment')
compiledScripts = {}
getIntegrationScript = (integration) ->
compiledScript = compiledScripts[integration._id]
if compiledScript? and +compiledScript._updatedAt is +integration._updatedAt
return compiledScript.script
script = integration.scriptCompiled
vmScript = undefined
buildSandbox = (store = {}) ->
sandbox =
_: _
s: s
console: console
console: console,
moment: moment,
Store:
set: (key, val) ->
return store[key] = val
@ -26,17 +22,36 @@ getIntegrationScript = (integration) ->
return {} =
error: e
Object.keys(RocketChat.models).filter((k) ->
return !k.startsWith('_')
).forEach (k) =>
sandbox[k] = RocketChat.models[k]
return {} =
store: store,
sandbox: sandbox
getIntegrationScript = (integration) ->
compiledScript = compiledScripts[integration._id]
if compiledScript? and +compiledScript._updatedAt is +integration._updatedAt
return compiledScript.script
script = integration.scriptCompiled
vmScript = undefined
sandboxItems = buildSandbox()
try
logger.incoming.info 'Will evaluate script of Trigger', integration.name
logger.incoming.debug script
vmScript = vm.createScript script, 'script.js'
vmScript.runInNewContext sandbox
vmScript.runInNewContext sandboxItems.sandbox
if sandbox.Script?
if sandboxItems.sandbox.Script?
compiledScripts[integration._id] =
script: new sandbox.Script()
script: new sandboxItems.sandbox.Script()
store: sandboxItems.store
_updatedAt: integration._updatedAt
return compiledScripts[integration._id].script
@ -47,7 +62,7 @@ getIntegrationScript = (integration) ->
logger.incoming.error e.stack.replace(/^/gm, ' ')
throw RocketChat.API.v1.failure 'error-evaluating-script'
if not sandbox.Script?
if not sandboxItems.sandbox.Script?
logger.incoming.error '[Class "Script" not in Trigger', integration.name, ']'
throw RocketChat.API.v1.failure 'class-script-not-found'
@ -133,9 +148,9 @@ removeIntegration = (options, user) ->
executeIntegrationRest = ->
logger.incoming.info 'Post integration', @integration.name
logger.incoming.debug '@urlParams', @urlParams
logger.incoming.debug '@bodyParams', @bodyParams
logger.incoming.info 'Post integration:', @integration.name
logger.incoming.debug '@urlParams:', @urlParams
logger.incoming.debug '@bodyParams:', @bodyParams
if @integration.enabled isnt true
return {} =
@ -148,13 +163,13 @@ executeIntegrationRest = ->
avatar: @integration.avatar
emoji: @integration.emoji
if @integration.scriptEnabled is true and @integration.scriptCompiled? and @integration.scriptCompiled.trim() isnt ''
script = undefined
try
script = getIntegrationScript(@integration)
catch e
return e
logger.incoming.warn e
return RocketChat.API.v1.failure e.message
request =
url:
@ -174,24 +189,11 @@ executeIntegrationRest = ->
username: @user.username
try
sandbox =
_: _
s: s
console: console
Store:
set: (key, val) ->
return store[key] = val
get: (key) ->
return store[key]
HTTP: (method, url, options) ->
try
return {} =
result: HTTP.call method, url, options
catch e
return {} =
error: e
script: script
request: request
sandboxItems = buildSandbox(compiledScripts[@integration._id].store)
sandbox = sandboxItems.sandbox
sandbox.script = script
sandbox.request = request
result = vm.runInNewContext('script.process_incoming_request({ request: request })', sandbox, { timeout: 3000 })
if result?.error?

@ -187,14 +187,7 @@ RocketChat.integrations.triggerHandler = new class RocketChatIntegrationHandler
return message;
}
getIntegrationScript(integration) {
const compiledScript = this.compiledScripts[integration._id];
if (compiledScript && +compiledScript._updatedAt === +integration._updatedAt) {
return compiledScript.script;
}
const script = integration.scriptCompiled;
const store = {};
buildSandbox(store = {}) {
const sandbox = {
_, s, console, moment,
Store: {
@ -212,6 +205,22 @@ RocketChat.integrations.triggerHandler = new class RocketChatIntegrationHandler
}
};
Object.keys(RocketChat.models).filter(k => !k.startsWith('_')).forEach(k => {
sandbox[k] = RocketChat.models[k];
});
return { store, sandbox };
}
getIntegrationScript(integration) {
const compiledScript = this.compiledScripts[integration._id];
if (compiledScript && +compiledScript._updatedAt === +integration._updatedAt) {
return compiledScript.script;
}
const script = integration.scriptCompiled;
const { store, sandbox } = this.buildSandbox();
let vmScript;
try {
logger.outgoing.info('Will evaluate script of Trigger', integration.name);
@ -275,26 +284,10 @@ RocketChat.integrations.triggerHandler = new class RocketChatIntegrationHandler
}
try {
const store = this.compiledScripts[integration._id].store;
const sandbox = {
_, s, console, moment,
Store: {
set: (key, val) => store[key] = val,
get: (key) => store[key]
},
HTTP: (method, url, options) => {
try {
return {
result: HTTP.call(method, url, options)
};
} catch (error) {
return { error };
}
},
script,
method,
params
};
const { sandbox } = this.buildSandbox(this.compiledScripts[integration._id].store);
sandbox.script = script;
sandbox.method = method;
sandbox.params = params;
this.updateHistory({ historyId, step: `execute-script-before-running-${method}` });
const result = this.vm.runInNewContext('script[method](params)', sandbox, { timeout: 3000 });

Loading…
Cancel
Save