2022-11-26 08:57:07 +13:00
|
|
|
import fetch from "node-fetch"
|
|
|
|
import { getFetchResponse } from "./utils"
|
2022-11-27 04:10:41 +13:00
|
|
|
import * as automationUtils from "../automationUtils"
|
2022-11-26 08:57:07 +13:00
|
|
|
import {
|
|
|
|
AutomationActionStepId,
|
2023-04-07 05:11:44 +12:00
|
|
|
AutomationCustomIOType,
|
|
|
|
AutomationIOType,
|
2022-11-26 08:57:07 +13:00
|
|
|
AutomationStepInput,
|
2023-04-07 05:11:44 +12:00
|
|
|
AutomationStepSchema,
|
|
|
|
AutomationStepType,
|
2022-11-26 08:57:07 +13:00
|
|
|
} from "@budibase/types"
|
2020-10-28 01:33:25 +13:00
|
|
|
|
2022-11-26 08:57:07 +13:00
|
|
|
enum RequestType {
|
|
|
|
POST = "POST",
|
|
|
|
GET = "GET",
|
|
|
|
PUT = "PUT",
|
|
|
|
DELETE = "DELETE",
|
|
|
|
PATCH = "PATCH",
|
2020-10-28 01:33:25 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
const BODY_REQUESTS = [RequestType.POST, RequestType.PUT, RequestType.PATCH]
|
|
|
|
|
|
|
|
/**
|
2021-12-15 06:59:02 +13:00
|
|
|
* NOTE: this functionality is deprecated - it no longer should be used.
|
2020-10-28 01:33:25 +13:00
|
|
|
*/
|
|
|
|
|
2022-11-27 04:10:41 +13:00
|
|
|
export const definition: AutomationStepSchema = {
|
2021-12-15 06:59:02 +13:00
|
|
|
deprecated: true,
|
2020-10-28 01:33:25 +13:00
|
|
|
name: "Outgoing webhook",
|
|
|
|
tagline: "Send a {{inputs.requestMethod}} request",
|
2021-09-08 01:32:43 +12:00
|
|
|
icon: "Send",
|
2020-10-28 01:33:25 +13:00
|
|
|
description: "Send a request of specified method to a URL",
|
2023-04-07 05:11:44 +12:00
|
|
|
type: AutomationStepType.ACTION,
|
2021-09-14 23:40:19 +12:00
|
|
|
internal: true,
|
2022-11-26 08:57:07 +13:00
|
|
|
stepId: AutomationActionStepId.OUTGOING_WEBHOOK,
|
2020-10-28 01:33:25 +13:00
|
|
|
inputs: {
|
|
|
|
requestMethod: "POST",
|
|
|
|
url: "http://",
|
|
|
|
requestBody: "{}",
|
2021-08-04 08:39:01 +12:00
|
|
|
headers: "{}",
|
2020-10-28 01:33:25 +13:00
|
|
|
},
|
|
|
|
schema: {
|
|
|
|
inputs: {
|
|
|
|
properties: {
|
|
|
|
requestMethod: {
|
2023-04-07 05:11:44 +12:00
|
|
|
type: AutomationIOType.STRING,
|
2020-10-28 01:33:25 +13:00
|
|
|
enum: Object.values(RequestType),
|
|
|
|
title: "Request method",
|
|
|
|
},
|
|
|
|
url: {
|
2023-04-07 05:11:44 +12:00
|
|
|
type: AutomationIOType.STRING,
|
2020-10-28 01:33:25 +13:00
|
|
|
title: "URL",
|
|
|
|
},
|
|
|
|
requestBody: {
|
2023-04-07 05:11:44 +12:00
|
|
|
type: AutomationIOType.STRING,
|
2020-10-28 01:33:25 +13:00
|
|
|
title: "JSON Body",
|
2023-04-07 05:11:44 +12:00
|
|
|
customType: AutomationCustomIOType.WIDE,
|
2020-10-28 01:33:25 +13:00
|
|
|
},
|
2021-08-04 08:39:01 +12:00
|
|
|
headers: {
|
2023-04-07 05:11:44 +12:00
|
|
|
type: AutomationIOType.STRING,
|
2021-08-04 08:39:01 +12:00
|
|
|
title: "Headers",
|
2023-04-07 05:11:44 +12:00
|
|
|
customType: AutomationCustomIOType.WIDE,
|
2021-08-04 08:39:01 +12:00
|
|
|
},
|
2020-10-28 01:33:25 +13:00
|
|
|
},
|
|
|
|
required: ["requestMethod", "url"],
|
|
|
|
},
|
|
|
|
outputs: {
|
|
|
|
properties: {
|
|
|
|
response: {
|
2023-04-07 05:11:44 +12:00
|
|
|
type: AutomationIOType.OBJECT,
|
2020-10-28 01:33:25 +13:00
|
|
|
description: "The response from the webhook",
|
|
|
|
},
|
2021-09-08 04:31:54 +12:00
|
|
|
httpStatus: {
|
2023-04-07 05:11:44 +12:00
|
|
|
type: AutomationIOType.NUMBER,
|
2021-09-08 04:31:54 +12:00
|
|
|
description: "The HTTP status code returned",
|
|
|
|
},
|
2020-10-28 01:33:25 +13:00
|
|
|
success: {
|
2023-04-07 05:11:44 +12:00
|
|
|
type: AutomationIOType.BOOLEAN,
|
2020-10-28 01:33:25 +13:00
|
|
|
description: "Whether the action was successful",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
required: ["response", "success"],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-11-26 08:57:07 +13:00
|
|
|
export async function run({ inputs }: AutomationStepInput) {
|
2021-08-04 08:39:01 +12:00
|
|
|
let { requestMethod, url, requestBody, headers } = inputs
|
2020-10-28 01:33:25 +13:00
|
|
|
if (!url.startsWith("http")) {
|
|
|
|
url = `http://${url}`
|
|
|
|
}
|
2022-11-26 08:57:07 +13:00
|
|
|
const request: any = {
|
2020-10-28 01:33:25 +13:00
|
|
|
method: requestMethod,
|
|
|
|
}
|
2021-11-04 02:13:22 +13:00
|
|
|
if (headers) {
|
|
|
|
try {
|
|
|
|
const customHeaders =
|
|
|
|
typeof headers === "string" ? JSON.parse(headers) : headers
|
|
|
|
request.headers = { ...request.headers, ...customHeaders }
|
|
|
|
} catch (err) {
|
|
|
|
return {
|
|
|
|
success: false,
|
|
|
|
response: "Unable to process headers, must be a JSON object.",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-28 01:33:25 +13:00
|
|
|
if (
|
|
|
|
requestBody &&
|
|
|
|
requestBody.length !== 0 &&
|
|
|
|
BODY_REQUESTS.indexOf(requestMethod) !== -1
|
|
|
|
) {
|
2021-06-24 07:18:21 +12:00
|
|
|
request.body =
|
|
|
|
typeof requestBody === "string"
|
|
|
|
? requestBody
|
|
|
|
: JSON.stringify(requestBody)
|
2021-06-24 06:28:33 +12:00
|
|
|
request.headers = {
|
2021-11-04 02:13:22 +13:00
|
|
|
...request.headers,
|
2021-06-24 06:28:33 +12:00
|
|
|
"Content-Type": "application/json",
|
|
|
|
}
|
2020-10-28 01:33:25 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2021-06-24 06:28:33 +12:00
|
|
|
// do a quick JSON parse if there is a body, to generate an error if its invalid
|
|
|
|
if (request.body) {
|
|
|
|
JSON.parse(request.body)
|
|
|
|
}
|
2020-10-28 03:16:57 +13:00
|
|
|
const response = await fetch(url, request)
|
2021-09-08 04:31:54 +12:00
|
|
|
const { status, message } = await getFetchResponse(response)
|
2020-10-28 01:33:25 +13:00
|
|
|
return {
|
2021-09-08 04:31:54 +12:00
|
|
|
httpStatus: status,
|
|
|
|
response: message,
|
2021-11-04 02:13:22 +13:00
|
|
|
success: status >= 200 && status <= 206,
|
2020-10-28 01:33:25 +13:00
|
|
|
}
|
|
|
|
} catch (err) {
|
2021-03-13 04:32:16 +13:00
|
|
|
/* istanbul ignore next */
|
2020-10-28 01:33:25 +13:00
|
|
|
return {
|
|
|
|
success: false,
|
2021-10-20 05:00:54 +13:00
|
|
|
response: automationUtils.getError(err),
|
2020-10-28 01:33:25 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|