Cleanup, prepping for automation history, some refactoring to get rid of concept of builtin.
This commit is contained in:
parent
5cc5bd4533
commit
2531d9a681
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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, {
|
||||
|
|
|
@ -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}`
|
||||
|
|
|
@ -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 = "<h1>No content</h1>"
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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}`)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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",
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
exports.defintion = {
|
||||
name: "Cron Trigger",
|
||||
event: "cron:trigger",
|
||||
icon: "ri-timer-line",
|
||||
tagline: "Cron Trigger (<b>{{inputs.cron}}</b>)",
|
||||
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",
|
||||
}
|
|
@ -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,
|
||||
}
|
|
@ -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",
|
||||
}
|
|
@ -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",
|
||||
}
|
|
@ -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",
|
||||
}
|
|
@ -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",
|
||||
}
|
|
@ -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 (<b>{{inputs.cron}}</b>)",
|
||||
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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue