From ee3d8bc343c4917a1369f2ebc959a5291e1bd6ba Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Fri, 21 Mar 2025 12:20:22 -0700 Subject: [PATCH] feat[webhook]: added github webhook (#136) --- sim/app/blocks/blocks/starter.ts | 2 +- .../components/providers/github-config.tsx | 121 +++++++++++++++--- .../webhook/components/ui/copyable.tsx | 3 +- .../webhook/components/ui/webhook-footer.tsx | 2 +- .../webhook/components/ui/webhook-header.tsx | 3 +- .../webhook/components/ui/webhook-url.tsx | 3 +- .../webhook/components/webhook-modal.tsx | 9 +- 7 files changed, 117 insertions(+), 26 deletions(-) diff --git a/sim/app/blocks/blocks/starter.ts b/sim/app/blocks/blocks/starter.ts index 163bd7f274..aaa019f376 100644 --- a/sim/app/blocks/blocks/starter.ts +++ b/sim/app/blocks/blocks/starter.ts @@ -40,7 +40,7 @@ export const StarterBlock: BlockConfig = { options: [ { label: 'Generic', id: 'generic' }, { label: 'WhatsApp', id: 'whatsapp' }, - // { label: 'GitHub', id: 'github' }, + { label: 'GitHub', id: 'github' }, // { label: 'Stripe', id: 'stripe' }, ], value: () => 'generic', diff --git a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/github-config.tsx b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/github-config.tsx index 5a2ba9e78d..84586a92b5 100644 --- a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/github-config.tsx +++ b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/providers/github-config.tsx @@ -1,10 +1,21 @@ -import { Loader2 } from 'lucide-react' -import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { CopyableField } from '../ui/copyable' +import { TestResultDisplay } from '../ui/test-result' interface GithubConfigProps { contentType: string setContentType: (contentType: string) => void + webhookSecret: string + setWebhookSecret: (secret: string) => void + sslVerification: string + setSslVerification: (value: string) => void isLoadingToken: boolean testResult: { success: boolean @@ -13,50 +24,122 @@ interface GithubConfigProps { } | null copied: string | null copyToClipboard: (text: string, type: string) => void + testWebhook: () => Promise } export function GithubConfig({ contentType, setContentType, + webhookSecret, + setWebhookSecret, + sslVerification, + setSslVerification, isLoadingToken, testResult, + copied, + copyToClipboard, }: GithubConfigProps) { return (
- {isLoadingToken ? ( -
- -
- ) : ( - setContentType(e.target.value)} - placeholder="application/json" - className="flex-1" - /> - )} + +

+ Format GitHub will use when sending the webhook payload. +

+ + +
+ + +

+ GitHub will verify SSL certificates when delivering webhooks. +

+
+ + +

Setup Instructions

  1. Go to your GitHub repository
  2. Navigate to Settings {'>'} Webhooks
  3. Click "Add webhook"
  4. -
  5. Enter the Webhook URL shown above
  6. +
  7. Enter the Webhook URL shown above as the "Payload URL"
  8. Set Content type to "{contentType}"
  9. -
  10. Choose which events you want to trigger the webhook
  11. -
  12. Ensure "Active" is checked and save
  13. + {webhookSecret && ( +
  14. Enter the same secret shown above in the "Secret" field for validation
  15. + )} +
  16. Choose SSL verification
  17. +
  18. + Choose which events trigger the webhook (e.g., "Just the push event" or "Send me + everything") +
  19. +
  20. Ensure "Active" is checked and click "Add webhook"
+
+
+ Security Best Practices +
+
    +
  • + • + + Always use a secret token to validate requests from GitHub + +
  • +
  • + • + + Keep SSL verification enabled unless you have a specific reason to disable it + +
  • +
+
+

💡 - After saving, GitHub will send a ping event to verify your webhook. + After saving, GitHub will send a ping event to verify your webhook. You can view delivery + details and redeliver events from the webhook settings.

diff --git a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/copyable.tsx b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/copyable.tsx index 169ced5162..2e87a514d4 100644 --- a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/copyable.tsx +++ b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/copyable.tsx @@ -33,7 +33,7 @@ export function CopyableField({ return (
-
+
{isLoading ? (
@@ -54,6 +54,7 @@ export function CopyableField({ size="icon" onClick={() => copyToClipboard(value, copyType)} disabled={isLoading || !value} + className="ml-1" > {copied === copyType ? : } diff --git a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-footer.tsx b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-footer.tsx index b592affdc2..a09ecb3a9d 100644 --- a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-footer.tsx +++ b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-footer.tsx @@ -31,7 +31,7 @@ export function WebhookDialogFooter({ webhookId && (webhookProvider === 'whatsapp' || webhookProvider === 'generic') && onTest return ( - +
{webhookId && (
diff --git a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-header.tsx b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-header.tsx index 140943fb3f..ba0a74b824 100644 --- a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-header.tsx +++ b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-header.tsx @@ -13,7 +13,8 @@ export function WebhookDialogHeader({ webhookProvider, webhookId }: WebhookDialo // Get provider icon const getProviderIcon = () => { return provider.icon({ - className: 'h-5 w-5 text-green-500 dark:text-green-400', + className: + webhookProvider === 'github' ? 'h-5 w-5' : 'h-5 w-5 text-green-500 dark:text-green-400', }) } diff --git a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-url.tsx b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-url.tsx index bcb697b062..16715e453c 100644 --- a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-url.tsx +++ b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/ui/webhook-url.tsx @@ -19,7 +19,7 @@ export function WebhookUrlField({ return (
-
+
{isLoadingToken ? (
@@ -33,6 +33,7 @@ export function WebhookUrlField({ size="icon" onClick={() => copyToClipboard(webhookUrl, 'url')} disabled={isLoadingToken} + className="ml-1" > {copied === 'url' ? : } diff --git a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx index 7e060f431c..96f6398f00 100644 --- a/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx +++ b/sim/app/w/[id]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx @@ -374,10 +374,15 @@ export function WebhookModal({ setRequireAuth(value === 'enabled')} isLoadingToken={isLoadingToken} testResult={testResult} copied={copied} copyToClipboard={copyToClipboard} + testWebhook={testWebhook} /> ) case 'stripe': @@ -414,10 +419,10 @@ export function WebhookModal({ return ( <> - + -
+