Joe-ifying some of the work on webhooks to make it a bit easier to understand and finished up some testing around it.
This commit is contained in:
parent
fdf0fdd145
commit
c66541ad99
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { backendUiStore, automationStore } from "builderStore"
|
||||
import CreateWebookModal from "./CreateWebhookModal.svelte"
|
||||
import CreateWebookModal from "../../Shared/CreateWebhookModal.svelte"
|
||||
import analytics from "analytics"
|
||||
import { Modal } from "@budibase/bbui"
|
||||
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
import RowSelector from "./ParamInputs/RowSelector.svelte"
|
||||
import { Button, Input, TextArea, Select, Label } from "@budibase/bbui"
|
||||
import { automationStore } from "builderStore"
|
||||
import WebhookDisplay from "../AutomationPanel/BlockList/WebhookDisplay.svelte"
|
||||
import WebhookDisplay from "../Shared/WebhookDisplay.svelte"
|
||||
import BindableInput from "../../userInterface/BindableInput.svelte"
|
||||
|
||||
export let block
|
||||
export let webhookModal
|
||||
$: inputs = Object.entries(block.schema?.inputs?.properties || {})
|
||||
$: stepId = block.stepId
|
||||
$: bindings = getAvailableBindings(
|
||||
block,
|
||||
$automationStore.selectedAutomation?.automation?.definition
|
||||
|
@ -76,6 +78,11 @@
|
|||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{#if stepId === "WEBHOOK"}
|
||||
<Button wide secondary on:click={() => webhookModal.show()}>
|
||||
Setup webhook
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
import { backendUiStore, automationStore } from "builderStore"
|
||||
import { notifier } from "builderStore/store/notifications"
|
||||
import AutomationBlockSetup from "./AutomationBlockSetup.svelte"
|
||||
import { Button, Input, Label } from "@budibase/bbui"
|
||||
import { Button, Input, Label, Modal } from "@budibase/bbui"
|
||||
import CreateWebookModal from "../Shared/CreateWebhookModal.svelte"
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||
|
||||
let selectedTab = "SETUP"
|
||||
let confirmDeleteDialog
|
||||
let webhookModal
|
||||
|
||||
$: instanceId = $backendUiStore.selectedDatabase._id
|
||||
$: automation = $automationStore.selectedAutomation?.automation
|
||||
|
@ -60,7 +62,7 @@
|
|||
</header>
|
||||
<div class="content">
|
||||
{#if $automationStore.selectedBlock}
|
||||
<AutomationBlockSetup bind:block={$automationStore.selectedBlock} />
|
||||
<AutomationBlockSetup bind:block={$automationStore.selectedBlock} webhookModal={webhookModal} />
|
||||
{:else if $automationStore.selectedAutomation}
|
||||
<div class="block-label">Automation <b>{automation.name}</b></div>
|
||||
<Button secondary wide on:click={testAutomation}>Test Automation</Button>
|
||||
|
@ -102,6 +104,9 @@
|
|||
body={`Are you sure you wish to delete the automation '${name}'?`}
|
||||
okText="Delete Automation"
|
||||
onOk={deleteAutomation} />
|
||||
<Modal bind:this={webhookModal} width="30%">
|
||||
<CreateWebookModal />
|
||||
</Modal>
|
||||
|
||||
<style>
|
||||
section {
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
const DEFAULT_SCHEMA_OUTPUT = "Any input allowed"
|
||||
let name
|
||||
let interval
|
||||
let valid = false
|
||||
let finished = false
|
||||
let schemaURL
|
||||
let schema = DEFAULT_SCHEMA_OUTPUT
|
||||
let propCount = 0
|
||||
|
||||
$: instanceId = $backendUiStore.selectedDatabase._id
|
||||
$: appId = $store.appId
|
||||
|
@ -27,16 +27,10 @@
|
|||
interval = setInterval(async () => {
|
||||
await automationStore.actions.fetch()
|
||||
const outputs = automation?.definition?.trigger.schema.outputs?.properties
|
||||
if (Object.keys(outputs).length !== 0) {
|
||||
schema = cloneDeep(outputs)
|
||||
// clear out the "description" properties
|
||||
for (let key of Object.keys(schema)) {
|
||||
delete schema[key].description
|
||||
}
|
||||
schema = JSON.stringify(schema, null, 2)
|
||||
//schema = schema.replace(/(?:\r\n|\r|\n)/g, "<br />")
|
||||
//console.log(schema)
|
||||
valid = true
|
||||
// always one prop for the "body"
|
||||
if (Object.keys(outputs).length > 1) {
|
||||
propCount = Object.keys(outputs).length - 1
|
||||
finished = true
|
||||
}
|
||||
}, POLL_RATE_MS)
|
||||
schemaURL = automation?.definition?.trigger?.inputs.schemaUrl
|
||||
|
@ -50,17 +44,18 @@
|
|||
<ModalContent
|
||||
title="Webhook Setup"
|
||||
confirmText="Finished"
|
||||
cancelText="Skip"
|
||||
disabled={!valid}>
|
||||
<p class="webhook-exp">
|
||||
To configure a webhook we need to create a schema for your webhook to
|
||||
validate against. Use the URL shown below and send a
|
||||
<b>POST</b>
|
||||
request to it with a JSON body in the format that your webhook should use!
|
||||
showConfirmButton={finished}
|
||||
cancelText="Skip">
|
||||
<p>
|
||||
Webhooks are for receiving data. To make them easier please use the URL
|
||||
shown below and send a <code>POST</code> request to it from your other application.
|
||||
If you're unable to do this now then you can skip this step, however we
|
||||
will not be able to configure bindings for your later actions!
|
||||
</p>
|
||||
<WebhookDisplay value={schemaURL} />
|
||||
<h5>Schema</h5>
|
||||
<code> {schema} </code>
|
||||
{#if finished}
|
||||
<p class="finished-text">Request received! We found {propCount} bindable value{propCount > 1 ? "s" : ""}.</p>
|
||||
{/if}
|
||||
<div slot="footer">
|
||||
<a target="_blank" href="https://docs.budibase.com/automate/steps/triggers">
|
||||
<i class="ri-information-line" />
|
||||
|
@ -91,16 +86,19 @@
|
|||
padding-top: 0;
|
||||
text-align: justify;
|
||||
}
|
||||
.finished-text {
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
color: var(--blue);
|
||||
}
|
||||
h5 {
|
||||
margin: 0;
|
||||
}
|
||||
code {
|
||||
padding: 8px;
|
||||
padding: 1px 4px 1px 4px;
|
||||
font-size: 14px;
|
||||
color: var(--grey-5);
|
||||
color: var(--grey-7);
|
||||
background-color: var(--grey-4);
|
||||
border-radius: 6px;
|
||||
display: block;
|
||||
white-space: pre-wrap;
|
||||
border-radius: 2px;
|
||||
}
|
||||
</style>
|
|
@ -19,19 +19,23 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<div class="copy-area">
|
||||
<div>
|
||||
<Input disabled="true" thin value={fullWebhookURL(value)} />
|
||||
<span class="copy-btn" on:click={() => copyToClipboard()}>
|
||||
<span on:click={() => copyToClipboard()}>
|
||||
<i class="ri-clipboard-line copy-icon" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.copy-area {
|
||||
div {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
div :global(input:disabled) {
|
||||
color: var(--grey-7);
|
||||
}
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
|
@ -46,7 +50,7 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
span:hover {
|
||||
background-color: var(--grey-3);
|
||||
}
|
||||
</style>
|
|
@ -87,7 +87,13 @@ exports.trigger = async ctx => {
|
|||
validate(ctx.request.body, webhook.bodySchema)
|
||||
const target = await db.get(webhook.action.target)
|
||||
if (webhook.action.type === exports.WebhookType.AUTOMATION) {
|
||||
await triggers.externalTrigger(target, ctx.request.body)
|
||||
// trigger with both the pure request and then expand it
|
||||
// incase the user has produced a schema to bind to
|
||||
await triggers.externalTrigger(target, {
|
||||
body: ctx.request.body,
|
||||
...ctx.request.body,
|
||||
instanceId: ctx.params.instance,
|
||||
})
|
||||
}
|
||||
ctx.status = 200
|
||||
ctx.body = "Webhook trigger fired successfully"
|
||||
|
|
|
@ -108,8 +108,13 @@ const BUILTIN_DEFINITIONS = {
|
|||
required: ["schemaUrl", "triggerUrl"],
|
||||
},
|
||||
outputs: {
|
||||
properties: {},
|
||||
required: [],
|
||||
properties: {
|
||||
body: {
|
||||
type: "object",
|
||||
description: "Body of the request which hit the webhook",
|
||||
},
|
||||
},
|
||||
required: ["body"],
|
||||
},
|
||||
},
|
||||
type: "TRIGGER",
|
||||
|
|
Loading…
Reference in New Issue