When you use Rovo APIs, you must comply with the Atlassian Acceptable Use Policy, including the section titled “Artificial intelligence offerings and features.” For the protection of our customers, Atlassian performs safety screening on Agents at our sole discretion. If we identify any issues with your Agent, we may take protective actions, such as preventing the Agent from being deployed or suspending your use of Rovo APIs. Where possible we will notify you of the nature of the issue, and you must use reasonable commercial efforts to correct the issue before deploying your Agent again.
This tutorial guides you in building a Forge Rovo Agent called Jira Issue Analyst, which integrates with Atlassian Rovo to help identify trends, recognize patterns in issue queues leading to improved response times and customer satisfaction.
The source code of the app is available here. Readers are recommended to review the code as they complete this tutorial.
This agent must be used within the context of an issue page. It will not function correctly in other views, such as the board view, project settings, list view, etc. We have identified this bug and will be fixed soon.
Before starting this tutorial, you must familiarize with the following:
Enabling Rovo for your organization
Install the @forge/cli
version 10.3.0
or higher
To install:
1 2npm install --g @forge/cli@latest or npm install --g @forge/cli@^10.3.0`
Building a Rovo agent tutorial to ensure you are familiar with the basics of creating, installing and viewing Rovo apps.
Basic knowledge of JavaScript, React and the Forge platform.
Forge APIs
When you create a new app, Forge will prompt you to set a default environment. In this
tutorial we use the development
environment as our default.
Learn more about staging and production environments.
Navigate to the directory where you want to create the app. A new subdirectory with the app’s name will be created there.
Create your app by running:
1 2forge create
Enter a name for your app (up to 50 characters). For example, Jira Analyst.
Select the Rovo agent and action (EAP) category.
Select the action template.
Change to the app subdirectory to see the app files:
1 2cd Jira Analyst
1 2modules: rovo:agent: - key: analyst-agent name: Jira Analyst description: An agent that can analyze Jira issues. prompt: > You are an experienced data analyst specializing in analyzing Jira issues. You can perform the following jobs based on the user's request: a. Analyze a list of Jira issues I'll separate the instructions for each job with a '---' on a new line, followed by the job title. --- a. Analyze a list of Jira issues To do this, follow these steps: 1. Check if the project key is available in the context. If not, prompt the user to provide the project key. Also check if the user has provided labels to filter the issues by. 2. Fetch the issues using the get-issues action. If there are no issues, skip steps 3 and 4 and return a message to the user specifying the project key and label used in this run. 3. Analyze the Jira issues data according to the user's request. Structure your response as follows: i. A brief summary of the main findings ii. Show the data in tabular format wherever possible. Table should have columns 'Category', 'Count', 'Percentage of Total'. iii. Detailed explanations of identified trends or patterns iv. Any additional insights that may be relevant to the user's request v. If applicable, recommendations based on your analysis Follow these rules: - Mention the common theme between issues of certain type. - Do not mention specific issue details unless asked by the user. 4. Return the analysis to the user. conversationStarters: - Analyse Jira Issues actions: - get-issues
rovo:agent
module has the following properties:
key
: A unique identifier for the Rovo agent module, used for referencing the agent within the app.name
: The display name of the agent, indicating its primary function, in this case, "Jira Analyst."description
: A brief explanation of the agent's purpose, which is to analyze Jira issues.prompt
: A detailed instruction set guiding the agent's behavior and outlining the tasks it can perform for the user. The prompt lets the agent know its capabilities and how to perform them. You can learn here about how to write effective prompts. A good prompt has multiple parts:
conversationStarters
: Predefined phrases or prompts that users can use to initiate interactions with the agent, such as "Analyze Jira Issues."actions
: Specifies the actions the agent can perform, such as fetching issues using the get-issues action.For more information on the manifest structure and properties of the rovo:agent
module, see here.
1 2action: - key: get-issues function: getIssues description: Fetches issues from a project. inputs: label: title: Label type: string description: The label to filter the issues by. required: false actionVerb: GET function: - key: getIssues handler: index.getIssues app: runtime: name: nodejs22.x id: <your-app-id> permissions: scopes: - read:jira-work
getIssues
, which handles the action logic.For more information on actions
, see here
getIssues
, which is used to link the action to its handling logic.getIssues
function within the index.js
file.For more information on Functions, see here
read:jira-work
scope grants the app permission to read Jira work data, which is necessary to call the Search for issues using JQL (GET) API.For more information on permissions, see here
Your manifest file which includes rovo:agent
and action
modules should look like this:
1 2modules: rovo:agent: - key: analyst-agent name: Jira Analyst description: An agent that can analyze Jira issues. prompt: > You are an experienced data analyst specializing in analyzing Jira issues. You can perform the following jobs based on the user's request: a. Analyze a list of Jira issues I'll separate the instructions for each job with a '---' on a new line, followed by the job title. --- a. Analyze a list of Jira issues To do this, follow these steps: 1. Check if the project key is available in the context. If not, prompt the user to provide the project key. Also check if the user has provided labels to filter the issues by. 2. Fetch the issues using the get-issues action. If there are no issues, skip steps 3 and 4 and return a message to the user specifying the project key and label used in this run. 3. Analyze the Jira issues data according to the user's request. Structure your response as follows: i. A brief summary of the main findings ii. Show the data in tabular format wherever possible. Table should have columns 'Category', 'Count', 'Percentage of Total'. iii. Detailed explanations of identified trends or patterns iv. Any additional insights that may be relevant to the user's request v. If applicable, recommendations based on your analysis Follow these rules: - Mention the common theme between issues of certain type. - Do not mention specific issue details unless asked by the user. 4. Return the analysis to the user. conversationStarters: - Analyse Jira Issues actions: - get-issues action: - key: get-issues function: getIssues description: Fetches issues from a project. inputs: label: title: Label type: string description: The label to filter the issues by. required: false actionVerb: GET function: - key: getIssues handler: index.getIssues app: runtime: name: nodejs22.x id: ari:cloud:ecosystem::app/fbe803d8-7661-4267-bef4-0916ce416720 permissions: scopes: - read:jira-work
The index.js
file contains functions that interact with Jira's API to fetch and process issue data. When the get-issues
action is invoked, it triggers the getIssues
function, as defined in the manifest. This function retrieves and processes Jira issue data based on user input and context.
Replace the index.jsx with the following code:
1 2import api, { route } from '@forge/api'; // Fetch issues from jira in a specific project export const getIssues = async (payload, requestContext) => { console.log(`Payload: ${JSON.stringify(payload)}`); console.log(`Request Context: ${JSON.stringify(requestContext)}`); const projectKey = payload.context.jira.projectKey; const label = payload.label ? payload.label : null; console.log(`Fetching issues for project: ${projectKey} and label: ${label}`); const jql = label ? `project=${projectKey} AND labels=${label}` : `project=${projectKey}`; const response = await api.asApp().requestJira(route`/rest/api/3/search?jql=${jql}`); const data = await response.json(); const cleanData = await extractIssueDetails(data); return cleanData; } // Extract issue details from the response export const extractIssueDetails = async (data) => { // console.log(`Extracting issue details from response: ${JSON.stringify(data)}`); return data.issues.map(issue => ({ key: issue.key, summary: issue.fields.summary })); }
getIssues
function is triggered once the get-issues
action is invoked, as specified in the manifest.payload
containing necessary information like the project key and any user-specified labels.api.asApp().requestJira()
to execute the JQL query and fetch matching issues from Jira.extractIssueDetails
function processes the raw API response, extracting only the key
and summary
for each issue, making the data more manageable.Let's understand the purpose of different components in the code:
Import statements:
import api, { route } from '@forge/api';
: This imports the Forge API module, which allows the function to make requests to Jira's REST API.getIssues function:
payload
: Contains the context and user inputs, such as project key and label.requestContext
: Provides additional context about the request (not explicitly used in the function).projectKey
from the payload.context.jira
.label
in the user input. If none is provided, it defaults to null
.projectKey
and, if present, the label
uses the api.asApp().requestJira()
method to call the Search for issues using JQL (GET) API and then parses the response as JSON and passes the data to the extractIssueDetails
function for further processing.extractIssueDetails function:
data.issues
array to create a new array containing only the key
and summary
of each issue.To use your app, it must be installed onto an Atlassian site. The
forge deploy
command builds, compiles, and deploys your code; it'll also report any compilation errors.
The forge install
command then installs the deployed app onto an Atlassian site with the
required API access.
You must run the forge deploy
command before forge install
because an installation
links your deployed app to an Atlassian site.
Navigate to the app's top-level directory and deploy your app by running:
1 2forge deploy
Install your app by running:
1 2forge install
Select your Atlassian product using the arrow keys and press the enter key.
Enter the URL for your development site. For example, example.atlassian.net. View a list of your active sites at Atlassian administration.
Once the successful installation message appears, your app is installed and ready
to use on the specified site.
You can always delete your app from the site by running the forge uninstall
command.
Running the forge install
command only installs your app onto the selected organization.
To install onto multiple organizations, repeat these steps again, selecting another organization each time.
You must run forge deploy
before running forge install
in any of the Forge environments.
With your app installed, it is time to chat with your new agent.
This agent must be used within the context of an issue page. It will not function correctly in other views, such as the board view, project settings, list view, etc. We have identified this bug and will be fixed soon.
Jira Analyst
agent and then select it.
Congratulations on creating your first Rovo Agent! For more inspiration on building AI agents compatible with other Atlassian products, be sure to check out the Rovo example apps.
Rate this page: