Event Triggers#

React to Jira events in real-time by executing custom JavaScript scripts.


Overview#

Event Triggers allow you to execute scripts automatically when specific events occur in Jira. Unlike workflow post functions (which only run on transitions) or automation rules (which require configuration per rule), event triggers provide a direct way to respond to Jira events with custom code.


Prerequisites#

Before configuring Event Triggers, ensure you have:

  1. Jira Administrator permissions - Required to access Automan settings
  2. Automan installed - The app must be installed on your Jira instance
  3. A Script Definition - Create a script in the Definitions tab first

Configuring Event Triggers#

Step 1: Create a Script Definition#

  1. Navigate to Apps > Automan
  2. Click New Definition to create a new script
  3. Write your JavaScript code that will handle the event
  4. Save the definition

{TODO: “Screenshot of new definition form”}

Step 2: Assign Triggers to the Definition#

  1. In the definition form, locate the Triggers field
  2. Click to open the trigger selector
  3. Select one or more event types that should execute this script
  4. Save the definition

Available Event Triggers#

Automan supports the following Jira events:

Work Item Events#

Event Trigger ID Description
Work Item Created ISSUE_CREATED Fired when a new work item is created
Work Item Updated ISSUE_UPDATED Fired when any field on a work item changes
Work Item Deleted ISSUE_DELETED Fired when a work item is deleted
Work Item Assigned ISSUE_ASSIGNED Fired when a work item’s assignee changes
Work Item Mentioned ISSUE_MENTIONED Fired when a user is mentioned in a work item

Comment Events#

Event Trigger ID Description
Comment Created COMMENT_CREATED Fired when a comment is added to a work item
Comment Updated COMMENT_UPDATE Fired when a comment is edited
Comment Deleted COMMENT_DELETED Fired when a comment is deleted
Comment Mentioned COMMENT_MENTIONED Fired when a user is mentioned in a comment

Worklog Events#

Event Trigger ID Description
Worklog Created WORKLOG_CREATED Fired when time is logged
Worklog Updated WORKLOG_UPDATED Fired when a worklog entry is modified
Worklog Deleted WORKLOG_DELETED Fired when a worklog entry is removed
Event Trigger ID Description
Work Item Link Created ISSUELINK_CREATED Fired when work items are linked
Work Item Link Deleted ISSUELINK_DELETED Fired when a work item link is removed

Version Events#

Event Trigger ID Description
Version Created VERSION_CREATED Fired when a version is created
Version Updated VERSION_UPDATED Fired when a version is modified
Version Released VERSION_RELEASED Fired when a version is released
Version Unreleased VERSION_UNRELEASED Fired when a version release is reverted
Version Archived VERSION_ARCHIVED Fired when a version is archived
Version Unarchived VERSION_UNARCHIVED Fired when a version is unarchived
Version Moved VERSION_MOVED Fired when a version’s order changes
Version Merged VERSION_MERGED Fired when versions are merged

Project Events#

Event Trigger ID Description
Project Created PROJECT_CREATED Fired when a new project is created
Project Updated PROJECT_UPDATED Fired when project settings change
Project Deleted PROJECT_DELETED Fired when a project is permanently deleted
Project Soft Deleted PROJECT_SOFTDELETED Fired when a project is moved to trash
Project Archived PROJECT_ARCHIVED Fired when a project is archived
Project Unarchived PROJECT_UNARCHIVED Fired when a project is unarchived
Project Restored PROJECT_RESTORED Fired when a project is restored from trash

Component Events#

Event Trigger ID Description
Component Created COMPONENT_CREATED Fired when a component is created
Component Updated COMPONENT_UPDATED Fired when a component is modified

Attachment Events#

Event Trigger ID Description
Attachment Created ATTACHMENT_CREATED Fired when a file is attached
Attachment Deleted ATTACHMENT_DELETED Fired when an attachment is removed

Field Events#

Event Trigger ID Description
Field Created FIELD_CREATED Fired when a custom field is created
Field Updated FIELD_UPDATED Fired when a custom field is modified
Field Trashed FIELD_TRASHED Fired when a custom field is trashed
Field Restored FIELD_RESTORED Fired when a custom field is restored
Field Deleted FIELD_DELETED Fired when a custom field is permanently deleted

Work Item Type Events#

Event Trigger ID Description
Work Item Type Created ISSUETYPE_CREATED Fired when a new work item type is created
Work Item Type Updated ISSUETYPE_UPDATED Fired when a work item type is modified

User Events#

Event Trigger ID Description
User Created USER_CREATED Fired when a user is added to the site
User Updated USER_UPDATED Fired when user details change
User Deleted USER_DELETED Fired when a user is removed

Context Variables#

The event object structure varies depending on the event type. Here are common patterns:

Work Item Events#

{
  eventType: "avi:jira:created:issue",
  atlassianId: "5a0000000000000000000001",  // User who triggered
  issue: {
    id: "10001",
    key: "PROJ-123",
    self: "https://your-site.atlassian.net/rest/api/3/issue/10001"
  },
  // Additional fields vary by event type
  changelog: {  // For update events
    items: [
      {
        field: "status",
        fromString: "To Do",
        toString: "In Progress"
      }
    ]
  }
}

Comment Events#

{
  eventType: "avi:jira:commented:issue",
  atlassianId: "5a0000000000000000000001",
  issue: {
    id: "10001",
    key: "PROJ-123"
  },
  comment: {
    id: "10050",
    author: {
      accountId: "5a0000000000000000000001",
      displayName: "John Doe"
    },
    body: {
      type: "doc",
      version: 1,
      content: [...]
    },
    created: "2024-01-15T10:30:00.000Z",
    updated: "2024-01-15T10:30:00.000Z"
  }
}

Version Events#

{
  eventType: "avi:jira:released:version",
  atlassianId: "5a0000000000000000000001",
  version: {
    id: "10000",
    name: "v1.0.0",
    description: "First release",
    projectId: "10001",
    released: true,
    releaseDate: "2024-01-15"
  }
}

Examples#

Example 1: Notify on High Priority Work Item Created#

if (event.eventType !== "avi:jira:created:issue") return;

// Get the full work item details
const response = await requestJira(
  route`/rest/api/3/issue/${event.issue.key}`
);
const issue = await response.json();

// Check if high priority
if (issue.fields.priority.name === "Highest") {
  // Add a comment alerting the team
  await requestJira(
    route`/rest/api/3/issue/${event.issue.key}/comment`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        body: {
          type: "doc",
          version: 1,
          content: [{
            type: "paragraph",
            content: [{
              type: "text",
              text: "High priority work item created - requires immediate attention!"
            }]
          }]
        }
      })
    }
  );

  console.log("Alert added to high priority work item:", event.issue.key);
}

Example 2: Auto-Assign Based on Component#

if (event.eventType !== "avi:jira:created:issue") return;

// Get work item details
const response = await requestJira(
  route`/rest/api/3/issue/${event.issue.key}`
);
const issue = await response.json();

// Map components to assignees
const componentOwners = {
  "Frontend": process.env.FRONTEND_LEAD_ID,
  "Backend": process.env.BACKEND_LEAD_ID,
  "Database": process.env.DB_LEAD_ID
};

// Find matching component owner
const components = issue.fields.components || [];
for (const comp of components) {
  const ownerId = componentOwners[comp.name];
  if (ownerId) {
    await requestJira(
      route`/rest/api/3/issue/${event.issue.key}`,
      {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          fields: {
            assignee: { accountId: ownerId }
          }
        })
      }
    );
    console.log(`Assigned ${event.issue.key} to ${comp.name} lead`);
    break;
  }
}

Example 3: Track Work Item Updates#

if (event.eventType !== "avi:jira:updated:issue") return;

const changes = event.changelog?.items || [];

// Log significant changes
for (const change of changes) {
  console.log(
    `Field "${change.field}" changed from "${change.fromString}" to "${change.toString}"`
  );
}

// Check for status changes
const statusChange = changes.find(c => c.field === "status");
if (statusChange) {
  console.log(`Work item ${event.issue.key} moved to ${statusChange.toString}`);

  // Add a comment documenting the change
  await requestJira(
    route`/rest/api/3/issue/${event.issue.key}/comment`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        body: {
          type: "doc",
          version: 1,
          content: [{
            type: "paragraph",
            content: [{
              type: "text",
              text: `Status changed: ${statusChange.fromString}${statusChange.toString}`
            }]
          }]
        }
      })
    }
  );
}

Example 4: Cascade Version Release#

if (event.eventType !== "avi:jira:released:version") return;

const versionName = event.version.name;
console.log(`Version ${versionName} released!`);

// Find all work items in this version and add a label
const jql = `fixVersion = "${versionName}"`;
const searchResponse = await requestJira(
  route`/rest/api/3/search/jql?jql=${encodeURIComponent(jql)}&maxResults=100`
);
const searchResult = await searchResponse.json();

console.log(`Found ${searchResult.total} work items in version ${versionName}`);

// Update each work item
for (const issue of searchResult.issues) {
  const currentLabels = issue.fields.labels || [];
  if (!currentLabels.includes("released")) {
    await requestJira(
      route`/rest/api/3/issue/${issue.key}`,
      {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          fields: {
            labels: [...currentLabels, "released"]
          }
        })
      }
    );
    console.log(`Added 'released' label to ${issue.key}`);
  }
}

Example 5: Monitor Comment Mentions#

if (event.eventType !== "avi:jira:commented:issue") return;

const comment = event.comment;
const content = comment.body?.content || [];

// Find all mentions in the comment
function findMentions(nodes) {
  const mentions = [];
  for (const node of nodes) {
    if (node.type === "mention") {
      mentions.push(node.attrs?.id);
    }
    if (node.content) {
      mentions.push(...findMentions(node.content));
    }
  }
  return mentions;
}

const mentionedUsers = findMentions(content);
if (mentionedUsers.length > 0) {
  console.log(`Comment on ${event.issue.key} mentioned ${mentionedUsers.length} users`);

  // You could log this, send notifications, etc.
  for (const userId of mentionedUsers) {
    console.log(`User mentioned: ${userId}`);
  }
}

Multiple Triggers#

A single script definition can be triggered by multiple events. This is useful when:

  • You want the same logic to run on related events (e.g., work item created AND updated)
  • You need to handle a family of events (e.g., all worklog events)

Troubleshooting#

Script Not Running on Events#

  1. Verify the trigger is assigned to your definition
  2. Check that the definition has saved code (not empty)
  3. Review the Executions tab for error logs

Missing Event Data#

  1. Some events provide minimal data; use the Jira API to fetch full details
  2. Check the event log for expected payload structure

Finding Execution Logs#

  1. Navigate to Apps > Automan
  2. Go to the Executions tab
  3. Filter by type “trigger” to see event trigger executions
  4. Click on an execution to view the event payload and script output

{TODO: “Screenshot of executions tab filtered by trigger type”}