feat(triggers): add Twilio SMS, Clerk, incident.io, Rootly, RevenueCat, Loops, and Sentry webhook triggers#5230
Conversation
…t, Loops, Sentry webhook triggers Adds inbound webhook triggers for seven existing integrations, each verified against the provider's official webhook docs (event types, payload fields, signature scheme) and aligned with Sim's trigger conventions. - Twilio SMS: inbound message + status callback (X-Twilio-Signature, HMAC-SHA1) - Clerk: user/session/organization lifecycle (Svix) - incident.io: incident created/updated/status + alert created (Svix) - Rootly: incident created/updated/resolved + alert created (HMAC-SHA256); auto-registers and tears down the webhook via the Rootly API - RevenueCat: purchase/renewal/cancellation/expiration/product-change (Authorization header); auto-registers via the RevenueCat v2 API - Loops: email lifecycle + campaign/loop/transactional sent (Svix-compatible) - Sentry: issue/error/issue-alert/metric-alert (Sentry-Hook-Signature, fail-closed) Clerk, incident.io, Loops, Twilio, and Sentry use manual signing-secret setup where the provider exposes no clean webhook-management API; Rootly and RevenueCat auto-provision so the user only supplies an API key.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Each new handler implements fail-closed auth (Svix-style signatures for Clerk/incident.io/Loops, HMAC for Rootly/Sentry, Authorization header for RevenueCat, existing Twilio signature verification), trigger-scoped Twilio SMS is extended beyond verification-only: it now splits inbound vs status callbacks, maps form payloads to workflow inputs (including MMS media), and dedupes status updates by SID + delivery state. A few blocks mark sensitive API fields as Reviewed by Cursor Bugbot for commit f5af963. Configure here. |
Greptile SummaryThis PR adds webhook triggers for several existing integrations. The main changes are:
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (6): Last reviewed commit: "fix(triggers): mark shared block-level A..." | Re-trigger Greptile |
…ing, user-only secrets - Twilio: add matchEvent so inbound-SMS and status-callback triggers don't cross-fire on a shared webhook URL (inbound = SmsStatus 'received') - Rootly + RevenueCat: verifyAuth now fails closed (401) when the signing secret is absent from provider config (both auto-register, so it is always present after deploy) instead of skipping verification - Mark every user-provided credential field paramVisibility 'user-only' (Clerk, incident.io, RevenueCat, Sentry, Twilio) so secrets are never exposed as LLM-visible trigger params - Sentry: correct metric_alert web_url description per docs
|
@greptile |
|
@cursor review |
…tency Twilio sends multiple delivery callbacks per message (sent -> delivered -> ...) sharing one MessageSid; keying idempotency on the SID alone dropped every status after the first. Status callbacks now key on SID + delivery status so each state is distinct (while still deduping Twilio's retries of the same status); inbound messages still key by SID since they fire once.
|
@greptile |
|
@cursor review |
Previously an empty MessageStatus/SmsStatus was treated as a status callback, so an ambiguous or partial payload could match twilio_sms_status (or skip twilio_sms_received). Both triggers now require a positive signal — inbound needs status 'received', status callbacks need a non-'received' status — so a payload missing both fields matches neither rather than misrouting.
|
@greptile |
|
@cursor review |
…allbacks are verified The Account SID / Auth Token fields were only on the primary trigger, so deploying twilio_sms_status alone never captured authToken into providerConfig and signature verification was silently skipped. Following the incident.io / Rootly / RevenueCat pattern, the auth fields are now added to each trigger conditioned on its own selectedTriggerId; the shared inner subBlock IDs keep the values persisted across trigger types.
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ 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 3625f27. Configure here.
…trigger secrets The trigger credential fields (RevenueCat/Rootly apiKey, Twilio authToken) are user-only, but the same-id tool-level block fields were not, so the stored secret stayed reachable as an LLM-visible block parameter. Mark those block credential fields paramVisibility 'user-only' too (matching instantly.ts) so the secret is user-only on every path. accountSid is an identifier, not a secret, so it is left as-is.
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ 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 f5af963. Configure here.
Summary
formatInputare 1:1 alignedcreateSubscription/deleteSubscription) — the user only supplies an API key. The other five use signed manual setup because the provider exposes no clean webhook-management API (dashboard-only, destructive resource-overwrite, or undocumented/org-admin-scoped)safeCompare, fail closed where the provider always signs, and use stable timestamp-free idempotency keysTriggers
X-Twilio-Signature, HMAC-SHA1; form-encoded)Sentry-Hook-Signature, HMAC-SHA256, fail-closed)Type of Change
Testing
formatInput↔outputsalignment, idempotency, and auto-register create/delete for Rootly + RevenueCat) — all passingtsc --noEmitclean;biome checkcleanChecklist