Skip to content

feat(triggers): add Resend webhook triggers with auto-registration#3986

Merged
waleedlatif1 merged 5 commits intostagingfrom
waleedlatif1/add-resend-trigger
Apr 6, 2026
Merged

feat(triggers): add Resend webhook triggers with auto-registration#3986
waleedlatif1 merged 5 commits intostagingfrom
waleedlatif1/add-resend-trigger

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Add 8 Resend webhook triggers (email sent, delivered, bounced, complained, opened, clicked, failed, generic webhook)
  • Automatic webhook creation/deletion via Resend API — users just enter API key and save
  • Resend provider handler with formatInput to flatten webhook payloads and createSubscription/deleteSubscription for lifecycle management
  • Block updated with trigger config and subBlocks

Type of Change

  • New feature

Testing

Tested manually — type-check and lint pass

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
Copy link
Copy Markdown

vercel bot commented Apr 6, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 6, 2026 6:31pm

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 6, 2026

PR Summary

Medium Risk
Adds a new webhook provider that performs signature verification and manages external webhook lifecycle via Resend’s API; mistakes could break event delivery or incorrectly accept/reject requests.

Overview
Adds Resend webhook trigger support: 7 email-event triggers plus a generic “all events” trigger, registered in apps/sim/triggers/registry.ts and exposed on the Resend block UI.

Introduces a new resend webhook provider handler that auto-creates and deletes webhook subscriptions in Resend (storing externalId and signingSecret), verifies incoming requests via Svix signature headers, filters events by trigger type, and flattens webhook payloads into consistent trigger inputs.

Updates webhook subscription recreation logic to treat signingSecret/secretToken as system-managed fields (avoiding unnecessary subscription churn).

Reviewed by Cursor Bugbot for commit f4365a7. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 6, 2026

Greptile Summary

Adds full Resend webhook trigger support — 8 event-specific triggers (email.sent, email.delivered, email.bounced, email.complained, email.opened, email.clicked, email.failed, and a generic all-events webhook) with automatic webhook registration/deregistration via the Resend API.

  • Provider handler (lib/webhooks/providers/resend.ts): Svix HMAC-SHA256 signature verification with a ±5-minute timestamp staleness guard, per-trigger event-type filtering via matchEvent, payload flattening in formatInput, and createSubscription/deleteSubscription for full lifecycle management
  • Trigger configs (triggers/resend/): Eight trigger files following the established pattern; resend_email_sent is the primary trigger with the event-type dropdown; remaining triggers are additive entries
  • signingSecret in SYSTEM_MANAGED_FIELDS: Correctly prevents spurious webhook re-registration when the signing secret is refreshed after subscription creation
  • Block update (blocks/blocks/resend.ts): Trigger availability list wired up with getTrigger subBlock spreads for all 8 event types
  • One code-quality note: The trigger-ID → event-type mapping is defined in two places within resend.ts (EVENT_TYPE_MAP in matchEvent and eventTypeMap in createSubscription). They are currently in sync but could diverge on future additions.

Confidence Score: 5/5

PR is safe to merge; all prior security concerns (Svix signature verification, replay protection, event-type filtering, credential visibility) have been resolved

All P0/P1 issues from prior review rounds are fixed. The only open finding is a P2 maintainability suggestion (duplicated event-type map) that does not affect correctness today. The implementation faithfully follows established patterns.

apps/sim/lib/webhooks/providers/resend.ts — minor duplication between matchEvent and createSubscription event maps worth addressing before the trigger count grows

Important Files Changed

Filename Overview
apps/sim/lib/webhooks/providers/resend.ts Core Resend webhook provider handler — verifyAuth (Svix HMAC-SHA256 + ±5 min staleness guard), matchEvent, formatInput, createSubscription/deleteSubscription all implemented correctly; minor: EVENT_TYPE_MAP duplicated between matchEvent and createSubscription
apps/sim/triggers/resend/utils.ts Shared Resend trigger utilities; paramVisibility: 'user-only' correctly set on API key field; clean per-event output builders
apps/sim/triggers/resend/webhook.ts Generic Resend webhook trigger (all events) — standard pattern, no issues
apps/sim/blocks/blocks/resend.ts Resend block updated with trigger availability list and getTrigger subBlock spreads for all 8 event types
apps/sim/lib/webhooks/provider-subscriptions.ts signingSecret correctly added to SYSTEM_MANAGED_FIELDS to prevent unintended webhook re-registration on secret refresh
apps/sim/lib/webhooks/providers/registry.ts resend handler correctly registered in provider registry
apps/sim/triggers/registry.ts All 8 Resend triggers correctly registered in TRIGGER_REGISTRY
apps/sim/triggers/resend/index.ts Barrel export for all 8 Resend triggers — complete and correct
apps/sim/triggers/resend/email_sent.ts Primary Email Sent trigger with includeDropdown — standard pattern, correctly structured
apps/sim/triggers/resend/email_bounced.ts Email Bounced trigger with bounce-specific output fields — standard pattern
apps/sim/triggers/resend/email_clicked.ts Email Clicked trigger with click-specific output fields — standard pattern
apps/sim/triggers/resend/email_failed.ts Email Failed trigger — standard pattern, no issues

Sequence Diagram

sequenceDiagram
    participant U as User
    participant S as Sim (save trigger)
    participant R as Resend API
    participant W as Sim Webhook Endpoint
    participant WF as Workflow Engine

    U->>S: Save trigger config (apiKey, triggerId)
    S->>R: POST /webhooks {endpoint, events}
    R-->>S: {id, signing_secret}
    S->>S: Store externalId + signingSecret in providerConfig

    Note over R,W: On email event
    R->>W: POST /webhook {svix-id, svix-timestamp, svix-signature, body}
    W->>W: verifySvixSignature (HMAC-SHA256 + staleness check)
    W->>W: matchEvent (check payload.type vs triggerId)
    W->>W: formatInput (flatten payload)
    W->>WF: Execute workflow with flattened inputs

    U->>S: Delete trigger
    S->>R: DELETE /webhooks/{externalId}
    R-->>S: 200 OK
Loading

Reviews (3): Last reviewed commit: "fix(triggers): use Number.parseInt and N..." | Re-trigger Greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

…ttacks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

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

Reviewed by Cursor Bugbot for commit f4365a7. Configure here.

@waleedlatif1 waleedlatif1 merged commit 796384a into staging Apr 6, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/add-resend-trigger branch April 6, 2026 18:44
emir-karabeg pushed a commit that referenced this pull request Apr 7, 2026
…3986)

* feat(triggers): add Resend webhook triggers with auto-registration

* fix(triggers): capture Resend signing secret and add Svix webhook verification

* fix(triggers): add paramVisibility, event-type filtering for Resend triggers

* fix(triggers): add Svix timestamp staleness check to prevent replay attacks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(triggers): use Number.parseInt and Number.isNaN for lint compliance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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