Skip to content

Commit 9abb8d5

Browse files
committed
feat(triggers): add Twilio SMS, Clerk, incident.io, Rootly, RevenueCat, 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.
1 parent c7eda5b commit 9abb8d5

73 files changed

Lines changed: 5769 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/sim/blocks/blocks/clerk.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ClerkIcon } from '@/components/icons'
22
import type { BlockConfig, BlockMeta } from '@/blocks/types'
33
import { IntegrationType } from '@/blocks/types'
44
import type { ClerkResponse } from '@/tools/clerk/types'
5+
import { getTrigger } from '@/triggers'
56

67
export const ClerkBlock: BlockConfig<ClerkResponse> = {
78
type: 'clerk',
@@ -275,8 +276,28 @@ export const ClerkBlock: BlockConfig<ClerkResponse> = {
275276
},
276277
mode: 'advanced',
277278
},
279+
...getTrigger('clerk_user_created').subBlocks,
280+
...getTrigger('clerk_user_updated').subBlocks,
281+
...getTrigger('clerk_user_deleted').subBlocks,
282+
...getTrigger('clerk_session_created').subBlocks,
283+
...getTrigger('clerk_organization_created').subBlocks,
284+
...getTrigger('clerk_organization_membership_created').subBlocks,
285+
...getTrigger('clerk_webhook').subBlocks,
278286
],
279287

288+
triggers: {
289+
enabled: true,
290+
available: [
291+
'clerk_user_created',
292+
'clerk_user_updated',
293+
'clerk_user_deleted',
294+
'clerk_session_created',
295+
'clerk_organization_created',
296+
'clerk_organization_membership_created',
297+
'clerk_webhook',
298+
],
299+
},
300+
280301
tools: {
281302
access: [
282303
'clerk_list_users',

apps/sim/blocks/blocks/incidentio.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { IncidentioIcon } from '@/components/icons'
22
import type { BlockConfig, BlockMeta } from '@/blocks/types'
33
import { AuthMode, IntegrationType } from '@/blocks/types'
44
import type { IncidentioResponse } from '@/tools/incidentio/types'
5+
import { getTrigger } from '@/triggers'
56

67
export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
78
type: 'incidentio',
@@ -15,6 +16,15 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
1516
integrationType: IntegrationType.Observability,
1617
bgColor: '#FFFFFF',
1718
icon: IncidentioIcon,
19+
triggers: {
20+
enabled: true,
21+
available: [
22+
'incidentio_incident_created',
23+
'incidentio_incident_updated',
24+
'incidentio_incident_status_updated',
25+
'incidentio_alert_created',
26+
],
27+
},
1828
subBlocks: [
1929
{
2030
id: 'operation',
@@ -929,6 +939,11 @@ Return ONLY the JSON array - no explanations or markdown formatting.`,
929939
password: true,
930940
required: true,
931941
},
942+
// Trigger subBlocks (webhook configuration)
943+
...getTrigger('incidentio_incident_created').subBlocks,
944+
...getTrigger('incidentio_incident_updated').subBlocks,
945+
...getTrigger('incidentio_incident_status_updated').subBlocks,
946+
...getTrigger('incidentio_alert_created').subBlocks,
932947
],
933948
tools: {
934949
access: [

apps/sim/blocks/blocks/loops.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { LoopsIcon } from '@/components/icons'
22
import type { BlockConfig, BlockMeta } from '@/blocks/types'
33
import { AuthMode, IntegrationType } from '@/blocks/types'
44
import type { LoopsResponse } from '@/tools/loops/types'
5+
import { getTrigger } from '@/triggers'
56

67
export const LoopsBlock: BlockConfig<LoopsResponse> = {
78
type: 'loops',
@@ -391,7 +392,28 @@ Return ONLY the JSON object - no explanations, no extra text.`,
391392
password: true,
392393
required: true,
393394
},
395+
...getTrigger('loops_email_delivered').subBlocks,
396+
...getTrigger('loops_email_opened').subBlocks,
397+
...getTrigger('loops_email_clicked').subBlocks,
398+
...getTrigger('loops_email_hard_bounced').subBlocks,
399+
...getTrigger('loops_email_soft_bounced').subBlocks,
400+
...getTrigger('loops_campaign_email_sent').subBlocks,
401+
...getTrigger('loops_loop_email_sent').subBlocks,
402+
...getTrigger('loops_transactional_email_sent').subBlocks,
394403
],
404+
triggers: {
405+
enabled: true,
406+
available: [
407+
'loops_email_delivered',
408+
'loops_email_opened',
409+
'loops_email_clicked',
410+
'loops_email_hard_bounced',
411+
'loops_email_soft_bounced',
412+
'loops_campaign_email_sent',
413+
'loops_loop_email_sent',
414+
'loops_transactional_email_sent',
415+
],
416+
},
395417
tools: {
396418
access: [
397419
'loops_create_contact',

apps/sim/blocks/blocks/revenuecat.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { RevenueCatIcon } from '@/components/icons'
22
import type { BlockConfig, BlockMeta } from '@/blocks/types'
33
import { AuthMode, IntegrationType } from '@/blocks/types'
44
import type { RevenueCatResponse } from '@/tools/revenuecat/types'
5+
import { getTrigger } from '@/triggers'
56

67
export const RevenueCatBlock: BlockConfig<RevenueCatResponse> = {
78
type: 'revenuecat',
@@ -359,7 +360,24 @@ Return ONLY the numeric timestamp, no text.`,
359360
},
360361
mode: 'advanced',
361362
},
363+
...getTrigger('revenuecat_initial_purchase').subBlocks,
364+
...getTrigger('revenuecat_renewal').subBlocks,
365+
...getTrigger('revenuecat_cancellation').subBlocks,
366+
...getTrigger('revenuecat_expiration').subBlocks,
367+
...getTrigger('revenuecat_non_renewing_purchase').subBlocks,
368+
...getTrigger('revenuecat_product_change').subBlocks,
362369
],
370+
triggers: {
371+
enabled: true,
372+
available: [
373+
'revenuecat_initial_purchase',
374+
'revenuecat_renewal',
375+
'revenuecat_cancellation',
376+
'revenuecat_expiration',
377+
'revenuecat_non_renewing_purchase',
378+
'revenuecat_product_change',
379+
],
380+
},
363381
tools: {
364382
access: [
365383
'revenuecat_get_customer',

apps/sim/blocks/blocks/rootly.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { RootlyIcon } from '@/components/icons'
22
import type { BlockConfig, BlockMeta } from '@/blocks/types'
33
import { AuthMode, IntegrationType } from '@/blocks/types'
44
import type { RootlyResponse } from '@/tools/rootly/types'
5+
import { getTrigger } from '@/triggers'
56

67
export const RootlyBlock: BlockConfig<RootlyResponse> = {
78
type: 'rootly',
@@ -16,6 +17,15 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
1617
bgColor: '#6C72C8',
1718
iconColor: '#6C72C8',
1819
icon: RootlyIcon,
20+
triggers: {
21+
enabled: true,
22+
available: [
23+
'rootly_incident_created',
24+
'rootly_incident_updated',
25+
'rootly_incident_resolved',
26+
'rootly_alert_created',
27+
],
28+
},
1929
subBlocks: [
2030
{
2131
id: 'operation',
@@ -1642,6 +1652,11 @@ export const RootlyBlock: BlockConfig<RootlyResponse> = {
16421652
password: true,
16431653
required: true,
16441654
},
1655+
1656+
...getTrigger('rootly_incident_created').subBlocks,
1657+
...getTrigger('rootly_incident_updated').subBlocks,
1658+
...getTrigger('rootly_incident_resolved').subBlocks,
1659+
...getTrigger('rootly_alert_created').subBlocks,
16451660
],
16461661
tools: {
16471662
access: [

apps/sim/blocks/blocks/sentry.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { SentryIcon } from '@/components/icons'
33
import type { BlockConfig, BlockMeta } from '@/blocks/types'
44
import { AuthMode, IntegrationType } from '@/blocks/types'
55
import type { SentryResponse } from '@/tools/sentry/types'
6+
import { getTrigger } from '@/triggers'
67

78
export const SentryBlock: BlockConfig<SentryResponse> = {
89
type: 'sentry',
@@ -605,7 +606,23 @@ Return ONLY the timestamp string - no explanations, no quotes, no extra text.`,
605606
placeholder: 'Your Sentry organization slug',
606607
required: true,
607608
},
609+
610+
...getTrigger('sentry_issue_created').subBlocks,
611+
...getTrigger('sentry_issue_resolved').subBlocks,
612+
...getTrigger('sentry_error_created').subBlocks,
613+
...getTrigger('sentry_issue_alert').subBlocks,
614+
...getTrigger('sentry_metric_alert').subBlocks,
608615
],
616+
triggers: {
617+
enabled: true,
618+
available: [
619+
'sentry_issue_created',
620+
'sentry_issue_resolved',
621+
'sentry_error_created',
622+
'sentry_issue_alert',
623+
'sentry_metric_alert',
624+
],
625+
},
609626
tools: {
610627
access: [
611628
'sentry_issues_list',

apps/sim/blocks/blocks/twilio.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { TwilioIcon } from '@/components/icons'
22
import type { BlockConfig, BlockMeta } from '@/blocks/types'
33
import { AuthMode, IntegrationType } from '@/blocks/types'
44
import type { TwilioSMSBlockOutput } from '@/tools/twilio/types'
5+
import { getTrigger } from '@/triggers'
56

67
export const TwilioSMSBlock: BlockConfig<TwilioSMSBlockOutput> = {
78
type: 'twilio_sms',
@@ -52,7 +53,13 @@ export const TwilioSMSBlock: BlockConfig<TwilioSMSBlockOutput> = {
5253
placeholder: 'e.g. +1234567890',
5354
required: true,
5455
},
56+
...getTrigger('twilio_sms_received').subBlocks,
57+
...getTrigger('twilio_sms_status').subBlocks,
5558
],
59+
triggers: {
60+
enabled: true,
61+
available: ['twilio_sms_received', 'twilio_sms_status'],
62+
},
5663
tools: {
5764
access: ['twilio_send_sms'],
5865
config: {

0 commit comments

Comments
 (0)