Skip to content

feat(webhooks): dedup and custom ack configuration - #3525

Merged
icecrasher321 merged 3 commits into
stagingfrom
feat/webhook-trigger-configs
Mar 11, 2026
Merged

feat(webhooks): dedup and custom ack configuration#3525
icecrasher321 merged 3 commits into
stagingfrom
feat/webhook-trigger-configs

Conversation

@icecrasher321

Copy link
Copy Markdown
Collaborator

Summary

Deduplication and Custom Acknowledgemetn Configuration for generic webhooks.

Type of Change

  • New feature

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercelBot commented Mar 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
docsSkippedSkippedMar 11, 2026 10:46pm

Request Review

@cursor

cursorBot commented Mar 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Adds configurable idempotency and custom HTTP responses to the generic webhook ingestion path, which can change execution de-dup behavior and what external providers receive. Also tweaks trigger output caching and workflow-change detection, which could affect reruns and deployment change detection.

Overview
Generic webhooks now support configurable deduplication by extracting an idempotency key from a user-specified dot-path in the payload and feeding it into the webhook idempotency key (x-sim-idempotency-key), enabling 7-day duplicate suppression.

Generic webhooks also gain custom acknowledgement responses (status code + optional JSON/text body) returned directly from the webhook endpoint when responseMode is set to custom, along with updated trigger UI/docs to surface these options.

Separately, trigger execution reuses any existing cached output (even empty), and workflow comparison/normalization now ignores subBlock type differences to avoid false-positive “changed” detection.

Written by Cursor Bugbot for commit 781cc28. Configure here.

@greptile-apps

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds two features to the generic webhook trigger: payload-based deduplication (via a configurable dot-notation field path that maps to an idempotency key) and custom acknowledgement responses (allowing users to specify a status code and body to return to the webhook caller synchronously). The changes span the webhook processor, idempotency service, trigger config, and executor handler.

Key changes and concerns:

  • Trigger handler regression risk (trigger-handler.ts): The guard Object.keys(existingState.output).length > 0 was removed, meaning a trigger block with an empty-object state ({}) now short-circuits before falling back to the starter block's webhook data. The sibling executeStarterBlock method still uses the original length guard, making the asymmetry look unintentional.
  • Missing defaultValue on responseMode dropdown (webhook.ts): Without a default, the field is undefined for new/existing webhooks, leaving the responseStatusCode and responseBody conditional fields in an indeterminate UI state.
  • Global type exclusion in diff comparison (normalize.ts): Removing type from extractSubBlockRest globally hides subBlock type changes across all blocks during workflow comparison — not scoped to just the new responseBody subBlock — which may silently suppress legitimate structural diffs.
  • No status code validation (processor.ts): responseStatusCode accepts any numeric value without range-checking, allowing invalid HTTP codes (e.g. 0, 999) to be forwarded to NextResponse.

Confidence Score: 2/5

  • Not safe to merge as-is — the trigger handler change may silently return empty output for trigger blocks, and the global type exclusion in the diff normaliser could suppress legitimate workflow change detection.
  • Two of the four issues are logic-level: the empty-output short-circuit in the trigger handler (inconsistent with the same guard in executeStarterBlock) and the global removal of type from subBlock comparison which could hide structural changes. The missing defaultValue on the dropdown is a correctness gap for the UI. These together lower confidence meaningfully despite the happy-path being straightforward.
  • apps/sim/executor/handlers/trigger/trigger-handler.ts and apps/sim/lib/workflows/comparison/normalize.ts need the most attention before merging.

Important Files Changed

FilenameOverview
apps/sim/executor/handlers/trigger/trigger-handler.tsRemoved Object.keys(existingState.output).length > 0 guard — trigger blocks with an empty-object state now short-circuit before the webhook-data fallback, a potential regression inconsistent with the still-present guard in executeStarterBlock.
apps/sim/triggers/generic/webhook.tsAdds four new subBlock configs for deduplication and custom acknowledgement; responseMode dropdown is missing a defaultValue, which can leave dependent conditional fields in an indeterminate state.
apps/sim/lib/webhooks/processor.tsAdds payload-field extraction for idempotency key injection and custom response emission for generic webhooks; responseStatusCode is not validated, allowing out-of-range HTTP codes to be forwarded.
apps/sim/lib/core/idempotency/service.tsAdds x-sim-idempotency-key as the highest-priority header in createWebhookIdempotencyKey, ensuring the payload-extracted deduplication value is used when present.
apps/sim/lib/workflows/comparison/normalize.tsGlobally excludes the type field from subBlock comparison; this hides subBlock type changes across all blocks, not just the newly added responseBody code block, risking silent misses in the diff/save logic.
apps/sim/blocks/blocks/generic_webhook.tsDocumentation-only change: adds a best-practice hint about the new deduplication field. No logic issues.

Sequence Diagram

sequenceDiagram
participant Caller as Webhook Caller
participant Processor as processor.ts
participant IdempSvc as IdempotencyService
participant Queue as Job Queue
participant TriggerHandler as TriggerBlockHandler
Caller->>Processor: POST /api/webhooks/trigger/:path
Processor->>Processor: Parse headers & body
alt provider === 'generic' && idempotencyField set
Processor->>Processor: Extract value via dot-notation path from body
Processor->>Processor: Set headers['x-sim-idempotency-key'] = extracted value
end
Processor->>IdempSvc: createWebhookIdempotencyKey(webhookId, headers, body, provider)
IdempSvc->>IdempSvc: Check x-sim-idempotency-key (NEW, highest priority)
IdempSvc->>IdempSvc: Fallback to webhook-id, x-webhook-id, etc.
IdempSvc-->>Processor: idempotency key
Processor->>IdempSvc: claim(key, ttl=7days)
alt duplicate within 7 days
IdempSvc-->>Processor: already processed
Processor-->>Caller: 200 (skipped)
else new event
Processor->>Queue: enqueue('webhook-execution', payload)
Queue-->>Processor: jobId
alt provider === 'generic' && responseMode === 'custom'
Processor->>Processor: Read responseStatusCode & responseBody from providerConfig
Processor-->>Caller: Custom HTTP response (status + body)
else default
Processor-->>Caller: 200 { message: 'Webhook processed' }
end
Queue->>TriggerHandler: execute(ctx, block, inputs)
TriggerHandler->>TriggerHandler: Check existingState.output (truthy check only now)
TriggerHandler-->>Queue: trigger output
end
Loading

Last reviewed commit: 69cd0fd

Comment threadapps/sim/executor/handlers/trigger/trigger-handler.ts
Comment threadapps/sim/triggers/generic/webhook.ts
Comment threadapps/sim/lib/workflows/comparison/normalize.ts
Comment threadapps/sim/lib/webhooks/processor.ts Outdated
Comment threadapps/sim/lib/webhooks/processor.ts
Comment threadapps/sim/executor/handlers/trigger/trigger-handler.ts
@icecrasher321

Copy link
Copy Markdown
CollaboratorAuthor

bugbot run

Comment threadapps/sim/lib/webhooks/processor.ts
@icecrasher321

Copy link
Copy Markdown
CollaboratorAuthor

bugbot run

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@icecrasher321
icecrasher321 merged commit d5502d6 into stagingMar 11, 2026
12 checks passed
@waleedlatif1
waleedlatif1 deleted the feat/webhook-trigger-configs branch March 13, 2026 05:50
adithyaakrishna pushed a commit to adithyaakrishna/sim that referenced this pull request Mar 20, 2026
* feat(webhooks): dedup and custom ack configuration
* address review comments
* reject object typed idempotency key
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@icecrasher321