0

Create Issue

by
Published Nov 2, 2023

Create an issue in a project. The description is plain text (converted to Atlassian Document Format, one paragraph per line); set any other field through `fields`, keyed by field ID, e.g. `{ "labels": ["bug"], "priority": { "name": "High" }, "assignee": { "accountId": "..." }, "parent": { "key": "PROJ-1" } }`.

Script jira Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 8 days ago
1
//native
2

3
async function get(auth: RT.Jira, path: string) {
4
  const response = await fetch(`https://${auth.domain}.atlassian.net${path}`, {
5
    headers: {
6
      Authorization: `Basic ${btoa(`${auth.username}:${auth.password}`)}`,
7
      Accept: "application/json",
8
    },
9
  })
10
  if (!response.ok) {
11
    throw new Error(`${response.status} ${await response.text()}`)
12
  }
13
  return await response.json()
14
}
15

16
export type DynSelect_project_id = string
17

18
// Resolver: the site's projects (first 100).
19
export async function project_id(auth: RT.Jira) {
20
  const { values } = await get(
21
    auth,
22
    "/rest/api/3/project/search?maxResults=100"
23
  )
24
  return values.map((p: { id: string; key: string; name: string }) => ({
25
    value: p.id,
26
    label: `${p.name} (${p.key})`,
27
  }))
28
}
29

30
export type DynSelect_issue_type_id = string
31

32
// Resolver: the issue types available in the chosen project.
33
export async function issue_type_id(auth: RT.Jira, project_id: string) {
34
  if (!project_id) return []
35
  const types = await get(
36
    auth,
37
    `/rest/api/3/issuetype/project?projectId=${project_id}`
38
  )
39
  return types.map((t: { id: string; name: string }) => ({
40
    value: t.id,
41
    label: t.name,
42
  }))
43
}
44

45
// Wraps plain text in Atlassian Document Format, one paragraph per line.
46
function adf(text: string) {
47
  return {
48
    type: "doc",
49
    version: 1,
50
    content: text.split("\n").map((line) => ({
51
      type: "paragraph",
52
      content: line ? [{ type: "text", text: line }] : [],
53
    })),
54
  }
55
}
56

57
/**
58
 * Create Issue
59
 * Create an issue in a project. The description is plain text (converted to Atlassian Document Format, one paragraph per line); set any other field through `fields`, keyed by field ID, e.g. `{ "labels": ["bug"], "priority": { "name": "High" }, "assignee": { "accountId": "..." }, "parent": { "key": "PROJ-1" } }`.
60
 */
61
export async function main(
62
  auth: RT.Jira,
63
  project_id: DynSelect_project_id,
64
  issue_type_id: DynSelect_issue_type_id,
65
  summary: string,
66
  description: string | undefined,
67
  fields: { [key: string]: any } | undefined,
68
  update: { [key: string]: any } | undefined
69
) {
70
  const url = new URL(`https://${auth.domain}.atlassian.net/rest/api/3/issue`)
71

72
  const body: { [key: string]: any } = {
73
    fields: {
74
      ...fields,
75
      project: { id: project_id },
76
      issuetype: { id: issue_type_id },
77
      summary,
78
    },
79
  }
80
  if (description != null && description !== "") {
81
    body.fields.description = adf(description)
82
  }
83
  if (update && Object.keys(update).length) {
84
    body.update = update
85
  }
86

87
  const response = await fetch(url, {
88
    method: "POST",
89
    headers: {
90
      Authorization: `Basic ${btoa(`${auth.username}:${auth.password}`)}`,
91
      "Content-Type": "application/json",
92
      Accept: "application/json",
93
    },
94
    body: JSON.stringify(body),
95
  })
96

97
  if (!response.ok) {
98
    throw new Error(`${response.status} ${await response.text()}`)
99
  }
100

101
  return await response.json()
102
}
103

Other submissions
  • Submitted by hugo697 Typescript (fetch-only)
    Created 532 days ago
    1
    type Jira = {
    2
      username: string;
    3
      password: string;
    4
      domain: string;
    5
    };
    6
    /**
    7
     * Create issue
    8
     * Creates an issue or, where the option to create subtasks is enabled in Jira, a subtask.
    9
     */
    10
    export async function main(
    11
      auth: Jira,
    12
      updateHistory: string | undefined,
    13
      body: {
    14
        fields?: { [k: string]: unknown };
    15
        historyMetadata?: {
    16
          activityDescription?: string;
    17
          activityDescriptionKey?: string;
    18
          actor?: {
    19
            avatarUrl?: string;
    20
            displayName?: string;
    21
            displayNameKey?: string;
    22
            id?: string;
    23
            type?: string;
    24
            url?: string;
    25
            [k: string]: unknown;
    26
          };
    27
          cause?: {
    28
            avatarUrl?: string;
    29
            displayName?: string;
    30
            displayNameKey?: string;
    31
            id?: string;
    32
            type?: string;
    33
            url?: string;
    34
            [k: string]: unknown;
    35
          };
    36
          description?: string;
    37
          descriptionKey?: string;
    38
          emailDescription?: string;
    39
          emailDescriptionKey?: string;
    40
          extraData?: { [k: string]: string };
    41
          generator?: {
    42
            avatarUrl?: string;
    43
            displayName?: string;
    44
            displayNameKey?: string;
    45
            id?: string;
    46
            type?: string;
    47
            url?: string;
    48
            [k: string]: unknown;
    49
          };
    50
          type?: string;
    51
          [k: string]: unknown;
    52
        };
    53
        properties?: { key?: string; value?: { [k: string]: unknown } }[];
    54
        transition?: {
    55
          expand?: string;
    56
          fields?: {
    57
            [k: string]: {
    58
              allowedValues?: { [k: string]: unknown }[];
    59
              autoCompleteUrl?: string;
    60
              configuration?: { [k: string]: { [k: string]: unknown } };
    61
              defaultValue?: { [k: string]: unknown };
    62
              hasDefaultValue?: boolean;
    63
              key: string;
    64
              name: string;
    65
              operations: string[];
    66
              required: boolean;
    67
              schema: {
    68
                configuration?: { [k: string]: { [k: string]: unknown } };
    69
                custom?: string;
    70
                customId?: number;
    71
                items?: string;
    72
                system?: string;
    73
                type: string;
    74
              };
    75
            };
    76
          };
    77
          hasScreen?: boolean;
    78
          id?: string;
    79
          isAvailable?: boolean;
    80
          isConditional?: boolean;
    81
          isGlobal?: boolean;
    82
          isInitial?: boolean;
    83
          looped?: boolean;
    84
          name?: string;
    85
          to?: {
    86
            description?: string;
    87
            iconUrl?: string;
    88
            id?: string;
    89
            name?: string;
    90
            scope?: {
    91
              project?: {
    92
                avatarUrls?: {
    93
                  "16x16"?: string;
    94
                  "24x24"?: string;
    95
                  "32x32"?: string;
    96
                  "48x48"?: string;
    97
                };
    98
                id?: string;
    99
                key?: string;
    100
                name?: string;
    101
                projectCategory?: {
    102
                  description?: string;
    103
                  id?: string;
    104
                  name?: string;
    105
                  self?: string;
    106
                };
    107
                projectTypeKey?: "software" | "service_desk" | "business";
    108
                self?: string;
    109
                simplified?: boolean;
    110
              };
    111
              type?: "PROJECT" | "TEMPLATE";
    112
              [k: string]: unknown;
    113
            };
    114
            self?: string;
    115
            statusCategory?: {
    116
              colorName?: string;
    117
              id?: number;
    118
              key?: string;
    119
              name?: string;
    120
              self?: string;
    121
              [k: string]: unknown;
    122
            };
    123
            [k: string]: unknown;
    124
          };
    125
          [k: string]: unknown;
    126
        };
    127
        update?: {
    128
          [k: string]: {
    129
            add?: { [k: string]: unknown };
    130
            copy?: { [k: string]: unknown };
    131
            edit?: { [k: string]: unknown };
    132
            remove?: { [k: string]: unknown };
    133
            set?: { [k: string]: unknown };
    134
          }[];
    135
        };
    136
        [k: string]: unknown;
    137
      }
    138
    ) {
    139
      const url = new URL(`https://${auth.domain}.atlassian.net/rest/api/2/issue`);
    140
      for (const [k, v] of [["updateHistory", updateHistory]]) {
    141
        if (v !== undefined && v !== "") {
    142
          url.searchParams.append(k, v);
    143
        }
    144
      }
    145
      const response = await fetch(url, {
    146
        method: "POST",
    147
        headers: {
    148
          "Content-Type": "application/json",
    149
          Authorization: "Basic " + btoa(`${auth.username}:${auth.password}`),
    150
        },
    151
        body: JSON.stringify(body),
    152
      });
    153
      if (!response.ok) {
    154
        const text = await response.text();
    155
        throw new Error(`${response.status} ${text}`);
    156
      }
    157
      return await response.json();
    158
    }
    159