Skip to content

fix(webhooks): accept the methods and expose the request metadata the generic webhook advertises - #6889

Open
minijeong-log wants to merge 5 commits into
simstudioai:stagingfrom
minijeong-log:feat/generic-webhook-request-metadata
Open

fix(webhooks): accept the methods and expose the request metadata the generic webhook advertises#6889
minijeong-log wants to merge 5 commits into
simstudioai:stagingfrom
minijeong-log:feat/generic-webhook-request-metadata

Conversation

@minijeong-log

Copy link
Copy Markdown
Contributor

Summary

Makes the generic webhook behave the way its Setup Instructions describe: it accepts the documented HTTP methods and exposes the request method, query parameters, and headers to the workflow.

Fixes #6888

Four commits, each self-contained:

  1. query parameters + GET deliveries — carry the request query string into the execution payload and merge it under a reserved query key; add an opt-in delivery-method capability so a generic webhook can be triggered by a plain URL fetch (a link in an email). Providers that have not opted in still answer 405, and unknown paths keep answering 405 on GET so probes cannot distinguish them.
  2. request headers — expose them under a reserved headers key, withholding credential-bearing ones (fixed denylist + the webhook's own secretHeaderName). A denylist rather than an allowlist keeps arbitrary custom headers usable, which is the point of the feature; exposing a credential would copy it into execution logs and trace spans, where it outlives the request.
  3. PUT, PATCH, DELETE + method — turn the GET-only opt-in into a per-provider method set (extraDeliveryMethods, generic only) and expose the method on the trigger input, so a workflow behind one URL can tell a create from a delete.
  4. trigger outputs — declare method, query, headers so the reference dropdown offers completions instead of users typing query.id by hand. Body fields stay undeclared because a generic webhook receives whatever JSON the caller sends.

Merging is key-wise with the body taking precedence, so a payload that already carries a query/headers/method field resolves exactly as it does today. payload.query and payload.method are optional, so jobs already queued at deploy time keep executing.

Setup Instructions are corrected in the same commits that make each claim true, including one unrelated inaccuracy: authentication accepts only the configured method (custom header or Bearer), not either one — verifyTokenAuth returns early when secretHeaderName is set.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

bun vitest run lib/webhooks triggers app/api/webhooks → 764 passed. New coverage:

  • lib/webhooks/providers/generic.test.ts — headers exposed lowercased, credential denylist, configured secretHeaderName withheld, method exposed, body precedence for each reserved key, non-object bodies untouched.
  • app/api/webhooks/trigger/[path]/route.test.ts — PUT/PATCH/DELETE dispatch to a generic webhook, 405 for a PUT to a POST-only provider, 405 for a DELETE to an unknown path.
  • triggers/generic/webhook.test.ts (new) — declared outputs and the instruction text that documents them.

Two pre-existing failures in this tree are unrelated to the change and reproduce on staging without it: lib/webhooks/polling/hubspot.test.ts (z.string().datetime().meta is not a function) and packages/audit type-check (duplicate drizzle-orm installs).

What reviewers may want to focus on: the credential denylist in apps/sim/lib/webhooks/providers/generic.ts, and whether PUT/PATCH/DELETE should reuse the POST route contract as they do here.

An equivalent change was verified end-to-end against a running instance in a fork (28 requests: all five methods with query parameters and custom headers, credential headers absent from the execution input, other providers still 405). I have not re-run that manual pass against this branch's structure — happy to if you'd like it before merge.

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)

Screenshots/Videos

No visual change beyond the Setup Instructions text in the trigger panel, which is quoted in full in the diff.

…c webhooks

The generic webhook Setup Instructions promised that query parameters would be
available in the workflow and that any HTTP method would be accepted, but
neither was true: query parameters were never carried past the route, and every
GET that was not a provider challenge got a 405.

Carry the request query string into the execution payload and expose it to
providers through FormatInputContext. The generic provider merges it into the
workflow input under a reserved `query` key, leaving the body's own fields
untouched so existing payloads resolve exactly as before.

Add an opt-in `acceptsGetDelivery` provider capability and enable it for the
generic provider, so a workflow can be triggered by a plain URL fetch such as a
link in an email. Providers that have not opted in still answer 405, and unknown
paths keep answering 405 on GET so probes cannot distinguish them.

Update the Setup Instructions to describe what the endpoint actually accepts.

Signed-off-by: mini.jeong <mini.jeong@navercorp.com>
The generic webhook's Setup Instructions promised that request headers would be
available in the workflow, but formatInput returned only the body: headers were
used solely for the idempotency key and provider signature checks.

Expose them under a reserved `headers` key, withholding the ones that carry
credentials. Exposing a credential would copy it into execution logs and trace
spans, where it outlives the request, so a fixed denylist (authorization,
cookie, x-api-key, ...) is combined with the webhook's own configured
secretHeaderName. A denylist rather than an allowlist keeps arbitrary custom
headers usable, which is the point of the feature.

Generalize the query-parameter merge so query and headers share the same
key-wise body-precedence rule.

Also correct the authentication instruction: only the configured method is
accepted, not either one.

Refs simstudioai#6888

Signed-off-by: mini.jeong <mini.jeong@navercorp.com>
…e request method

The generic webhook's Setup Instructions promised any HTTP method, and the /api
CORS policy already advertises PUT, PATCH and DELETE, yet the route answered 405
for everything except POST and GET. Open the remaining methods for providers that
opt in, which today is only the generic webhook.

Expose the method on the trigger input as well. Without it a workflow behind one
URL cannot tell a create from a delete, which makes multi-method delivery half a
feature. The payload field is optional so jobs already queued at deploy time keep
executing.

Turn the GET-only opt-in into a per-provider method set, and let the request
metadata merge carry scalar values so `method` follows the same key-wise
body-precedence rule as query and headers.

Refs simstudioai#6888

Signed-off-by: mini.jeong <mini.jeong@navercorp.com>
The trigger declared no outputs, so the reference dropdown in the editor offered
no completions for it and users had to type paths like `query.id` by hand after
reading the setup instructions. Declare the request metadata that is known ahead
of time. Body fields stay undeclared because a generic webhook receives whatever
JSON the caller sends.

Refs simstudioai#6888

Signed-off-by: mini.jeong <mini.jeong@navercorp.com>
@vercel

vercel Bot commented Aug 20, 2026

Copy link
Copy Markdown

@minijeong-log is attempting to deploy a commit to the Sim Team on Vercel.

A member of the Team first needs to authorize it.

@cursor

cursor Bot commented Aug 20, 2026

Copy link
Copy Markdown

PR Summary

Cursor Bugbot is generating a summary for commit 6914b8e. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR expands generic webhook delivery to GET, PUT, PATCH, and DELETE and exposes sanitized request metadata to workflows.

  • Adds per-provider opt-in delivery methods while preserving POST-only behavior for other providers.
  • Carries the HTTP method and query parameters through the queued webhook payload.
  • Merges method, query, and non-credential headers into generic webhook input without overwriting body fields.
  • Declares the metadata outputs and updates setup instructions and focused tests.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking issues identified.

The added methods remain provider-gated, queued payload changes are backward compatible, empty requests are accepted by the existing parsing path, and sensitive headers are removed before metadata reaches workflow inputs.

Important Files Changed

Filename Overview
apps/sim/app/api/webhooks/trigger/[path]/route.ts Adds method-aware generic webhook routing and preserves rejection behavior for non-opted-in providers and unknown non-POST paths.
apps/sim/lib/webhooks/processor.ts Captures request method and decoded query parameters in the durable webhook execution payload.
apps/sim/background/webhook-execution.ts Extends queued webhook jobs compatibly and forwards metadata into provider input formatting.
apps/sim/lib/webhooks/providers/generic.ts Opts generic webhooks into additional methods and safely merges sanitized request metadata into object payloads.
apps/sim/lib/webhooks/providers/index.ts Introduces a provider capability check that keeps POST as the default and requires explicit opt-in for other methods.
apps/sim/triggers/generic/webhook.ts Documents the supported behavior and declares method, query, and header outputs for downstream references.
apps/sim/app/api/webhooks/trigger/[path]/route.test.ts Covers dispatch and rejection behavior for the newly supported HTTP methods.
apps/sim/lib/webhooks/providers/generic.test.ts Covers metadata merging, body precedence, and credential-header filtering.

Sequence Diagram

sequenceDiagram
  participant Client
  participant Route as Webhook Route
  participant Provider as Generic Provider
  participant Queue as Webhook Queue
  participant Workflow

  Client->>Route: GET/POST/PUT/PATCH/DELETE + query, headers, body
  Route->>Provider: Check path, method capability, and authentication
  Provider-->>Route: Accept generic delivery
  Route->>Queue: Enqueue body, headers, query, and method
  Queue->>Provider: Format workflow input
  Provider->>Provider: Remove credential headers
  Provider->>Provider: Merge metadata without replacing body fields
  Provider->>Workflow: Execute with normalized input
Loading

Reviews (1): Last reviewed commit: "feat(webhooks): declare the generic webh..." | Re-trigger Greptile

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6914b8e. Configure here.

Comment thread apps/sim/app/api/webhooks/trigger/[path]/route.ts
…ders' deliveries

The challenge handlers run before webhook lookup and are provider-blind, so two
query parameter names are effectively reserved across every path. Now that a
generic webhook can be triggered by a URL fetch, a link carrying either name
answers the challenge instead of running the workflow:

- `?validationToken=x` is echoed back as a Microsoft Graph subscription
  validation. Graph sends that validation as a POST, so ignore the parameter on
  every other method.
- `hub.mode`, `hub.verify_token` and `hub.challenge` answer 403 when no WhatsApp
  webhook on the path expects a token. A path with no such webhook is not a
  failed verification - the parameters belong to whoever owns that path - so fall
  through and let the delivery route normally. A token mismatch against a
  WhatsApp webhook still fails with 403.

Refs simstudioai#6888

Signed-off-by: mini.jeong <mini.jeong@navercorp.com>
@vercel

vercel Bot commented Aug 20, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 20, 2026 10:17am

Request Review

Sign up for free to 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