2020-09-10 16:00:21 +02:00
|
|
|
const CouchDB = require("../db")
|
|
|
|
const emitter = require("../events/index")
|
2021-05-05 18:49:34 +02:00
|
|
|
const env = require("../environment")
|
2021-05-05 18:49:53 +02:00
|
|
|
const Queue = env.isTest()
|
|
|
|
? require("../utilities/queue/inMemoryQueue")
|
|
|
|
: require("bull")
|
2020-10-01 18:22:08 +02:00
|
|
|
const { getAutomationParams } = require("../db/utils")
|
2021-02-10 17:10:39 +01:00
|
|
|
const { coerce } = require("../utilities/rowProcessor")
|
2021-05-14 16:43:41 +02:00
|
|
|
const { utils } = require("@budibase/auth/redis")
|
2021-05-18 17:37:54 +02:00
|
|
|
const { JobQueues } = require("../constants")
|
2021-09-06 18:53:02 +02:00
|
|
|
const { definitions } = require("./triggerInfo")
|
2021-09-07 14:58:53 +02:00
|
|
|
const { isDevAppID } = require("../db/utils")
|
2020-09-10 16:00:21 +02:00
|
|
|
|
2021-05-04 19:13:44 +02:00
|
|
|
const { opts } = utils.getRedisOptions()
|
2021-05-18 17:37:54 +02:00
|
|
|
let automationQueue = new Queue(JobQueues.AUTOMATIONS, { redis: opts })
|
2021-03-26 15:56:34 +01:00
|
|
|
|
2021-09-06 18:53:02 +02:00
|
|
|
const TRIGGER_DEFINITIONS = definitions
|
2020-09-16 15:00:04 +02:00
|
|
|
|
2020-10-09 20:10:28 +02:00
|
|
|
async function queueRelevantRowAutomations(event, eventType) {
|
2020-10-29 11:28:27 +01:00
|
|
|
if (event.appId == null) {
|
|
|
|
throw `No appId specified for ${eventType} - check event emitters.`
|
2020-09-14 11:30:35 +02:00
|
|
|
}
|
2021-09-07 14:58:53 +02:00
|
|
|
// don't queue events which are for dev apps, only way to test automations is
|
|
|
|
// running tests on them
|
|
|
|
if (isDevAppID(event.appId)) {
|
|
|
|
return
|
|
|
|
}
|
2020-10-29 11:28:27 +01:00
|
|
|
const db = new CouchDB(event.appId)
|
2020-10-02 13:37:46 +02:00
|
|
|
let automations = await db.allDocs(
|
2020-10-01 18:22:08 +02:00
|
|
|
getAutomationParams(null, { include_docs: true })
|
2020-09-21 14:49:34 +02:00
|
|
|
)
|
2020-09-10 16:00:21 +02:00
|
|
|
|
2020-10-02 13:37:46 +02:00
|
|
|
// filter down to the correct event type
|
|
|
|
automations = automations.rows
|
2021-05-04 12:32:22 +02:00
|
|
|
.map(automation => automation.doc)
|
|
|
|
.filter(automation => {
|
2020-10-02 13:37:46 +02:00
|
|
|
const trigger = automation.definition.trigger
|
|
|
|
return trigger && trigger.event === eventType
|
|
|
|
})
|
|
|
|
|
2020-09-21 14:49:34 +02:00
|
|
|
for (let automation of automations) {
|
|
|
|
let automationDef = automation.definition
|
|
|
|
let automationTrigger = automationDef ? automationDef.trigger : {}
|
2020-09-18 14:51:56 +02:00
|
|
|
if (
|
2020-09-21 14:49:34 +02:00
|
|
|
!automation.live ||
|
|
|
|
!automationTrigger.inputs ||
|
2020-10-09 20:10:28 +02:00
|
|
|
automationTrigger.inputs.tableId !== event.row.tableId
|
2020-09-18 14:51:56 +02:00
|
|
|
) {
|
2020-09-11 19:47:22 +02:00
|
|
|
continue
|
|
|
|
}
|
2021-09-06 18:53:02 +02:00
|
|
|
await automationQueue.add({ automation, event })
|
2020-09-10 16:00:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-03 09:31:09 +02:00
|
|
|
emitter.on("row:save", async function (event) {
|
2021-03-15 15:11:13 +01:00
|
|
|
/* istanbul ignore next */
|
2020-10-09 20:10:28 +02:00
|
|
|
if (!event || !event.row || !event.row.tableId) {
|
2020-09-18 14:51:56 +02:00
|
|
|
return
|
|
|
|
}
|
2020-10-09 20:10:28 +02:00
|
|
|
await queueRelevantRowAutomations(event, "row:save")
|
2021-02-23 15:07:19 +01:00
|
|
|
})
|
|
|
|
|
2021-05-03 09:31:09 +02:00
|
|
|
emitter.on("row:update", async function (event) {
|
2021-03-15 15:11:13 +01:00
|
|
|
/* istanbul ignore next */
|
2021-02-23 15:07:19 +01:00
|
|
|
if (!event || !event.row || !event.row.tableId) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
await queueRelevantRowAutomations(event, "row:update")
|
2020-09-10 16:00:21 +02:00
|
|
|
})
|
|
|
|
|
2021-05-03 09:31:09 +02:00
|
|
|
emitter.on("row:delete", async function (event) {
|
2021-03-15 15:11:13 +01:00
|
|
|
/* istanbul ignore next */
|
2020-10-09 20:10:28 +02:00
|
|
|
if (!event || !event.row || !event.row.tableId) {
|
2020-09-18 14:51:56 +02:00
|
|
|
return
|
|
|
|
}
|
2020-10-09 20:10:28 +02:00
|
|
|
await queueRelevantRowAutomations(event, "row:delete")
|
2020-09-10 16:00:21 +02:00
|
|
|
})
|
|
|
|
|
2021-09-06 18:53:02 +02:00
|
|
|
exports.externalTrigger = async function (automation, params) {
|
2021-01-08 18:25:06 +01:00
|
|
|
if (automation.definition != null && automation.definition.trigger != null) {
|
|
|
|
if (automation.definition.trigger.stepId === "APP") {
|
|
|
|
// values are likely to be submitted as strings, so we shall convert to correct type
|
|
|
|
const coercedFields = {}
|
|
|
|
const fields = automation.definition.trigger.inputs.fields
|
2021-02-10 17:10:39 +01:00
|
|
|
for (let key of Object.keys(fields)) {
|
|
|
|
coercedFields[key] = coerce(params.fields[key], fields[key])
|
2021-01-08 18:25:06 +01:00
|
|
|
}
|
|
|
|
params.fields = coercedFields
|
|
|
|
}
|
2020-09-17 16:14:08 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:53:02 +02:00
|
|
|
await automationQueue.add({ automation, event: params })
|
2020-09-10 16:00:21 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 18:53:02 +02:00
|
|
|
exports.getQueues = () => {
|
2021-05-07 14:55:57 +02:00
|
|
|
return [automationQueue]
|
2021-05-07 13:24:51 +02:00
|
|
|
}
|
2021-09-06 18:53:02 +02:00
|
|
|
exports.automationQueue = automationQueue
|
2020-09-16 15:00:04 +02:00
|
|
|
|
2021-09-06 18:53:02 +02:00
|
|
|
exports.TRIGGER_DEFINITIONS = TRIGGER_DEFINITIONS
|