chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -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'
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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 = [
|
||||
'<strong>Note:</strong> You must have admin permissions in your Jira workspace to create webhooks. JSM uses the Jira webhook system. See the <a href="https://support.atlassian.com/jira-cloud-administration/docs/manage-webhooks/" target="_blank" rel="noopener noreferrer">Jira webhook documentation</a> for details.',
|
||||
'In Jira, navigate to <strong>Settings > System > WebHooks</strong>.',
|
||||
'Click <strong>"Create a WebHook"</strong> to add a new webhook.',
|
||||
'Paste the <strong>Webhook URL</strong> from above into the URL field.',
|
||||
'Optionally, enter the <strong>Webhook Secret</strong> from above into the secret field for added security.',
|
||||
`Select the events you want to trigger this workflow. For this trigger, select <strong>${eventType}</strong>.`,
|
||||
'Optionally add a JQL filter to restrict webhooks to your service desk project (e.g., <code>project = SD</code>).',
|
||||
'Click <strong>"Create"</strong> to activate the webhook.',
|
||||
]
|
||||
|
||||
if (additionalNotes) {
|
||||
instructions.push(additionalNotes)
|
||||
}
|
||||
|
||||
return instructions
|
||||
.map(
|
||||
(instruction, index) =>
|
||||
`<div class="mb-3">${index === 0 ? instruction : `<strong>${index}.</strong> ${instruction}`}</div>`
|
||||
)
|
||||
.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<string, TriggerOutput> {
|
||||
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<string, TriggerOutput> {
|
||||
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<string, TriggerOutput> {
|
||||
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<string, TriggerOutput> {
|
||||
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<string, unknown>) {
|
||||
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<string, unknown>) {
|
||||
return {
|
||||
webhookEvent: body.webhookEvent,
|
||||
timestamp: body.timestamp,
|
||||
user: body.user || null,
|
||||
issue: body.issue || {},
|
||||
comment: body.comment || {},
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user