227 lines
6.3 KiB
TypeScript
227 lines
6.3 KiB
TypeScript
import * as triggers from "../../automations/triggers"
|
|
import { sdk as coreSdk } from "@budibase/shared-core"
|
|
import { DocumentType } from "../../db/utils"
|
|
import { updateTestHistory, removeDeprecated } from "../../automations/utils"
|
|
import { setTestFlag, clearTestFlag } from "../../utilities/redis"
|
|
import { context, cache, events, db as dbCore } from "@budibase/backend-core"
|
|
import { automations, features } from "@budibase/pro"
|
|
import {
|
|
App,
|
|
Automation,
|
|
AutomationActionStepId,
|
|
AutomationResults,
|
|
UserCtx,
|
|
DeleteAutomationResponse,
|
|
FetchAutomationResponse,
|
|
} from "@budibase/types"
|
|
import { getActionDefinitions as actionDefs } from "../../automations/actions"
|
|
import sdk from "../../sdk"
|
|
import { builderSocket } from "../../websockets"
|
|
import env from "../../environment"
|
|
|
|
async function getActionDefinitions() {
|
|
return removeDeprecated(await actionDefs())
|
|
}
|
|
|
|
function getTriggerDefinitions() {
|
|
return removeDeprecated(triggers.TRIGGER_DEFINITIONS)
|
|
}
|
|
|
|
/*************************
|
|
* *
|
|
* BUILDER FUNCTIONS *
|
|
* *
|
|
*************************/
|
|
|
|
export async function create(
|
|
ctx: UserCtx<Automation, { message: string; automation: Automation }>
|
|
) {
|
|
let automation = ctx.request.body
|
|
automation.appId = ctx.appId
|
|
|
|
// call through to update if already exists
|
|
if (automation._id && automation._rev) {
|
|
await update(ctx)
|
|
return
|
|
}
|
|
|
|
const createdAutomation = await sdk.automations.create(automation)
|
|
|
|
ctx.status = 200
|
|
ctx.body = {
|
|
message: "Automation created successfully",
|
|
automation: createdAutomation,
|
|
}
|
|
builderSocket?.emitAutomationUpdate(ctx, automation)
|
|
}
|
|
|
|
export async function update(ctx: UserCtx) {
|
|
let automation = ctx.request.body
|
|
automation.appId = ctx.appId
|
|
|
|
// Call through to create if it doesn't exist
|
|
if (!automation._id || !automation._rev) {
|
|
await create(ctx)
|
|
return
|
|
}
|
|
|
|
const updatedAutomation = await sdk.automations.update(automation)
|
|
|
|
ctx.status = 200
|
|
ctx.body = {
|
|
message: `Automation ${automation._id} updated successfully.`,
|
|
automation: updatedAutomation,
|
|
}
|
|
builderSocket?.emitAutomationUpdate(ctx, automation)
|
|
}
|
|
|
|
export async function fetch(ctx: UserCtx<void, FetchAutomationResponse>) {
|
|
const query: { enrich?: string } = ctx.request.query || {}
|
|
const enrich = query.enrich === "true"
|
|
|
|
const automations = await sdk.automations.fetch()
|
|
ctx.body = { automations }
|
|
if (enrich) {
|
|
ctx.body.builderData = await sdk.automations.utils.getBuilderData(
|
|
automations
|
|
)
|
|
}
|
|
}
|
|
|
|
export async function find(ctx: UserCtx) {
|
|
ctx.body = await sdk.automations.get(ctx.params.id)
|
|
}
|
|
|
|
export async function destroy(ctx: UserCtx<void, DeleteAutomationResponse>) {
|
|
const automationId = ctx.params.id
|
|
|
|
const automation = await sdk.automations.get(ctx.params.id)
|
|
if (coreSdk.automations.isRowAction(automation)) {
|
|
ctx.throw("Row actions automations cannot be deleted", 422)
|
|
}
|
|
|
|
ctx.body = await sdk.automations.remove(automationId, ctx.params.rev)
|
|
builderSocket?.emitAutomationDeletion(ctx, automationId)
|
|
}
|
|
|
|
export async function logSearch(ctx: UserCtx) {
|
|
ctx.body = await automations.logs.logSearch(ctx.request.body)
|
|
}
|
|
|
|
export async function clearLogError(ctx: UserCtx) {
|
|
const { automationId, appId } = ctx.request.body
|
|
await context.doInAppContext(appId, async () => {
|
|
const db = context.getProdAppDB()
|
|
const metadata = await db.get<App>(DocumentType.APP_METADATA)
|
|
if (!automationId) {
|
|
delete metadata.automationErrors
|
|
} else if (
|
|
metadata.automationErrors &&
|
|
metadata.automationErrors[automationId]
|
|
) {
|
|
delete metadata.automationErrors[automationId]
|
|
}
|
|
await db.put(metadata)
|
|
await cache.app.invalidateAppMetadata(metadata.appId, metadata)
|
|
ctx.body = { message: `Error logs cleared.` }
|
|
})
|
|
}
|
|
|
|
export async function getActionList(ctx: UserCtx) {
|
|
ctx.body = await getActionDefinitions()
|
|
}
|
|
|
|
export async function getTriggerList(ctx: UserCtx) {
|
|
ctx.body = getTriggerDefinitions()
|
|
}
|
|
|
|
export async function getDefinitionList(ctx: UserCtx) {
|
|
ctx.body = {
|
|
trigger: getTriggerDefinitions(),
|
|
action: await getActionDefinitions(),
|
|
}
|
|
}
|
|
|
|
/*********************
|
|
* *
|
|
* API FUNCTIONS *
|
|
* *
|
|
*********************/
|
|
|
|
export async function trigger(ctx: UserCtx) {
|
|
const db = context.getAppDB()
|
|
let automation = await db.get<Automation>(ctx.params.id)
|
|
|
|
let hasCollectStep = sdk.automations.utils.checkForCollectStep(automation)
|
|
if (hasCollectStep && (await features.isSyncAutomationsEnabled())) {
|
|
try {
|
|
const response: AutomationResults = await triggers.externalTrigger(
|
|
automation,
|
|
{
|
|
fields: ctx.request.body.fields,
|
|
timeout:
|
|
ctx.request.body.timeout * 1000 || env.AUTOMATION_THREAD_TIMEOUT,
|
|
},
|
|
{ getResponses: true }
|
|
)
|
|
|
|
let collectedValue = response.steps.find(
|
|
step => step.stepId === AutomationActionStepId.COLLECT
|
|
)
|
|
ctx.body = collectedValue?.outputs
|
|
} catch (err: any) {
|
|
if (err.message) {
|
|
ctx.throw(400, err.message)
|
|
} else {
|
|
throw err
|
|
}
|
|
}
|
|
} else {
|
|
if (ctx.appId && !dbCore.isProdAppID(ctx.appId)) {
|
|
ctx.throw(400, "Only apps in production support this endpoint")
|
|
}
|
|
await triggers.externalTrigger(automation, {
|
|
...ctx.request.body,
|
|
appId: ctx.appId,
|
|
})
|
|
ctx.body = {
|
|
message: `Automation ${automation._id} has been triggered.`,
|
|
automation,
|
|
}
|
|
}
|
|
}
|
|
|
|
function prepareTestInput(input: any) {
|
|
// prepare the test parameters
|
|
if (input.id && input.row) {
|
|
input.row._id = input.id
|
|
}
|
|
if (input.revision && input.row) {
|
|
input.row._rev = input.revision
|
|
}
|
|
return input
|
|
}
|
|
|
|
export async function test(ctx: UserCtx) {
|
|
const db = context.getAppDB()
|
|
let automation = await db.get<Automation>(ctx.params.id)
|
|
await setTestFlag(automation._id!)
|
|
const testInput = prepareTestInput(ctx.request.body)
|
|
const response = await triggers.externalTrigger(
|
|
automation,
|
|
{
|
|
...testInput,
|
|
appId: ctx.appId,
|
|
},
|
|
{ getResponses: true }
|
|
)
|
|
// save a test history run
|
|
await updateTestHistory(ctx.appId, automation, {
|
|
...ctx.request.body,
|
|
occurredAt: new Date().getTime(),
|
|
})
|
|
await clearTestFlag(automation._id!)
|
|
ctx.body = response
|
|
await events.automation.tested(automation)
|
|
}
|