Name
-
updateField(field.id, 'name', e.target.value)}
- placeholder={placeholder}
- disabled={isReadOnly}
- autoComplete='off'
- />
+
{renderNameInput(field)}
{showType && (
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx
index e99a1eb04d..6823e303b4 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx
@@ -50,6 +50,7 @@ import {
} from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal'
import { ToolCredentialSelector } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tool-credential-selector'
import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-value'
+import { useChildDeployment } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/hooks/use-child-deployment'
import { getAllBlocks } from '@/blocks'
import {
type CustomTool as CustomToolDefinition,
@@ -582,6 +583,8 @@ function WorkflowSelectorSyncWrapper({
onChange={onChange}
placeholder={uiComponent.placeholder || 'Select workflow'}
disabled={disabled || isLoading}
+ searchable
+ searchPlaceholder='Search workflows...'
/>
)
}
@@ -752,6 +755,81 @@ function CodeEditorSyncWrapper({
)
}
+/**
+ * Badge component showing deployment status for workflow tools
+ */
+function WorkflowToolDeployBadge({
+ workflowId,
+ onDeploySuccess,
+}: {
+ workflowId: string
+ onDeploySuccess?: () => void
+}) {
+ const { isDeployed, needsRedeploy, isLoading, refetch } = useChildDeployment(workflowId)
+ const [isDeploying, setIsDeploying] = useState(false)
+
+ const deployWorkflow = useCallback(async () => {
+ if (isDeploying || !workflowId) return
+
+ try {
+ setIsDeploying(true)
+ const response = await fetch(`/api/workflows/${workflowId}/deploy`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ deployChatEnabled: false,
+ }),
+ })
+
+ if (response.ok) {
+ refetch()
+ onDeploySuccess?.()
+ } else {
+ logger.error('Failed to deploy workflow')
+ }
+ } catch (error) {
+ logger.error('Error deploying workflow:', error)
+ } finally {
+ setIsDeploying(false)
+ }
+ }, [isDeploying, workflowId, refetch, onDeploySuccess])
+
+ if (isLoading || (isDeployed && !needsRedeploy)) {
+ return null
+ }
+
+ if (typeof isDeployed !== 'boolean') {
+ return null
+ }
+
+ return (
+
+
+ {
+ e.stopPropagation()
+ e.preventDefault()
+ if (!isDeploying) {
+ deployWorkflow()
+ }
+ }}
+ >
+ {isDeploying ? 'Deploying...' : !isDeployed ? 'undeployed' : 'redeploy'}
+
+
+
+ {!isDeployed ? 'Click to deploy' : 'Click to redeploy'}
+
+
+ )
+}
+
/**
* Set of built-in tool types that are core platform tools.
*
@@ -2219,10 +2297,15 @@ export function ToolInput({
{getIssueBadgeLabel(issue)}
-
{issue.message}: click to open settings
+
+ {issue.message}: click to open settings
+
)
})()}
+ {tool.type === 'workflow' && tool.params?.workflowId && (
+
+ )}
{supportsToolControl && !(isMcpTool && isMcpToolUnavailable(tool)) && (
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/trigger-save/trigger-save.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/trigger-save/trigger-save.tsx
index d26e7aa26d..af9d11beaf 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/trigger-save/trigger-save.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/trigger-save/trigger-save.tsx
@@ -361,9 +361,9 @@ export function TriggerSave({
onClick={handleSave}
disabled={disabled || isProcessing}
className={cn(
- 'h-[32px] flex-1 rounded-[8px] px-[12px] transition-all duration-200',
- saveStatus === 'saved' && 'bg-green-600 hover:bg-green-700',
- saveStatus === 'error' && 'bg-red-600 hover:bg-red-700'
+ 'flex-1',
+ saveStatus === 'saved' && '!bg-green-600 !text-white hover:!bg-green-700',
+ saveStatus === 'error' && '!bg-red-600 !text-white hover:!bg-red-700'
)}
>
{saveStatus === 'saving' && 'Saving...'}
@@ -373,12 +373,7 @@ export function TriggerSave({
{webhookId && (
-
+
)}
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
index 853cd544ff..ecec650641 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
@@ -1947,11 +1947,26 @@ const WorkflowContent = React.memo(() => {
const handleKeyUp = (e: KeyboardEvent) => {
if (e.key === 'Shift') setIsShiftPressed(false)
}
+ const handleFocusLoss = () => {
+ setIsShiftPressed(false)
+ setIsSelectionDragActive(false)
+ }
+ const handleVisibilityChange = () => {
+ if (document.hidden) {
+ handleFocusLoss()
+ }
+ }
+
window.addEventListener('keydown', handleKeyDown)
window.addEventListener('keyup', handleKeyUp)
+ window.addEventListener('blur', handleFocusLoss)
+ document.addEventListener('visibilitychange', handleVisibilityChange)
+
return () => {
window.removeEventListener('keydown', handleKeyDown)
window.removeEventListener('keyup', handleKeyUp)
+ window.removeEventListener('blur', handleFocusLoss)
+ document.removeEventListener('visibilitychange', handleVisibilityChange)
}
}, [])
diff --git a/apps/sim/blocks/blocks.test.ts b/apps/sim/blocks/blocks.test.ts
index e61658eefc..2f9191e355 100644
--- a/apps/sim/blocks/blocks.test.ts
+++ b/apps/sim/blocks/blocks.test.ts
@@ -352,53 +352,6 @@ describe('Blocks Module', () => {
expect(typeof block?.tools.config?.tool).toBe('function')
})
})
-
- describe('WebhookBlock', () => {
- const block = getBlock('webhook')
-
- it('should have correct metadata', () => {
- expect(block?.type).toBe('webhook')
- expect(block?.name).toBe('Webhook')
- expect(block?.category).toBe('triggers')
- expect(block?.authMode).toBe(AuthMode.OAuth)
- expect(block?.triggerAllowed).toBe(true)
- expect(block?.hideFromToolbar).toBe(true)
- })
-
- it('should have webhookProvider dropdown with multiple providers', () => {
- const providerSubBlock = block?.subBlocks.find((sb) => sb.id === 'webhookProvider')
- expect(providerSubBlock).toBeDefined()
- expect(providerSubBlock?.type).toBe('dropdown')
- const options = providerSubBlock?.options as Array<{ label: string; id: string }>
- expect(options?.map((o) => o.id)).toContain('slack')
- expect(options?.map((o) => o.id)).toContain('generic')
- expect(options?.map((o) => o.id)).toContain('github')
- })
-
- it('should have conditional OAuth inputs', () => {
- const gmailCredentialSubBlock = block?.subBlocks.find((sb) => sb.id === 'gmailCredential')
- expect(gmailCredentialSubBlock).toBeDefined()
- expect(gmailCredentialSubBlock?.type).toBe('oauth-input')
- expect(gmailCredentialSubBlock?.condition).toEqual({
- field: 'webhookProvider',
- value: 'gmail',
- })
-
- const outlookCredentialSubBlock = block?.subBlocks.find(
- (sb) => sb.id === 'outlookCredential'
- )
- expect(outlookCredentialSubBlock).toBeDefined()
- expect(outlookCredentialSubBlock?.type).toBe('oauth-input')
- expect(outlookCredentialSubBlock?.condition).toEqual({
- field: 'webhookProvider',
- value: 'outlook',
- })
- })
-
- it('should have empty tools access', () => {
- expect(block?.tools.access).toEqual([])
- })
- })
})
describe('SubBlock Validation', () => {
@@ -545,8 +498,8 @@ describe('Blocks Module', () => {
})
it('should handle blocks with triggerAllowed flag', () => {
- const webhookBlock = getBlock('webhook')
- expect(webhookBlock?.triggerAllowed).toBe(true)
+ const gmailBlock = getBlock('gmail')
+ expect(gmailBlock?.triggerAllowed).toBe(true)
const functionBlock = getBlock('function')
expect(functionBlock?.triggerAllowed).toBeUndefined()
@@ -663,16 +616,6 @@ describe('Blocks Module', () => {
expect(temperatureSubBlock?.min).toBe(0)
expect(temperatureSubBlock?.max).toBe(2)
})
-
- it('should have required scopes on OAuth inputs', () => {
- const webhookBlock = getBlock('webhook')
- const gmailCredentialSubBlock = webhookBlock?.subBlocks.find(
- (sb) => sb.id === 'gmailCredential'
- )
- expect(gmailCredentialSubBlock?.requiredScopes).toBeDefined()
- expect(Array.isArray(gmailCredentialSubBlock?.requiredScopes)).toBe(true)
- expect((gmailCredentialSubBlock?.requiredScopes?.length ?? 0) > 0).toBe(true)
- })
})
describe('Block Consistency', () => {
diff --git a/apps/sim/blocks/blocks/human_in_the_loop.ts b/apps/sim/blocks/blocks/human_in_the_loop.ts
index 9c727929da..df3d24a481 100644
--- a/apps/sim/blocks/blocks/human_in_the_loop.ts
+++ b/apps/sim/blocks/blocks/human_in_the_loop.ts
@@ -10,6 +10,7 @@ export const HumanInTheLoopBlock: BlockConfig = {
'Combines response and start functionality. Sends structured responses and allows workflow to resume from this point.',
category: 'blocks',
bgColor: '#10B981',
+ docsLink: 'https://docs.sim.ai/blocks/human-in-the-loop',
icon: HumanInTheLoopIcon,
subBlocks: [
// Operation dropdown hidden - block defaults to human approval mode
diff --git a/apps/sim/blocks/blocks/tts.ts b/apps/sim/blocks/blocks/tts.ts
index b6da4abca3..c3ab813fdf 100644
--- a/apps/sim/blocks/blocks/tts.ts
+++ b/apps/sim/blocks/blocks/tts.ts
@@ -9,7 +9,7 @@ export const TtsBlock: BlockConfig = {
authMode: AuthMode.ApiKey,
longDescription:
'Generate natural-sounding speech from text using state-of-the-art AI voices from OpenAI, Deepgram, ElevenLabs, Cartesia, Google Cloud, Azure, and PlayHT. Supports multiple voices, languages, and audio formats.',
- docsLink: 'https://docs.sim.ai/blocks/tts',
+ docsLink: 'https://docs.sim.ai/tools/tts',
category: 'tools',
bgColor: '#181C1E',
icon: TTSIcon,
diff --git a/apps/sim/blocks/blocks/webhook.ts b/apps/sim/blocks/blocks/webhook.ts
deleted file mode 100644
index a7a9a1a737..0000000000
--- a/apps/sim/blocks/blocks/webhook.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-import {
- AirtableIcon,
- DiscordIcon,
- GithubIcon,
- GmailIcon,
- MicrosoftTeamsIcon,
- OutlookIcon,
- SignalIcon,
- SlackIcon,
- StripeIcon,
- TelegramIcon,
- WebhookIcon,
- WhatsAppIcon,
-} from '@/components/icons'
-import type { BlockConfig } from '@/blocks/types'
-import { AuthMode } from '@/blocks/types'
-
-const getWebhookProviderIcon = (provider: string) => {
- const iconMap: Record> = {
- slack: SlackIcon,
- gmail: GmailIcon,
- outlook: OutlookIcon,
- airtable: AirtableIcon,
- telegram: TelegramIcon,
- generic: SignalIcon,
- whatsapp: WhatsAppIcon,
- github: GithubIcon,
- discord: DiscordIcon,
- stripe: StripeIcon,
- microsoftteams: MicrosoftTeamsIcon,
- }
-
- return iconMap[provider.toLowerCase()]
-}
-
-export const WebhookBlock: BlockConfig = {
- type: 'webhook',
- name: 'Webhook',
- description: 'Trigger workflow execution from external webhooks',
- authMode: AuthMode.OAuth,
- category: 'triggers',
- icon: WebhookIcon,
- bgColor: '#10B981', // Green color for triggers
- docsLink: 'https://docs.sim.ai/triggers/webhook',
- triggerAllowed: true,
- hideFromToolbar: true, // Hidden for backwards compatibility - use generic webhook trigger instead
-
- subBlocks: [
- {
- id: 'webhookProvider',
- title: 'Webhook Provider',
- type: 'dropdown',
- options: [
- 'slack',
- 'gmail',
- 'outlook',
- 'airtable',
- 'telegram',
- 'generic',
- 'whatsapp',
- 'github',
- 'discord',
- 'stripe',
- 'microsoftteams',
- ].map((provider) => {
- const providerLabels = {
- slack: 'Slack',
- gmail: 'Gmail',
- outlook: 'Outlook',
- airtable: 'Airtable',
- telegram: 'Telegram',
- generic: 'Generic',
- whatsapp: 'WhatsApp',
- github: 'GitHub',
- discord: 'Discord',
- stripe: 'Stripe',
- microsoftteams: 'Microsoft Teams',
- }
-
- const icon = getWebhookProviderIcon(provider)
- return {
- label: providerLabels[provider as keyof typeof providerLabels],
- id: provider,
- ...(icon && { icon }),
- }
- }),
- value: () => 'generic',
- },
- {
- id: 'gmailCredential',
- title: 'Gmail Account',
- type: 'oauth-input',
- serviceId: 'gmail',
- requiredScopes: [
- 'https://www.googleapis.com/auth/gmail.modify',
- 'https://www.googleapis.com/auth/gmail.labels',
- ],
- placeholder: 'Select Gmail account',
- condition: { field: 'webhookProvider', value: 'gmail' },
- required: true,
- },
- {
- id: 'outlookCredential',
- title: 'Microsoft Account',
- type: 'oauth-input',
- serviceId: 'outlook',
- requiredScopes: [
- 'Mail.ReadWrite',
- 'Mail.ReadBasic',
- 'Mail.Read',
- 'Mail.Send',
- 'offline_access',
- ],
- placeholder: 'Select Microsoft account',
- condition: { field: 'webhookProvider', value: 'outlook' },
- required: true,
- },
- {
- id: 'webhookConfig',
- title: 'Webhook Configuration',
- type: 'webhook-config',
- },
- ],
-
- tools: {
- access: [], // No external tools needed
- },
-
- inputs: {}, // No inputs - webhook triggers receive data externally
-
- outputs: {}, // No outputs - webhook data is injected directly into workflow context
-}
diff --git a/apps/sim/blocks/blocks/workflow.ts b/apps/sim/blocks/blocks/workflow.ts
index 1af666b7af..1f099e0ebe 100644
--- a/apps/sim/blocks/blocks/workflow.ts
+++ b/apps/sim/blocks/blocks/workflow.ts
@@ -32,7 +32,7 @@ export const WorkflowBlock: BlockConfig = {
description:
'This is a core workflow block. Execute another workflow as a block in your workflow. Enter the input variable to pass to the child workflow.',
category: 'blocks',
- bgColor: '#705335',
+ bgColor: '#6366F1',
icon: WorkflowIcon,
subBlocks: [
{
diff --git a/apps/sim/blocks/blocks/workflow_input.ts b/apps/sim/blocks/blocks/workflow_input.ts
index be268b89df..c918ded44a 100644
--- a/apps/sim/blocks/blocks/workflow_input.ts
+++ b/apps/sim/blocks/blocks/workflow_input.ts
@@ -2,7 +2,6 @@ import { WorkflowIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
-// Helper: list workflows excluding self
const getAvailableWorkflows = (): Array<{ label: string; id: string }> => {
try {
const { workflows, activeWorkflowId } = useWorkflowRegistry.getState()
@@ -15,7 +14,6 @@ const getAvailableWorkflows = (): Array<{ label: string; id: string }> => {
}
}
-// New workflow block variant that visualizes child Input Trigger schema for mapping
export const WorkflowInputBlock: BlockConfig = {
type: 'workflow_input',
name: 'Workflow',
@@ -26,6 +24,7 @@ export const WorkflowInputBlock: BlockConfig = {
- Remember, that the start point of the child workflow is the Start block.
`,
category: 'blocks',
+ docsLink: 'https://docs.sim.ai/blocks/workflow',
bgColor: '#6366F1', // Indigo - modern and professional
icon: WorkflowIcon,
subBlocks: [
diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts
index 0c98f666da..c2d9104569 100644
--- a/apps/sim/blocks/registry.ts
+++ b/apps/sim/blocks/registry.ts
@@ -130,7 +130,6 @@ import { VisionBlock } from '@/blocks/blocks/vision'
import { WaitBlock } from '@/blocks/blocks/wait'
import { WealthboxBlock } from '@/blocks/blocks/wealthbox'
import { WebflowBlock } from '@/blocks/blocks/webflow'
-import { WebhookBlock } from '@/blocks/blocks/webhook'
import { WebhookRequestBlock } from '@/blocks/blocks/webhook_request'
import { WhatsAppBlock } from '@/blocks/blocks/whatsapp'
import { WikipediaBlock } from '@/blocks/blocks/wikipedia'
@@ -281,7 +280,6 @@ export const registry: Record = {
wait: WaitBlock,
wealthbox: WealthboxBlock,
webflow: WebflowBlock,
- webhook: WebhookBlock,
webhook_request: WebhookRequestBlock,
whatsapp: WhatsAppBlock,
wikipedia: WikipediaBlock,
@@ -296,11 +294,9 @@ export const registry: Record = {
}
export const getBlock = (type: string): BlockConfig | undefined => {
- // Direct lookup first
if (registry[type]) {
return registry[type]
}
- // Fallback: normalize hyphens to underscores (e.g., 'microsoft-teams' -> 'microsoft_teams')
const normalized = type.replace(/-/g, '_')
return registry[normalized]
}
diff --git a/apps/sim/executor/handlers/response/response-handler.ts b/apps/sim/executor/handlers/response/response-handler.ts
index 1c2f4d9982..7cb15495b7 100644
--- a/apps/sim/executor/handlers/response/response-handler.ts
+++ b/apps/sim/executor/handlers/response/response-handler.ts
@@ -1,7 +1,6 @@
import { createLogger } from '@sim/logger'
-import type { BlockOutput } from '@/blocks/types'
import { BlockType, HTTP, REFERENCE } from '@/executor/constants'
-import type { BlockHandler, ExecutionContext } from '@/executor/types'
+import type { BlockHandler, ExecutionContext, NormalizedBlockOutput } from '@/executor/types'
import type { SerializedBlock } from '@/serializer/types'
const logger = createLogger('ResponseBlockHandler')
@@ -23,7 +22,7 @@ export class ResponseBlockHandler implements BlockHandler {
ctx: ExecutionContext,
block: SerializedBlock,
inputs: Record
- ): Promise {
+ ): Promise {
logger.info(`Executing response block: ${block.id}`)
try {
@@ -38,23 +37,19 @@ export class ResponseBlockHandler implements BlockHandler {
})
return {
- response: {
- data: responseData,
- status: statusCode,
- headers: responseHeaders,
- },
+ data: responseData,
+ status: statusCode,
+ headers: responseHeaders,
}
} catch (error: any) {
logger.error('Response block execution failed:', error)
return {
- response: {
- data: {
- error: 'Response block execution failed',
- message: error.message || 'Unknown error',
- },
- status: HTTP.STATUS.SERVER_ERROR,
- headers: { 'Content-Type': HTTP.CONTENT_TYPE.JSON },
+ data: {
+ error: 'Response block execution failed',
+ message: error.message || 'Unknown error',
},
+ status: HTTP.STATUS.SERVER_ERROR,
+ headers: { 'Content-Type': HTTP.CONTENT_TYPE.JSON },
}
}
}
diff --git a/apps/sim/executor/variables/resolvers/block.test.ts b/apps/sim/executor/variables/resolvers/block.test.ts
index 36a5166a17..3d773d6bce 100644
--- a/apps/sim/executor/variables/resolvers/block.test.ts
+++ b/apps/sim/executor/variables/resolvers/block.test.ts
@@ -293,6 +293,532 @@ describe('BlockResolver', () => {
})
})
+ describe('Response block backwards compatibility', () => {
+ it.concurrent('should resolve new format: ', () => {
+ const workflow = createTestWorkflow([
+ { id: 'response-block', name: 'Response', type: 'response' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'response-block': {
+ data: { message: 'hello', userId: 123 },
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ },
+ })
+
+ expect(resolver.resolve('', ctx)).toEqual({ message: 'hello', userId: 123 })
+ expect(resolver.resolve('', ctx)).toBe('hello')
+ expect(resolver.resolve('', ctx)).toBe(123)
+ })
+
+ it.concurrent('should resolve new format: ', () => {
+ const workflow = createTestWorkflow([
+ { id: 'response-block', name: 'Response', type: 'response' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'response-block': {
+ data: { message: 'hello' },
+ status: 201,
+ headers: {},
+ },
+ })
+
+ expect(resolver.resolve('', ctx)).toBe(201)
+ })
+
+ it.concurrent('should resolve new format: ', () => {
+ const workflow = createTestWorkflow([
+ { id: 'response-block', name: 'Response', type: 'response' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'response-block': {
+ data: {},
+ status: 200,
+ headers: { 'X-Custom-Header': 'custom-value', 'Content-Type': 'application/json' },
+ },
+ })
+
+ expect(resolver.resolve('', ctx)).toEqual({
+ 'X-Custom-Header': 'custom-value',
+ 'Content-Type': 'application/json',
+ })
+ })
+
+ it.concurrent(
+ 'should resolve old format (backwards compat): ',
+ () => {
+ const workflow = createTestWorkflow([
+ { id: 'response-block', name: 'Response', type: 'response' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'response-block': {
+ data: { message: 'hello', userId: 123 },
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ },
+ })
+
+ // Old format: should strip 'response.' and resolve to data
+ expect(resolver.resolve('', ctx)).toEqual({
+ message: 'hello',
+ userId: 123,
+ })
+ expect(resolver.resolve('', ctx)).toBe('hello')
+ expect(resolver.resolve('', ctx)).toBe(123)
+ }
+ )
+
+ it.concurrent(
+ 'should resolve old format (backwards compat): ',
+ () => {
+ const workflow = createTestWorkflow([
+ { id: 'response-block', name: 'Response', type: 'response' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'response-block': {
+ data: { message: 'hello' },
+ status: 404,
+ headers: {},
+ },
+ })
+
+ // Old format: should strip 'response.' and resolve to status
+ expect(resolver.resolve('', ctx)).toBe(404)
+ }
+ )
+
+ it.concurrent(
+ 'should resolve old format (backwards compat): ',
+ () => {
+ const workflow = createTestWorkflow([
+ { id: 'response-block', name: 'Response', type: 'response' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'response-block': {
+ data: {},
+ status: 200,
+ headers: { 'X-Request-Id': 'abc-123' },
+ },
+ })
+
+ // Old format: should strip 'response.' and resolve to headers
+ expect(resolver.resolve('', ctx)).toEqual({
+ 'X-Request-Id': 'abc-123',
+ })
+ }
+ )
+
+ it.concurrent('should resolve entire Response block output with new format', () => {
+ const workflow = createTestWorkflow([
+ { id: 'response-block', name: 'My Response', type: 'response' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const fullOutput = {
+ data: { result: 'success' },
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ }
+ const ctx = createTestContext('current', { 'response-block': fullOutput })
+
+ expect(resolver.resolve('', ctx)).toEqual(fullOutput)
+ })
+
+ it.concurrent(
+ 'should only strip response prefix for response block type, not other blocks',
+ () => {
+ // For non-response blocks, 'response' is a valid property name that should NOT be stripped
+ const workflow = createTestWorkflow([{ id: 'agent-block', name: 'Agent', type: 'agent' }])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'agent-block': {
+ response: { content: 'AI generated text' },
+ tokens: { input: 100, output: 50 },
+ },
+ })
+
+ // For agent blocks, 'response' is a valid property and should be accessed normally
+ expect(resolver.resolve('', ctx)).toBe('AI generated text')
+ }
+ )
+
+ it.concurrent(
+ 'should NOT strip response prefix if output actually has response key (edge case)',
+ () => {
+ // Edge case: What if a Response block somehow has a 'response' key in its output?
+ // This shouldn't happen in practice, but if it does, we should respect it.
+ const workflow = createTestWorkflow([
+ { id: 'response-block', name: 'Response', type: 'response' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ // Hypothetical edge case where output has an actual 'response' property
+ const ctx = createTestContext('current', {
+ 'response-block': {
+ response: { legacyData: 'some value' },
+ data: { newData: 'other value' },
+ },
+ })
+
+ // Since output.response exists, we should NOT strip it - access the actual 'response' property
+ expect(resolver.resolve('', ctx)).toBe('some value')
+ expect(resolver.resolve('', ctx)).toBe('other value')
+ }
+ )
+ })
+
+ describe('Workflow block with child Response block backwards compatibility', () => {
+ it.concurrent('should resolve new format: ', () => {
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ // After our change, child workflow with Response block returns { data, status, headers }
+ // Workflow block wraps it in { success, result: { data, status, headers }, ... }
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: {
+ data: { userId: 456, name: 'Test User' },
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ },
+ },
+ })
+
+ expect(resolver.resolve('', ctx)).toEqual({
+ userId: 456,
+ name: 'Test User',
+ })
+ expect(resolver.resolve('', ctx)).toBe(456)
+ expect(resolver.resolve('', ctx)).toBe('Test User')
+ })
+
+ it.concurrent('should resolve new format: ', () => {
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: {
+ data: { message: 'created' },
+ status: 201,
+ headers: {},
+ },
+ },
+ })
+
+ expect(resolver.resolve('', ctx)).toBe(201)
+ })
+
+ it.concurrent('should resolve new format: ', () => {
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: {
+ data: {},
+ status: 200,
+ headers: { 'X-Trace-Id': 'trace-abc-123' },
+ },
+ },
+ })
+
+ expect(resolver.resolve('', ctx)).toEqual({
+ 'X-Trace-Id': 'trace-abc-123',
+ })
+ })
+
+ it.concurrent(
+ 'should resolve old format (backwards compat): ',
+ () => {
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: {
+ data: { userId: 456, name: 'Test User' },
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ },
+ },
+ })
+
+ // Old format: should strip 'response.' and resolve to result.data
+ expect(resolver.resolve('', ctx)).toEqual({
+ userId: 456,
+ name: 'Test User',
+ })
+ expect(resolver.resolve('', ctx)).toBe(456)
+ expect(resolver.resolve('', ctx)).toBe('Test User')
+ }
+ )
+
+ it.concurrent(
+ 'should resolve old format (backwards compat): ',
+ () => {
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: {
+ data: { message: 'error' },
+ status: 500,
+ headers: {},
+ },
+ },
+ })
+
+ // Old format: should strip 'response.' and resolve to result.status
+ expect(resolver.resolve('', ctx)).toBe(500)
+ }
+ )
+
+ it.concurrent(
+ 'should resolve old format (backwards compat): ',
+ () => {
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: {
+ data: {},
+ status: 200,
+ headers: { 'Cache-Control': 'no-cache' },
+ },
+ },
+ })
+
+ // Old format: should strip 'response.' and resolve to result.headers
+ expect(resolver.resolve('', ctx)).toEqual({
+ 'Cache-Control': 'no-cache',
+ })
+ }
+ )
+
+ it.concurrent('should resolve workflow block success and other properties', () => {
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: { data: {}, status: 200, headers: {} },
+ },
+ })
+
+ expect(resolver.resolve('', ctx)).toBe(true)
+ expect(resolver.resolve('', ctx)).toBe('Child Workflow')
+ })
+
+ it.concurrent('should handle workflow block with failed child workflow', () => {
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: false,
+ childWorkflowName: 'Child Workflow',
+ result: {},
+ error: 'Child workflow execution failed',
+ },
+ })
+
+ expect(resolver.resolve('', ctx)).toBe(false)
+ expect(resolver.resolve('', ctx)).toBe('Child workflow execution failed')
+ })
+
+ it.concurrent('should handle workflow block where child has non-Response final block', () => {
+ // When child workflow does NOT have a Response block as final block,
+ // the result structure will be different (not data/status/headers)
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: {
+ content: 'AI generated response',
+ tokens: { input: 100, output: 50 },
+ },
+ },
+ })
+
+ // No backwards compat needed here since child didn't have Response block
+ expect(resolver.resolve('', ctx)).toBe('AI generated response')
+ expect(resolver.resolve('', ctx)).toBe(100)
+ })
+
+ it.concurrent('should not apply workflow backwards compat for non-workflow blocks', () => {
+ // For non-workflow blocks, 'result.response' is a valid path that should NOT be modified
+ const workflow = createTestWorkflow([
+ { id: 'function-block', name: 'Function', type: 'function' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'function-block': {
+ result: {
+ response: { apiData: 'test' },
+ other: 'value',
+ },
+ },
+ })
+
+ // For function blocks, 'result.response' is a valid nested property
+ expect(resolver.resolve('', ctx)).toBe('test')
+ })
+
+ it.concurrent(
+ 'should NOT strip result.response if child actually has response property (edge case)',
+ () => {
+ // Edge case: Child workflow's final output legitimately has a 'response' property
+ // (e.g., child ended with an Agent block that outputs response data)
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'Child Workflow',
+ result: {
+ // Child workflow ended with Agent block, not Response block
+ content: 'AI generated text',
+ response: { apiCallData: 'from external API' }, // legitimate 'response' property
+ },
+ },
+ })
+
+ // Since output.result.response exists, we should NOT strip it - access the actual property
+ expect(resolver.resolve('', ctx)).toBe(
+ 'from external API'
+ )
+ expect(resolver.resolve('', ctx)).toBe('AI generated text')
+ }
+ )
+
+ it.concurrent('should handle mixed scenarios correctly', () => {
+ // Test that new format works when child workflow had Response block
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'My Workflow', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+
+ // Scenario 1: Child had Response block (new format - no 'response' key in result)
+ const ctx1 = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ result: { data: { id: 1 }, status: 200, headers: {} },
+ },
+ })
+ // New format works
+ expect(resolver.resolve('', ctx1)).toBe(1)
+ // Old format also works (backwards compat kicks in because result.response is undefined)
+ expect(resolver.resolve('', ctx1)).toBe(1)
+
+ // Scenario 2: Child had Agent block with 'response' property
+ const ctx2 = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ result: {
+ content: 'text',
+ response: { external: 'data' }, // actual 'response' property
+ },
+ },
+ })
+ // Access the actual 'response' property - no stripping
+ expect(resolver.resolve('', ctx2)).toBe('data')
+ })
+
+ it.concurrent(
+ 'real-world scenario: parent workflow referencing child Response block via ',
+ () => {
+ /**
+ * This test simulates the exact scenario from user workflows:
+ *
+ * Child workflow (vibrant-cliff):
+ * Start → Function 1 (returns "fuck") → Response 1
+ * Response 1 outputs: { data: { hi: "fuck" }, status: 200, headers: {...} }
+ *
+ * Parent workflow (flying-glacier):
+ * Start → Workflow 1 (calls vibrant-cliff) → Function 1
+ * Function 1 code: return
+ *
+ * After our changes:
+ * - Child Response block outputs { data, status, headers } (no wrapper)
+ * - Workflow block wraps it in { success, result: { data, status, headers }, ... }
+ * - Parent uses OLD reference
+ * - Backwards compat should strip 'response.' and resolve to result.data
+ */
+ const workflow = createTestWorkflow([
+ { id: 'workflow-block', name: 'Workflow 1', type: 'workflow' },
+ ])
+ const resolver = new BlockResolver(workflow)
+
+ // Simulate the workflow block output after child (vibrant-cliff) executes
+ // Child's Response block now outputs { data, status, headers } directly (no wrapper)
+ // Workflow block wraps it in { success, result: , ... }
+ const ctx = createTestContext('current', {
+ 'workflow-block': {
+ success: true,
+ childWorkflowName: 'vibrant-cliff',
+ result: {
+ // This is what Response block outputs after our changes (no 'response' wrapper)
+ data: { hi: 'fuck' },
+ status: 200,
+ headers: { 'Content-Type': 'application/json' },
+ },
+ },
+ })
+
+ // OLD reference pattern:
+ // Should work via backwards compatibility (strips 'response.')
+ expect(resolver.resolve('', ctx)).toEqual({ hi: 'fuck' })
+ expect(resolver.resolve('', ctx)).toBe('fuck')
+ expect(resolver.resolve('', ctx)).toBe(200)
+
+ // NEW reference pattern:
+ // Should work directly
+ expect(resolver.resolve('', ctx)).toEqual({ hi: 'fuck' })
+ expect(resolver.resolve('', ctx)).toBe('fuck')
+ expect(resolver.resolve('', ctx)).toBe(200)
+
+ // Other workflow block properties should still work
+ expect(resolver.resolve('', ctx)).toBe(true)
+ expect(resolver.resolve('', ctx)).toBe('vibrant-cliff')
+ }
+ )
+ })
+
describe('edge cases', () => {
it.concurrent('should handle case-insensitive block name matching', () => {
const workflow = createTestWorkflow([{ id: 'block-1', name: 'My Block' }])
diff --git a/apps/sim/executor/variables/resolvers/block.ts b/apps/sim/executor/variables/resolvers/block.ts
index 5bd9fd6e67..e555c9e4fe 100644
--- a/apps/sim/executor/variables/resolvers/block.ts
+++ b/apps/sim/executor/variables/resolvers/block.ts
@@ -48,7 +48,6 @@ export class BlockResolver implements Resolver {
}
const output = this.getBlockOutput(blockId, context)
-
if (output === undefined) {
return undefined
}
@@ -56,16 +55,62 @@ export class BlockResolver implements Resolver {
return output
}
- const result = navigatePath(output, pathParts)
+ // Try the original path first
+ let result = navigatePath(output, pathParts)
+
+ // If successful, return it immediately
+ if (result !== undefined) {
+ return result
+ }
- if (result === undefined) {
- const availableKeys = output && typeof output === 'object' ? Object.keys(output) : []
- throw new Error(
- `No value found at path "${pathParts.join('.')}" in block "${blockName}". Available fields: ${availableKeys.join(', ')}`
- )
+ // If failed, check if we should try backwards compatibility fallback
+ const block = this.workflow.blocks.find((b) => b.id === blockId)
+
+ // Response block backwards compatibility:
+ // Old: -> New:
+ // Only apply fallback if:
+ // 1. Block type is 'response'
+ // 2. Path starts with 'response.'
+ // 3. Output doesn't have a 'response' key (confirming it's the new format)
+ if (
+ block?.metadata?.id === 'response' &&
+ pathParts[0] === 'response' &&
+ output?.response === undefined
+ ) {
+ const adjustedPathParts = pathParts.slice(1)
+ if (adjustedPathParts.length === 0) {
+ return output
+ }
+ result = navigatePath(output, adjustedPathParts)
+ if (result !== undefined) {
+ return result
+ }
+ }
+
+ // Workflow block backwards compatibility:
+ // Old: -> New:
+ // Only apply fallback if:
+ // 1. Block type is 'workflow'
+ // 2. Path starts with 'result.response.'
+ // 3. output.result.response doesn't exist (confirming child used new format)
+ if (
+ block?.metadata?.id === 'workflow' &&
+ pathParts[0] === 'result' &&
+ pathParts[1] === 'response' &&
+ output?.result?.response === undefined
+ ) {
+ const adjustedPathParts = ['result', ...pathParts.slice(2)]
+ result = navigatePath(output, adjustedPathParts)
+ if (result !== undefined) {
+ return result
+ }
}
- return result
+ // If still undefined, throw error with original path
+ const availableKeys = output && typeof output === 'object' ? Object.keys(output) : []
+ throw new Error(
+ `No value found at path "${pathParts.join('.')}" in block "${blockName}". Available fields: ${availableKeys.join(', ')}`
+ )
}
private getBlockOutput(blockId: string, context: ResolutionContext): any {
diff --git a/apps/sim/lib/core/config/redis.ts b/apps/sim/lib/core/config/redis.ts
index f4250b91bb..ede72eaea9 100644
--- a/apps/sim/lib/core/config/redis.ts
+++ b/apps/sim/lib/core/config/redis.ts
@@ -61,54 +61,6 @@ export function getRedisClient(): Redis | null {
}
}
-/**
- * Check if Redis is ready for commands.
- * Use for health checks only - commands should be sent regardless (ioredis queues them).
- */
-export function isRedisConnected(): boolean {
- return globalRedisClient?.status === 'ready'
-}
-
-/**
- * Get Redis connection status for diagnostics.
- */
-export function getRedisStatus(): string {
- return globalRedisClient?.status ?? 'not initialized'
-}
-
-const MESSAGE_ID_PREFIX = 'processed:'
-const MESSAGE_ID_EXPIRY = 60 * 60 * 24 * 7
-
-/**
- * Check if a message has been processed (for idempotency).
- * Requires Redis - throws if Redis is not available.
- */
-export async function hasProcessedMessage(key: string): Promise {
- const redis = getRedisClient()
- if (!redis) {
- throw new Error('Redis not available for message deduplication')
- }
-
- const result = await redis.exists(`${MESSAGE_ID_PREFIX}${key}`)
- return result === 1
-}
-
-/**
- * Mark a message as processed (for idempotency).
- * Requires Redis - throws if Redis is not available.
- */
-export async function markMessageAsProcessed(
- key: string,
- expirySeconds: number = MESSAGE_ID_EXPIRY
-): Promise {
- const redis = getRedisClient()
- if (!redis) {
- throw new Error('Redis not available for message deduplication')
- }
-
- await redis.set(`${MESSAGE_ID_PREFIX}${key}`, '1', 'EX', expirySeconds)
-}
-
/**
* Lua script for safe lock release.
* Only deletes the key if the value matches (ownership verification).
@@ -125,7 +77,10 @@ end
/**
* Acquire a distributed lock using Redis SET NX.
* Returns true if lock acquired, false if already held.
- * Requires Redis - throws if Redis is not available.
+ *
+ * When Redis is not available, returns true (lock "acquired") to allow
+ * single-replica deployments to function without Redis. In multi-replica
+ * deployments without Redis, the idempotency layer prevents duplicate processing.
*/
export async function acquireLock(
lockKey: string,
@@ -134,36 +89,24 @@ export async function acquireLock(
): Promise {
const redis = getRedisClient()
if (!redis) {
- throw new Error('Redis not available for distributed locking')
+ return true // No-op when Redis unavailable; idempotency layer handles duplicates
}
const result = await redis.set(lockKey, value, 'EX', expirySeconds, 'NX')
return result === 'OK'
}
-/**
- * Get the value of a lock key.
- * Requires Redis - throws if Redis is not available.
- */
-export async function getLockValue(key: string): Promise {
- const redis = getRedisClient()
- if (!redis) {
- throw new Error('Redis not available')
- }
-
- return redis.get(key)
-}
-
/**
* Release a distributed lock safely.
* Only releases if the caller owns the lock (value matches).
* Returns true if lock was released, false if not owned or already expired.
- * Requires Redis - throws if Redis is not available.
+ *
+ * When Redis is not available, returns true (no-op) since no lock was held.
*/
export async function releaseLock(lockKey: string, value: string): Promise {
const redis = getRedisClient()
if (!redis) {
- throw new Error('Redis not available for distributed locking')
+ return true // No-op when Redis unavailable; no lock was actually held
}
const result = await redis.eval(RELEASE_LOCK_SCRIPT, 1, lockKey, value)
diff --git a/apps/sim/lib/workflows/streaming/streaming.ts b/apps/sim/lib/workflows/streaming/streaming.ts
index da606c6a9c..6a12d78722 100644
--- a/apps/sim/lib/workflows/streaming/streaming.ts
+++ b/apps/sim/lib/workflows/streaming/streaming.ts
@@ -42,11 +42,7 @@ interface StreamingState {
}
function extractOutputValue(output: any, path: string): any {
- let value = traverseObjectPath(output, path)
- if (value === undefined && output?.response) {
- value = traverseObjectPath(output.response, path)
- }
- return value
+ return traverseObjectPath(output, path)
}
function isDangerousKey(key: string): boolean {
diff --git a/apps/sim/lib/workflows/utils.ts b/apps/sim/lib/workflows/utils.ts
index 25c10f24c3..f3bf49ece3 100644
--- a/apps/sim/lib/workflows/utils.ts
+++ b/apps/sim/lib/workflows/utils.ts
@@ -136,12 +136,7 @@ export async function updateWorkflowRunCounts(workflowId: string, runs = 1) {
}
export const workflowHasResponseBlock = (executionResult: ExecutionResult): boolean => {
- if (
- !executionResult?.logs ||
- !Array.isArray(executionResult.logs) ||
- !executionResult.success ||
- !executionResult.output.response
- ) {
+ if (!executionResult?.logs || !Array.isArray(executionResult.logs) || !executionResult.success) {
return false
}
@@ -154,8 +149,7 @@ export const workflowHasResponseBlock = (executionResult: ExecutionResult): bool
// Create a HTTP response from response block
export const createHttpResponseFromBlock = (executionResult: ExecutionResult): NextResponse => {
- const output = executionResult.output.response
- const { data = {}, status = 200, headers = {} } = output
+ const { data = {}, status = 200, headers = {} } = executionResult.output
const responseHeaders = new Headers({
'Content-Type': 'application/json',
diff --git a/apps/sim/tools/workflow/executor.test.ts b/apps/sim/tools/workflow/executor.test.ts
new file mode 100644
index 0000000000..8ad3bca43e
--- /dev/null
+++ b/apps/sim/tools/workflow/executor.test.ts
@@ -0,0 +1,230 @@
+import { describe, expect, it } from 'vitest'
+import { workflowExecutorTool } from '@/tools/workflow/executor'
+
+describe('workflowExecutorTool', () => {
+ describe('request.body', () => {
+ const buildBody = workflowExecutorTool.request.body!
+
+ it.concurrent('should pass through object inputMapping unchanged (LLM-provided args)', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: { firstName: 'John', lastName: 'Doe', age: 30 },
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: { firstName: 'John', lastName: 'Doe', age: 30 },
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should parse JSON string inputMapping (UI-provided via tool-input)', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: '{"firstName": "John", "lastName": "Doe"}',
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: { firstName: 'John', lastName: 'Doe' },
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should handle nested objects in JSON string inputMapping', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: '{"user": {"name": "John", "email": "john@example.com"}, "count": 5}',
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: { user: { name: 'John', email: 'john@example.com' }, count: 5 },
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should handle arrays in JSON string inputMapping', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: '{"tags": ["a", "b", "c"], "ids": [1, 2, 3]}',
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: { tags: ['a', 'b', 'c'], ids: [1, 2, 3] },
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should default to empty object when inputMapping is undefined', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: undefined,
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: {},
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should default to empty object when inputMapping is null', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: null as any,
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: {},
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should fallback to empty object for invalid JSON string', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: 'not valid json {',
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: {},
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should fallback to empty object for empty string', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: '',
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: {},
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should handle empty object inputMapping', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: {},
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: {},
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should handle empty JSON object string', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: '{}',
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: {},
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should preserve special characters in string values', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: '{"message": "Hello\\nWorld", "path": "C:\\\\Users"}',
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: { message: 'Hello\nWorld', path: 'C:\\Users' },
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should handle unicode characters in JSON string', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: '{"greeting": "こんにちは", "emoji": "👋"}',
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: { greeting: 'こんにちは', emoji: '👋' },
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+
+ it.concurrent('should not modify object with string values that look like JSON', () => {
+ const params = {
+ workflowId: 'test-workflow-id',
+ inputMapping: { data: '{"nested": "json"}' },
+ }
+
+ const result = buildBody(params)
+
+ expect(result).toEqual({
+ input: { data: '{"nested": "json"}' },
+ triggerType: 'api',
+ useDraftState: false,
+ })
+ })
+ })
+
+ describe('request.url', () => {
+ it.concurrent('should build correct URL with workflowId', () => {
+ const url = workflowExecutorTool.request.url as (params: any) => string
+
+ expect(url({ workflowId: 'abc-123' })).toBe('/api/workflows/abc-123/execute')
+ expect(url({ workflowId: 'my-workflow' })).toBe('/api/workflows/my-workflow/execute')
+ })
+ })
+
+ describe('tool metadata', () => {
+ it.concurrent('should have correct id', () => {
+ expect(workflowExecutorTool.id).toBe('workflow_executor')
+ })
+
+ it.concurrent('should have required workflowId param', () => {
+ expect(workflowExecutorTool.params.workflowId.required).toBe(true)
+ })
+
+ it.concurrent('should have optional inputMapping param', () => {
+ expect(workflowExecutorTool.params.inputMapping.required).toBe(false)
+ })
+
+ it.concurrent('should use POST method', () => {
+ expect(workflowExecutorTool.request.method).toBe('POST')
+ })
+ })
+})
diff --git a/apps/sim/tools/workflow/executor.ts b/apps/sim/tools/workflow/executor.ts
index a5c054dc49..036769eb71 100644
--- a/apps/sim/tools/workflow/executor.ts
+++ b/apps/sim/tools/workflow/executor.ts
@@ -33,11 +33,21 @@ export const workflowExecutorTool: ToolConfig<
url: (params: WorkflowExecutorParams) => `/api/workflows/${params.workflowId}/execute`,
method: 'POST',
headers: () => ({ 'Content-Type': 'application/json' }),
- body: (params: WorkflowExecutorParams) => ({
- input: params.inputMapping || {},
- triggerType: 'api',
- useDraftState: false,
- }),
+ body: (params: WorkflowExecutorParams) => {
+ let inputData = params.inputMapping || {}
+ if (typeof inputData === 'string') {
+ try {
+ inputData = JSON.parse(inputData)
+ } catch {
+ inputData = {}
+ }
+ }
+ return {
+ input: inputData,
+ triggerType: 'api',
+ useDraftState: false,
+ }
+ },
},
transformResponse: async (response: Response) => {
const data = await response.json()
diff --git a/apps/sim/tools/workflow/types.ts b/apps/sim/tools/workflow/types.ts
index f86f8961e8..b0f4339d64 100644
--- a/apps/sim/tools/workflow/types.ts
+++ b/apps/sim/tools/workflow/types.ts
@@ -2,7 +2,8 @@ import type { ToolResponse } from '@/tools/types'
export interface WorkflowExecutorParams {
workflowId: string
- inputMapping?: Record
+ /** Can be a JSON string (from tool-input UI) or an object (from LLM args) */
+ inputMapping?: Record | string
}
export interface WorkflowExecutorResponse extends ToolResponse {
diff --git a/apps/sim/triggers/airtable/webhook.ts b/apps/sim/triggers/airtable/webhook.ts
index 45c8f6cf3a..1b352afc18 100644
--- a/apps/sim/triggers/airtable/webhook.ts
+++ b/apps/sim/triggers/airtable/webhook.ts
@@ -47,6 +47,14 @@ export const airtableWebhookTrigger: TriggerConfig = {
defaultValue: false,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'airtable_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -67,14 +75,6 @@ export const airtableWebhookTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'airtable_webhook',
- },
],
outputs: {
diff --git a/apps/sim/triggers/calendly/invitee_canceled.ts b/apps/sim/triggers/calendly/invitee_canceled.ts
index 242e592f7b..eb04c491d6 100644
--- a/apps/sim/triggers/calendly/invitee_canceled.ts
+++ b/apps/sim/triggers/calendly/invitee_canceled.ts
@@ -38,6 +38,18 @@ export const calendlyInviteeCanceledTrigger: TriggerConfig = {
value: 'calendly_invitee_canceled',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'calendly_invitee_canceled',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'calendly_invitee_canceled',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -61,18 +73,6 @@ export const calendlyInviteeCanceledTrigger: TriggerConfig = {
value: 'calendly_invitee_canceled',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'calendly_invitee_canceled',
- condition: {
- field: 'selectedTriggerId',
- value: 'calendly_invitee_canceled',
- },
- },
],
outputs: buildInviteeOutputs(),
diff --git a/apps/sim/triggers/calendly/invitee_created.ts b/apps/sim/triggers/calendly/invitee_created.ts
index 8fe7e13eb9..b8775433ea 100644
--- a/apps/sim/triggers/calendly/invitee_created.ts
+++ b/apps/sim/triggers/calendly/invitee_created.ts
@@ -47,6 +47,18 @@ export const calendlyInviteeCreatedTrigger: TriggerConfig = {
value: 'calendly_invitee_created',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'calendly_invitee_created',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'calendly_invitee_created',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -70,18 +82,6 @@ export const calendlyInviteeCreatedTrigger: TriggerConfig = {
value: 'calendly_invitee_created',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'calendly_invitee_created',
- condition: {
- field: 'selectedTriggerId',
- value: 'calendly_invitee_created',
- },
- },
],
outputs: buildInviteeOutputs(),
diff --git a/apps/sim/triggers/calendly/routing_form_submitted.ts b/apps/sim/triggers/calendly/routing_form_submitted.ts
index 003751dcdb..ee98c1a975 100644
--- a/apps/sim/triggers/calendly/routing_form_submitted.ts
+++ b/apps/sim/triggers/calendly/routing_form_submitted.ts
@@ -38,6 +38,18 @@ export const calendlyRoutingFormSubmittedTrigger: TriggerConfig = {
value: 'calendly_routing_form_submitted',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'calendly_routing_form_submitted',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'calendly_routing_form_submitted',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -61,18 +73,6 @@ export const calendlyRoutingFormSubmittedTrigger: TriggerConfig = {
value: 'calendly_routing_form_submitted',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'calendly_routing_form_submitted',
- condition: {
- field: 'selectedTriggerId',
- value: 'calendly_routing_form_submitted',
- },
- },
],
outputs: buildRoutingFormOutputs(),
diff --git a/apps/sim/triggers/calendly/webhook.ts b/apps/sim/triggers/calendly/webhook.ts
index 658e7078af..d3d02a79d9 100644
--- a/apps/sim/triggers/calendly/webhook.ts
+++ b/apps/sim/triggers/calendly/webhook.ts
@@ -37,6 +37,18 @@ export const calendlyWebhookTrigger: TriggerConfig = {
value: 'calendly_webhook',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'calendly_webhook',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'calendly_webhook',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -60,18 +72,6 @@ export const calendlyWebhookTrigger: TriggerConfig = {
value: 'calendly_webhook',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'calendly_webhook',
- condition: {
- field: 'selectedTriggerId',
- value: 'calendly_webhook',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/circleback/meeting_completed.ts b/apps/sim/triggers/circleback/meeting_completed.ts
index 904ee70865..9da936d5e8 100644
--- a/apps/sim/triggers/circleback/meeting_completed.ts
+++ b/apps/sim/triggers/circleback/meeting_completed.ts
@@ -40,24 +40,24 @@ export const circlebackMeetingCompletedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: circlebackSetupInstructions('All meeting data'),
mode: 'trigger',
+ triggerId: 'circleback_meeting_completed',
condition: {
field: 'selectedTriggerId',
value: 'circleback_meeting_completed',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: circlebackSetupInstructions('All meeting data'),
mode: 'trigger',
- triggerId: 'circleback_meeting_completed',
condition: {
field: 'selectedTriggerId',
value: 'circleback_meeting_completed',
diff --git a/apps/sim/triggers/circleback/meeting_notes.ts b/apps/sim/triggers/circleback/meeting_notes.ts
index d8b3af7afd..5d814efcf3 100644
--- a/apps/sim/triggers/circleback/meeting_notes.ts
+++ b/apps/sim/triggers/circleback/meeting_notes.ts
@@ -40,24 +40,24 @@ export const circlebackMeetingNotesTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: circlebackSetupInstructions('Meeting notes and action items'),
mode: 'trigger',
+ triggerId: 'circleback_meeting_notes',
condition: {
field: 'selectedTriggerId',
value: 'circleback_meeting_notes',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: circlebackSetupInstructions('Meeting notes and action items'),
mode: 'trigger',
- triggerId: 'circleback_meeting_notes',
condition: {
field: 'selectedTriggerId',
value: 'circleback_meeting_notes',
diff --git a/apps/sim/triggers/circleback/webhook.ts b/apps/sim/triggers/circleback/webhook.ts
index b1c6f5ee79..017a066b9e 100644
--- a/apps/sim/triggers/circleback/webhook.ts
+++ b/apps/sim/triggers/circleback/webhook.ts
@@ -49,24 +49,24 @@ export const circlebackWebhookTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: circlebackSetupInstructions('All events'),
mode: 'trigger',
+ triggerId: 'circleback_webhook',
condition: {
field: 'selectedTriggerId',
value: 'circleback_webhook',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: circlebackSetupInstructions('All events'),
mode: 'trigger',
- triggerId: 'circleback_webhook',
condition: {
field: 'selectedTriggerId',
value: 'circleback_webhook',
diff --git a/apps/sim/triggers/generic/webhook.ts b/apps/sim/triggers/generic/webhook.ts
index 7a4be9e1ad..5dd24a489a 100644
--- a/apps/sim/triggers/generic/webhook.ts
+++ b/apps/sim/triggers/generic/webhook.ts
@@ -56,6 +56,14 @@ export const genericWebhookTrigger: TriggerConfig = {
'Define the expected JSON input schema for this webhook (optional). Use type "files" for file uploads.',
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'generic_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -76,14 +84,6 @@ export const genericWebhookTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'generic_webhook',
- },
],
outputs: {},
diff --git a/apps/sim/triggers/github/issue_closed.ts b/apps/sim/triggers/github/issue_closed.ts
index 3af72c1064..f2bbe12e39 100644
--- a/apps/sim/triggers/github/issue_closed.ts
+++ b/apps/sim/triggers/github/issue_closed.ts
@@ -75,6 +75,18 @@ export const githubIssueClosedTrigger: TriggerConfig = {
value: 'github_issue_closed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_issue_closed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_issue_closed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -101,18 +113,6 @@ export const githubIssueClosedTrigger: TriggerConfig = {
value: 'github_issue_closed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_issue_closed',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_issue_closed',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/issue_comment.ts b/apps/sim/triggers/github/issue_comment.ts
index d834f6185d..972d244120 100644
--- a/apps/sim/triggers/github/issue_comment.ts
+++ b/apps/sim/triggers/github/issue_comment.ts
@@ -75,6 +75,18 @@ export const githubIssueCommentTrigger: TriggerConfig = {
value: 'github_issue_comment',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_issue_comment',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_issue_comment',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -102,18 +114,6 @@ export const githubIssueCommentTrigger: TriggerConfig = {
value: 'github_issue_comment',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_issue_comment',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_issue_comment',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/issue_opened.ts b/apps/sim/triggers/github/issue_opened.ts
index d5e71fe70f..e05caad03b 100644
--- a/apps/sim/triggers/github/issue_opened.ts
+++ b/apps/sim/triggers/github/issue_opened.ts
@@ -96,6 +96,18 @@ export const githubIssueOpenedTrigger: TriggerConfig = {
value: 'github_issue_opened',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_issue_opened',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_issue_opened',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -122,18 +134,6 @@ export const githubIssueOpenedTrigger: TriggerConfig = {
value: 'github_issue_opened',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_issue_opened',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_issue_opened',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/pr_closed.ts b/apps/sim/triggers/github/pr_closed.ts
index ad9a8013c7..b60c1043f4 100644
--- a/apps/sim/triggers/github/pr_closed.ts
+++ b/apps/sim/triggers/github/pr_closed.ts
@@ -76,6 +76,18 @@ export const githubPRClosedTrigger: TriggerConfig = {
value: 'github_pr_closed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_pr_closed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_pr_closed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -102,18 +114,6 @@ export const githubPRClosedTrigger: TriggerConfig = {
value: 'github_pr_closed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_pr_closed',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_pr_closed',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/pr_comment.ts b/apps/sim/triggers/github/pr_comment.ts
index 4cc968a170..2fab088a70 100644
--- a/apps/sim/triggers/github/pr_comment.ts
+++ b/apps/sim/triggers/github/pr_comment.ts
@@ -75,6 +75,18 @@ export const githubPRCommentTrigger: TriggerConfig = {
value: 'github_pr_comment',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_pr_comment',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_pr_comment',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -102,18 +114,6 @@ export const githubPRCommentTrigger: TriggerConfig = {
value: 'github_pr_comment',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_pr_comment',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_pr_comment',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/pr_merged.ts b/apps/sim/triggers/github/pr_merged.ts
index 1b0b0f9c76..23ecdad3a8 100644
--- a/apps/sim/triggers/github/pr_merged.ts
+++ b/apps/sim/triggers/github/pr_merged.ts
@@ -75,6 +75,18 @@ export const githubPRMergedTrigger: TriggerConfig = {
value: 'github_pr_merged',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_pr_merged',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_pr_merged',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -101,18 +113,6 @@ export const githubPRMergedTrigger: TriggerConfig = {
value: 'github_pr_merged',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_pr_merged',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_pr_merged',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/pr_opened.ts b/apps/sim/triggers/github/pr_opened.ts
index 6ea5741b20..cced084ba5 100644
--- a/apps/sim/triggers/github/pr_opened.ts
+++ b/apps/sim/triggers/github/pr_opened.ts
@@ -75,6 +75,18 @@ export const githubPROpenedTrigger: TriggerConfig = {
value: 'github_pr_opened',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_pr_opened',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_pr_opened',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -101,18 +113,6 @@ export const githubPROpenedTrigger: TriggerConfig = {
value: 'github_pr_opened',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_pr_opened',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_pr_opened',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/pr_reviewed.ts b/apps/sim/triggers/github/pr_reviewed.ts
index 4c77a1add4..a5affcd839 100644
--- a/apps/sim/triggers/github/pr_reviewed.ts
+++ b/apps/sim/triggers/github/pr_reviewed.ts
@@ -76,6 +76,18 @@ export const githubPRReviewedTrigger: TriggerConfig = {
value: 'github_pr_reviewed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_pr_reviewed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_pr_reviewed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -102,18 +114,6 @@ export const githubPRReviewedTrigger: TriggerConfig = {
value: 'github_pr_reviewed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_pr_reviewed',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_pr_reviewed',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/push.ts b/apps/sim/triggers/github/push.ts
index 1dfae2dc39..7892110245 100644
--- a/apps/sim/triggers/github/push.ts
+++ b/apps/sim/triggers/github/push.ts
@@ -75,6 +75,18 @@ export const githubPushTrigger: TriggerConfig = {
value: 'github_push',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_push',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_push',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -101,18 +113,6 @@ export const githubPushTrigger: TriggerConfig = {
value: 'github_push',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_push',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_push',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/release_published.ts b/apps/sim/triggers/github/release_published.ts
index 57def978cb..3d10bb7423 100644
--- a/apps/sim/triggers/github/release_published.ts
+++ b/apps/sim/triggers/github/release_published.ts
@@ -75,6 +75,18 @@ export const githubReleasePublishedTrigger: TriggerConfig = {
value: 'github_release_published',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_release_published',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_release_published',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -101,18 +113,6 @@ export const githubReleasePublishedTrigger: TriggerConfig = {
value: 'github_release_published',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_release_published',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_release_published',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/webhook.ts b/apps/sim/triggers/github/webhook.ts
index c1e2b57452..a73d61e262 100644
--- a/apps/sim/triggers/github/webhook.ts
+++ b/apps/sim/triggers/github/webhook.ts
@@ -72,6 +72,18 @@ export const githubWebhookTrigger: TriggerConfig = {
value: 'github_webhook',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_webhook',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_webhook',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -98,18 +110,6 @@ export const githubWebhookTrigger: TriggerConfig = {
value: 'github_webhook',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_webhook',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_webhook',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/github/workflow_run.ts b/apps/sim/triggers/github/workflow_run.ts
index 84c78bd707..65e8053301 100644
--- a/apps/sim/triggers/github/workflow_run.ts
+++ b/apps/sim/triggers/github/workflow_run.ts
@@ -76,6 +76,18 @@ export const githubWorkflowRunTrigger: TriggerConfig = {
value: 'github_workflow_run',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'github_workflow_run',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'github_workflow_run',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -102,18 +114,6 @@ export const githubWorkflowRunTrigger: TriggerConfig = {
value: 'github_workflow_run',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'github_workflow_run',
- condition: {
- field: 'selectedTriggerId',
- value: 'github_workflow_run',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/gmail/poller.ts b/apps/sim/triggers/gmail/poller.ts
index cfda07a2d9..54f0e297d9 100644
--- a/apps/sim/triggers/gmail/poller.ts
+++ b/apps/sim/triggers/gmail/poller.ts
@@ -128,6 +128,14 @@ Return ONLY the Gmail search query, no explanations or markdown.`,
required: false,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'gmail_poller',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -145,14 +153,6 @@ Return ONLY the Gmail search query, no explanations or markdown.`,
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'gmail_poller',
- },
],
outputs: {
diff --git a/apps/sim/triggers/googleforms/webhook.ts b/apps/sim/triggers/googleforms/webhook.ts
index 7dd717098b..12106c74f1 100644
--- a/apps/sim/triggers/googleforms/webhook.ts
+++ b/apps/sim/triggers/googleforms/webhook.ts
@@ -59,6 +59,14 @@ export const googleFormsWebhookTrigger: TriggerConfig = {
defaultValue: true,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'google_forms_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -86,12 +94,12 @@ export const googleFormsWebhookTrigger: TriggerConfig = {
const script = `function onFormSubmit(e) {
const WEBHOOK_URL = "{{WEBHOOK_URL}}";
const SHARED_SECRET = "{{SHARED_SECRET}}";
-
+
try {
const form = FormApp.getActiveForm();
const formResponse = e.response;
const itemResponses = formResponse.getItemResponses();
-
+
// Build answers object
const answers = {};
for (var i = 0; i < itemResponses.length; i++) {
@@ -100,7 +108,7 @@ export const googleFormsWebhookTrigger: TriggerConfig = {
const answer = itemResponse.getResponse();
answers[question] = answer;
}
-
+
// Build payload
const payload = {
provider: "google_forms",
@@ -110,7 +118,7 @@ export const googleFormsWebhookTrigger: TriggerConfig = {
lastSubmittedTime: formResponse.getTimestamp().toISOString(),
answers: answers
};
-
+
// Send to webhook
const options = {
method: "post",
@@ -121,9 +129,9 @@ export const googleFormsWebhookTrigger: TriggerConfig = {
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
-
+
const response = UrlFetchApp.fetch(WEBHOOK_URL, options);
-
+
if (response.getResponseCode() !== 200) {
Logger.log("Webhook failed: " + response.getContentText());
} else {
@@ -145,14 +153,6 @@ export const googleFormsWebhookTrigger: TriggerConfig = {
description: 'Copy this code and paste it into your Google Forms Apps Script editor',
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'google_forms_webhook',
- },
],
outputs: {
diff --git a/apps/sim/triggers/grain/highlight_created.ts b/apps/sim/triggers/grain/highlight_created.ts
index 4301187950..d1347a4f31 100644
--- a/apps/sim/triggers/grain/highlight_created.ts
+++ b/apps/sim/triggers/grain/highlight_created.ts
@@ -35,24 +35,24 @@ export const grainHighlightCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: grainSetupInstructions('Highlight (new)'),
mode: 'trigger',
+ triggerId: 'grain_highlight_created',
condition: {
field: 'selectedTriggerId',
value: 'grain_highlight_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: grainSetupInstructions('Highlight (new)'),
mode: 'trigger',
- triggerId: 'grain_highlight_created',
condition: {
field: 'selectedTriggerId',
value: 'grain_highlight_created',
diff --git a/apps/sim/triggers/grain/highlight_updated.ts b/apps/sim/triggers/grain/highlight_updated.ts
index e4a3b7eb65..9c770e5f82 100644
--- a/apps/sim/triggers/grain/highlight_updated.ts
+++ b/apps/sim/triggers/grain/highlight_updated.ts
@@ -35,24 +35,24 @@ export const grainHighlightUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: grainSetupInstructions('Highlight (updated)'),
mode: 'trigger',
+ triggerId: 'grain_highlight_updated',
condition: {
field: 'selectedTriggerId',
value: 'grain_highlight_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: grainSetupInstructions('Highlight (updated)'),
mode: 'trigger',
- triggerId: 'grain_highlight_updated',
condition: {
field: 'selectedTriggerId',
value: 'grain_highlight_updated',
diff --git a/apps/sim/triggers/grain/recording_created.ts b/apps/sim/triggers/grain/recording_created.ts
index 6877ee6993..f8c592081f 100644
--- a/apps/sim/triggers/grain/recording_created.ts
+++ b/apps/sim/triggers/grain/recording_created.ts
@@ -35,24 +35,24 @@ export const grainRecordingCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: grainSetupInstructions('Recording (new)'),
mode: 'trigger',
+ triggerId: 'grain_recording_created',
condition: {
field: 'selectedTriggerId',
value: 'grain_recording_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: grainSetupInstructions('Recording (new)'),
mode: 'trigger',
- triggerId: 'grain_recording_created',
condition: {
field: 'selectedTriggerId',
value: 'grain_recording_created',
diff --git a/apps/sim/triggers/grain/recording_updated.ts b/apps/sim/triggers/grain/recording_updated.ts
index 1e3130371f..c64bb0f656 100644
--- a/apps/sim/triggers/grain/recording_updated.ts
+++ b/apps/sim/triggers/grain/recording_updated.ts
@@ -35,24 +35,24 @@ export const grainRecordingUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: grainSetupInstructions('Recording (updated)'),
mode: 'trigger',
+ triggerId: 'grain_recording_updated',
condition: {
field: 'selectedTriggerId',
value: 'grain_recording_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: grainSetupInstructions('Recording (updated)'),
mode: 'trigger',
- triggerId: 'grain_recording_updated',
condition: {
field: 'selectedTriggerId',
value: 'grain_recording_updated',
diff --git a/apps/sim/triggers/grain/story_created.ts b/apps/sim/triggers/grain/story_created.ts
index f3250e5fab..32267976ae 100644
--- a/apps/sim/triggers/grain/story_created.ts
+++ b/apps/sim/triggers/grain/story_created.ts
@@ -35,24 +35,24 @@ export const grainStoryCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: grainSetupInstructions('Story (new)'),
mode: 'trigger',
+ triggerId: 'grain_story_created',
condition: {
field: 'selectedTriggerId',
value: 'grain_story_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: grainSetupInstructions('Story (new)'),
mode: 'trigger',
- triggerId: 'grain_story_created',
condition: {
field: 'selectedTriggerId',
value: 'grain_story_created',
diff --git a/apps/sim/triggers/grain/webhook.ts b/apps/sim/triggers/grain/webhook.ts
index d41f21433a..93154193b3 100644
--- a/apps/sim/triggers/grain/webhook.ts
+++ b/apps/sim/triggers/grain/webhook.ts
@@ -35,24 +35,24 @@ export const grainWebhookTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: grainSetupInstructions('All events'),
mode: 'trigger',
+ triggerId: 'grain_webhook',
condition: {
field: 'selectedTriggerId',
value: 'grain_webhook',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: grainSetupInstructions('All events'),
mode: 'trigger',
- triggerId: 'grain_webhook',
condition: {
field: 'selectedTriggerId',
value: 'grain_webhook',
diff --git a/apps/sim/triggers/hubspot/company_created.ts b/apps/sim/triggers/hubspot/company_created.ts
index 4a1f4e3883..3a26e1ac66 100644
--- a/apps/sim/triggers/hubspot/company_created.ts
+++ b/apps/sim/triggers/hubspot/company_created.ts
@@ -93,6 +93,17 @@ export const hubspotCompanyCreatedTrigger: TriggerConfig = {
value: 'hubspot_company_created',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_company_created',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_company_created',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotCompanyCreatedTrigger: TriggerConfig = {
value: 'hubspot_company_created',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_company_created',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_company_created',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/company_deleted.ts b/apps/sim/triggers/hubspot/company_deleted.ts
index 5ca5a3ad99..654cb30395 100644
--- a/apps/sim/triggers/hubspot/company_deleted.ts
+++ b/apps/sim/triggers/hubspot/company_deleted.ts
@@ -93,6 +93,17 @@ export const hubspotCompanyDeletedTrigger: TriggerConfig = {
value: 'hubspot_company_deleted',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_company_deleted',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_company_deleted',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotCompanyDeletedTrigger: TriggerConfig = {
value: 'hubspot_company_deleted',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_company_deleted',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_company_deleted',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/company_property_changed.ts b/apps/sim/triggers/hubspot/company_property_changed.ts
index 18b597712b..c34e62b656 100644
--- a/apps/sim/triggers/hubspot/company_property_changed.ts
+++ b/apps/sim/triggers/hubspot/company_property_changed.ts
@@ -107,6 +107,17 @@ export const hubspotCompanyPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_company_property_changed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_company_property_changed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_company_property_changed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -170,17 +181,6 @@ export const hubspotCompanyPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_company_property_changed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_company_property_changed',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_company_property_changed',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/contact_created.ts b/apps/sim/triggers/hubspot/contact_created.ts
index c8ef178160..0984e73339 100644
--- a/apps/sim/triggers/hubspot/contact_created.ts
+++ b/apps/sim/triggers/hubspot/contact_created.ts
@@ -93,6 +93,17 @@ export const hubspotContactCreatedTrigger: TriggerConfig = {
value: 'hubspot_contact_created',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_contact_created',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_contact_created',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotContactCreatedTrigger: TriggerConfig = {
value: 'hubspot_contact_created',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_contact_created',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_contact_created',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/contact_deleted.ts b/apps/sim/triggers/hubspot/contact_deleted.ts
index 44e412ae7e..767ddb1861 100644
--- a/apps/sim/triggers/hubspot/contact_deleted.ts
+++ b/apps/sim/triggers/hubspot/contact_deleted.ts
@@ -93,6 +93,17 @@ export const hubspotContactDeletedTrigger: TriggerConfig = {
value: 'hubspot_contact_deleted',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_contact_deleted',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_contact_deleted',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotContactDeletedTrigger: TriggerConfig = {
value: 'hubspot_contact_deleted',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_contact_deleted',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_contact_deleted',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/contact_privacy_deleted.ts b/apps/sim/triggers/hubspot/contact_privacy_deleted.ts
index a9e9e95e06..9da858923f 100644
--- a/apps/sim/triggers/hubspot/contact_privacy_deleted.ts
+++ b/apps/sim/triggers/hubspot/contact_privacy_deleted.ts
@@ -94,6 +94,17 @@ export const hubspotContactPrivacyDeletedTrigger: TriggerConfig = {
value: 'hubspot_contact_privacy_deleted',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_contact_privacy_deleted',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_contact_privacy_deleted',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -157,17 +168,6 @@ export const hubspotContactPrivacyDeletedTrigger: TriggerConfig = {
value: 'hubspot_contact_privacy_deleted',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_contact_privacy_deleted',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_contact_privacy_deleted',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/contact_property_changed.ts b/apps/sim/triggers/hubspot/contact_property_changed.ts
index 65c9d3e6d2..27dfb7a93f 100644
--- a/apps/sim/triggers/hubspot/contact_property_changed.ts
+++ b/apps/sim/triggers/hubspot/contact_property_changed.ts
@@ -107,6 +107,17 @@ export const hubspotContactPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_contact_property_changed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_contact_property_changed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_contact_property_changed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -170,17 +181,6 @@ export const hubspotContactPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_contact_property_changed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_contact_property_changed',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_contact_property_changed',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/conversation_creation.ts b/apps/sim/triggers/hubspot/conversation_creation.ts
index 14e7639289..1d1b30e6fc 100644
--- a/apps/sim/triggers/hubspot/conversation_creation.ts
+++ b/apps/sim/triggers/hubspot/conversation_creation.ts
@@ -93,6 +93,17 @@ export const hubspotConversationCreationTrigger: TriggerConfig = {
value: 'hubspot_conversation_creation',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_conversation_creation',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_conversation_creation',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotConversationCreationTrigger: TriggerConfig = {
value: 'hubspot_conversation_creation',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_conversation_creation',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_conversation_creation',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/conversation_deletion.ts b/apps/sim/triggers/hubspot/conversation_deletion.ts
index 647a4c763f..8299b49f7b 100644
--- a/apps/sim/triggers/hubspot/conversation_deletion.ts
+++ b/apps/sim/triggers/hubspot/conversation_deletion.ts
@@ -93,6 +93,17 @@ export const hubspotConversationDeletionTrigger: TriggerConfig = {
value: 'hubspot_conversation_deletion',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_conversation_deletion',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_conversation_deletion',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotConversationDeletionTrigger: TriggerConfig = {
value: 'hubspot_conversation_deletion',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_conversation_deletion',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_conversation_deletion',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/conversation_new_message.ts b/apps/sim/triggers/hubspot/conversation_new_message.ts
index a5d1664272..0f9007ea9f 100644
--- a/apps/sim/triggers/hubspot/conversation_new_message.ts
+++ b/apps/sim/triggers/hubspot/conversation_new_message.ts
@@ -93,6 +93,17 @@ export const hubspotConversationNewMessageTrigger: TriggerConfig = {
value: 'hubspot_conversation_new_message',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_conversation_new_message',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_conversation_new_message',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotConversationNewMessageTrigger: TriggerConfig = {
value: 'hubspot_conversation_new_message',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_conversation_new_message',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_conversation_new_message',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/conversation_privacy_deletion.ts b/apps/sim/triggers/hubspot/conversation_privacy_deletion.ts
index 7ede1098d2..bc269c4b44 100644
--- a/apps/sim/triggers/hubspot/conversation_privacy_deletion.ts
+++ b/apps/sim/triggers/hubspot/conversation_privacy_deletion.ts
@@ -94,6 +94,17 @@ export const hubspotConversationPrivacyDeletionTrigger: TriggerConfig = {
value: 'hubspot_conversation_privacy_deletion',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_conversation_privacy_deletion',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_conversation_privacy_deletion',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -157,17 +168,6 @@ export const hubspotConversationPrivacyDeletionTrigger: TriggerConfig = {
value: 'hubspot_conversation_privacy_deletion',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_conversation_privacy_deletion',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_conversation_privacy_deletion',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/conversation_property_changed.ts b/apps/sim/triggers/hubspot/conversation_property_changed.ts
index 9359a5f294..efe19e07e0 100644
--- a/apps/sim/triggers/hubspot/conversation_property_changed.ts
+++ b/apps/sim/triggers/hubspot/conversation_property_changed.ts
@@ -107,6 +107,17 @@ export const hubspotConversationPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_conversation_property_changed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_conversation_property_changed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_conversation_property_changed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -170,17 +181,6 @@ export const hubspotConversationPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_conversation_property_changed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_conversation_property_changed',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_conversation_property_changed',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/deal_created.ts b/apps/sim/triggers/hubspot/deal_created.ts
index cc20e7743b..a4923de69a 100644
--- a/apps/sim/triggers/hubspot/deal_created.ts
+++ b/apps/sim/triggers/hubspot/deal_created.ts
@@ -93,6 +93,17 @@ export const hubspotDealCreatedTrigger: TriggerConfig = {
value: 'hubspot_deal_created',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_deal_created',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_deal_created',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotDealCreatedTrigger: TriggerConfig = {
value: 'hubspot_deal_created',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_deal_created',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_deal_created',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/deal_deleted.ts b/apps/sim/triggers/hubspot/deal_deleted.ts
index 2b7d4afcb1..b53ab112ce 100644
--- a/apps/sim/triggers/hubspot/deal_deleted.ts
+++ b/apps/sim/triggers/hubspot/deal_deleted.ts
@@ -93,6 +93,17 @@ export const hubspotDealDeletedTrigger: TriggerConfig = {
value: 'hubspot_deal_deleted',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_deal_deleted',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_deal_deleted',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotDealDeletedTrigger: TriggerConfig = {
value: 'hubspot_deal_deleted',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_deal_deleted',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_deal_deleted',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/deal_property_changed.ts b/apps/sim/triggers/hubspot/deal_property_changed.ts
index 82914ad2cd..a49bbeb26d 100644
--- a/apps/sim/triggers/hubspot/deal_property_changed.ts
+++ b/apps/sim/triggers/hubspot/deal_property_changed.ts
@@ -107,6 +107,17 @@ export const hubspotDealPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_deal_property_changed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_deal_property_changed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_deal_property_changed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -170,17 +181,6 @@ export const hubspotDealPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_deal_property_changed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_deal_property_changed',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_deal_property_changed',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/ticket_created.ts b/apps/sim/triggers/hubspot/ticket_created.ts
index 85e29e1016..1cff8fb8a4 100644
--- a/apps/sim/triggers/hubspot/ticket_created.ts
+++ b/apps/sim/triggers/hubspot/ticket_created.ts
@@ -93,6 +93,17 @@ export const hubspotTicketCreatedTrigger: TriggerConfig = {
value: 'hubspot_ticket_created',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_ticket_created',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_ticket_created',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotTicketCreatedTrigger: TriggerConfig = {
value: 'hubspot_ticket_created',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_ticket_created',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_ticket_created',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/ticket_deleted.ts b/apps/sim/triggers/hubspot/ticket_deleted.ts
index 23034fd6e1..28ef9748b7 100644
--- a/apps/sim/triggers/hubspot/ticket_deleted.ts
+++ b/apps/sim/triggers/hubspot/ticket_deleted.ts
@@ -93,6 +93,17 @@ export const hubspotTicketDeletedTrigger: TriggerConfig = {
value: 'hubspot_ticket_deleted',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_ticket_deleted',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_ticket_deleted',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -156,17 +167,6 @@ export const hubspotTicketDeletedTrigger: TriggerConfig = {
value: 'hubspot_ticket_deleted',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_ticket_deleted',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_ticket_deleted',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/ticket_property_changed.ts b/apps/sim/triggers/hubspot/ticket_property_changed.ts
index 157ac38edc..f7dbcf9acf 100644
--- a/apps/sim/triggers/hubspot/ticket_property_changed.ts
+++ b/apps/sim/triggers/hubspot/ticket_property_changed.ts
@@ -107,6 +107,17 @@ export const hubspotTicketPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_ticket_property_changed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ mode: 'trigger',
+ triggerId: 'hubspot_ticket_property_changed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'hubspot_ticket_property_changed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -170,17 +181,6 @@ export const hubspotTicketPropertyChangedTrigger: TriggerConfig = {
value: 'hubspot_ticket_property_changed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- mode: 'trigger',
- triggerId: 'hubspot_ticket_property_changed',
- condition: {
- field: 'selectedTriggerId',
- value: 'hubspot_ticket_property_changed',
- },
- },
{
id: 'samplePayload',
title: 'Event Payload Example',
diff --git a/apps/sim/triggers/hubspot/utils.ts b/apps/sim/triggers/hubspot/utils.ts
index a2de47d6bf..09ef6fcfcc 100644
--- a/apps/sim/triggers/hubspot/utils.ts
+++ b/apps/sim/triggers/hubspot/utils.ts
@@ -82,7 +82,7 @@ export function hubspotSetupInstructions(eventType: string, additionalNotes?: st
'Step 3: Configure OAuth Settings After creating your app via CLI, configure it to add the OAuth Redirect URL: https://www.sim.ai/api/auth/oauth2/callback/hubspot. Then retrieve your Client ID and Client Secret from your app configuration and enter them in the fields above.',
"Step 4: Get App ID and Developer API Key In your HubSpot developer account, find your App ID (shown below your app name) and your Developer API Key (in app settings). You'll need both for the next steps.",
'Step 5: Set Required Scopes Configure your app to include the required OAuth scope: crm.objects.contacts.read',
- 'Step 6: Save Configuration in Sim Click the "Save Configuration" button below. This will generate your unique webhook URL.',
+ 'Step 6: Save Configuration in Sim Click the "Save Configuration" button above. This will generate your unique webhook URL.',
'Step 7: Configure Webhook in HubSpot via API After saving above, copy the Webhook URL and run the two curl commands below (replace {YOUR_APP_ID}, {YOUR_DEVELOPER_API_KEY}, and {YOUR_WEBHOOK_URL_FROM_ABOVE} with your actual values).',
"Step 8: Test Your Webhook Create or modify a contact in HubSpot to trigger the webhook. Check your workflow execution logs in Sim to verify it's working.",
]
diff --git a/apps/sim/triggers/imap/poller.ts b/apps/sim/triggers/imap/poller.ts
index fe0ae078fe..cfcc5c5d72 100644
--- a/apps/sim/triggers/imap/poller.ts
+++ b/apps/sim/triggers/imap/poller.ts
@@ -202,6 +202,14 @@ Return ONLY valid JSON, no explanations or markdown.`,
mode: 'trigger',
},
// Instructions
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'imap_poller',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -222,14 +230,6 @@ Return ONLY valid JSON, no explanations or markdown.`,
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'imap_poller',
- },
],
outputs: {
diff --git a/apps/sim/triggers/jira/issue_commented.ts b/apps/sim/triggers/jira/issue_commented.ts
index 3ebeb3709f..348a0c889c 100644
--- a/apps/sim/triggers/jira/issue_commented.ts
+++ b/apps/sim/triggers/jira/issue_commented.ts
@@ -57,24 +57,24 @@ export const jiraIssueCommentedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: jiraSetupInstructions('comment_created'),
mode: 'trigger',
+ triggerId: 'jira_issue_commented',
condition: {
field: 'selectedTriggerId',
value: 'jira_issue_commented',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('comment_created'),
mode: 'trigger',
- triggerId: 'jira_issue_commented',
condition: {
field: 'selectedTriggerId',
value: 'jira_issue_commented',
diff --git a/apps/sim/triggers/jira/issue_created.ts b/apps/sim/triggers/jira/issue_created.ts
index f6cb716752..df9a5f8f83 100644
--- a/apps/sim/triggers/jira/issue_created.ts
+++ b/apps/sim/triggers/jira/issue_created.ts
@@ -66,24 +66,24 @@ export const jiraIssueCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: jiraSetupInstructions('jira:issue_created'),
mode: 'trigger',
+ triggerId: 'jira_issue_created',
condition: {
field: 'selectedTriggerId',
value: 'jira_issue_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('jira:issue_created'),
mode: 'trigger',
- triggerId: 'jira_issue_created',
condition: {
field: 'selectedTriggerId',
value: 'jira_issue_created',
diff --git a/apps/sim/triggers/jira/issue_deleted.ts b/apps/sim/triggers/jira/issue_deleted.ts
index 559d5ebdce..190c23739e 100644
--- a/apps/sim/triggers/jira/issue_deleted.ts
+++ b/apps/sim/triggers/jira/issue_deleted.ts
@@ -57,24 +57,24 @@ export const jiraIssueDeletedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: jiraSetupInstructions('jira:issue_deleted'),
mode: 'trigger',
+ triggerId: 'jira_issue_deleted',
condition: {
field: 'selectedTriggerId',
value: 'jira_issue_deleted',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('jira:issue_deleted'),
mode: 'trigger',
- triggerId: 'jira_issue_deleted',
condition: {
field: 'selectedTriggerId',
value: 'jira_issue_deleted',
diff --git a/apps/sim/triggers/jira/issue_updated.ts b/apps/sim/triggers/jira/issue_updated.ts
index f8a0afb5b4..52189c1793 100644
--- a/apps/sim/triggers/jira/issue_updated.ts
+++ b/apps/sim/triggers/jira/issue_updated.ts
@@ -71,24 +71,24 @@ export const jiraIssueUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: jiraSetupInstructions('jira:issue_updated'),
mode: 'trigger',
+ triggerId: 'jira_issue_updated',
condition: {
field: 'selectedTriggerId',
value: 'jira_issue_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('jira:issue_updated'),
mode: 'trigger',
- triggerId: 'jira_issue_updated',
condition: {
field: 'selectedTriggerId',
value: 'jira_issue_updated',
diff --git a/apps/sim/triggers/jira/webhook.ts b/apps/sim/triggers/jira/webhook.ts
index aeb7722435..c44a5aea3b 100644
--- a/apps/sim/triggers/jira/webhook.ts
+++ b/apps/sim/triggers/jira/webhook.ts
@@ -44,24 +44,24 @@ export const jiraWebhookTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: jiraSetupInstructions('All Events'),
mode: 'trigger',
+ triggerId: 'jira_webhook',
condition: {
field: 'selectedTriggerId',
value: 'jira_webhook',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('All Events'),
mode: 'trigger',
- triggerId: 'jira_webhook',
condition: {
field: 'selectedTriggerId',
value: 'jira_webhook',
diff --git a/apps/sim/triggers/jira/worklog_created.ts b/apps/sim/triggers/jira/worklog_created.ts
index 0a26870502..f2603deb35 100644
--- a/apps/sim/triggers/jira/worklog_created.ts
+++ b/apps/sim/triggers/jira/worklog_created.ts
@@ -57,24 +57,24 @@ export const jiraWorklogCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: jiraSetupInstructions('worklog_created'),
mode: 'trigger',
+ triggerId: 'jira_worklog_created',
condition: {
field: 'selectedTriggerId',
value: 'jira_worklog_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('worklog_created'),
mode: 'trigger',
- triggerId: 'jira_worklog_created',
condition: {
field: 'selectedTriggerId',
value: 'jira_worklog_created',
diff --git a/apps/sim/triggers/linear/comment_created.ts b/apps/sim/triggers/linear/comment_created.ts
index 532d6956e8..893061cc5e 100644
--- a/apps/sim/triggers/linear/comment_created.ts
+++ b/apps/sim/triggers/linear/comment_created.ts
@@ -40,24 +40,24 @@ export const linearCommentCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Comment (create)'),
mode: 'trigger',
+ triggerId: 'linear_comment_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_comment_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Comment (create)'),
mode: 'trigger',
- triggerId: 'linear_comment_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_comment_created',
diff --git a/apps/sim/triggers/linear/comment_updated.ts b/apps/sim/triggers/linear/comment_updated.ts
index 941ac5e2dc..d837d71494 100644
--- a/apps/sim/triggers/linear/comment_updated.ts
+++ b/apps/sim/triggers/linear/comment_updated.ts
@@ -40,24 +40,24 @@ export const linearCommentUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Comment (update)'),
mode: 'trigger',
+ triggerId: 'linear_comment_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_comment_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Comment (update)'),
mode: 'trigger',
- triggerId: 'linear_comment_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_comment_updated',
diff --git a/apps/sim/triggers/linear/customer_request_created.ts b/apps/sim/triggers/linear/customer_request_created.ts
index 8c88ad584c..b08b16985d 100644
--- a/apps/sim/triggers/linear/customer_request_created.ts
+++ b/apps/sim/triggers/linear/customer_request_created.ts
@@ -40,24 +40,24 @@ export const linearCustomerRequestCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Customer Requests'),
mode: 'trigger',
+ triggerId: 'linear_customer_request_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_customer_request_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Customer Requests'),
mode: 'trigger',
- triggerId: 'linear_customer_request_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_customer_request_created',
diff --git a/apps/sim/triggers/linear/customer_request_updated.ts b/apps/sim/triggers/linear/customer_request_updated.ts
index a12cd455ab..e4f91cfa8f 100644
--- a/apps/sim/triggers/linear/customer_request_updated.ts
+++ b/apps/sim/triggers/linear/customer_request_updated.ts
@@ -40,24 +40,24 @@ export const linearCustomerRequestUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('CustomerNeed (update)'),
mode: 'trigger',
+ triggerId: 'linear_customer_request_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_customer_request_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('CustomerNeed (update)'),
mode: 'trigger',
- triggerId: 'linear_customer_request_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_customer_request_updated',
diff --git a/apps/sim/triggers/linear/cycle_created.ts b/apps/sim/triggers/linear/cycle_created.ts
index 21fe093d1e..dc80861ab0 100644
--- a/apps/sim/triggers/linear/cycle_created.ts
+++ b/apps/sim/triggers/linear/cycle_created.ts
@@ -40,24 +40,24 @@ export const linearCycleCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Cycle (create)'),
mode: 'trigger',
+ triggerId: 'linear_cycle_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_cycle_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Cycle (create)'),
mode: 'trigger',
- triggerId: 'linear_cycle_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_cycle_created',
diff --git a/apps/sim/triggers/linear/cycle_updated.ts b/apps/sim/triggers/linear/cycle_updated.ts
index b3e746ebf8..7922adafcd 100644
--- a/apps/sim/triggers/linear/cycle_updated.ts
+++ b/apps/sim/triggers/linear/cycle_updated.ts
@@ -40,24 +40,24 @@ export const linearCycleUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Cycle (update)'),
mode: 'trigger',
+ triggerId: 'linear_cycle_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_cycle_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Cycle (update)'),
mode: 'trigger',
- triggerId: 'linear_cycle_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_cycle_updated',
diff --git a/apps/sim/triggers/linear/issue_created.ts b/apps/sim/triggers/linear/issue_created.ts
index fae43d8a2f..e10b00663f 100644
--- a/apps/sim/triggers/linear/issue_created.ts
+++ b/apps/sim/triggers/linear/issue_created.ts
@@ -53,24 +53,24 @@ export const linearIssueCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Issue (create)'),
mode: 'trigger',
+ triggerId: 'linear_issue_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_issue_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Issue (create)'),
mode: 'trigger',
- triggerId: 'linear_issue_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_issue_created',
diff --git a/apps/sim/triggers/linear/issue_removed.ts b/apps/sim/triggers/linear/issue_removed.ts
index 5bb9739e52..8f1361acbf 100644
--- a/apps/sim/triggers/linear/issue_removed.ts
+++ b/apps/sim/triggers/linear/issue_removed.ts
@@ -40,24 +40,24 @@ export const linearIssueRemovedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Issue (remove)'),
mode: 'trigger',
+ triggerId: 'linear_issue_removed',
condition: {
field: 'selectedTriggerId',
value: 'linear_issue_removed',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Issue (remove)'),
mode: 'trigger',
- triggerId: 'linear_issue_removed',
condition: {
field: 'selectedTriggerId',
value: 'linear_issue_removed',
diff --git a/apps/sim/triggers/linear/issue_updated.ts b/apps/sim/triggers/linear/issue_updated.ts
index 4f80d90292..7546026829 100644
--- a/apps/sim/triggers/linear/issue_updated.ts
+++ b/apps/sim/triggers/linear/issue_updated.ts
@@ -40,24 +40,24 @@ export const linearIssueUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Issue (update)'),
mode: 'trigger',
+ triggerId: 'linear_issue_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_issue_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Issue (update)'),
mode: 'trigger',
- triggerId: 'linear_issue_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_issue_updated',
diff --git a/apps/sim/triggers/linear/label_created.ts b/apps/sim/triggers/linear/label_created.ts
index d35391efd2..f3e9638aeb 100644
--- a/apps/sim/triggers/linear/label_created.ts
+++ b/apps/sim/triggers/linear/label_created.ts
@@ -40,24 +40,24 @@ export const linearLabelCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('IssueLabel (create)'),
mode: 'trigger',
+ triggerId: 'linear_label_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_label_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('IssueLabel (create)'),
mode: 'trigger',
- triggerId: 'linear_label_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_label_created',
diff --git a/apps/sim/triggers/linear/label_updated.ts b/apps/sim/triggers/linear/label_updated.ts
index 8ca6620774..2f0941f72e 100644
--- a/apps/sim/triggers/linear/label_updated.ts
+++ b/apps/sim/triggers/linear/label_updated.ts
@@ -40,24 +40,24 @@ export const linearLabelUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('IssueLabel (update)'),
mode: 'trigger',
+ triggerId: 'linear_label_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_label_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('IssueLabel (update)'),
mode: 'trigger',
- triggerId: 'linear_label_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_label_updated',
diff --git a/apps/sim/triggers/linear/project_created.ts b/apps/sim/triggers/linear/project_created.ts
index 5a30e16ebe..4175b78170 100644
--- a/apps/sim/triggers/linear/project_created.ts
+++ b/apps/sim/triggers/linear/project_created.ts
@@ -40,24 +40,24 @@ export const linearProjectCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Project (create)'),
mode: 'trigger',
+ triggerId: 'linear_project_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_project_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Project (create)'),
mode: 'trigger',
- triggerId: 'linear_project_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_project_created',
diff --git a/apps/sim/triggers/linear/project_update_created.ts b/apps/sim/triggers/linear/project_update_created.ts
index aff4f44202..9d84548025 100644
--- a/apps/sim/triggers/linear/project_update_created.ts
+++ b/apps/sim/triggers/linear/project_update_created.ts
@@ -40,24 +40,24 @@ export const linearProjectUpdateCreatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('ProjectUpdate (create)'),
mode: 'trigger',
+ triggerId: 'linear_project_update_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_project_update_created',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('ProjectUpdate (create)'),
mode: 'trigger',
- triggerId: 'linear_project_update_created',
condition: {
field: 'selectedTriggerId',
value: 'linear_project_update_created',
diff --git a/apps/sim/triggers/linear/project_updated.ts b/apps/sim/triggers/linear/project_updated.ts
index 3c708593c2..1e569e6cbf 100644
--- a/apps/sim/triggers/linear/project_updated.ts
+++ b/apps/sim/triggers/linear/project_updated.ts
@@ -40,24 +40,24 @@ export const linearProjectUpdatedTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions('Project (update)'),
mode: 'trigger',
+ triggerId: 'linear_project_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_project_updated',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions('Project (update)'),
mode: 'trigger',
- triggerId: 'linear_project_updated',
condition: {
field: 'selectedTriggerId',
value: 'linear_project_updated',
diff --git a/apps/sim/triggers/linear/webhook.ts b/apps/sim/triggers/linear/webhook.ts
index a1158746e5..9239e4b494 100644
--- a/apps/sim/triggers/linear/webhook.ts
+++ b/apps/sim/triggers/linear/webhook.ts
@@ -40,27 +40,27 @@ export const linearWebhookTrigger: TriggerConfig = {
},
},
{
- id: 'triggerInstructions',
- title: 'Setup Instructions',
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
hideFromPreview: true,
- type: 'text',
- defaultValue: linearSetupInstructions(
- 'all events',
- 'This webhook will receive all Linear events. Use the type and action fields in the payload to filter and handle different event types.'
- ),
mode: 'trigger',
+ triggerId: 'linear_webhook',
condition: {
field: 'selectedTriggerId',
value: 'linear_webhook',
},
},
{
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
hideFromPreview: true,
+ type: 'text',
+ defaultValue: linearSetupInstructions(
+ 'all events',
+ 'This webhook will receive all Linear events. Use the type and action fields in the payload to filter and handle different event types.'
+ ),
mode: 'trigger',
- triggerId: 'linear_webhook',
condition: {
field: 'selectedTriggerId',
value: 'linear_webhook',
diff --git a/apps/sim/triggers/microsoftteams/chat_webhook.ts b/apps/sim/triggers/microsoftteams/chat_webhook.ts
index 340b2a567b..dcd155a57a 100644
--- a/apps/sim/triggers/microsoftteams/chat_webhook.ts
+++ b/apps/sim/triggers/microsoftteams/chat_webhook.ts
@@ -72,6 +72,18 @@ export const microsoftTeamsChatSubscriptionTrigger: TriggerConfig = {
value: 'microsoftteams_chat_subscription',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'microsoftteams_chat_subscription',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'microsoftteams_chat_subscription',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -93,18 +105,6 @@ export const microsoftTeamsChatSubscriptionTrigger: TriggerConfig = {
value: 'microsoftteams_chat_subscription',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'microsoftteams_chat_subscription',
- condition: {
- field: 'selectedTriggerId',
- value: 'microsoftteams_chat_subscription',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/microsoftteams/webhook.ts b/apps/sim/triggers/microsoftteams/webhook.ts
index 1777c5d307..eb0adaaacf 100644
--- a/apps/sim/triggers/microsoftteams/webhook.ts
+++ b/apps/sim/triggers/microsoftteams/webhook.ts
@@ -51,6 +51,18 @@ export const microsoftTeamsWebhookTrigger: TriggerConfig = {
value: 'microsoftteams_webhook',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'microsoftteams_webhook',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'microsoftteams_webhook',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -76,18 +88,6 @@ export const microsoftTeamsWebhookTrigger: TriggerConfig = {
value: 'microsoftteams_webhook',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'microsoftteams_webhook',
- condition: {
- field: 'selectedTriggerId',
- value: 'microsoftteams_webhook',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/outlook/poller.ts b/apps/sim/triggers/outlook/poller.ts
index 9beeba252c..e298fdb53d 100644
--- a/apps/sim/triggers/outlook/poller.ts
+++ b/apps/sim/triggers/outlook/poller.ts
@@ -93,6 +93,14 @@ export const outlookPollingTrigger: TriggerConfig = {
required: false,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'outlook_poller',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -110,14 +118,6 @@ export const outlookPollingTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'outlook_poller',
- },
],
outputs: {
diff --git a/apps/sim/triggers/rss/poller.ts b/apps/sim/triggers/rss/poller.ts
index 1b9548e4cf..8d295d4758 100644
--- a/apps/sim/triggers/rss/poller.ts
+++ b/apps/sim/triggers/rss/poller.ts
@@ -19,6 +19,14 @@ export const rssPollingTrigger: TriggerConfig = {
required: true,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'rss_poller',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -36,14 +44,6 @@ export const rssPollingTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'rss_poller',
- },
],
outputs: {
diff --git a/apps/sim/triggers/slack/webhook.ts b/apps/sim/triggers/slack/webhook.ts
index 0a6f0cf1d8..fdea1e7f62 100644
--- a/apps/sim/triggers/slack/webhook.ts
+++ b/apps/sim/triggers/slack/webhook.ts
@@ -30,6 +30,14 @@ export const slackWebhookTrigger: TriggerConfig = {
required: true,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'slack_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -51,14 +59,6 @@ export const slackWebhookTrigger: TriggerConfig = {
hideFromPreview: true,
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'slack_webhook',
- },
],
outputs: {
diff --git a/apps/sim/triggers/stripe/webhook.ts b/apps/sim/triggers/stripe/webhook.ts
index e4fabd2c6e..051d63f765 100644
--- a/apps/sim/triggers/stripe/webhook.ts
+++ b/apps/sim/triggers/stripe/webhook.ts
@@ -165,6 +165,14 @@ export const stripeWebhookTrigger: TriggerConfig = {
password: true,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'stripe_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -187,14 +195,6 @@ export const stripeWebhookTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'stripe_webhook',
- },
],
outputs: {
diff --git a/apps/sim/triggers/telegram/webhook.ts b/apps/sim/triggers/telegram/webhook.ts
index fdf53a2623..aad6174d6f 100644
--- a/apps/sim/triggers/telegram/webhook.ts
+++ b/apps/sim/triggers/telegram/webhook.ts
@@ -30,6 +30,14 @@ export const telegramWebhookTrigger: TriggerConfig = {
required: true,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'telegram_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -47,14 +55,6 @@ export const telegramWebhookTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'telegram_webhook',
- },
],
outputs: {
diff --git a/apps/sim/triggers/twilio_voice/webhook.ts b/apps/sim/triggers/twilio_voice/webhook.ts
index ef18acd5fe..d3fb1c62b2 100644
--- a/apps/sim/triggers/twilio_voice/webhook.ts
+++ b/apps/sim/triggers/twilio_voice/webhook.ts
@@ -49,6 +49,14 @@ export const twilioVoiceWebhookTrigger: TriggerConfig = {
required: false,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'twilio_voice_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -69,14 +77,6 @@ export const twilioVoiceWebhookTrigger: TriggerConfig = {
.join('\n\n'),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'twilio_voice_webhook',
- },
],
outputs: {
diff --git a/apps/sim/triggers/typeform/webhook.ts b/apps/sim/triggers/typeform/webhook.ts
index 34f1a94c04..90d5069fc8 100644
--- a/apps/sim/triggers/typeform/webhook.ts
+++ b/apps/sim/triggers/typeform/webhook.ts
@@ -61,6 +61,14 @@ export const typeformWebhookTrigger: TriggerConfig = {
defaultValue: false,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'typeform_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -71,7 +79,7 @@ export const typeformWebhookTrigger: TriggerConfig = {
'Find your Form ID in the URL when editing your form (e.g., https://admin.typeform.com/form/ABC123/create → Form ID is ABC123)',
'Fill in the form above with your Form ID and Personal Access Token',
'Optionally add a Webhook Secret for enhanced security - Sim will verify all incoming webhooks match this secret',
- 'Click "Save" below - Sim will automatically register the webhook with Typeform',
+ 'Click "Save" above - Sim will automatically register the webhook with Typeform',
'Note: Requires a Typeform PRO or PRO+ account to use webhooks',
]
.map(
@@ -81,14 +89,6 @@ export const typeformWebhookTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'typeform_webhook',
- },
],
outputs: {
diff --git a/apps/sim/triggers/webflow/collection_item_changed.ts b/apps/sim/triggers/webflow/collection_item_changed.ts
index 68657d588b..e66590f5c6 100644
--- a/apps/sim/triggers/webflow/collection_item_changed.ts
+++ b/apps/sim/triggers/webflow/collection_item_changed.ts
@@ -53,6 +53,18 @@ export const webflowCollectionItemChangedTrigger: TriggerConfig = {
value: 'webflow_collection_item_changed',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'webflow_collection_item_changed',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'webflow_collection_item_changed',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -77,18 +89,6 @@ export const webflowCollectionItemChangedTrigger: TriggerConfig = {
value: 'webflow_collection_item_changed',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'webflow_collection_item_changed',
- condition: {
- field: 'selectedTriggerId',
- value: 'webflow_collection_item_changed',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/webflow/collection_item_created.ts b/apps/sim/triggers/webflow/collection_item_created.ts
index a4eaa831a8..e0fdc7e8a0 100644
--- a/apps/sim/triggers/webflow/collection_item_created.ts
+++ b/apps/sim/triggers/webflow/collection_item_created.ts
@@ -66,6 +66,18 @@ export const webflowCollectionItemCreatedTrigger: TriggerConfig = {
value: 'webflow_collection_item_created',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'webflow_collection_item_created',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'webflow_collection_item_created',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -90,18 +102,6 @@ export const webflowCollectionItemCreatedTrigger: TriggerConfig = {
value: 'webflow_collection_item_created',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'webflow_collection_item_created',
- condition: {
- field: 'selectedTriggerId',
- value: 'webflow_collection_item_created',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/webflow/collection_item_deleted.ts b/apps/sim/triggers/webflow/collection_item_deleted.ts
index 6b50f63986..12a10f3ed9 100644
--- a/apps/sim/triggers/webflow/collection_item_deleted.ts
+++ b/apps/sim/triggers/webflow/collection_item_deleted.ts
@@ -53,6 +53,18 @@ export const webflowCollectionItemDeletedTrigger: TriggerConfig = {
value: 'webflow_collection_item_deleted',
},
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'webflow_collection_item_deleted',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'webflow_collection_item_deleted',
+ },
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -78,18 +90,6 @@ export const webflowCollectionItemDeletedTrigger: TriggerConfig = {
value: 'webflow_collection_item_deleted',
},
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'webflow_collection_item_deleted',
- condition: {
- field: 'selectedTriggerId',
- value: 'webflow_collection_item_deleted',
- },
- },
],
outputs: {
diff --git a/apps/sim/triggers/webflow/form_submission.ts b/apps/sim/triggers/webflow/form_submission.ts
index e0a0725e8c..7c27599c65 100644
--- a/apps/sim/triggers/webflow/form_submission.ts
+++ b/apps/sim/triggers/webflow/form_submission.ts
@@ -40,6 +40,14 @@ export const webflowFormSubmissionTrigger: TriggerConfig = {
required: false,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'webflow_form_submission',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -61,14 +69,6 @@ export const webflowFormSubmissionTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'webflow_form_submission',
- },
],
outputs: {
diff --git a/apps/sim/triggers/whatsapp/webhook.ts b/apps/sim/triggers/whatsapp/webhook.ts
index 49a308d2e5..46e8f0f1d3 100644
--- a/apps/sim/triggers/whatsapp/webhook.ts
+++ b/apps/sim/triggers/whatsapp/webhook.ts
@@ -31,6 +31,14 @@ export const whatsappWebhookTrigger: TriggerConfig = {
required: true,
mode: 'trigger',
},
+ {
+ id: 'triggerSave',
+ title: '',
+ type: 'trigger-save',
+ hideFromPreview: true,
+ mode: 'trigger',
+ triggerId: 'whatsapp_webhook',
+ },
{
id: 'triggerInstructions',
title: 'Setup Instructions',
@@ -53,14 +61,6 @@ export const whatsappWebhookTrigger: TriggerConfig = {
.join(''),
mode: 'trigger',
},
- {
- id: 'triggerSave',
- title: '',
- type: 'trigger-save',
- hideFromPreview: true,
- mode: 'trigger',
- triggerId: 'whatsapp_webhook',
- },
],
outputs: {