Files
botpress--botpress/integrations/jira/src/actions/new-issues.ts
T
2026-07-13 13:34:48 +08:00

55 lines
2.5 KiB
TypeScript

import { RuntimeError } from '@botpress/sdk'
import type { Version3Models } from 'jira.js'
import { newIssuesInputSchema, newIssuesOutputSchema } from '../misc/custom-schemas'
import type { Implementation } from '../misc/types'
import { buildRuntimeError, getClient, resolveIssueTypeIds, serializeErrorForLog, textToAdfDocument } from '../utils'
type IssueInput = Version3Models.IssueUpdateDetails
export const newIssues: Implementation['actions']['newIssues'] = async ({ client, ctx, input, logger }) => {
const validatedInput = newIssuesInputSchema.parse(input)
if (validatedInput.issues.length === 0) {
throw new RuntimeError('At least one issue must be provided')
}
if (validatedInput.issues.length > 50) {
throw new RuntimeError(`Jira allows up to 50 issues per batch; received ${validatedInput.issues.length}`)
}
const jiraClient = await getClient({ client, ctx, logger })
try {
const issueTypeIds = await resolveIssueTypeIds(jiraClient, validatedInput.issues)
const issueUpdates: IssueInput[] = validatedInput.issues.map((i) => {
const issueTypeId = issueTypeIds.get(`${i.projectKey}::${i.issueType}`)!
const fields: NonNullable<IssueInput['fields']> = {
summary: i.summary,
issuetype: { id: issueTypeId },
project: { key: i.projectKey },
}
if (i.description !== undefined) fields.description = textToAdfDocument(i.description)
if (i.parentKey !== undefined) fields.parent = { key: i.parentKey }
if (i.assigneeId !== undefined) fields.assignee = { accountId: i.assigneeId }
return { fields }
})
const response = await jiraClient.newIssues({ issueUpdates })
const created = (response.issues ?? []).map((c) => ({ issueKey: c.key }))
const errors = (response.errors ?? []).map((e) => {
const fieldErrors = (e.elementErrors?.errors ?? {}) as Record<string, string>
const detail = [
...(e.elementErrors?.errorMessages ?? []),
...Object.entries(fieldErrors).map(([k, v]) => `${k}: ${v}`),
].join('; ')
return {
index: e.failedElementNumber,
message: detail.length > 0 ? detail : `HTTP ${e.status ?? 'unknown'}`,
}
})
logger.forBot().info(`Successful - New Issues - ${created.length} created, ${errors.length} failed`)
return newIssuesOutputSchema.parse({ created, errors })
} catch (error) {
logger.forBot().debug(`'New Issues' exception ${serializeErrorForLog(error)}`)
throw buildRuntimeError('Failed to create issues', error)
}
}