return {
- webhookEvent: body.webhookEvent,
- timestamp: body.timestamp,
- issue: body.issue || {},
- worklog: body.worklog || {},
+ webhookEvent: obj.webhookEvent,
+ timestamp: obj.timestamp,
+ user: obj.user || null,
+ version: obj.version || {},
}
}
diff --git a/apps/sim/triggers/jira/version_released.ts b/apps/sim/triggers/jira/version_released.ts
new file mode 100644
index 00000000000..8085bb8e2ff
--- /dev/null
+++ b/apps/sim/triggers/jira/version_released.ts
@@ -0,0 +1,70 @@
+import { JiraIcon } from '@/components/icons'
+import { buildVersionReleasedOutputs, jiraSetupInstructions } from '@/triggers/jira/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+/**
+ * Jira Version Released Trigger
+ * Triggers when a version/release is released
+ */
+export const jiraVersionReleasedTrigger: TriggerConfig = {
+ id: 'jira_version_released',
+ name: 'Jira Version Released',
+ provider: 'jira',
+ description: 'Trigger workflow when a version is released in Jira',
+ version: '1.0.0',
+ icon: JiraIcon,
+
+ subBlocks: [
+ {
+ id: 'webhookUrlDisplay',
+ title: 'Webhook URL',
+ type: 'short-input',
+ readOnly: true,
+ showCopyButton: true,
+ useWebhookUrl: true,
+ placeholder: 'Webhook URL will be generated',
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_version_released',
+ },
+ },
+ {
+ id: 'webhookSecret',
+ title: 'Webhook Secret',
+ type: 'short-input',
+ placeholder: 'Enter a strong secret',
+ description: 'Optional secret to validate webhook deliveries from Jira using HMAC signature',
+ password: true,
+ required: false,
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_version_released',
+ },
+ },
+ {
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
+ hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('jira:version_released'),
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_version_released',
+ },
+ },
+ ],
+
+ outputs: buildVersionReleasedOutputs(),
+
+ webhook: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Hub-Signature': 'sha256=...',
+ 'X-Atlassian-Webhook-Identifier': 'unique-webhook-id',
+ },
+ },
+}
diff --git a/apps/sim/triggers/jira/worklog_deleted.ts b/apps/sim/triggers/jira/worklog_deleted.ts
new file mode 100644
index 00000000000..d2a1c17d14c
--- /dev/null
+++ b/apps/sim/triggers/jira/worklog_deleted.ts
@@ -0,0 +1,83 @@
+import { JiraIcon } from '@/components/icons'
+import { buildWorklogOutputs, jiraSetupInstructions } from '@/triggers/jira/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+/**
+ * Jira Worklog Deleted Trigger
+ * Triggers when a worklog entry is deleted from an issue
+ */
+export const jiraWorklogDeletedTrigger: TriggerConfig = {
+ id: 'jira_worklog_deleted',
+ name: 'Jira Worklog Deleted',
+ provider: 'jira',
+ description: 'Trigger workflow when a worklog entry is deleted from a Jira issue',
+ version: '1.0.0',
+ icon: JiraIcon,
+
+ subBlocks: [
+ {
+ id: 'webhookUrlDisplay',
+ title: 'Webhook URL',
+ type: 'short-input',
+ readOnly: true,
+ showCopyButton: true,
+ useWebhookUrl: true,
+ placeholder: 'Webhook URL will be generated',
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_worklog_deleted',
+ },
+ },
+ {
+ id: 'webhookSecret',
+ title: 'Webhook Secret',
+ type: 'short-input',
+ placeholder: 'Enter a strong secret',
+ description: 'Optional secret to validate webhook deliveries from Jira using HMAC signature',
+ password: true,
+ required: false,
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_worklog_deleted',
+ },
+ },
+ {
+ id: 'jqlFilter',
+ title: 'JQL Filter',
+ type: 'long-input',
+ placeholder: 'project = PROJ',
+ description: 'Filter which worklog deletions trigger this workflow using JQL',
+ required: false,
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_worklog_deleted',
+ },
+ },
+ {
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
+ hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('worklog_deleted'),
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_worklog_deleted',
+ },
+ },
+ ],
+
+ outputs: buildWorklogOutputs(),
+
+ webhook: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Hub-Signature': 'sha256=...',
+ 'X-Atlassian-Webhook-Identifier': 'unique-webhook-id',
+ },
+ },
+}
diff --git a/apps/sim/triggers/jira/worklog_updated.ts b/apps/sim/triggers/jira/worklog_updated.ts
new file mode 100644
index 00000000000..5a26c7f7e33
--- /dev/null
+++ b/apps/sim/triggers/jira/worklog_updated.ts
@@ -0,0 +1,83 @@
+import { JiraIcon } from '@/components/icons'
+import { buildWorklogOutputs, jiraSetupInstructions } from '@/triggers/jira/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+/**
+ * Jira Worklog Updated Trigger
+ * Triggers when a worklog entry is updated on an issue
+ */
+export const jiraWorklogUpdatedTrigger: TriggerConfig = {
+ id: 'jira_worklog_updated',
+ name: 'Jira Worklog Updated',
+ provider: 'jira',
+ description: 'Trigger workflow when a worklog entry is updated on a Jira issue',
+ version: '1.0.0',
+ icon: JiraIcon,
+
+ subBlocks: [
+ {
+ id: 'webhookUrlDisplay',
+ title: 'Webhook URL',
+ type: 'short-input',
+ readOnly: true,
+ showCopyButton: true,
+ useWebhookUrl: true,
+ placeholder: 'Webhook URL will be generated',
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_worklog_updated',
+ },
+ },
+ {
+ id: 'webhookSecret',
+ title: 'Webhook Secret',
+ type: 'short-input',
+ placeholder: 'Enter a strong secret',
+ description: 'Optional secret to validate webhook deliveries from Jira using HMAC signature',
+ password: true,
+ required: false,
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_worklog_updated',
+ },
+ },
+ {
+ id: 'jqlFilter',
+ title: 'JQL Filter',
+ type: 'long-input',
+ placeholder: 'project = PROJ',
+ description: 'Filter which worklog updates trigger this workflow using JQL',
+ required: false,
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_worklog_updated',
+ },
+ },
+ {
+ id: 'triggerInstructions',
+ title: 'Setup Instructions',
+ hideFromPreview: true,
+ type: 'text',
+ defaultValue: jiraSetupInstructions('worklog_updated'),
+ mode: 'trigger',
+ condition: {
+ field: 'selectedTriggerId',
+ value: 'jira_worklog_updated',
+ },
+ },
+ ],
+
+ outputs: buildWorklogOutputs(),
+
+ webhook: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Hub-Signature': 'sha256=...',
+ 'X-Atlassian-Webhook-Identifier': 'unique-webhook-id',
+ },
+ },
+}
diff --git a/apps/sim/triggers/jsm/index.ts b/apps/sim/triggers/jsm/index.ts
new file mode 100644
index 00000000000..c76b4d0597d
--- /dev/null
+++ b/apps/sim/triggers/jsm/index.ts
@@ -0,0 +1,10 @@
+/**
+ * Jira Service Management Triggers
+ * Export all JSM webhook triggers
+ */
+
+export { jsmRequestCommentedTrigger } from './request_commented'
+export { jsmRequestCreatedTrigger } from './request_created'
+export { jsmRequestResolvedTrigger } from './request_resolved'
+export { jsmRequestUpdatedTrigger } from './request_updated'
+export { jsmWebhookTrigger } from './webhook'
diff --git a/apps/sim/triggers/jsm/request_commented.ts b/apps/sim/triggers/jsm/request_commented.ts
new file mode 100644
index 00000000000..4487c0c7e34
--- /dev/null
+++ b/apps/sim/triggers/jsm/request_commented.ts
@@ -0,0 +1,41 @@
+import { JiraServiceManagementIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildJsmCommentOutputs,
+ buildJsmExtraFields,
+ jsmSetupInstructions,
+ jsmTriggerOptions,
+} from '@/triggers/jsm/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+/**
+ * JSM Request Commented Trigger
+ *
+ * Triggers when a comment is added to a service request (public or internal).
+ */
+export const jsmRequestCommentedTrigger: TriggerConfig = {
+ id: 'jsm_request_commented',
+ name: 'JSM Request Commented',
+ provider: 'jsm',
+ description: 'Trigger workflow when a comment is added to a Jira Service Management request',
+ version: '1.0.0',
+ icon: JiraServiceManagementIcon,
+
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'jsm_request_commented',
+ triggerOptions: jsmTriggerOptions,
+ setupInstructions: jsmSetupInstructions('comment_created'),
+ extraFields: buildJsmExtraFields('jsm_request_commented'),
+ }),
+
+ outputs: buildJsmCommentOutputs(),
+
+ webhook: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Hub-Signature': 'sha256=...',
+ 'X-Atlassian-Webhook-Identifier': 'unique-webhook-id',
+ },
+ },
+}
diff --git a/apps/sim/triggers/jsm/request_created.ts b/apps/sim/triggers/jsm/request_created.ts
new file mode 100644
index 00000000000..6a4691709f9
--- /dev/null
+++ b/apps/sim/triggers/jsm/request_created.ts
@@ -0,0 +1,43 @@
+import { JiraServiceManagementIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildJsmExtraFields,
+ buildJsmRequestOutputs,
+ jsmSetupInstructions,
+ jsmTriggerOptions,
+} from '@/triggers/jsm/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+/**
+ * JSM Request Created Trigger
+ *
+ * Primary trigger — includes the dropdown for selecting trigger type.
+ * Triggers when a new service request is created in Jira Service Management.
+ */
+export const jsmRequestCreatedTrigger: TriggerConfig = {
+ id: 'jsm_request_created',
+ name: 'JSM Request Created',
+ provider: 'jsm',
+ description: 'Trigger workflow when a new service request is created in Jira Service Management',
+ version: '1.0.0',
+ icon: JiraServiceManagementIcon,
+
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'jsm_request_created',
+ triggerOptions: jsmTriggerOptions,
+ includeDropdown: true,
+ setupInstructions: jsmSetupInstructions('jira:issue_created'),
+ extraFields: buildJsmExtraFields('jsm_request_created'),
+ }),
+
+ outputs: buildJsmRequestOutputs(),
+
+ webhook: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Hub-Signature': 'sha256=...',
+ 'X-Atlassian-Webhook-Identifier': 'unique-webhook-id',
+ },
+ },
+}
diff --git a/apps/sim/triggers/jsm/request_resolved.ts b/apps/sim/triggers/jsm/request_resolved.ts
new file mode 100644
index 00000000000..2dd216efb64
--- /dev/null
+++ b/apps/sim/triggers/jsm/request_resolved.ts
@@ -0,0 +1,45 @@
+import { JiraServiceManagementIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildJsmExtraFields,
+ buildJsmRequestUpdatedOutputs,
+ jsmSetupInstructions,
+ jsmTriggerOptions,
+} from '@/triggers/jsm/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+/**
+ * JSM Request Resolved Trigger
+ *
+ * Triggers when a service request is resolved (status changed to Resolved, Done, or Closed).
+ * This is a specialized issue_updated event filtered by changelog status changes.
+ */
+export const jsmRequestResolvedTrigger: TriggerConfig = {
+ id: 'jsm_request_resolved',
+ name: 'JSM Request Resolved',
+ provider: 'jsm',
+ description: 'Trigger workflow when a service request is resolved in Jira Service Management',
+ version: '1.0.0',
+ icon: JiraServiceManagementIcon,
+
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'jsm_request_resolved',
+ triggerOptions: jsmTriggerOptions,
+ setupInstructions: jsmSetupInstructions(
+ 'jira:issue_updated',
+ 'This trigger fires when a request status changes to Resolved, Done, or Closed.'
+ ),
+ extraFields: buildJsmExtraFields('jsm_request_resolved'),
+ }),
+
+ outputs: buildJsmRequestUpdatedOutputs(),
+
+ webhook: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Hub-Signature': 'sha256=...',
+ 'X-Atlassian-Webhook-Identifier': 'unique-webhook-id',
+ },
+ },
+}
diff --git a/apps/sim/triggers/jsm/request_updated.ts b/apps/sim/triggers/jsm/request_updated.ts
new file mode 100644
index 00000000000..fe078b9d5fc
--- /dev/null
+++ b/apps/sim/triggers/jsm/request_updated.ts
@@ -0,0 +1,41 @@
+import { JiraServiceManagementIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildJsmExtraFields,
+ buildJsmRequestUpdatedOutputs,
+ jsmSetupInstructions,
+ jsmTriggerOptions,
+} from '@/triggers/jsm/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+/**
+ * JSM Request Updated Trigger
+ *
+ * Triggers when a service request is updated in Jira Service Management.
+ */
+export const jsmRequestUpdatedTrigger: TriggerConfig = {
+ id: 'jsm_request_updated',
+ name: 'JSM Request Updated',
+ provider: 'jsm',
+ description: 'Trigger workflow when a service request is updated in Jira Service Management',
+ version: '1.0.0',
+ icon: JiraServiceManagementIcon,
+
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'jsm_request_updated',
+ triggerOptions: jsmTriggerOptions,
+ setupInstructions: jsmSetupInstructions('jira:issue_updated'),
+ extraFields: buildJsmExtraFields('jsm_request_updated'),
+ }),
+
+ outputs: buildJsmRequestUpdatedOutputs(),
+
+ webhook: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Hub-Signature': 'sha256=...',
+ 'X-Atlassian-Webhook-Identifier': 'unique-webhook-id',
+ },
+ },
+}
diff --git a/apps/sim/triggers/jsm/utils.ts b/apps/sim/triggers/jsm/utils.ts
new file mode 100644
index 00000000000..984784bf9c6
--- /dev/null
+++ b/apps/sim/triggers/jsm/utils.ts
@@ -0,0 +1,412 @@
+import type { SubBlockConfig } from '@/blocks/types'
+import type { TriggerOutput } from '@/triggers/types'
+
+/**
+ * Shared trigger dropdown options for all JSM triggers
+ */
+export const jsmTriggerOptions = [
+ { label: 'Request Created', id: 'jsm_request_created' },
+ { label: 'Request Updated', id: 'jsm_request_updated' },
+ { label: 'Request Commented', id: 'jsm_request_commented' },
+ { label: 'Request Resolved', id: 'jsm_request_resolved' },
+ { label: 'Generic Webhook (All Events)', id: 'jsm_webhook' },
+]
+
+/**
+ * Generates setup instructions for JSM webhooks.
+ * JSM uses the Jira webhook infrastructure with service desk context.
+ */
+export function jsmSetupInstructions(eventType: string, additionalNotes?: string): string {
+ const instructions = [
+ 'Note: You must have admin permissions in your Jira workspace to create webhooks. JSM uses the Jira webhook system. See the Jira webhook documentation for details.',
+ 'In Jira, navigate to Settings > System > WebHooks.',
+ 'Click "Create a WebHook" to add a new webhook.',
+ 'Paste the Webhook URL from above into the URL field.',
+ 'Optionally, enter the Webhook Secret from above into the secret field for added security.',
+ `Select the events you want to trigger this workflow. For this trigger, select ${eventType}.`,
+ 'Optionally add a JQL filter to restrict webhooks to your service desk project (e.g., project = SD).',
+ 'Click "Create" to activate the webhook.',
+ ]
+
+ if (additionalNotes) {
+ instructions.push(additionalNotes)
+ }
+
+ return instructions
+ .map(
+ (instruction, index) =>
+ `${index === 0 ? instruction : `${index}. ${instruction}`}
`
+ )
+ .join('')
+}
+
+/**
+ * Webhook secret field for JSM triggers
+ */
+function jsmWebhookSecretField(triggerId: string): SubBlockConfig {
+ return {
+ id: 'webhookSecret',
+ title: 'Webhook Secret',
+ type: 'short-input',
+ placeholder: 'Enter a strong secret',
+ description: 'Optional secret to validate webhook deliveries from Jira using HMAC signature',
+ password: true,
+ required: false,
+ mode: 'trigger',
+ condition: { field: 'selectedTriggerId', value: triggerId },
+ }
+}
+
+/**
+ * Extra fields for JSM triggers (webhook secret + JQL filter)
+ */
+export function buildJsmExtraFields(triggerId: string): SubBlockConfig[] {
+ return [
+ jsmWebhookSecretField(triggerId),
+ {
+ id: 'jqlFilter',
+ title: 'JQL Filter',
+ type: 'long-input',
+ placeholder: 'project = SD AND issuetype = "Service Request"',
+ description:
+ 'Filter which service desk requests trigger this workflow using JQL (Jira Query Language)',
+ required: false,
+ mode: 'trigger',
+ condition: { field: 'selectedTriggerId', value: triggerId },
+ },
+ ]
+}
+
+/**
+ * Base webhook output fields shared across all JSM triggers
+ */
+function buildBaseWebhookOutputs(): Record {
+ return {
+ webhookEvent: {
+ type: 'string',
+ description:
+ 'The webhook event type (e.g., jira:issue_created, jira:issue_updated, comment_created)',
+ },
+ timestamp: {
+ type: 'number',
+ description: 'Timestamp of the webhook event',
+ },
+ user: {
+ displayName: {
+ type: 'string',
+ description: 'Display name of the user who triggered the event',
+ },
+ accountId: {
+ type: 'string',
+ description: 'Account ID of the user who triggered the event',
+ },
+ },
+
+ issue: {
+ id: {
+ type: 'string',
+ description: 'Jira issue ID',
+ },
+ key: {
+ type: 'string',
+ description: 'Issue key (e.g., SD-123)',
+ },
+ self: {
+ type: 'string',
+ description: 'REST API URL for this issue',
+ },
+ fields: {
+ summary: {
+ type: 'string',
+ description: 'Request summary/title',
+ },
+ status: {
+ name: {
+ type: 'string',
+ description: 'Current status name',
+ },
+ id: {
+ type: 'string',
+ description: 'Status ID',
+ },
+ statusCategory: {
+ type: 'json',
+ description: 'Status category information',
+ },
+ },
+ priority: {
+ name: {
+ type: 'string',
+ description: 'Priority name',
+ },
+ id: {
+ type: 'string',
+ description: 'Priority ID',
+ },
+ },
+ issuetype: {
+ name: {
+ type: 'string',
+ description: 'Issue type name (e.g., Service Request, Incident)',
+ },
+ id: {
+ type: 'string',
+ description: 'Issue type ID',
+ },
+ },
+ project: {
+ key: {
+ type: 'string',
+ description: 'Project key',
+ },
+ name: {
+ type: 'string',
+ description: 'Project name',
+ },
+ id: {
+ type: 'string',
+ description: 'Project ID',
+ },
+ },
+ reporter: {
+ displayName: {
+ type: 'string',
+ description: 'Reporter display name',
+ },
+ accountId: {
+ type: 'string',
+ description: 'Reporter account ID',
+ },
+ emailAddress: {
+ type: 'string',
+ description:
+ 'Email address (Jira Server only — not available in Jira Cloud webhook payloads)',
+ },
+ },
+ assignee: {
+ displayName: {
+ type: 'string',
+ description: 'Assignee display name',
+ },
+ accountId: {
+ type: 'string',
+ description: 'Assignee account ID',
+ },
+ emailAddress: {
+ type: 'string',
+ description:
+ 'Email address (Jira Server only — not available in Jira Cloud webhook payloads)',
+ },
+ },
+ creator: {
+ displayName: {
+ type: 'string',
+ description: 'Creator display name',
+ },
+ accountId: {
+ type: 'string',
+ description: 'Creator account ID',
+ },
+ emailAddress: {
+ type: 'string',
+ description:
+ 'Email address (Jira Server only — not available in Jira Cloud webhook payloads)',
+ },
+ },
+ created: {
+ type: 'string',
+ description: 'Request creation date (ISO format)',
+ },
+ updated: {
+ type: 'string',
+ description: 'Last updated date (ISO format)',
+ },
+ duedate: {
+ type: 'string',
+ description: 'Due date for the request',
+ },
+ labels: {
+ type: 'array',
+ description: 'Array of labels applied to this request',
+ },
+ resolution: {
+ name: {
+ type: 'string',
+ description: 'Resolution name (e.g., Done, Fixed)',
+ },
+ id: {
+ type: 'string',
+ description: 'Resolution ID',
+ },
+ },
+ },
+ },
+ }
+}
+
+/**
+ * Outputs for request created triggers
+ */
+export function buildJsmRequestOutputs(): Record {
+ return {
+ ...buildBaseWebhookOutputs(),
+ issue_event_type_name: {
+ type: 'string',
+ description: 'Issue event type name from Jira',
+ },
+ }
+}
+
+/**
+ * Outputs for request updated/resolved triggers (includes changelog)
+ */
+export function buildJsmRequestUpdatedOutputs(): Record {
+ return {
+ ...buildBaseWebhookOutputs(),
+ issue_event_type_name: {
+ type: 'string',
+ description: 'Issue event type name from Jira',
+ },
+ changelog: {
+ id: {
+ type: 'string',
+ description: 'Changelog ID',
+ },
+ items: {
+ type: 'array',
+ description:
+ 'Array of changed items. Each item contains field, fieldtype, from, fromString, to, toString',
+ },
+ },
+ }
+}
+
+/**
+ * Outputs for comment triggers
+ */
+export function buildJsmCommentOutputs(): Record {
+ return {
+ ...buildBaseWebhookOutputs(),
+
+ comment: {
+ id: {
+ type: 'string',
+ description: 'Comment ID',
+ },
+ body: {
+ type: 'json',
+ description:
+ 'Comment body in Atlassian Document Format (ADF). On Jira Server this may be a plain string.',
+ },
+ author: {
+ displayName: {
+ type: 'string',
+ description: 'Comment author display name',
+ },
+ accountId: {
+ type: 'string',
+ description: 'Comment author account ID',
+ },
+ emailAddress: {
+ type: 'string',
+ description: 'Comment author email address',
+ },
+ },
+ updateAuthor: {
+ displayName: {
+ type: 'string',
+ description: 'Display name of the user who last updated the comment',
+ },
+ accountId: {
+ type: 'string',
+ description: 'Account ID of the user who last updated the comment',
+ },
+ },
+ created: {
+ type: 'string',
+ description: 'Comment creation date (ISO format)',
+ },
+ updated: {
+ type: 'string',
+ description: 'Comment last updated date (ISO format)',
+ },
+ },
+ }
+}
+
+/**
+ * Checks whether a JSM webhook event matches the configured trigger.
+ *
+ * JSM events come through Jira's webhook system. The matching logic considers:
+ * - The webhook event type (jira:issue_created, jira:issue_updated, comment_created)
+ * - The issue_event_type_name for finer-grained matching
+ * - Changelog items for approval, SLA, and resolution events
+ */
+export function isJsmEventMatch(
+ triggerId: string,
+ webhookEvent: string,
+ issueEventTypeName?: string,
+ changelog?: { items?: Array<{ field?: string; toString?: string }> }
+): boolean {
+ switch (triggerId) {
+ case 'jsm_request_created':
+ return webhookEvent === 'jira:issue_created' || issueEventTypeName === 'issue_created'
+
+ case 'jsm_request_updated':
+ return (
+ webhookEvent === 'jira:issue_updated' ||
+ issueEventTypeName === 'issue_updated' ||
+ issueEventTypeName === 'issue_generic'
+ )
+
+ case 'jsm_request_commented':
+ return webhookEvent === 'comment_created'
+
+ case 'jsm_request_resolved': {
+ if (webhookEvent !== 'jira:issue_updated' && issueEventTypeName !== 'issue_updated') {
+ return false
+ }
+ const resolvedItems = changelog?.items ?? []
+ return resolvedItems.some(
+ (item) =>
+ item.field === 'status' &&
+ (item.toString?.toLowerCase() === 'resolved' ||
+ item.toString?.toLowerCase() === 'done' ||
+ item.toString?.toLowerCase() === 'closed')
+ )
+ }
+
+ case 'jsm_webhook':
+ return true
+
+ default:
+ return false
+ }
+}
+
+/**
+ * Extracts request data from a JSM webhook payload
+ */
+export function extractRequestData(body: Record) {
+ return {
+ webhookEvent: body.webhookEvent,
+ timestamp: body.timestamp,
+ user: body.user || null,
+ issue_event_type_name: body.issue_event_type_name,
+ issue: body.issue || {},
+ changelog: body.changelog,
+ }
+}
+
+/**
+ * Extracts comment data from a JSM webhook payload
+ */
+export function extractCommentData(body: Record) {
+ return {
+ webhookEvent: body.webhookEvent,
+ timestamp: body.timestamp,
+ user: body.user || null,
+ issue: body.issue || {},
+ comment: body.comment || {},
+ }
+}
diff --git a/apps/sim/triggers/jsm/webhook.ts b/apps/sim/triggers/jsm/webhook.ts
new file mode 100644
index 00000000000..3ef23743178
--- /dev/null
+++ b/apps/sim/triggers/jsm/webhook.ts
@@ -0,0 +1,87 @@
+import { JiraServiceManagementIcon } from '@/components/icons'
+import { buildTriggerSubBlocks } from '@/triggers'
+import {
+ buildJsmExtraFields,
+ buildJsmRequestOutputs,
+ jsmSetupInstructions,
+ jsmTriggerOptions,
+} from '@/triggers/jsm/utils'
+import type { TriggerConfig } from '@/triggers/types'
+
+/**
+ * Generic JSM Webhook Trigger
+ *
+ * Captures all Jira Service Management webhook events.
+ */
+export const jsmWebhookTrigger: TriggerConfig = {
+ id: 'jsm_webhook',
+ name: 'JSM Webhook (All Events)',
+ provider: 'jsm',
+ description: 'Trigger workflow on any Jira Service Management webhook event',
+ version: '1.0.0',
+ icon: JiraServiceManagementIcon,
+
+ subBlocks: buildTriggerSubBlocks({
+ triggerId: 'jsm_webhook',
+ triggerOptions: jsmTriggerOptions,
+ setupInstructions: jsmSetupInstructions('All Events'),
+ extraFields: buildJsmExtraFields('jsm_webhook'),
+ }),
+
+ outputs: {
+ ...buildJsmRequestOutputs(),
+ changelog: {
+ id: {
+ type: 'string',
+ description: 'Changelog ID',
+ },
+ items: {
+ type: 'array',
+ description:
+ 'Array of changed items. Each item contains field, fieldtype, from, fromString, to, toString',
+ },
+ },
+ comment: {
+ id: {
+ type: 'string',
+ description: 'Comment ID',
+ },
+ body: {
+ type: 'json',
+ description:
+ 'Comment body in Atlassian Document Format (ADF). On Jira Server this may be a plain string.',
+ },
+ author: {
+ displayName: {
+ type: 'string',
+ description: 'Comment author display name',
+ },
+ accountId: {
+ type: 'string',
+ description: 'Comment author account ID',
+ },
+ emailAddress: {
+ type: 'string',
+ description: 'Comment author email address',
+ },
+ },
+ created: {
+ type: 'string',
+ description: 'Comment creation date (ISO format)',
+ },
+ updated: {
+ type: 'string',
+ description: 'Comment last updated date (ISO format)',
+ },
+ },
+ },
+
+ webhook: {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Hub-Signature': 'sha256=...',
+ 'X-Atlassian-Webhook-Identifier': 'unique-webhook-id',
+ },
+ },
+}
diff --git a/apps/sim/triggers/registry.ts b/apps/sim/triggers/registry.ts
index c1895086494..adc44a9e649 100644
--- a/apps/sim/triggers/registry.ts
+++ b/apps/sim/triggers/registry.ts
@@ -56,19 +56,26 @@ import {
import {
confluenceAttachmentCreatedTrigger,
confluenceAttachmentRemovedTrigger,
+ confluenceAttachmentUpdatedTrigger,
confluenceBlogCreatedTrigger,
confluenceBlogRemovedTrigger,
+ confluenceBlogRestoredTrigger,
confluenceBlogUpdatedTrigger,
confluenceCommentCreatedTrigger,
confluenceCommentRemovedTrigger,
+ confluenceCommentUpdatedTrigger,
confluenceLabelAddedTrigger,
confluenceLabelRemovedTrigger,
confluencePageCreatedTrigger,
confluencePageMovedTrigger,
+ confluencePagePermissionsUpdatedTrigger,
confluencePageRemovedTrigger,
+ confluencePageRestoredTrigger,
confluencePageUpdatedTrigger,
confluenceSpaceCreatedTrigger,
+ confluenceSpaceRemovedTrigger,
confluenceSpaceUpdatedTrigger,
+ confluenceUserCreatedTrigger,
confluenceWebhookTrigger,
} from '@/triggers/confluence'
import { fathomNewMeetingTrigger, fathomWebhookTrigger } from '@/triggers/fathom'
@@ -153,13 +160,29 @@ import {
intercomWebhookTrigger,
} from '@/triggers/intercom'
import {
+ jiraCommentDeletedTrigger,
+ jiraCommentUpdatedTrigger,
jiraIssueCommentedTrigger,
jiraIssueCreatedTrigger,
jiraIssueDeletedTrigger,
jiraIssueUpdatedTrigger,
+ jiraProjectCreatedTrigger,
+ jiraSprintClosedTrigger,
+ jiraSprintCreatedTrigger,
+ jiraSprintStartedTrigger,
+ jiraVersionReleasedTrigger,
jiraWebhookTrigger,
jiraWorklogCreatedTrigger,
+ jiraWorklogDeletedTrigger,
+ jiraWorklogUpdatedTrigger,
} from '@/triggers/jira'
+import {
+ jsmRequestCommentedTrigger,
+ jsmRequestCreatedTrigger,
+ jsmRequestResolvedTrigger,
+ jsmRequestUpdatedTrigger,
+ jsmWebhookTrigger,
+} from '@/triggers/jsm'
import {
lemlistEmailBouncedTrigger,
lemlistEmailClickedTrigger,
@@ -337,6 +360,13 @@ export const TRIGGER_REGISTRY: TriggerRegistry = {
confluence_space_updated: confluenceSpaceUpdatedTrigger,
confluence_label_added: confluenceLabelAddedTrigger,
confluence_label_removed: confluenceLabelRemovedTrigger,
+ confluence_comment_updated: confluenceCommentUpdatedTrigger,
+ confluence_attachment_updated: confluenceAttachmentUpdatedTrigger,
+ confluence_page_restored: confluencePageRestoredTrigger,
+ confluence_blog_restored: confluenceBlogRestoredTrigger,
+ confluence_space_removed: confluenceSpaceRemovedTrigger,
+ confluence_page_permissions_updated: confluencePagePermissionsUpdatedTrigger,
+ confluence_user_created: confluenceUserCreatedTrigger,
generic_webhook: genericWebhookTrigger,
greenhouse_candidate_hired: greenhouseCandidateHiredTrigger,
greenhouse_new_application: greenhouseNewApplicationTrigger,
@@ -383,7 +413,21 @@ export const TRIGGER_REGISTRY: TriggerRegistry = {
jira_issue_updated: jiraIssueUpdatedTrigger,
jira_issue_deleted: jiraIssueDeletedTrigger,
jira_issue_commented: jiraIssueCommentedTrigger,
+ jira_comment_updated: jiraCommentUpdatedTrigger,
+ jira_comment_deleted: jiraCommentDeletedTrigger,
jira_worklog_created: jiraWorklogCreatedTrigger,
+ jira_worklog_updated: jiraWorklogUpdatedTrigger,
+ jira_worklog_deleted: jiraWorklogDeletedTrigger,
+ jira_sprint_created: jiraSprintCreatedTrigger,
+ jira_sprint_started: jiraSprintStartedTrigger,
+ jira_sprint_closed: jiraSprintClosedTrigger,
+ jira_project_created: jiraProjectCreatedTrigger,
+ jira_version_released: jiraVersionReleasedTrigger,
+ jsm_request_created: jsmRequestCreatedTrigger,
+ jsm_request_updated: jsmRequestUpdatedTrigger,
+ jsm_request_commented: jsmRequestCommentedTrigger,
+ jsm_request_resolved: jsmRequestResolvedTrigger,
+ jsm_webhook: jsmWebhookTrigger,
lemlist_webhook: lemlistWebhookTrigger,
lemlist_email_replied: lemlistEmailRepliedTrigger,
lemlist_email_opened: lemlistEmailOpenedTrigger,
diff --git a/apps/sim/triggers/types.ts b/apps/sim/triggers/types.ts
index 69e5a5d2fbd..2fb5498c92b 100644
--- a/apps/sim/triggers/types.ts
+++ b/apps/sim/triggers/types.ts
@@ -1,6 +1,6 @@
export interface TriggerOutput {
type?: string
- description?: string
+ description?: string | TriggerOutput
[key: string]: TriggerOutput | string | undefined
}