From c4cac4a0b1813c762f5985a257c281409ff72f00 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 23 Jun 2021 19:28:33 +0100 Subject: [PATCH 1/3] Fixing some issues discovered with POSTing JSON. --- .../src/automations/steps/outgoingWebhook.js | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/server/src/automations/steps/outgoingWebhook.js b/packages/server/src/automations/steps/outgoingWebhook.js index f476d57ac5..3e56834d3f 100644 --- a/packages/server/src/automations/steps/outgoingWebhook.js +++ b/packages/server/src/automations/steps/outgoingWebhook.js @@ -77,14 +77,31 @@ module.exports.run = async function ({ inputs }) { requestBody.length !== 0 && BODY_REQUESTS.indexOf(requestMethod) !== -1 ) { - request.body = JSON.parse(requestBody) + request.body = requestBody + request.headers = { + "Content-Type": "application/json", + } } try { + // do a quick JSON parse if there is a body, to generate an error if its invalid + if (request.body) { + JSON.parse(request.body) + } const response = await fetch(url, request) + const contentType = response.headers.get("content-type") + const success = response.status === 200 + let resp + if (!success) { + resp = response.statusText + } else if (contentType && contentType.indexOf("application/json") !== -1) { + resp = await response.json() + } else { + resp = await response.text() + } return { - response: await response.json(), - success: response.status === 200, + response: resp, + success: success, } } catch (err) { /* istanbul ignore next */ From 2a0cfc949d183ab2605a2238c046477eb9b14cd6 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 23 Jun 2021 20:11:05 +0100 Subject: [PATCH 2/3] Fixing issue with automation webhook URL being undefined. --- .../Shared/CreateWebhookModal.svelte | 12 +++--- .../automation/Shared/WebhookDisplay.svelte | 3 ++ .../server/src/api/controllers/automation.js | 37 ++++++++++++------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/packages/builder/src/components/automation/Shared/CreateWebhookModal.svelte b/packages/builder/src/components/automation/Shared/CreateWebhookModal.svelte index 44e91efd50..04656c1e2e 100644 --- a/packages/builder/src/components/automation/Shared/CreateWebhookModal.svelte +++ b/packages/builder/src/components/automation/Shared/CreateWebhookModal.svelte @@ -16,11 +16,13 @@ $: automation = $automationStore.selectedAutomation?.automation onMount(async () => { - // save the automation initially - await automationStore.actions.save({ - instanceId, - automation, - }) + if (!automation?.definition?.trigger?.inputs.schemaUrl) { + // save the automation initially + await automationStore.actions.save({ + instanceId, + automation, + }) + } interval = setInterval(async () => { await automationStore.actions.fetch() const outputs = automation?.definition?.trigger.schema.outputs?.properties diff --git a/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte b/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte index e1f2fe78d8..fc5e20f241 100644 --- a/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte +++ b/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte @@ -9,6 +9,9 @@ $: appUrl = $hostingStore.appUrl function fullWebhookURL(uri) { + if (!uri) { + return "" + } if (production) { return `${appUrl}/${uri}` } else { diff --git a/packages/server/src/api/controllers/automation.js b/packages/server/src/api/controllers/automation.js index e1e721b347..2d164b415d 100644 --- a/packages/server/src/api/controllers/automation.js +++ b/packages/server/src/api/controllers/automation.js @@ -88,6 +88,8 @@ async function checkForCronTriggers({ appId, oldAuto, newAuto }) { async function checkForWebhooks({ appId, oldAuto, newAuto }) { const oldTrigger = oldAuto ? oldAuto.definition.trigger : null const newTrigger = newAuto ? newAuto.definition.trigger : null + const triggerChanged = + oldTrigger && newTrigger && oldTrigger.id !== newTrigger.id function isWebhookTrigger(auto) { return ( auto && @@ -98,25 +100,32 @@ async function checkForWebhooks({ appId, oldAuto, newAuto }) { // need to delete webhook if ( isWebhookTrigger(oldAuto) && - !isWebhookTrigger(newAuto) && + (!isWebhookTrigger(newAuto) || triggerChanged) && oldTrigger.webhookId ) { - let db = new CouchDB(appId) - // need to get the webhook to get the rev - const webhook = await db.get(oldTrigger.webhookId) - const ctx = { - appId, - params: { id: webhook._id, rev: webhook._rev }, + try { + let db = new CouchDB(appId) + // need to get the webhook to get the rev + const webhook = await db.get(oldTrigger.webhookId) + const ctx = { + appId, + params: { id: webhook._id, rev: webhook._rev }, + } + // might be updating - reset the inputs to remove the URLs + if (newTrigger) { + delete newTrigger.webhookId + newTrigger.inputs = {} + } + await webhooks.destroy(ctx) + } catch (err) { + // don't worry about not being able to delete, if it doesn't exist all good } - // might be updating - reset the inputs to remove the URLs - if (newTrigger) { - delete newTrigger.webhookId - newTrigger.inputs = {} - } - await webhooks.destroy(ctx) } // need to create webhook - else if (!isWebhookTrigger(oldAuto) && isWebhookTrigger(newAuto)) { + if ( + (!isWebhookTrigger(oldAuto) || triggerChanged) && + isWebhookTrigger(newAuto) + ) { const ctx = { appId, request: { From 2db995c90620bac70ba8c22557f642c1c9967c15 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 23 Jun 2021 20:18:21 +0100 Subject: [PATCH 3/3] Fixing test case and removing console.log. --- .../automation/AutomationBuilder/FlowChart/FlowItem.svelte | 1 - packages/server/__mocks__/node-fetch.js | 5 +++++ packages/server/src/automations/steps/outgoingWebhook.js | 5 ++++- .../server/src/automations/tests/outgoingWebhook.spec.js | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 45594c0f0d..439db62639 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -14,7 +14,6 @@ $: allowDeleteTrigger = !steps.length function deleteStep() { - console.log("Running") automationStore.actions.deleteAutomationBlock(block) } diff --git a/packages/server/__mocks__/node-fetch.js b/packages/server/__mocks__/node-fetch.js index dfca7fd379..a06d026f38 100644 --- a/packages/server/__mocks__/node-fetch.js +++ b/packages/server/__mocks__/node-fetch.js @@ -4,6 +4,11 @@ module.exports = async (url, opts) => { function json(body, status = 200) { return { status, + headers: { + get: () => { + return ["application/json"] + }, + }, json: async () => { return body }, diff --git a/packages/server/src/automations/steps/outgoingWebhook.js b/packages/server/src/automations/steps/outgoingWebhook.js index 3e56834d3f..269e075018 100644 --- a/packages/server/src/automations/steps/outgoingWebhook.js +++ b/packages/server/src/automations/steps/outgoingWebhook.js @@ -77,7 +77,10 @@ module.exports.run = async function ({ inputs }) { requestBody.length !== 0 && BODY_REQUESTS.indexOf(requestMethod) !== -1 ) { - request.body = requestBody + request.body = + typeof requestBody === "string" + ? requestBody + : JSON.stringify(requestBody) request.headers = { "Content-Type": "application/json", } diff --git a/packages/server/src/automations/tests/outgoingWebhook.spec.js b/packages/server/src/automations/tests/outgoingWebhook.spec.js index f1d8d25ba8..9f82fb7604 100644 --- a/packages/server/src/automations/tests/outgoingWebhook.spec.js +++ b/packages/server/src/automations/tests/outgoingWebhook.spec.js @@ -25,7 +25,7 @@ describe("test the outgoing webhook action", () => { expect(res.success).toEqual(true) expect(res.response.url).toEqual("http://www.test.com") expect(res.response.method).toEqual("POST") - expect(res.response.body.a).toEqual(1) + expect(JSON.parse(res.response.body).a).toEqual(1) }) it("should return an error if something goes wrong in fetch", async () => {