Skip to content

Commit

Permalink
✨ Add Webhook block (#1815)
Browse files Browse the repository at this point in the history
Closes #1531
  • Loading branch information
baptisteArno authored Oct 7, 2024
1 parent 9d3537e commit 59c0ea0
Show file tree
Hide file tree
Showing 130 changed files with 2,454 additions and 644 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/deploy-partykit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Deploy Partykit server

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
# https://github.com/vercel/turborepo/issues/6348
- name: Run Turbo ignore
id: check_changes
run: |
echo "Running script..."
# Enable error handling
set +e
bunx turbo-ignore @typebot.io/partykit -task=build exit_code=$?
# Disable error handling
set -e
echo "Exit code: $exit_code"
if I $exit_code -eq 0 ]; then
echo "hasClientApiHostChanged=0" >> $GITHUB_OUTPUT
# echo "::save-state name=project_changed: :0"
# # echo "::set-output name=project_changed:: 0"
else
echo "hasClientApiHostChanged=1" » $GITHUB_OUTPUT
# echo "::set-output name=project_changed: : 1"
fi
- run: bun install
- run: bunx partykit deploy --domain ${PARTYKIT_DOMAIN}
working-directory: ./packages/partykit
env:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
PARTYKIT_DOMAIN: ${{ secrets.PARTYKIT_DOMAIN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ snapshots
.tsup

.env.docker

.partykit
1 change: 1 addition & 0 deletions apps/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"test:ui": "dotenv -e ./.env -e ../../.env -- playwright test --ui"
},
"dependencies": {
"partysocket": "1.0.2",
"@braintree/sanitize-url": "7.0.1",
"@chakra-ui/anatomy": "2.2.2",
"@chakra-ui/react": "2.8.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { fetchLinkedTypebots } from "@/features/blocks/logic/typebotLink/helpers
import { canReadTypebots } from "@/helpers/databaseRules";
import { authenticatedProcedure } from "@/helpers/server/trpc";
import { TRPCError } from "@trpc/server";
import { parseSampleResult } from "@typebot.io/bot-engine/blocks/integrations/webhook/parseSampleResult";
import { parseSampleResult } from "@typebot.io/bot-engine/blocks/integrations/httpRequest/parseSampleResult";
import { getBlockById } from "@typebot.io/groups/helpers";
import prisma from "@typebot.io/prisma";
import type { Typebot } from "@typebot.io/typebot/schemas/typebot";
Expand All @@ -16,8 +16,8 @@ export const getResultExample = authenticatedProcedure
protect: true,
summary: "Get result example",
description:
'Returns "fake" result for webhook block to help you anticipate how the webhook will behave.',
tags: ["Webhook"],
'Returns "fake" result for http request block to help you anticipate how the webhook will behave.',
tags: ["HTTP request"],
},
})
.input(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { canReadTypebots } from "@/helpers/databaseRules";
import { authenticatedProcedure } from "@/helpers/server/trpc";
import { TRPCError } from "@trpc/server";
import { isWebhookBlock } from "@typebot.io/blocks-core/helpers";
import { isHttpRequestBlock } from "@typebot.io/blocks-core/helpers";
import type { Block } from "@typebot.io/blocks-core/schemas/schema";
import { IntegrationBlockType } from "@typebot.io/blocks-integrations/constants";
import { parseGroups } from "@typebot.io/groups/schemas";
import { byId } from "@typebot.io/lib/utils";
import prisma from "@typebot.io/prisma";
import { z } from "@typebot.io/zod";

export const listWebhookBlocks = authenticatedProcedure
export const listHttpRequestBlocks = authenticatedProcedure
.meta({
openapi: {
method: "GET",
path: "/v1/typebots/{typebotId}/webhookBlocks",
protect: true,
summary: "List webhook blocks",
summary: "List HTTP request blocks",
description:
"Returns a list of all the webhook blocks that you can subscribe to.",
tags: ["Webhook"],
"Returns a list of all the HTTP request blocks that you can subscribe to.",
tags: ["HTTP request"],
},
})
.input(
Expand All @@ -32,7 +32,7 @@ export const listWebhookBlocks = authenticatedProcedure
z.object({
id: z.string(),
type: z.enum([
IntegrationBlockType.WEBHOOK,
IntegrationBlockType.HTTP_REQUEST,
IntegrationBlockType.ZAPIER,
IntegrationBlockType.MAKE_COM,
IntegrationBlockType.PABBLY_CONNECT,
Expand All @@ -59,21 +59,21 @@ export const listWebhookBlocks = authenticatedProcedure
typebotVersion: typebot.version,
});

const webhookBlocks = groups.reduce<
const httpRequestBlocks = groups.reduce<
{
id: string;
label: string;
url: string | undefined;
type:
| IntegrationBlockType.WEBHOOK
| IntegrationBlockType.HTTP_REQUEST
| IntegrationBlockType.ZAPIER
| IntegrationBlockType.MAKE_COM
| IntegrationBlockType.PABBLY_CONNECT;
}[]
>((webhookBlocks, group) => {
const blocks = (group.blocks as Block[]).filter(isWebhookBlock);
>((httpRequestBlock, group) => {
const blocks = (group.blocks as Block[]).filter(isHttpRequestBlock);
return [
...webhookBlocks,
...httpRequestBlock,
...blocks.map((block) => ({
id: block.id,
type: block.type,
Expand All @@ -87,5 +87,5 @@ export const listWebhookBlocks = authenticatedProcedure
];
}, []);

return { webhookBlocks };
return { webhookBlocks: httpRequestBlocks };
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { router } from "@/helpers/server/trpc";
import { getResultExample } from "./getResultExample";
import { listHttpRequestBlocks } from "./listHttpRequestBlocks";
import { subscribeHttpRequest } from "./subscribeHttpRequest";
import { unsubscribeHttpRequest } from "./unsubscribeHttpRequest";

export const httpRequestRouter = router({
listHttpRequestBlocks,
getResultExample,
subscribeHttpRequest,
unsubscribeHttpRequest,
});
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { canWriteTypebots } from "@/helpers/databaseRules";
import { authenticatedProcedure } from "@/helpers/server/trpc";
import { TRPCError } from "@trpc/server";
import { isWebhookBlock } from "@typebot.io/blocks-core/helpers";
import { isHttpRequestBlock } from "@typebot.io/blocks-core/helpers";
import type { Block } from "@typebot.io/blocks-core/schemas/schema";
import type { HttpRequestBlock } from "@typebot.io/blocks-integrations/webhook/schema";
import type { HttpRequestBlock } from "@typebot.io/blocks-integrations/httpRequest/schema";
import { parseGroups } from "@typebot.io/groups/schemas";
import { byId } from "@typebot.io/lib/utils";
import prisma from "@typebot.io/prisma";
import { z } from "@typebot.io/zod";

export const subscribeWebhook = authenticatedProcedure
export const subscribeHttpRequest = authenticatedProcedure
.meta({
openapi: {
method: "POST",
path: "/v1/typebots/{typebotId}/webhookBlocks/{blockId}/subscribe",
protect: true,
summary: "Subscribe to webhook block",
tags: ["Webhook"],
summary: "Subscribe to HTTP request block",
tags: ["HTTP request"],
},
})
.input(
Expand Down Expand Up @@ -48,30 +48,30 @@ export const subscribeWebhook = authenticatedProcedure
typebotVersion: typebot.version,
});

const webhookBlock = groups
const httpRequestBlock = groups
.flatMap<Block>((g) => g.blocks)
.find(byId(blockId)) as HttpRequestBlock | null;

if (!webhookBlock || !isWebhookBlock(webhookBlock))
if (!httpRequestBlock || !isHttpRequestBlock(httpRequestBlock))
throw new TRPCError({
code: "NOT_FOUND",
message: "Webhook block not found",
message: "HttpRequest block not found",
});

if (webhookBlock.options?.webhook || typebot.version === "6") {
if (httpRequestBlock.options?.webhook || typebot.version === "6") {
const updatedGroups = groups.map((group) =>
group.blocks.some((b) => b.id === webhookBlock.id)
group.blocks.some((b) => b.id === httpRequestBlock.id)
? {
...group,
blocks: group.blocks.map((block) =>
block.id !== webhookBlock.id
block.id !== httpRequestBlock.id
? block
: {
...block,
options: {
...webhookBlock.options,
...httpRequestBlock.options,
webhook: {
...webhookBlock.options?.webhook,
...httpRequestBlock.options?.webhook,
url,
},
},
Expand All @@ -87,15 +87,15 @@ export const subscribeWebhook = authenticatedProcedure
},
});
} else {
if ("webhookId" in webhookBlock)
if ("webhookId" in httpRequestBlock)
await prisma.webhook.update({
where: { id: webhookBlock.webhookId },
where: { id: httpRequestBlock.webhookId },
data: { url },
});
else
throw new TRPCError({
code: "NOT_FOUND",
message: "Webhook block not found",
message: "HttpRequest block not found",
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { canWriteTypebots } from "@/helpers/databaseRules";
import { authenticatedProcedure } from "@/helpers/server/trpc";
import { TRPCError } from "@trpc/server";
import { isWebhookBlock } from "@typebot.io/blocks-core/helpers";
import { isHttpRequestBlock } from "@typebot.io/blocks-core/helpers";
import type { Block } from "@typebot.io/blocks-core/schemas/schema";
import type { HttpRequestBlock } from "@typebot.io/blocks-integrations/webhook/schema";
import type { HttpRequestBlock } from "@typebot.io/blocks-integrations/httpRequest/schema";
import { parseGroups } from "@typebot.io/groups/schemas";
import { byId } from "@typebot.io/lib/utils";
import prisma from "@typebot.io/prisma";
import { z } from "@typebot.io/zod";

export const unsubscribeWebhook = authenticatedProcedure
export const unsubscribeHttpRequest = authenticatedProcedure
.meta({
openapi: {
method: "POST",
path: "/v1/typebots/{typebotId}/webhookBlocks/{blockId}/unsubscribe",
protect: true,
summary: "Unsubscribe from webhook block",
tags: ["Webhook"],
summary: "Unsubscribe from HTTP request block",
tags: ["HTTP request"],
},
})
.input(
Expand Down Expand Up @@ -47,30 +47,30 @@ export const unsubscribeWebhook = authenticatedProcedure
typebotVersion: typebot.version,
});

const webhookBlock = groups
const httpRequestBlock = groups
.flatMap<Block>((g) => g.blocks)
.find(byId(blockId)) as HttpRequestBlock | null;

if (!webhookBlock || !isWebhookBlock(webhookBlock))
if (!httpRequestBlock || !isHttpRequestBlock(httpRequestBlock))
throw new TRPCError({
code: "NOT_FOUND",
message: "Webhook block not found",
message: "HTTP request block not found",
});

if (webhookBlock.options?.webhook || typebot.version === "6") {
if (httpRequestBlock.options?.webhook || typebot.version === "6") {
const updatedGroups = groups.map((group) =>
group.blocks.some((b) => b.id === webhookBlock.id)
group.blocks.some((b) => b.id === httpRequestBlock.id)
? {
...group,
blocks: group.blocks.map((block) =>
block.id !== webhookBlock.id
block.id !== httpRequestBlock.id
? block
: {
...block,
options: {
...webhookBlock.options,
...httpRequestBlock.options,
webhook: {
...webhookBlock.options?.webhook,
...httpRequestBlock.options?.webhook,
url: undefined,
},
},
Expand All @@ -86,15 +86,15 @@ export const unsubscribeWebhook = authenticatedProcedure
},
});
} else {
if ("webhookId" in webhookBlock)
if ("webhookId" in httpRequestBlock)
await prisma.webhook.update({
where: { id: webhookBlock.webhookId },
where: { id: httpRequestBlock.webhookId },
data: { url: null },
});
else
throw new TRPCError({
code: "NOT_FOUND",
message: "Webhook block not found",
message: "HTTP request block not found",
});
}

Expand Down
Loading

0 comments on commit 59c0ea0

Please sign in to comment.