2020-09-10 16:00:21 +02:00
|
|
|
const CouchDB = require("../db")
|
|
|
|
const emitter = require("../events/index")
|
2020-09-25 19:05:26 +02:00
|
|
|
const InMemoryQueue = require("../utilities/queue/inMemoryQueue")
|
2020-10-01 18:22:08 +02:00
|
|
|
const { getAutomationParams } = require("../db/utils")
|
2020-09-10 16:00:21 +02:00
|
|
|
|
2020-09-25 19:05:26 +02:00
|
|
|
let automationQueue = new InMemoryQueue("automationQueue")
|
2020-09-10 16:00:21 +02:00
|
|
|
|
2020-09-17 16:14:08 +02:00
|
|
|
const FAKE_STRING = "TEST"
|
|
|
|
const FAKE_BOOL = false
|
|
|
|
const FAKE_NUMBER = 1
|
|
|
|
const FAKE_DATETIME = "1970-01-01T00:00:00.000Z"
|
|
|
|
|
2020-09-16 15:00:04 +02:00
|
|
|
const BUILTIN_DEFINITIONS = {
|
2020-10-09 20:10:28 +02:00
|
|
|
ROW_SAVED: {
|
2020-09-25 16:01:48 +02:00
|
|
|
name: "Row Saved",
|
2020-10-09 20:10:28 +02:00
|
|
|
event: "row:save",
|
2020-09-16 15:00:04 +02:00
|
|
|
icon: "ri-save-line",
|
2020-10-09 19:49:23 +02:00
|
|
|
tagline: "Row is added to {{inputs.enriched.table.name}}",
|
2020-09-25 16:01:48 +02:00
|
|
|
description: "Fired when a row is saved to your database",
|
2020-10-09 20:10:28 +02:00
|
|
|
stepId: "ROW_SAVED",
|
2020-09-16 15:00:04 +02:00
|
|
|
inputs: {},
|
|
|
|
schema: {
|
|
|
|
inputs: {
|
|
|
|
properties: {
|
2020-10-09 19:49:23 +02:00
|
|
|
tableId: {
|
2020-09-16 15:00:04 +02:00
|
|
|
type: "string",
|
2020-10-09 19:49:23 +02:00
|
|
|
customType: "table",
|
2020-09-16 15:00:04 +02:00
|
|
|
title: "Table",
|
|
|
|
},
|
|
|
|
},
|
2020-10-09 19:49:23 +02:00
|
|
|
required: ["tableId"],
|
2020-09-16 15:00:04 +02:00
|
|
|
},
|
|
|
|
outputs: {
|
|
|
|
properties: {
|
2020-10-09 20:10:28 +02:00
|
|
|
row: {
|
2020-09-16 15:00:04 +02:00
|
|
|
type: "object",
|
2020-10-09 20:10:28 +02:00
|
|
|
customType: "row",
|
2020-09-25 16:01:48 +02:00
|
|
|
description: "The new row that was saved",
|
2020-09-16 15:00:04 +02:00
|
|
|
},
|
2020-09-23 13:29:20 +02:00
|
|
|
id: {
|
|
|
|
type: "string",
|
2020-09-25 16:01:48 +02:00
|
|
|
description: "Row ID - can be used for updating",
|
2020-09-23 13:29:20 +02:00
|
|
|
},
|
|
|
|
revision: {
|
|
|
|
type: "string",
|
2020-09-25 16:01:48 +02:00
|
|
|
description: "Revision of row",
|
2020-09-23 13:29:20 +02:00
|
|
|
},
|
2020-09-16 15:00:04 +02:00
|
|
|
},
|
2020-10-09 20:10:28 +02:00
|
|
|
required: ["row", "id"],
|
2020-09-16 15:00:04 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
type: "TRIGGER",
|
|
|
|
},
|
2020-10-09 20:10:28 +02:00
|
|
|
ROW_DELETED: {
|
2020-09-25 16:01:48 +02:00
|
|
|
name: "Row Deleted",
|
2020-10-09 20:10:28 +02:00
|
|
|
event: "row:delete",
|
2020-09-16 15:00:04 +02:00
|
|
|
icon: "ri-delete-bin-line",
|
2020-10-09 19:49:23 +02:00
|
|
|
tagline: "Row is deleted from {{inputs.enriched.table.name}}",
|
2020-09-25 16:01:48 +02:00
|
|
|
description: "Fired when a row is deleted from your database",
|
2020-10-09 20:10:28 +02:00
|
|
|
stepId: "ROW_DELETED",
|
2020-09-16 15:00:04 +02:00
|
|
|
inputs: {},
|
|
|
|
schema: {
|
|
|
|
inputs: {
|
|
|
|
properties: {
|
2020-10-09 19:49:23 +02:00
|
|
|
tableId: {
|
2020-09-16 15:00:04 +02:00
|
|
|
type: "string",
|
2020-10-09 19:49:23 +02:00
|
|
|
customType: "table",
|
2020-09-16 15:00:04 +02:00
|
|
|
title: "Table",
|
|
|
|
},
|
|
|
|
},
|
2020-10-09 19:49:23 +02:00
|
|
|
required: ["tableId"],
|
2020-09-16 15:00:04 +02:00
|
|
|
},
|
|
|
|
outputs: {
|
|
|
|
properties: {
|
2020-10-09 20:10:28 +02:00
|
|
|
row: {
|
2020-09-16 15:00:04 +02:00
|
|
|
type: "object",
|
2020-10-09 20:10:28 +02:00
|
|
|
customType: "row",
|
2020-09-25 16:01:48 +02:00
|
|
|
description: "The row that was deleted",
|
2020-09-16 15:00:04 +02:00
|
|
|
},
|
|
|
|
},
|
2020-10-09 20:10:28 +02:00
|
|
|
required: ["row", "id"],
|
2020-09-16 15:00:04 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
type: "TRIGGER",
|
|
|
|
},
|
2020-10-22 18:48:32 +02:00
|
|
|
WEBHOOK: {
|
|
|
|
name: "Webhook",
|
|
|
|
event: "web:trigger",
|
|
|
|
icon: "ri-global-line",
|
|
|
|
tagline: "Webhook endpoint is hit",
|
|
|
|
description: "Trigger an automation when a HTTP POST webhook is hit",
|
|
|
|
stepId: "WEBHOOK",
|
|
|
|
inputs: {},
|
|
|
|
schema: {
|
|
|
|
inputs: {
|
|
|
|
properties: {
|
|
|
|
schemaUrl: {
|
|
|
|
type: "string",
|
|
|
|
customType: "webhookUrl",
|
|
|
|
title: "Schema URL",
|
|
|
|
},
|
|
|
|
triggerUrl: {
|
|
|
|
type: "string",
|
|
|
|
customType: "webhookUrl",
|
|
|
|
title: "Trigger URL",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
required: ["schemaUrl", "triggerUrl"],
|
|
|
|
},
|
|
|
|
outputs: {
|
2020-10-26 17:04:02 +01:00
|
|
|
properties: {
|
|
|
|
body: {
|
|
|
|
type: "object",
|
|
|
|
description: "Body of the request which hit the webhook",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
required: ["body"],
|
2020-10-22 18:48:32 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
type: "TRIGGER",
|
|
|
|
},
|
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
|
|
|
}
|
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
|
|
|
|
.map(automation => automation.doc)
|
|
|
|
.filter(automation => {
|
|
|
|
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
|
|
|
|
}
|
2020-09-21 14:49:34 +02:00
|
|
|
automationQueue.add({ automation, event })
|
2020-09-10 16:00:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-09 20:10:28 +02:00
|
|
|
emitter.on("row:save", async function(event) {
|
|
|
|
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")
|
2020-09-10 16:00:21 +02:00
|
|
|
})
|
|
|
|
|
2020-10-09 20:10:28 +02:00
|
|
|
emitter.on("row:delete", async function(event) {
|
|
|
|
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
|
|
|
})
|
|
|
|
|
2020-10-09 20:10:28 +02:00
|
|
|
async function fillRowOutput(automation, params) {
|
2020-09-21 14:49:34 +02:00
|
|
|
let triggerSchema = automation.definition.trigger
|
2020-10-09 19:49:23 +02:00
|
|
|
let tableId = triggerSchema.inputs.tableId
|
2020-10-29 11:28:27 +01:00
|
|
|
const db = new CouchDB(params.appId)
|
2020-09-17 16:14:08 +02:00
|
|
|
try {
|
2020-10-09 19:49:23 +02:00
|
|
|
let table = await db.get(tableId)
|
2020-10-09 20:10:28 +02:00
|
|
|
let row = {}
|
2020-10-09 19:49:23 +02:00
|
|
|
for (let schemaKey of Object.keys(table.schema)) {
|
2020-12-07 18:55:35 +01:00
|
|
|
const paramValue = params[schemaKey]
|
2020-10-09 19:49:23 +02:00
|
|
|
let propSchema = table.schema[schemaKey]
|
2020-09-17 16:14:08 +02:00
|
|
|
switch (propSchema.constraints.type) {
|
|
|
|
case "string":
|
2020-12-07 18:55:35 +01:00
|
|
|
row[schemaKey] = paramValue || FAKE_STRING
|
2020-09-17 16:14:08 +02:00
|
|
|
break
|
|
|
|
case "boolean":
|
2020-12-07 18:55:35 +01:00
|
|
|
row[schemaKey] = paramValue || FAKE_BOOL
|
2020-09-17 16:14:08 +02:00
|
|
|
break
|
|
|
|
case "number":
|
2020-12-07 18:55:35 +01:00
|
|
|
row[schemaKey] = paramValue || FAKE_NUMBER
|
2020-09-17 16:14:08 +02:00
|
|
|
break
|
|
|
|
case "datetime":
|
2020-12-07 18:55:35 +01:00
|
|
|
row[schemaKey] = paramValue || FAKE_DATETIME
|
2020-09-17 16:14:08 +02:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2020-10-09 20:10:28 +02:00
|
|
|
params.row = row
|
2020-09-17 16:14:08 +02:00
|
|
|
} catch (err) {
|
2020-10-09 19:49:23 +02:00
|
|
|
throw "Failed to find table for trigger"
|
2020-09-17 16:14:08 +02:00
|
|
|
}
|
|
|
|
return params
|
|
|
|
}
|
|
|
|
|
2020-09-21 14:49:34 +02:00
|
|
|
module.exports.externalTrigger = async function(automation, params) {
|
2020-09-17 16:14:08 +02:00
|
|
|
// TODO: replace this with allowing user in builder to input values in future
|
|
|
|
if (
|
2020-09-21 14:49:34 +02:00
|
|
|
automation.definition != null &&
|
|
|
|
automation.definition.trigger != null &&
|
2020-10-09 19:49:23 +02:00
|
|
|
automation.definition.trigger.inputs.tableId != null
|
2020-09-17 16:14:08 +02:00
|
|
|
) {
|
2020-10-09 20:10:28 +02:00
|
|
|
params = await fillRowOutput(automation, params)
|
2020-09-17 16:14:08 +02:00
|
|
|
}
|
|
|
|
|
2020-09-21 14:49:34 +02:00
|
|
|
automationQueue.add({ automation, event: params })
|
2020-09-10 16:00:21 +02:00
|
|
|
}
|
|
|
|
|
2020-09-21 14:49:34 +02:00
|
|
|
module.exports.automationQueue = automationQueue
|
2020-09-16 15:00:04 +02:00
|
|
|
|
|
|
|
module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
|