diff --git a/packages/server/src/api/controllers/automation.js b/packages/server/src/api/controllers/automation.js
index 2d164b415d..8a3bbd93ec 100644
--- a/packages/server/src/api/controllers/automation.js
+++ b/packages/server/src/api/controllers/automation.js
@@ -5,8 +5,8 @@ const triggers = require("../../automations/triggers")
const webhooks = require("./webhook")
const { getAutomationParams, generateAutomationID } = require("../../db/utils")
-const WH_STEP_ID = triggers.BUILTIN_DEFINITIONS.WEBHOOK.stepId
-const CRON_STEP_ID = triggers.BUILTIN_DEFINITIONS.CRON.stepId
+const WH_STEP_ID = triggers.TRIGGER_DEFINITIONS.WEBHOOK.stepId
+const CRON_STEP_ID = triggers.TRIGGER_DEFINITIONS.CRON.stepId
/*************************
* *
@@ -242,22 +242,22 @@ exports.destroy = async function (ctx) {
}
exports.getActionList = async function (ctx) {
- ctx.body = actions.DEFINITIONS
+ ctx.body = actions.ACTION_DEFINITIONS
}
exports.getTriggerList = async function (ctx) {
- ctx.body = triggers.BUILTIN_DEFINITIONS
+ ctx.body = triggers.TRIGGER_DEFINITIONS
}
exports.getLogicList = async function (ctx) {
- ctx.body = logic.BUILTIN_DEFINITIONS
+ ctx.body = logic.LOGIC_DEFINITIONS
}
module.exports.getDefinitionList = async function (ctx) {
ctx.body = {
- logic: logic.BUILTIN_DEFINITIONS,
- trigger: triggers.BUILTIN_DEFINITIONS,
- action: actions.DEFINITIONS,
+ logic: logic.LOGIC_DEFINITIONS,
+ trigger: triggers.TRIGGER_DEFINITIONS,
+ action: actions.ACTION_DEFINITIONS,
}
}
diff --git a/packages/server/src/api/routes/tests/automation.spec.js b/packages/server/src/api/routes/tests/automation.spec.js
index 5654c14c17..09e8747813 100644
--- a/packages/server/src/api/routes/tests/automation.spec.js
+++ b/packages/server/src/api/routes/tests/automation.spec.js
@@ -44,7 +44,7 @@ describe("/automations", () => {
ACTION_DEFINITIONS = res.body
})
- it("returns a list of definitions for triggers", async () => {
+ it("returns a list of definitions for triggerInfo", async () => {
const res = await request
.get(`/api/automations/trigger/list`)
.set(config.defaultHeaders())
diff --git a/packages/server/src/automations/actions.js b/packages/server/src/automations/actions.js
index 4577eccbaa..767f1120d4 100644
--- a/packages/server/src/automations/actions.js
+++ b/packages/server/src/automations/actions.js
@@ -13,7 +13,7 @@ const discord = require("./steps/discord")
const zapier = require("./steps/zapier")
const integromat = require("./steps/integromat")
-const BUILTIN_ACTIONS = {
+const ACTION_IMPLS = {
SEND_EMAIL: sendgridEmail.run,
SEND_EMAIL_SMTP: sendSmtpEmail.run,
CREATE_ROW: createRow.run,
@@ -29,7 +29,7 @@ const BUILTIN_ACTIONS = {
zapier: zapier.run,
integromat: integromat.run,
}
-const BUILTIN_DEFINITIONS = {
+const ACTION_DEFINITIONS = {
SEND_EMAIL: sendgridEmail.definition,
SEND_EMAIL_SMTP: sendSmtpEmail.definition,
CREATE_ROW: createRow.definition,
@@ -47,12 +47,10 @@ const BUILTIN_DEFINITIONS = {
}
/* istanbul ignore next */
-module.exports.getAction = async function (actionName) {
- if (BUILTIN_ACTIONS[actionName] != null) {
- return BUILTIN_ACTIONS[actionName]
+exports.getAction = async function (actionName) {
+ if (ACTION_IMPLS[actionName] != null) {
+ return ACTION_IMPLS[actionName]
}
}
-// definitions will have downloaded ones added to it, while builtin won't
-module.exports.DEFINITIONS = BUILTIN_DEFINITIONS
-module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
+exports.ACTION_DEFINITIONS = ACTION_DEFINITIONS
diff --git a/packages/server/src/automations/logic.js b/packages/server/src/automations/logic.js
index cbd3d42430..52ee51252b 100644
--- a/packages/server/src/automations/logic.js
+++ b/packages/server/src/automations/logic.js
@@ -1,20 +1,20 @@
let filter = require("./steps/filter")
let delay = require("./steps/delay")
-let BUILTIN_LOGIC = {
+let LOGIC_IMPLS = {
DELAY: delay.run,
FILTER: filter.run,
}
-let BUILTIN_DEFINITIONS = {
+let LOGIC_DEFINITIONS = {
DELAY: delay.definition,
FILTER: filter.definition,
}
-module.exports.getLogic = function (logicName) {
- if (BUILTIN_LOGIC[logicName] != null) {
- return BUILTIN_LOGIC[logicName]
+exports.getLogic = function (logicName) {
+ if (LOGIC_IMPLS[logicName] != null) {
+ return LOGIC_IMPLS[logicName]
}
}
-module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
+exports.LOGIC_DEFINITIONS = LOGIC_DEFINITIONS
diff --git a/packages/server/src/automations/steps/bash.js b/packages/server/src/automations/steps/bash.js
index 76d6713c5b..f2d98ce944 100644
--- a/packages/server/src/automations/steps/bash.js
+++ b/packages/server/src/automations/steps/bash.js
@@ -1,7 +1,7 @@
const { execSync } = require("child_process")
const { processStringSync } = require("@budibase/string-templates")
-module.exports.definition = {
+exports.definition = {
name: "Bash Scripting",
tagline: "Execute a bash command",
icon: "ri-terminal-box-line",
@@ -32,7 +32,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs, context }) {
+exports.run = async function ({ inputs, context }) {
if (inputs.code == null) {
return {
stdout: "Budibase bash automation failed: Invalid inputs",
diff --git a/packages/server/src/automations/steps/createRow.js b/packages/server/src/automations/steps/createRow.js
index 889f7e98b9..a08adfb000 100644
--- a/packages/server/src/automations/steps/createRow.js
+++ b/packages/server/src/automations/steps/createRow.js
@@ -3,7 +3,7 @@ const automationUtils = require("../automationUtils")
const env = require("../../environment")
const usage = require("../../utilities/usageQuota")
-module.exports.definition = {
+exports.definition = {
name: "Create Row",
tagline: "Create a {{inputs.enriched.table.name}} row",
icon: "ri-save-3-line",
@@ -58,7 +58,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs, appId, apiKey, emitter }) {
+exports.run = async function ({ inputs, appId, apiKey, emitter }) {
if (inputs.row == null || inputs.row.tableId == null) {
return {
success: false,
diff --git a/packages/server/src/automations/steps/delay.js b/packages/server/src/automations/steps/delay.js
index f653d0a980..b79d28e92d 100644
--- a/packages/server/src/automations/steps/delay.js
+++ b/packages/server/src/automations/steps/delay.js
@@ -1,6 +1,6 @@
let { wait } = require("../../utilities")
-module.exports.definition = {
+exports.definition = {
name: "Delay",
icon: "ri-time-line",
tagline: "Delay for {{inputs.time}} milliseconds",
@@ -21,6 +21,6 @@ module.exports.definition = {
type: "LOGIC",
}
-module.exports.run = async function delay({ inputs }) {
+exports.run = async function delay({ inputs }) {
await wait(inputs.time)
}
diff --git a/packages/server/src/automations/steps/deleteRow.js b/packages/server/src/automations/steps/deleteRow.js
index 94243fa03a..83e5969381 100644
--- a/packages/server/src/automations/steps/deleteRow.js
+++ b/packages/server/src/automations/steps/deleteRow.js
@@ -2,7 +2,7 @@ const rowController = require("../../api/controllers/row")
const env = require("../../environment")
const usage = require("../../utilities/usageQuota")
-module.exports.definition = {
+exports.definition = {
description: "Delete a row from your database",
icon: "ri-delete-bin-line",
name: "Delete Row",
@@ -50,7 +50,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs, appId, apiKey, emitter }) {
+exports.run = async function ({ inputs, appId, apiKey, emitter }) {
if (inputs.id == null || inputs.revision == null) {
return {
success: false,
diff --git a/packages/server/src/automations/steps/discord.js b/packages/server/src/automations/steps/discord.js
index 36406da5ce..2fefc92916 100644
--- a/packages/server/src/automations/steps/discord.js
+++ b/packages/server/src/automations/steps/discord.js
@@ -1,6 +1,6 @@
const fetch = require("node-fetch")
-module.exports.definition = {
+exports.definition = {
name: "Discord Message",
tagline: "Send a message to a Discord server",
description: "Send a message to a Discord server",
@@ -44,7 +44,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs }) {
+exports.run = async function ({ inputs }) {
const { url, username, avatar_url, content } = inputs
const response = await fetch(url, {
diff --git a/packages/server/src/automations/steps/executeQuery.js b/packages/server/src/automations/steps/executeQuery.js
index d045a75544..474b03766e 100644
--- a/packages/server/src/automations/steps/executeQuery.js
+++ b/packages/server/src/automations/steps/executeQuery.js
@@ -1,6 +1,6 @@
const queryController = require("../../api/controllers/query")
-module.exports.definition = {
+exports.definition = {
name: "External Data Connector",
tagline: "Execute Data Connector",
icon: "ri-database-2-line",
@@ -42,7 +42,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs, appId, emitter }) {
+exports.run = async function ({ inputs, appId, emitter }) {
if (inputs.query == null) {
return {
success: false,
diff --git a/packages/server/src/automations/steps/executeScript.js b/packages/server/src/automations/steps/executeScript.js
index 33ffd3ee8e..6eca4f4244 100644
--- a/packages/server/src/automations/steps/executeScript.js
+++ b/packages/server/src/automations/steps/executeScript.js
@@ -1,6 +1,6 @@
const scriptController = require("../../api/controllers/script")
-module.exports.definition = {
+exports.definition = {
name: "JS Scripting",
tagline: "Execute JavaScript Code",
icon: "ri-terminal-box-line",
@@ -36,7 +36,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs, appId, context, emitter }) {
+exports.run = async function ({ inputs, appId, context, emitter }) {
if (inputs.code == null) {
return {
success: false,
diff --git a/packages/server/src/automations/steps/filter.js b/packages/server/src/automations/steps/filter.js
index 586e424cc4..e15722e8d0 100644
--- a/packages/server/src/automations/steps/filter.js
+++ b/packages/server/src/automations/steps/filter.js
@@ -12,10 +12,10 @@ const PrettyLogicConditions = {
[LogicConditions.LESS_THAN]: "Less than",
}
-module.exports.LogicConditions = LogicConditions
-module.exports.PrettyLogicConditions = PrettyLogicConditions
+exports.LogicConditions = LogicConditions
+exports.PrettyLogicConditions = PrettyLogicConditions
-module.exports.definition = {
+exports.definition = {
name: "Filter",
tagline: "{{inputs.field}} {{inputs.condition}} {{inputs.value}}",
icon: "ri-git-branch-line",
@@ -57,7 +57,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function filter({ inputs }) {
+exports.run = async function filter({ inputs }) {
let { field, condition, value } = inputs
// coerce types so that we can use them
if (!isNaN(value) && !isNaN(field)) {
diff --git a/packages/server/src/automations/steps/integromat.js b/packages/server/src/automations/steps/integromat.js
index 2f610d6852..ef9d551286 100644
--- a/packages/server/src/automations/steps/integromat.js
+++ b/packages/server/src/automations/steps/integromat.js
@@ -1,6 +1,6 @@
const fetch = require("node-fetch")
-module.exports.definition = {
+exports.definition = {
name: "Integromat Integration",
tagline: "Trigger an Integromat scenario",
description:
@@ -55,7 +55,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs }) {
+exports.run = async function ({ inputs }) {
const { url, value1, value2, value3, value4, value5 } = inputs
const response = await fetch(url, {
diff --git a/packages/server/src/automations/steps/outgoingWebhook.js b/packages/server/src/automations/steps/outgoingWebhook.js
index c1edde7b4e..317f8967f5 100644
--- a/packages/server/src/automations/steps/outgoingWebhook.js
+++ b/packages/server/src/automations/steps/outgoingWebhook.js
@@ -16,7 +16,7 @@ const BODY_REQUESTS = [RequestType.POST, RequestType.PUT, RequestType.PATCH]
* GET/DELETE requests cannot handle body elements so they will not be sent if configured.
*/
-module.exports.definition = {
+exports.definition = {
name: "Outgoing webhook",
tagline: "Send a {{inputs.requestMethod}} request",
icon: "ri-send-plane-line",
@@ -70,7 +70,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs }) {
+exports.run = async function ({ inputs }) {
let { requestMethod, url, requestBody, headers } = inputs
if (!url.startsWith("http")) {
url = `http://${url}`
diff --git a/packages/server/src/automations/steps/sendSmtpEmail.js b/packages/server/src/automations/steps/sendSmtpEmail.js
index 764972b402..8b8d9b6db9 100644
--- a/packages/server/src/automations/steps/sendSmtpEmail.js
+++ b/packages/server/src/automations/steps/sendSmtpEmail.js
@@ -1,6 +1,6 @@
const { sendSmtpEmail } = require("../../utilities/workerRequests")
-module.exports.definition = {
+exports.definition = {
description: "Send an email using SMTP",
tagline: "Send SMTP email to {{inputs.to}}",
icon: "ri-mail-open-line",
@@ -46,7 +46,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs }) {
+exports.run = async function ({ inputs }) {
let { to, from, subject, contents } = inputs
if (!contents) {
contents = "
No content
"
diff --git a/packages/server/src/automations/steps/sendgridEmail.js b/packages/server/src/automations/steps/sendgridEmail.js
index 5485116e89..bde5f96e4f 100644
--- a/packages/server/src/automations/steps/sendgridEmail.js
+++ b/packages/server/src/automations/steps/sendgridEmail.js
@@ -1,4 +1,4 @@
-module.exports.definition = {
+exports.definition = {
description: "Send an email using SendGrid",
tagline: "Send email to {{inputs.to}}",
icon: "ri-mail-open-line",
@@ -48,7 +48,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs }) {
+exports.run = async function ({ inputs }) {
const sgMail = require("@sendgrid/mail")
sgMail.setApiKey(inputs.apiKey)
const msg = {
diff --git a/packages/server/src/automations/steps/serverLog.js b/packages/server/src/automations/steps/serverLog.js
index 7389b65f54..7183ff89fd 100644
--- a/packages/server/src/automations/steps/serverLog.js
+++ b/packages/server/src/automations/steps/serverLog.js
@@ -4,7 +4,7 @@
* GET/DELETE requests cannot handle body elements so they will not be sent if configured.
*/
-module.exports.definition = {
+exports.definition = {
name: "Backend log",
tagline: "Console log a value in the backend",
icon: "ri-server-line",
@@ -36,6 +36,6 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs, appId }) {
+exports.run = async function ({ inputs, appId }) {
console.log(`App ${appId} - ${inputs.text}`)
}
diff --git a/packages/server/src/automations/steps/updateRow.js b/packages/server/src/automations/steps/updateRow.js
index 206e429efa..898869959e 100644
--- a/packages/server/src/automations/steps/updateRow.js
+++ b/packages/server/src/automations/steps/updateRow.js
@@ -1,7 +1,7 @@
const rowController = require("../../api/controllers/row")
const automationUtils = require("../automationUtils")
-module.exports.definition = {
+exports.definition = {
name: "Update Row",
tagline: "Update a {{inputs.enriched.table.name}} row",
icon: "ri-refresh-line",
@@ -53,7 +53,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs, appId, emitter }) {
+exports.run = async function ({ inputs, appId, emitter }) {
if (inputs.rowId == null || inputs.row == null) {
return {
success: false,
diff --git a/packages/server/src/automations/steps/zapier.js b/packages/server/src/automations/steps/zapier.js
index 676286e236..0a7362cede 100644
--- a/packages/server/src/automations/steps/zapier.js
+++ b/packages/server/src/automations/steps/zapier.js
@@ -1,6 +1,6 @@
const fetch = require("node-fetch")
-module.exports.definition = {
+exports.definition = {
name: "Zapier Webhook",
stepId: "zapier",
type: "ACTION",
@@ -52,7 +52,7 @@ module.exports.definition = {
},
}
-module.exports.run = async function ({ inputs }) {
+exports.run = async function ({ inputs }) {
const { url, value1, value2, value3, value4, value5 } = inputs
// send the platform to make sure zaps always work, even
diff --git a/packages/server/src/automations/tests/utilities/index.js b/packages/server/src/automations/tests/utilities/index.js
index ab9de55430..516463091d 100644
--- a/packages/server/src/automations/tests/utilities/index.js
+++ b/packages/server/src/automations/tests/utilities/index.js
@@ -56,5 +56,5 @@ exports.runStep = async function runStep(stepId, inputs) {
exports.apiKey = "test"
-exports.actions = actions.BUILTIN_DEFINITIONS
-exports.logic = logic.BUILTIN_DEFINITIONS
+exports.actions = actions.ACTION_DEFINITIONS
+exports.logic = logic.LOGIC_DEFINITIONS
diff --git a/packages/server/src/automations/thread.js b/packages/server/src/automations/thread.js
index aada0ca0ca..87d3f98d16 100644
--- a/packages/server/src/automations/thread.js
+++ b/packages/server/src/automations/thread.js
@@ -8,7 +8,7 @@ const CouchDB = require("../db")
const { DocumentTypes } = require("../db/utils")
const { doInTenant } = require("@budibase/auth/tenancy")
-const FILTER_STEP_ID = logic.BUILTIN_DEFINITIONS.FILTER.stepId
+const FILTER_STEP_ID = logic.LOGIC_DEFINITIONS.FILTER.stepId
/**
* The automation orchestrator is a class responsible for executing automations.
diff --git a/packages/server/src/automations/triggerInfo/app.js b/packages/server/src/automations/triggerInfo/app.js
new file mode 100644
index 0000000000..1c64795cf3
--- /dev/null
+++ b/packages/server/src/automations/triggerInfo/app.js
@@ -0,0 +1,31 @@
+exports.definition = {
+ name: "App Action",
+ event: "app:trigger",
+ icon: "ri-window-fill",
+ tagline: "Automation fired from the frontend",
+ description: "Trigger an automation from an action inside your app",
+ stepId: "APP",
+ inputs: {},
+ schema: {
+ inputs: {
+ properties: {
+ fields: {
+ type: "object",
+ customType: "triggerSchema",
+ title: "Fields",
+ },
+ },
+ required: [],
+ },
+ outputs: {
+ properties: {
+ fields: {
+ type: "object",
+ description: "Fields submitted from the app frontend",
+ },
+ },
+ required: ["fields"],
+ },
+ },
+ type: "TRIGGER",
+}
diff --git a/packages/server/src/automations/triggerInfo/cron.js b/packages/server/src/automations/triggerInfo/cron.js
new file mode 100644
index 0000000000..9ef4649b95
--- /dev/null
+++ b/packages/server/src/automations/triggerInfo/cron.js
@@ -0,0 +1,31 @@
+exports.defintion = {
+ name: "Cron Trigger",
+ event: "cron:trigger",
+ icon: "ri-timer-line",
+ tagline: "Cron Trigger ({{inputs.cron}})",
+ description: "Triggers automation on a cron schedule.",
+ stepId: "CRON",
+ inputs: {},
+ schema: {
+ inputs: {
+ properties: {
+ cron: {
+ type: "string",
+ customType: "cron",
+ title: "Expression",
+ },
+ },
+ required: ["cron"],
+ },
+ outputs: {
+ properties: {
+ timestamp: {
+ type: "number",
+ description: "Timestamp the cron was executed",
+ },
+ },
+ required: ["timestamp"],
+ },
+ },
+ type: "TRIGGER",
+}
diff --git a/packages/server/src/automations/triggerInfo/index.js b/packages/server/src/automations/triggerInfo/index.js
new file mode 100644
index 0000000000..476d37d54c
--- /dev/null
+++ b/packages/server/src/automations/triggerInfo/index.js
@@ -0,0 +1,15 @@
+const app = require("./app")
+const cron = require("./cron")
+const rowDeleted = require("./rowDeleted")
+const rowSaved = require("./rowSaved")
+const rowUpdated = require("./rowUpdated")
+const webhook = require("./webhook")
+
+exports.definitions = {
+ ROW_SAVED: rowSaved.definition,
+ ROW_UPDATED: rowUpdated.definition,
+ ROW_DELETED: rowDeleted.definition,
+ WEBHOOK: webhook.definition,
+ APP: app.definition,
+ CRON: cron.defintion,
+}
diff --git a/packages/server/src/automations/triggerInfo/rowDeleted.js b/packages/server/src/automations/triggerInfo/rowDeleted.js
new file mode 100644
index 0000000000..c7ead1fec4
--- /dev/null
+++ b/packages/server/src/automations/triggerInfo/rowDeleted.js
@@ -0,0 +1,32 @@
+exports.definition = {
+ name: "Row Deleted",
+ event: "row:delete",
+ icon: "ri-delete-bin-line",
+ tagline: "Row is deleted from {{inputs.enriched.table.name}}",
+ description: "Fired when a row is deleted from your database",
+ stepId: "ROW_DELETED",
+ inputs: {},
+ schema: {
+ inputs: {
+ properties: {
+ tableId: {
+ type: "string",
+ customType: "table",
+ title: "Table",
+ },
+ },
+ required: ["tableId"],
+ },
+ outputs: {
+ properties: {
+ row: {
+ type: "object",
+ customType: "row",
+ description: "The row that was deleted",
+ },
+ },
+ required: ["row"],
+ },
+ },
+ type: "TRIGGER",
+}
diff --git a/packages/server/src/automations/triggerInfo/rowSaved.js b/packages/server/src/automations/triggerInfo/rowSaved.js
new file mode 100644
index 0000000000..3a21a26878
--- /dev/null
+++ b/packages/server/src/automations/triggerInfo/rowSaved.js
@@ -0,0 +1,40 @@
+exports.definition = {
+ name: "Row Created",
+ event: "row:save",
+ icon: "ri-save-line",
+ tagline: "Row is added to {{inputs.enriched.table.name}}",
+ description: "Fired when a row is added to your database",
+ stepId: "ROW_SAVED",
+ inputs: {},
+ schema: {
+ inputs: {
+ properties: {
+ tableId: {
+ type: "string",
+ customType: "table",
+ title: "Table",
+ },
+ },
+ required: ["tableId"],
+ },
+ outputs: {
+ properties: {
+ row: {
+ type: "object",
+ customType: "row",
+ description: "The new row that was created",
+ },
+ id: {
+ type: "string",
+ description: "Row ID - can be used for updating",
+ },
+ revision: {
+ type: "string",
+ description: "Revision of row",
+ },
+ },
+ required: ["row", "id"],
+ },
+ },
+ type: "TRIGGER",
+}
diff --git a/packages/server/src/automations/triggerInfo/rowUpdated.js b/packages/server/src/automations/triggerInfo/rowUpdated.js
new file mode 100644
index 0000000000..099ce0a6b2
--- /dev/null
+++ b/packages/server/src/automations/triggerInfo/rowUpdated.js
@@ -0,0 +1,40 @@
+exports.definition = {
+ name: "Row Updated",
+ event: "row:update",
+ icon: "ri-refresh-line",
+ tagline: "Row is updated in {{inputs.enriched.table.name}}",
+ description: "Fired when a row is updated in your database",
+ stepId: "ROW_UPDATED",
+ inputs: {},
+ schema: {
+ inputs: {
+ properties: {
+ tableId: {
+ type: "string",
+ customType: "table",
+ title: "Table",
+ },
+ },
+ required: ["tableId"],
+ },
+ outputs: {
+ properties: {
+ row: {
+ type: "object",
+ customType: "row",
+ description: "The row that was updated",
+ },
+ id: {
+ type: "string",
+ description: "Row ID - can be used for updating",
+ },
+ revision: {
+ type: "string",
+ description: "Revision of row",
+ },
+ },
+ required: ["row", "id"],
+ },
+ },
+ type: "TRIGGER",
+}
diff --git a/packages/server/src/automations/triggerInfo/webhook.js b/packages/server/src/automations/triggerInfo/webhook.js
new file mode 100644
index 0000000000..dd83031d8f
--- /dev/null
+++ b/packages/server/src/automations/triggerInfo/webhook.js
@@ -0,0 +1,36 @@
+exports.definition = {
+ 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: {
+ properties: {
+ body: {
+ type: "object",
+ description: "Body of the request which hit the webhook",
+ },
+ },
+ required: ["body"],
+ },
+ },
+ type: "TRIGGER",
+}
diff --git a/packages/server/src/automations/triggers.js b/packages/server/src/automations/triggers.js
index 2a2d68ecb1..3ce09e15fd 100644
--- a/packages/server/src/automations/triggers.js
+++ b/packages/server/src/automations/triggers.js
@@ -8,232 +8,12 @@ const { getAutomationParams } = require("../db/utils")
const { coerce } = require("../utilities/rowProcessor")
const { utils } = require("@budibase/auth/redis")
const { JobQueues } = require("../constants")
-const {
- isExternalTable,
- breakExternalTableId,
-} = require("../integrations/utils")
-const { getExternalTable } = require("../api/controllers/table/utils")
+const { definitions } = require("./triggerInfo")
const { opts } = utils.getRedisOptions()
let automationQueue = new Queue(JobQueues.AUTOMATIONS, { redis: opts })
-const FAKE_STRING = "TEST"
-const FAKE_BOOL = false
-const FAKE_NUMBER = 1
-const FAKE_DATETIME = "1970-01-01T00:00:00.000Z"
-
-const BUILTIN_DEFINITIONS = {
- ROW_SAVED: {
- name: "Row Created",
- event: "row:save",
- icon: "ri-save-line",
- tagline: "Row is added to {{inputs.enriched.table.name}}",
- description: "Fired when a row is added to your database",
- stepId: "ROW_SAVED",
- inputs: {},
- schema: {
- inputs: {
- properties: {
- tableId: {
- type: "string",
- customType: "table",
- title: "Table",
- },
- },
- required: ["tableId"],
- },
- outputs: {
- properties: {
- row: {
- type: "object",
- customType: "row",
- description: "The new row that was created",
- },
- id: {
- type: "string",
- description: "Row ID - can be used for updating",
- },
- revision: {
- type: "string",
- description: "Revision of row",
- },
- },
- required: ["row", "id"],
- },
- },
- type: "TRIGGER",
- },
- ROW_UPDATED: {
- name: "Row Updated",
- event: "row:update",
- icon: "ri-refresh-line",
- tagline: "Row is updated in {{inputs.enriched.table.name}}",
- description: "Fired when a row is updated in your database",
- stepId: "ROW_UPDATED",
- inputs: {},
- schema: {
- inputs: {
- properties: {
- tableId: {
- type: "string",
- customType: "table",
- title: "Table",
- },
- },
- required: ["tableId"],
- },
- outputs: {
- properties: {
- row: {
- type: "object",
- customType: "row",
- description: "The row that was updated",
- },
- id: {
- type: "string",
- description: "Row ID - can be used for updating",
- },
- revision: {
- type: "string",
- description: "Revision of row",
- },
- },
- required: ["row", "id"],
- },
- },
- type: "TRIGGER",
- },
- ROW_DELETED: {
- name: "Row Deleted",
- event: "row:delete",
- icon: "ri-delete-bin-line",
- tagline: "Row is deleted from {{inputs.enriched.table.name}}",
- description: "Fired when a row is deleted from your database",
- stepId: "ROW_DELETED",
- inputs: {},
- schema: {
- inputs: {
- properties: {
- tableId: {
- type: "string",
- customType: "table",
- title: "Table",
- },
- },
- required: ["tableId"],
- },
- outputs: {
- properties: {
- row: {
- type: "object",
- customType: "row",
- description: "The row that was deleted",
- },
- },
- required: ["row"],
- },
- },
- type: "TRIGGER",
- },
- 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: {
- properties: {
- body: {
- type: "object",
- description: "Body of the request which hit the webhook",
- },
- },
- required: ["body"],
- },
- },
- type: "TRIGGER",
- },
- APP: {
- name: "App Action",
- event: "app:trigger",
- icon: "ri-window-fill",
- tagline: "Automation fired from the frontend",
- description: "Trigger an automation from an action inside your app",
- stepId: "APP",
- inputs: {},
- schema: {
- inputs: {
- properties: {
- fields: {
- type: "object",
- customType: "triggerSchema",
- title: "Fields",
- },
- },
- required: [],
- },
- outputs: {
- properties: {
- fields: {
- type: "object",
- description: "Fields submitted from the app frontend",
- },
- },
- required: ["fields"],
- },
- },
- type: "TRIGGER",
- },
- CRON: {
- name: "Cron Trigger",
- event: "cron:trigger",
- icon: "ri-timer-line",
- tagline: "Cron Trigger ({{inputs.cron}})",
- description: "Triggers automation on a cron schedule.",
- stepId: "CRON",
- inputs: {},
- schema: {
- inputs: {
- properties: {
- cron: {
- type: "string",
- customType: "cron",
- title: "Expression",
- },
- },
- required: ["cron"],
- },
- outputs: {
- properties: {
- timestamp: {
- type: "number",
- description: "Timestamp the cron was executed",
- },
- },
- required: ["timestamp"],
- },
- },
- type: "TRIGGER",
- },
-}
+const TRIGGER_DEFINITIONS = definitions
async function queueRelevantRowAutomations(event, eventType) {
if (event.appId == null) {
@@ -262,7 +42,7 @@ async function queueRelevantRowAutomations(event, eventType) {
) {
continue
}
- automationQueue.add({ automation, event })
+ await automationQueue.add({ automation, event })
}
}
@@ -290,51 +70,8 @@ emitter.on("row:delete", async function (event) {
await queueRelevantRowAutomations(event, "row:delete")
})
-async function fillRowOutput(automation, params) {
- let triggerSchema = automation.definition.trigger
- let tableId = triggerSchema.inputs.tableId
- try {
- let table
- if (!isExternalTable(tableId)) {
- const db = new CouchDB(params.appId)
- table = await db.get(tableId)
- } else {
- const { datasourceId, tableName } = breakExternalTableId(tableId)
- table = await getExternalTable(params.appId, datasourceId, tableName)
- }
- let row = {}
- for (let schemaKey of Object.keys(table.schema)) {
- const paramValue = params[schemaKey]
- let propSchema = table.schema[schemaKey]
- switch (propSchema.constraints.type) {
- case "string":
- row[schemaKey] = paramValue || FAKE_STRING
- break
- case "boolean":
- row[schemaKey] = paramValue || FAKE_BOOL
- break
- case "number":
- row[schemaKey] = paramValue || FAKE_NUMBER
- break
- case "datetime":
- row[schemaKey] = paramValue || FAKE_DATETIME
- break
- }
- }
- params.row = row
- } catch (err) {
- /* istanbul ignore next */
- throw "Failed to find table for trigger"
- }
- return params
-}
-
-module.exports.externalTrigger = async function (automation, params) {
- // TODO: replace this with allowing user in builder to input values in future
+exports.externalTrigger = async function (automation, params) {
if (automation.definition != null && automation.definition.trigger != null) {
- if (automation.definition.trigger.inputs.tableId != null) {
- params = await fillRowOutput(automation, params)
- }
if (automation.definition.trigger.stepId === "APP") {
// values are likely to be submitted as strings, so we shall convert to correct type
const coercedFields = {}
@@ -346,13 +83,12 @@ module.exports.externalTrigger = async function (automation, params) {
}
}
- automationQueue.add({ automation, event: params })
+ await automationQueue.add({ automation, event: params })
}
-module.exports.getQueues = () => {
+exports.getQueues = () => {
return [automationQueue]
}
-module.exports.fillRowOutput = fillRowOutput
-module.exports.automationQueue = automationQueue
+exports.automationQueue = automationQueue
-module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
+exports.TRIGGER_DEFINITIONS = TRIGGER_DEFINITIONS
diff --git a/packages/server/src/middleware/usageQuota.js b/packages/server/src/middleware/usageQuota.js
index ac8336e769..4647878721 100644
--- a/packages/server/src/middleware/usageQuota.js
+++ b/packages/server/src/middleware/usageQuota.js
@@ -14,7 +14,7 @@ const DOMAIN_MAP = {
views: usageQuota.Properties.VIEW,
users: usageQuota.Properties.USER,
// this will not be updated by endpoint calls
- // instead it will be updated by triggers
+ // instead it will be updated by triggerInfo
automationRuns: usageQuota.Properties.AUTOMATION,
}