Automation Action#

Integrate custom JavaScript scripts directly into Jira Automation rules as actions.


Overview#

Automan provides a custom action for Jira Automation that allows you to execute JavaScript code as part of your automation rules. This enables you to perform complex logic, integrate with external services, and manipulate data in ways that aren’t possible with built-in automation actions.

For more information about Jira Automation, see:


Prerequisites#

Before using Automation Actions, ensure you have:

  1. Jira Administrator permissions - Required to create automation rules
  2. Automan installed - The app must be installed on your Jira instance
  3. Access to Automation - Navigate to Project Settings > Automation or global Automation settings

Adding an Automan Action to an Automation Rule#

Step 1: Create or Edit an Automation Rule#

  1. Navigate to Project Settings > Automation (or Jira Settings > System > Automation)
  2. Click Create rule or edit an existing rule
  3. Add a trigger (e.g., “Issue created”, “Field value changed”, etc.)

Step 2: Add the Automan Action#

  1. Click Add action (or Add component > Then)
  2. Search for “Custom” or “Custom JS Action”
  3. Select Custom JS Action from the list

Step 3: Configure the Action#

The Automan configuration panel has two tabs:

Code Tab#

Write your JavaScript code in the code editor:

Smart Value Tab#

Configure the Smart Value that will be passed to your script:

The default smart value is {{issue}} which passes the work item key. You can customize this to pass any data available in the automation context.

Step 4: Save and Enable#

  1. Click Update to save the action configuration
  2. Name your rule and click Turn it on

Smart Values#

Smart Values are Jira Automation’s templating syntax that allows you to reference data from the automation context. The smart value you configure is evaluated by Jira and passed to your script in the event object. You can find all smart values here: https://support.atlassian.com/cloud-automation/docs/smart-values-in-jira-automation/

Common Smart Values#

Smart Value Description
{{issue}} Work item key (e.g., “PROJ-123”)
{{issue.key}} Work item key (e.g., “PROJ-123”)
{{issue.summary}} Work item summary
{{issue.description}} Work item description
{{issue.status.name}} Current status name
{{issue.assignee.displayName}} Assignee display name
{{issue.reporter.displayName}} Reporter display name
{{issue.priority.name}} Priority name
{{issue.project.key}} Project key
{{triggerUser.displayName}} User who triggered the rule
{{now}} Current timestamp

Accessing Smart Values in Your Script#

The smart value you configure is available in event.smart (or event.customInput):

// If smart value is set to "{{issue.key}}"
const issueKey = event.smart; // "PROJ-123"

For more complex data, you can use JSON smart values. Use .asJsonString to properly escape values containing quotes or special characters:

{{issue.summary.asJsonString}}           // Produces: "Hello World"
{{issue.fixVersions.first.name.asJsonString}}  // Produces: "Version 2.0"
{{issue.Decision.value.asJsonString}}    // Produces: "Yes"

Smart Value configuration:

{"key": {{issue.key.asJsonString}}, "status": {{issue.status.name.asJsonString}}}
const data = JSON.parse(event.smart);
console.log(data.key); // "PROJ-123"
console.log(data.status); // "Done"

Important: Always use .asJsonString when embedding smart values in JSON. Without it, values containing quotes or special characters will break the JSON syntax.

// ❌ Wrong - will break if summary contains quotes
{"summary": "{{issue.summary}}"}

// ✅ Correct - properly escaped
{"summary": {{issue.summary.asJsonString}}}

For more JSON functions, see Atlassian Documentation: JSON Functions.


Context Variables#

When your automation action executes, you have access to the following context through the event object:

{
  // The evaluated smart value you configured
  smart: "...", // or customInput

  // Automation context
  automationId: "abc-123-def",
}

Return Values#

Automan actions can return values that can be used by subsequent actions in the automation rule. The return value is available as a smart value in later actions.

// Your script can return a value
const result = {
  processed: true,
  count: 5,
  message: "Successfully processed"
};

// Return by making this the last expression
JSON.stringify(result);

The returned value is available in subsequent automation actions as {{triggeredAutomanScript.result}}.


Examples#

Example 1: Calculate Working Days#

Smart Value:

{"key": {{issue.key.asJsonString}}, "created": {{issue.created.asJsonString}}}

Code:

const input = JSON.parse(event.smart);
const createdDate = new Date(input.created);
const now = new Date();

// Calculate working days (excluding weekends)
let workingDays = 0;
const current = new Date(createdDate);

while (current < now) {
  const dayOfWeek = current.getDay();
  if (dayOfWeek !== 0 && dayOfWeek !== 6) {
    workingDays++;
  }
  current.setDate(current.getDate() + 1);
}

console.log(`Work item ${input.key} has been open for ${workingDays} working days`);

// Return the value for use in subsequent actions
JSON.stringify({ key: input.key, workingDays });

Smart Value:

{"key": {{issue.key.asJsonString}}, "projectKey": {{issue.project.key.asJsonString}}}

Code:

const input = JSON.parse(event.smart);
const projectKey = input.projectKey;
const issueKey = input.key;

// Search for related work items using JQL
const jql = `project = "${projectKey}" AND "Epic Link" = "${issueKey}"`;
const response = await requestJira(
  route`/rest/api/3/search/jql?jql=${encodeURIComponent(jql)}`
);
const searchResult = await response.json();

console.log(`Found ${searchResult.total} linked work items`);

// Return count for use in automation
JSON.stringify({ linkedCount: searchResult.total, linkedIssues: searchResult.issues.map(i => i.key) });

Example 3: Update Multiple Fields Based on Conditions#

Smart Value:

{
  "key": {{issue.key.asJsonString}},
  "priority": {{issue.priority.name.asJsonString}},
  "duedate": {{issue.duedate.asJsonString}},
  "components": {{issue.components.asJsonString}},
  "labels": {{issue.labels.asJsonString}}
}

Code:

const input = JSON.parse(event.smart);
const updates = {};

// Set due date if priority is High and no due date set
if (input.priority === "High" && !input.duedate) {
  const dueDate = new Date();
  dueDate.setDate(dueDate.getDate() + 3); // 3 days from now
  updates.duedate = dueDate.toISOString().split('T')[0];
}

// Set labels based on component
if (input.components && input.components.length > 0) {
  const componentNames = input.components.map(c => c.name.toLowerCase());
  if (componentNames.includes("frontend")) {
    updates.labels = [...(input.labels || []), "ui"];
  }
}

// Apply updates if any
if (Object.keys(updates).length > 0) {
  await requestJira(
    route`/rest/api/3/issue/${input.key}`,
    {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ fields: updates })
    }
  );
  console.log("Updated fields:", Object.keys(updates));
}

JSON.stringify({ updated: Object.keys(updates).length > 0, fields: Object.keys(updates) });

Example 4: Validate Work Item Data#

Smart Value:

{
  "key": {{issue.key.asJsonString}},
  "description": {{issue.description.asJsonString}},
  "components": {{issue.components.asJsonString}},
  "priority": {{issue.priority.name.asJsonString}},
  "duedate": {{issue.duedate.asJsonString}}
}

Code:

const input = JSON.parse(event.smart);
const errors = [];

// Validate required fields
if (!input.description || input.description.trim() === "") {
  errors.push("Description is required");
}

if (!input.components || input.components.length === 0) {
  errors.push("At least one component must be selected");
}

if (input.priority === "Highest" && !input.duedate) {
  errors.push("Highest priority work items must have a due date");
}

if (errors.length > 0) {
  // Add a comment with validation errors
  await requestJira(
    route`/rest/api/3/issue/${input.key}/comment`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        body: {
          type: "doc",
          version: 1,
          content: [{
            type: "paragraph",
            content: [{
              type: "text",
              text: "Validation warnings: " + errors.join(", ")
            }]
          }]
        }
      })
    }
  );
}

JSON.stringify({ valid: errors.length === 0, errors });

Best Practices#

  1. Use Smart Values wisely - Only request the data you need to reduce payload size
  2. Handle missing data - Smart values can be null or undefined; always check before using
  3. Return meaningful results - Return values that can be used by subsequent actions
  4. Log important steps - Use console.log() for debugging and audit trails
  5. Use environment variables - Store API keys and configuration securely
  6. Keep scripts focused - One action should do one thing well

Limitations#

Execution Timeout#

Automation actions have a limited execution time. For long-running operations, consider breaking the work into multiple rules or using scheduled scripts.

Smart Value Size#

Very large smart values may be truncated. For large datasets, consider fetching data within the script using the Jira API rather than passing it via smart values.

Automation Rule Limits#

Jira Automation has limits on the number of rule executions per month. Be mindful of this when creating rules that may trigger frequently.


Troubleshooting#

Script Not Executing#

  1. Check that the automation rule is enabled
  2. Verify the trigger conditions are met
  3. Review the automation audit log for errors

Smart Value Not Available#

  1. Ensure the smart value syntax is correct (use {{}} notation)
  2. Check that the data exists at the time of rule execution
  3. Test the smart value using Automation’s built-in testing