Skip to content

Commit f426038

Browse files
author
aadamgough
committed
updated jira
1 parent a68c47b commit f426038

File tree

8 files changed

+536
-14
lines changed

8 files changed

+536
-14
lines changed

apps/docs/content/docs/en/tools/jira.mdx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,16 @@ Write a Jira issue
9797
| `projectId` | string | Yes | Project ID for the issue |
9898
| `summary` | string | Yes | Summary for the issue |
9999
| `description` | string | No | Description for the issue |
100-
| `priority` | string | No | Priority for the issue |
101-
| `assignee` | string | No | Assignee for the issue |
100+
| `priority` | string | No | Priority ID or name for the issue \(e.g., "10000" or "High"\) |
101+
| `assignee` | string | No | Assignee account ID for the issue |
102102
| `cloudId` | string | No | Jira Cloud ID for the instance. If not provided, it will be fetched using the domain. |
103103
| `issueType` | string | Yes | Type of issue to create \(e.g., Task, Story\) |
104+
| `labels` | array | No | Labels for the issue \(array of label names\) |
105+
| `duedate` | string | No | Due date for the issue \(format: YYYY-MM-DD\) |
106+
| `reporter` | string | No | Reporter account ID for the issue |
107+
| `environment` | string | No | Environment information for the issue |
108+
| `customFieldId` | string | No | Custom field ID \(e.g., customfield_10001\) |
109+
| `customFieldValue` | string | No | Value for the custom field |
104110

105111
#### Output
106112

@@ -110,6 +116,7 @@ Write a Jira issue
110116
| `issueKey` | string | Created issue key \(e.g., PROJ-123\) |
111117
| `summary` | string | Issue summary |
112118
| `url` | string | URL to the created issue |
119+
| `assigneeId` | string | Account ID of the assigned user \(if assigned\) |
113120

114121
### `jira_bulk_read`
115122

@@ -523,6 +530,30 @@ Remove a watcher from a Jira issue
523530
| `issueKey` | string | Issue key |
524531
| `watcherAccountId` | string | Removed watcher account ID |
525532

533+
### `jira_get_users`
534+
535+
Get Jira users. If an account ID is provided, returns a single user. Otherwise, returns a list of all users.
536+
537+
#### Input
538+
539+
| Parameter | Type | Required | Description |
540+
| --------- | ---- | -------- | ----------- |
541+
| `domain` | string | Yes | Your Jira domain \(e.g., yourcompany.atlassian.net\) |
542+
| `accountId` | string | No | Optional account ID to get a specific user. If not provided, returns all users. |
543+
| `startAt` | number | No | The index of the first user to return \(for pagination, default: 0\) |
544+
| `maxResults` | number | No | Maximum number of users to return \(default: 50\) |
545+
| `cloudId` | string | No | Jira Cloud ID for the instance. If not provided, it will be fetched using the domain. |
546+
547+
#### Output
548+
549+
| Parameter | Type | Description |
550+
| --------- | ---- | ----------- |
551+
| `ts` | string | Timestamp of the operation |
552+
| `users` | json | Array of users with accountId, displayName, emailAddress, active status, and avatarUrls |
553+
| `total` | number | Total number of users returned |
554+
| `startAt` | number | Pagination start index |
555+
| `maxResults` | number | Maximum results per page |
556+
526557

527558

528559
## Notes

apps/sim/app/api/tools/jira/write/route.ts

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ export async function POST(request: Request) {
2020
cloudId: providedCloudId,
2121
issueType,
2222
parent,
23+
labels,
24+
duedate,
25+
reporter,
26+
environment,
27+
customFieldId,
28+
customFieldValue,
2329
} = await request.json()
2430

2531
if (!domain) {
@@ -94,17 +100,61 @@ export async function POST(request: Request) {
94100
}
95101

96102
if (priority !== undefined && priority !== null && priority !== '') {
97-
fields.priority = {
98-
name: priority,
103+
// Check if priority is a numeric ID or a name
104+
const isNumericId = /^\d+$/.test(priority)
105+
fields.priority = isNumericId ? { id: priority } : { name: priority }
106+
}
107+
108+
if (labels !== undefined && labels !== null && Array.isArray(labels) && labels.length > 0) {
109+
fields.labels = labels
110+
}
111+
112+
if (duedate !== undefined && duedate !== null && duedate !== '') {
113+
fields.duedate = duedate
114+
}
115+
116+
if (reporter !== undefined && reporter !== null && reporter !== '') {
117+
fields.reporter = {
118+
id: reporter,
99119
}
100120
}
101121

102-
if (assignee !== undefined && assignee !== null && assignee !== '') {
103-
fields.assignee = {
104-
id: assignee,
122+
if (environment !== undefined && environment !== null && environment !== '') {
123+
fields.environment = {
124+
type: 'doc',
125+
version: 1,
126+
content: [
127+
{
128+
type: 'paragraph',
129+
content: [
130+
{
131+
type: 'text',
132+
text: environment,
133+
},
134+
],
135+
},
136+
],
105137
}
106138
}
107139

140+
// Handle team assignment via custom field
141+
if (
142+
customFieldId !== undefined &&
143+
customFieldId !== null &&
144+
customFieldId !== '' &&
145+
customFieldValue !== undefined &&
146+
customFieldValue !== null &&
147+
customFieldValue !== ''
148+
) {
149+
// Normalize the field ID (ensure it starts with customfield_)
150+
const fieldId = customFieldId.startsWith('customfield_')
151+
? customFieldId
152+
: `customfield_${customFieldId}`
153+
154+
// Use the team UUID directly
155+
fields[fieldId] = customFieldValue
156+
}
157+
108158
const body = { fields }
109159

110160
const response = await fetch(url, {
@@ -132,16 +182,47 @@ export async function POST(request: Request) {
132182
}
133183

134184
const responseData = await response.json()
135-
logger.info('Successfully created Jira issue:', responseData.key)
185+
const issueKey = responseData.key || 'unknown'
186+
logger.info('Successfully created Jira issue:', issueKey)
187+
188+
let assigneeId: string | undefined
189+
if (assignee !== undefined && assignee !== null && assignee !== '') {
190+
const assignUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/issue/${issueKey}/assignee`
191+
logger.info('Assigning issue to:', assignee)
192+
193+
const assignResponse = await fetch(assignUrl, {
194+
method: 'PUT',
195+
headers: {
196+
Authorization: `Bearer ${accessToken}`,
197+
Accept: 'application/json',
198+
'Content-Type': 'application/json',
199+
},
200+
body: JSON.stringify({
201+
accountId: assignee,
202+
}),
203+
})
204+
205+
if (!assignResponse.ok) {
206+
const assignErrorText = await assignResponse.text()
207+
logger.warn('Failed to assign issue (issue was created successfully):', {
208+
status: assignResponse.status,
209+
error: assignErrorText,
210+
})
211+
} else {
212+
assigneeId = assignee
213+
logger.info('Successfully assigned issue to:', assignee)
214+
}
215+
}
136216

137217
return NextResponse.json({
138218
success: true,
139219
output: {
140220
ts: new Date().toISOString(),
141-
issueKey: responseData.key || 'unknown',
221+
issueKey: issueKey,
142222
summary: responseData.fields?.summary || 'Issue created',
143223
success: true,
144-
url: `https://${domain}/browse/${responseData.key}`,
224+
url: `https://${domain}/browse/${issueKey}`,
225+
...(assigneeId && { assigneeId }),
145226
},
146227
})
147228
} catch (error: any) {

0 commit comments

Comments
 (0)