0

Add Comment to Issue

by
Published Nov 2, 2023

Add a comment to an issue. Pass plain text in `comment` (converted to Atlassian Document Format, one paragraph per line) or a full ADF document in `adf_body` for mentions and rich formatting. `visibility` restricts the comment to a group or project role.

Script jira Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 4 hours ago
1
//native
2

3
// Wraps plain text in Atlassian Document Format, one paragraph per line.
4
function adf(text: string) {
5
  return {
6
    type: "doc",
7
    version: 1,
8
    content: text.split("\n").map((line) => ({
9
      type: "paragraph",
10
      content: line ? [{ type: "text", text: line }] : [],
11
    })),
12
  }
13
}
14

15
/**
16
 * Add Comment to Issue
17
 * Add a comment to an issue. Pass plain text in `comment` (converted to Atlassian Document Format, one paragraph per line) or a full ADF document in `adf_body` for mentions and rich formatting. `visibility` restricts the comment to a group or project role.
18
 */
19
export async function main(
20
  auth: RT.Jira,
21
  issue_id_or_key: string,
22
  comment: string | undefined,
23
  adf_body: { [key: string]: any } | undefined,
24
  visibility:
25
    { type: "group" | "role"; value?: string; identifier?: string } | undefined,
26
  render_body: boolean | undefined
27
) {
28
  const url = new URL(
29
    `https://${auth.domain}.atlassian.net/rest/api/3/issue/${issue_id_or_key}/comment`
30
  )
31

32
  if (render_body) {
33
    url.searchParams.append("expand", "renderedBody")
34
  }
35

36
  if (!adf_body && (comment == null || comment === "")) {
37
    throw new Error("Either comment or adf_body is required")
38
  }
39
  const body: { [key: string]: any } = { body: adf_body ?? adf(comment!) }
40
  if (visibility && Object.keys(visibility).length) {
41
    body.visibility = visibility
42
  }
43

44
  const response = await fetch(url, {
45
    method: "POST",
46
    headers: {
47
      Authorization: `Basic ${btoa(`${auth.username}:${auth.password}`)}`,
48
      "Content-Type": "application/json",
49
      Accept: "application/json",
50
    },
51
    body: JSON.stringify(body),
52
  })
53

54
  if (!response.ok) {
55
    throw new Error(`${response.status} ${await response.text()}`)
56
  }
57

58
  return await response.json()
59
}
60

Other submissions
  • Submitted by hugo697 Typescript (fetch-only)
    Created 525 days ago
    1
    type Jira = {
    2
      username: string;
    3
      password: string;
    4
      domain: string;
    5
    };
    6
    /**
    7
     * Add comment
    8
     * Adds a comment to an issue.
    9
    
    
    10
    This operation can be accessed anonymously.
    11
    
    
    12
    **[Permissions](#permissions) required:**
    13
    
    
    14
     *  *Browse projects* and *Add comments* [ project permission](https://confluence.atlassian.com/x/yodKLg) for the project that the issue containing the comment is in.
    15
     *  If [issue-level security](https://confluence.atlassian.com/x/J4lKLg) is configured, issue-level security permission to view the issue.
    16
     */
    17
    export async function main(
    18
      auth: Jira,
    19
      issueIdOrKey: string,
    20
      expand: string | undefined,
    21
      body: {
    22
        author?: {
    23
          accountId?: string;
    24
          accountType?: string;
    25
          active?: boolean;
    26
          avatarUrls?: {
    27
            "16x16"?: string;
    28
            "24x24"?: string;
    29
            "32x32"?: string;
    30
            "48x48"?: string;
    31
          };
    32
          displayName?: string;
    33
          emailAddress?: string;
    34
          key?: string;
    35
          name?: string;
    36
          self?: string;
    37
          timeZone?: string;
    38
        };
    39
        body?: string;
    40
        created?: string;
    41
        id?: string;
    42
        jsdAuthorCanSeeRequest?: boolean;
    43
        jsdPublic?: boolean;
    44
        properties?: { key?: string; value?: { [k: string]: unknown } }[];
    45
        renderedBody?: string;
    46
        self?: string;
    47
        updateAuthor?: {
    48
          accountId?: string;
    49
          accountType?: string;
    50
          active?: boolean;
    51
          avatarUrls?: {
    52
            "16x16"?: string;
    53
            "24x24"?: string;
    54
            "32x32"?: string;
    55
            "48x48"?: string;
    56
          };
    57
          displayName?: string;
    58
          emailAddress?: string;
    59
          key?: string;
    60
          name?: string;
    61
          self?: string;
    62
          timeZone?: string;
    63
        };
    64
        updated?: string;
    65
        visibility?: {
    66
          identifier?: string;
    67
          type?: "group" | "role";
    68
          value?: string;
    69
          [k: string]: unknown;
    70
        };
    71
        [k: string]: unknown;
    72
      }
    73
    ) {
    74
      const url = new URL(
    75
        `https://${auth.domain}.atlassian.net/rest/api/2/issue/${issueIdOrKey}/comment`
    76
      );
    77
      for (const [k, v] of [["expand", expand]]) {
    78
        if (v !== undefined && v !== "") {
    79
          url.searchParams.append(k, v);
    80
        }
    81
      }
    82
      const response = await fetch(url, {
    83
        method: "POST",
    84
        headers: {
    85
          "Content-Type": "application/json",
    86
          Authorization: "Basic " + btoa(`${auth.username}:${auth.password}`),
    87
        },
    88
        body: JSON.stringify(body),
    89
      });
    90
      if (!response.ok) {
    91
        const text = await response.text();
    92
        throw new Error(`${response.status} ${text}`);
    93
      }
    94
      return await response.json();
    95
    }
    96