@pipedream/jira_service_desk 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actions/create-comment-on-request/create-comment-on-request.mjs +1 -1
- package/actions/create-request/create-request.mjs +3 -3
- package/actions/download-issue-attachment/download-issue-attachment.mjs +1 -1
- package/actions/find-service-desk-customers/find-service-desk-customers.mjs +102 -0
- package/actions/find-users/find-users.mjs +93 -0
- package/actions/get-current-user/get-current-user.mjs +1 -1
- package/actions/get-request/get-request.mjs +1 -1
- package/actions/get-request-status/get-request-status.mjs +1 -1
- package/actions/list-cloud-id-options/list-cloud-id-options.mjs +1 -1
- package/actions/list-issue-attachments/list-issue-attachments.mjs +1 -1
- package/actions/list-my-requests/list-my-requests.mjs +1 -1
- package/actions/list-request-transitions/list-request-transitions.mjs +1 -1
- package/actions/list-request-type-fields/list-request-type-fields.mjs +1 -1
- package/actions/list-request-types/list-request-types.mjs +1 -1
- package/actions/list-service-desks/list-service-desks.mjs +1 -1
- package/actions/list-sites/list-sites.mjs +1 -1
- package/actions/manage-request-attachment/manage-request-attachment.mjs +1 -1
- package/actions/transition-request/transition-request.mjs +1 -1
- package/actions/update-issue-fields/update-issue-fields.mjs +1 -1
- package/common/constants.mjs +15 -0
- package/jira_service_desk.app.mjs +62 -1
- package/package.json +1 -1
- package/sources/new-request-created/new-request-created.mjs +1 -1
- package/sources/request-status-updated/request-status-updated.mjs +1 -1
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "jira_service_desk-create-comment-on-request",
|
|
5
5
|
name: "Create Comment on Request",
|
|
6
6
|
description: "Create a comment on a customer request. [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-issueidorkey-comment-post)",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.5",
|
|
8
8
|
annotations: {
|
|
9
9
|
destructiveHint: false,
|
|
10
10
|
openWorldHint: true,
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
+ " Optionally attach one or more files at creation time via `attachments`; to add, replace, or delete attachments on a request that already exists, use **Manage Request Attachment** instead."
|
|
16
16
|
+ " Returns the created request including its `issueKey` and `issueId`. If `attachments` is set, the response also includes either an `attachments` array (on success) or an `attachmentError` string (if the request was created but the attachment step failed) — the request itself is never rolled back because of an attachment failure."
|
|
17
17
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-post)",
|
|
18
|
-
version: "1.1.
|
|
18
|
+
version: "1.1.1",
|
|
19
19
|
annotations: {
|
|
20
20
|
destructiveHint: false,
|
|
21
21
|
openWorldHint: true,
|
|
@@ -69,13 +69,13 @@ export default {
|
|
|
69
69
|
requestParticipants: {
|
|
70
70
|
type: "string[]",
|
|
71
71
|
label: "Request Participants",
|
|
72
|
-
description: "Atlassian account IDs to add as participants, e.g. `[\"5b10a2844c20165700ede21g\"]`. Not available to users who only have the Service Desk Customer permission, or if the feature is turned off for customers.",
|
|
72
|
+
description: "Atlassian account IDs to add as participants, e.g. `[\"5b10a2844c20165700ede21g\"]`. Run **Find Users** to turn each name or email address into an `accountId`; participants are often approvers or managers who are not customers of this desk, which is why this uses the site-wide search rather than **Find Service Desk Customers**. Not available to users who only have the Service Desk Customer permission, or if the feature is turned off for customers.",
|
|
73
73
|
optional: true,
|
|
74
74
|
},
|
|
75
75
|
raiseOnBehalfOf: {
|
|
76
76
|
type: "string",
|
|
77
77
|
label: "Raise On Behalf Of",
|
|
78
|
-
description: "Atlassian account ID of the customer to raise this request for, e.g. `5b10a2844c20165700ede21g`. Not available to users who only have the Service Desk Customer permission.",
|
|
78
|
+
description: "Atlassian account ID of the customer to raise this request for, e.g. `5b10a2844c20165700ede21g`. Run **Find Service Desk Customers** with this same Service Desk ID to turn a name or email address into an `accountId`, which also confirms the person is a customer of this desk; fall back to **Find Users** if they are not found there. A desk that restricts who may be one of its customers can reject a reporter who is not, so if creation then fails on the reporter field, retry without this field and name the requester in the description instead. Never guess an ID, and never pass a name or email address here. Not available to users who only have the Service Desk Customer permission.",
|
|
79
79
|
optional: true,
|
|
80
80
|
},
|
|
81
81
|
form: {
|
|
@@ -12,7 +12,7 @@ export default {
|
|
|
12
12
|
key: "jira_service_desk-download-issue-attachment",
|
|
13
13
|
name: "Download Issue Attachment",
|
|
14
14
|
description: "Download the binary content of a Jira Service Desk attachment to the file-stash directory, returning the saved path plus the attachment metadata (`filename`, `mimeType`, `size`). Run **List Issue Attachments** first to obtain the attachment `id`, then pass both it and the same `issueIdOrKey` here. Example: passing `issueIdOrKey` `IT-42` and `attachmentId` `10042` downloads `screenshot.png` to `/tmp/10042-screenshot.png` and returns `{ \"filedata\": [\"10042-screenshot.png\", \"/tmp/10042-screenshot.png\"], \"attachment\": { \"id\": \"10042\", \"filename\": \"screenshot.png\", \"mimeType\": \"image/png\", \"size\": 84213 } }`. [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-issueidorkey-attachment-attachmentid-get)",
|
|
15
|
-
version: "0.0.
|
|
15
|
+
version: "0.0.4",
|
|
16
16
|
type: "action",
|
|
17
17
|
ai: "optimized",
|
|
18
18
|
annotations: {
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import app from "../../jira_service_desk.app.mjs";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
key: "jira_service_desk-find-service-desk-customers",
|
|
5
|
+
name: "Find Service Desk Customers",
|
|
6
|
+
description:
|
|
7
|
+
"Finds the customers of one service desk by name or email address and returns the `accountId` of each match."
|
|
8
|
+
+ " **Pick this tool when the person is the one the ticket is being raised for on a service desk you can identify**, i.e. to fill `raiseOnBehalfOf` on **Create Request**."
|
|
9
|
+
+ " Natural-language cues: \"raise a ticket for Jean on the IT desk\", \"open a request on behalf of john@acme.com\", \"file this for my colleague Dana\", \"submit a hardware request for the new starter\"."
|
|
10
|
+
+ " Pick **Find Users** instead when the person does not have to be a customer of this desk, such as an approver, manager, or agent you are adding to `requestParticipants`, or when you cannot tell which service desk applies."
|
|
11
|
+
+ " Prefer this tool wherever both would work: it searches only this desk's customer list, so a match proves the person can actually raise a request here, and bot accounts are excluded (a site-wide search on a live site returned 17 users of which 16 were integrations)."
|
|
12
|
+
+ " Use **List Sites** for `cloudId` and **List Service Desks** for `serviceDeskId` first."
|
|
13
|
+
+ " Worked example: for \"open a laptop request for Joseph Wilson on the IT desk\", call this with Service Desk ID `1` and Query `Joseph Wilson`, read `accountId` `5b10a2844c20165700ede21g` off the single match, then call **Create Request** with Service Desk ID `1` and that `accountId` as `raiseOnBehalfOf`."
|
|
14
|
+
+ " Omit Query to list every customer of the desk, which answers \"who can raise requests on this desk?\"."
|
|
15
|
+
+ " Query is matched against `displayName` and `emailAddress`, and matches more than just the start of them. Pass a full name or a full email address to keep the result set tight."
|
|
16
|
+
+ " If nobody matches, the person may exist on the site without being a customer of this desk, retry with **Find Users**."
|
|
17
|
+
+ " Results are paginated automatically up to `maxResults`."
|
|
18
|
+
+ " Returns `{ users, truncated }`, where `truncated` is `true` when more matches remained unfetched."
|
|
19
|
+
+ " `accountId` is the only field guaranteed present: Atlassian's profile visibility rules hide `emailAddress` on users who have not made it public, so match on `displayName` and never require an email to be returned."
|
|
20
|
+
+ " An unknown or inaccessible Service Desk ID fails with a 404 rather than returning an empty list, so an empty list really does mean nobody matched."
|
|
21
|
+
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-servicedesk/#api-rest-servicedeskapi-servicedesk-servicedeskid-customer-get)",
|
|
22
|
+
version: "0.0.1",
|
|
23
|
+
type: "action",
|
|
24
|
+
ai: "optimized",
|
|
25
|
+
annotations: {
|
|
26
|
+
destructiveHint: false,
|
|
27
|
+
openWorldHint: true,
|
|
28
|
+
readOnlyHint: true,
|
|
29
|
+
},
|
|
30
|
+
props: {
|
|
31
|
+
app,
|
|
32
|
+
cloudId: {
|
|
33
|
+
propDefinition: [
|
|
34
|
+
app,
|
|
35
|
+
"cloudId",
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
serviceDeskId: {
|
|
39
|
+
propDefinition: [
|
|
40
|
+
app,
|
|
41
|
+
"serviceDeskId",
|
|
42
|
+
],
|
|
43
|
+
description: "The service desk whose customers to search, e.g. `1`. Run **List Service Desks** to map a project name or key to its ID. Use the same ID you will pass to **Create Request**, so the match is checked against the desk the ticket will actually be raised on.",
|
|
44
|
+
},
|
|
45
|
+
query: {
|
|
46
|
+
propDefinition: [
|
|
47
|
+
app,
|
|
48
|
+
"query",
|
|
49
|
+
],
|
|
50
|
+
description: "Name or email address to search for, e.g. `Joseph Wilson` or `joseph@example.com`. Matched against `displayName` and `emailAddress`. Omit to list every customer of the desk.",
|
|
51
|
+
optional: true,
|
|
52
|
+
},
|
|
53
|
+
maxResults: {
|
|
54
|
+
propDefinition: [
|
|
55
|
+
app,
|
|
56
|
+
"maxResults",
|
|
57
|
+
],
|
|
58
|
+
description: "Maximum number of customers to return across all pages (1-1000).",
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
async run({ $ }) {
|
|
62
|
+
const {
|
|
63
|
+
app,
|
|
64
|
+
cloudId,
|
|
65
|
+
serviceDeskId,
|
|
66
|
+
query,
|
|
67
|
+
maxResults,
|
|
68
|
+
} = this;
|
|
69
|
+
|
|
70
|
+
const {
|
|
71
|
+
results, hasMore,
|
|
72
|
+
} = await app.searchServiceDeskCustomers({
|
|
73
|
+
$,
|
|
74
|
+
cloudId,
|
|
75
|
+
serviceDeskId,
|
|
76
|
+
query,
|
|
77
|
+
maxResults,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Dropping the avatar URLs and `_links` the raw payload carries.
|
|
81
|
+
const users = results.map(({
|
|
82
|
+
accountId, displayName, emailAddress, active,
|
|
83
|
+
}) => ({
|
|
84
|
+
accountId,
|
|
85
|
+
displayName,
|
|
86
|
+
emailAddress,
|
|
87
|
+
active,
|
|
88
|
+
}));
|
|
89
|
+
|
|
90
|
+
$.export("$summary", `Found ${users.length} customer${users.length === 1
|
|
91
|
+
? ""
|
|
92
|
+
: "s"} on service desk ${serviceDeskId}${query
|
|
93
|
+
? ` matching "${query}"`
|
|
94
|
+
: ""}${hasMore
|
|
95
|
+
? ", truncated at Max Results; raise it to fetch more"
|
|
96
|
+
: ""}`);
|
|
97
|
+
return {
|
|
98
|
+
users,
|
|
99
|
+
truncated: hasMore,
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import app from "../../jira_service_desk.app.mjs";
|
|
2
|
+
import constants from "../../common/constants.mjs";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
key: "jira_service_desk-find-users",
|
|
6
|
+
name: "Find Users",
|
|
7
|
+
description:
|
|
8
|
+
"Finds any active user on an Atlassian site by name or email address and returns the `accountId` of each match."
|
|
9
|
+
+ " **Pick this tool when the person does not have to be a customer of one particular service desk**, i.e. to fill `requestParticipants` on **Create Request** with an approver, manager, watcher, or agent, or when the user names somebody but no service desk is known yet."
|
|
10
|
+
+ " Natural-language cues: \"add my manager Dana as a participant\", \"cc the security lead on this ticket\", \"loop in john@acme.com\", \"what is the account ID for Jean?\"."
|
|
11
|
+
+ " Pick **Find Service Desk Customers** instead when you already know the service desk and the person is the one the ticket is being raised for (`raiseOnBehalfOf`). That tool is more precise, confirms the person can actually raise a request on that desk, and excludes bots."
|
|
12
|
+
+ " Use **List Sites** first to obtain the required `cloudId`."
|
|
13
|
+
+ " Worked example: for \"open a laptop request and add Dana Lee as a participant\", call this with Query `Dana Lee`, read `accountId` `5b10a2844c20165700ede21g` off the match whose `accountType` is `atlassian`, then pass `[\"5b10a2844c20165700ede21g\"]` as `requestParticipants` on **Create Request**."
|
|
14
|
+
+ " Most users on a Jira site are bots, not people. Integrations come back as ordinary matches carrying `accountType` `app`, so read `accountType` and use only `atlassian` accounts as `raiseOnBehalfOf` or `requestParticipants`."
|
|
15
|
+
+ " Query is matched against `displayName` and `emailAddress`, and matches more than just the start of them. Pass a full name or a full email address to keep the result set tight."
|
|
16
|
+
+ " Results are paginated automatically up to `maxResults`."
|
|
17
|
+
+ " Returns `{ users, truncated }`. `truncated` is `true` when the result set may be incomplete, either because more matches remained unfetched or because collection stopped at Atlassian's 1000-match limit, which looks the same whether or not further matches exist. Once you have 1000 matches, narrow the query rather than raising `maxResults`, which cannot go higher."
|
|
18
|
+
+ " `accountId` is the only field guaranteed present: Atlassian's profile visibility rules hide `emailAddress` on users who have not made it public, so match on `displayName` and never require an email to be returned."
|
|
19
|
+
+ " An empty `users` list means either nobody matched or the connected account lacks the \"Browse users and groups\" global permission, which Atlassian reports as zero results rather than as an error."
|
|
20
|
+
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-user-search/#api-rest-api-3-user-search-get)",
|
|
21
|
+
version: "0.0.1",
|
|
22
|
+
type: "action",
|
|
23
|
+
ai: "optimized",
|
|
24
|
+
annotations: {
|
|
25
|
+
destructiveHint: false,
|
|
26
|
+
openWorldHint: true,
|
|
27
|
+
readOnlyHint: true,
|
|
28
|
+
},
|
|
29
|
+
props: {
|
|
30
|
+
app,
|
|
31
|
+
cloudId: {
|
|
32
|
+
propDefinition: [
|
|
33
|
+
app,
|
|
34
|
+
"cloudId",
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
query: {
|
|
38
|
+
propDefinition: [
|
|
39
|
+
app,
|
|
40
|
+
"query",
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
maxResults: {
|
|
44
|
+
propDefinition: [
|
|
45
|
+
app,
|
|
46
|
+
"maxResults",
|
|
47
|
+
],
|
|
48
|
+
description: "Maximum number of users to return across all pages (1-1000).",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
async run({ $ }) {
|
|
52
|
+
const {
|
|
53
|
+
app,
|
|
54
|
+
cloudId,
|
|
55
|
+
query,
|
|
56
|
+
maxResults,
|
|
57
|
+
} = this;
|
|
58
|
+
|
|
59
|
+
const {
|
|
60
|
+
results, hasMore,
|
|
61
|
+
} = await app.searchUsers({
|
|
62
|
+
$,
|
|
63
|
+
cloudId,
|
|
64
|
+
query,
|
|
65
|
+
maxResults,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Dropping the four avatar URLs per user the raw payload carries.
|
|
69
|
+
const users = results.map(({
|
|
70
|
+
accountId, displayName, emailAddress, active, accountType,
|
|
71
|
+
}) => ({
|
|
72
|
+
accountId,
|
|
73
|
+
displayName,
|
|
74
|
+
emailAddress,
|
|
75
|
+
active,
|
|
76
|
+
accountType,
|
|
77
|
+
}));
|
|
78
|
+
|
|
79
|
+
// At the offset ceiling raising Max Results cannot help, so say so instead.
|
|
80
|
+
const atSiteLimit = users.length >= constants.USER_SEARCH_MAX_OFFSET;
|
|
81
|
+
$.export("$summary", `Found ${users.length} user${users.length === 1
|
|
82
|
+
? ""
|
|
83
|
+
: "s"} on the site matching "${query}"${hasMore
|
|
84
|
+
? atSiteLimit
|
|
85
|
+
? ", stopped at Atlassian's 1000-match limit; narrow the query to check for more"
|
|
86
|
+
: ", truncated at Max Results; raise it to fetch more"
|
|
87
|
+
: ""}`);
|
|
88
|
+
return {
|
|
89
|
+
users,
|
|
90
|
+
truncated: hasMore,
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
};
|
|
@@ -8,7 +8,7 @@ export default {
|
|
|
8
8
|
+ " Use this to identify who is logged in, or to filter requests by the current user's `account_id`."
|
|
9
9
|
+ " No `cloudId` required — this uses the Atlassian Identity API directly."
|
|
10
10
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/)",
|
|
11
|
-
version: "0.0.
|
|
11
|
+
version: "0.0.8",
|
|
12
12
|
type: "action",
|
|
13
13
|
ai: "optimized",
|
|
14
14
|
annotations: {
|
|
@@ -10,7 +10,7 @@ export default {
|
|
|
10
10
|
+ " Use **List Sites** first to obtain the required `cloudId`."
|
|
11
11
|
+ " Use **List My Requests** to find the `issueKey` of a request (e.g. `IT-42`)."
|
|
12
12
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-issueidorkey-get)",
|
|
13
|
-
version: "0.2.
|
|
13
|
+
version: "0.2.5",
|
|
14
14
|
type: "action",
|
|
15
15
|
ai: "optimized",
|
|
16
16
|
annotations: {
|
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
+ " Use **List Sites** first to obtain the required `cloudId`."
|
|
12
12
|
+ " Use **List My Requests** to find the `issueKey` (e.g. `IT-42`)."
|
|
13
13
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-issueidorkey-status-get)",
|
|
14
|
-
version: "1.1.
|
|
14
|
+
version: "1.1.5",
|
|
15
15
|
type: "action",
|
|
16
16
|
ai: "optimized",
|
|
17
17
|
annotations: {
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "jira_service_desk-list-cloud-id-options",
|
|
5
5
|
name: "List Cloud ID Options",
|
|
6
6
|
description: "Lists the Atlassian sites you can raise requests on, as `{label, value}` options, to discover the `cloudId` every other Jira Service Desk tool needs. Takes no input beyond the account. Example: returns `[{ \"label\": \"acme\", \"value\": \"822faf0d-5427-420e-9016-999d3dc76918\" }]`. Use **List Sites** instead if you want the full site records. [See the documentation](https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/#3-1-get-the-cloudid-for-your-site)",
|
|
7
|
-
version: "0.1.
|
|
7
|
+
version: "0.1.4",
|
|
8
8
|
type: "action",
|
|
9
9
|
annotations: {
|
|
10
10
|
destructiveHint: false,
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
key: "jira_service_desk-list-issue-attachments",
|
|
6
6
|
name: "List Issue Attachments",
|
|
7
7
|
description: "List metadata for every attachment on a Jira Service Desk request. `issueIdOrKey` accepts either a Jira issue key (e.g. `IT-42`) or a numeric Jira issue ID (e.g. `10001`). Results are paginated automatically up to `maxResults`. Returns `{ attachments, truncated }`, where each attachment includes `id`, `filename`, `size` (bytes), `mimeType`, and `content` (an opaque reference URL whose exact shape varies by account access level and is **not** directly fetchable through this connection's authentication), and `truncated` is `true` when more attachments remained unfetched. Use **Download Issue Attachment** with an attachment `id` and the same `issueIdOrKey` to fetch the binary content — do not call `content` directly. If this connection has customer-level access rather than agent access, only public attachments are returned; internal attachments exist but won't appear here. Returns `{ attachments: [], truncated: false }` (no error) when the request exists but has no visible attachments. Example: issue `IT-42` with one attachment returns `{ \"attachments\": [{ \"id\": \"10042\", \"filename\": \"screenshot.png\", \"size\": 84213, \"mimeType\": \"image/png\", \"content\": \"<opaque reference URL>\" }], \"truncated\": false }`. [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-issueidorkey-attachment-get)",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.4",
|
|
9
9
|
type: "action",
|
|
10
10
|
ai: "optimized",
|
|
11
11
|
annotations: {
|
|
@@ -13,7 +13,7 @@ export default {
|
|
|
13
13
|
+ " `requestStatus`: `OPEN_REQUESTS` (default), `CLOSED_REQUESTS`, or `ALL_REQUESTS`."
|
|
14
14
|
+ " `requestOwnership`: `OWNED_REQUESTS` (default) or `PARTICIPATED_REQUESTS`."
|
|
15
15
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-get)",
|
|
16
|
-
version: "1.1.
|
|
16
|
+
version: "1.1.5",
|
|
17
17
|
type: "action",
|
|
18
18
|
ai: "optimized",
|
|
19
19
|
annotations: {
|
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
+ " Use **List Sites** first to obtain the required `cloudId`."
|
|
12
12
|
+ " Use **List My Requests** or **Get Request** to find the `issueKey` (e.g. `IT-42`)."
|
|
13
13
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-issueidorkey-transition-get)",
|
|
14
|
-
version: "1.1.
|
|
14
|
+
version: "1.1.5",
|
|
15
15
|
type: "action",
|
|
16
16
|
ai: "optimized",
|
|
17
17
|
annotations: {
|
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
+ " Also returns `canRaiseOnBehalfOf` and `canAddRequestParticipants`, which tell you whether the `raiseOnBehalfOf` and `requestParticipants` arguments of **Create Request** are usable with this account."
|
|
12
12
|
+ " Hidden fields are only visible to service desk administrators."
|
|
13
13
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-servicedesk/#api-rest-servicedeskapi-servicedesk-servicedeskid-requesttype-requesttypeid-field-get)",
|
|
14
|
-
version: "0.0.
|
|
14
|
+
version: "0.0.6",
|
|
15
15
|
type: "action",
|
|
16
16
|
ai: "optimized",
|
|
17
17
|
annotations: {
|
|
@@ -14,7 +14,7 @@ export default {
|
|
|
14
14
|
+ " Types with `canCreateRequest: false` cannot be used to raise a request."
|
|
15
15
|
+ " Then call **List Request Type Fields** to see what the chosen type requires."
|
|
16
16
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-servicedesk/#api-rest-servicedeskapi-servicedesk-servicedeskid-requesttype-get)",
|
|
17
|
-
version: "0.0.
|
|
17
|
+
version: "0.0.6",
|
|
18
18
|
type: "action",
|
|
19
19
|
ai: "optimized",
|
|
20
20
|
annotations: {
|
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
+ " Returns `{ serviceDesks, truncated }`, where `truncated` is `true` when more desks remained unfetched."
|
|
12
12
|
+ " Example: a site with one desk returns `{ \"serviceDesks\": [{ \"id\": \"1\", \"projectName\": \"Support\", \"projectKey\": \"SUP\" }], \"truncated\": false }`."
|
|
13
13
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-servicedesk/#api-rest-servicedeskapi-servicedesk-get)",
|
|
14
|
-
version: "0.0.
|
|
14
|
+
version: "0.0.6",
|
|
15
15
|
type: "action",
|
|
16
16
|
ai: "optimized",
|
|
17
17
|
annotations: {
|
|
@@ -8,7 +8,7 @@ export default {
|
|
|
8
8
|
+ " **Call this tool first** to obtain the `cloudId` (returned as `id`) required by every other Jira Service Desk tool."
|
|
9
9
|
+ " Each site includes its `id` (cloudId), `name`, and `url`."
|
|
10
10
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/#3-1-get-the-cloudid-for-your-site)",
|
|
11
|
-
version: "0.0.
|
|
11
|
+
version: "0.0.8",
|
|
12
12
|
type: "action",
|
|
13
13
|
ai: "optimized",
|
|
14
14
|
annotations: {
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
+ " For `update`, if the new file attaches successfully but removing the old attachment then fails, the response includes a `deleteError` string alongside the successful attachment data — the request ends up with both files rather than losing either one, and the error is never masked as a full failure."
|
|
16
16
|
+ " By default the attachment is visible to the customer who raised the request (`public: true`); set `public` to `false` to attach an internal-only file."
|
|
17
17
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-issueidorkey-attachment-post)",
|
|
18
|
-
version: "0.0.
|
|
18
|
+
version: "0.0.2",
|
|
19
19
|
annotations: {
|
|
20
20
|
destructiveHint: true,
|
|
21
21
|
openWorldHint: true,
|
|
@@ -10,7 +10,7 @@ export default {
|
|
|
10
10
|
+ " Use **List My Requests** or **Get Request** to find the `issueKey` (e.g. `IT-42`)."
|
|
11
11
|
+ " Optionally include a comment to explain the transition."
|
|
12
12
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/api-group-request/#api-rest-servicedeskapi-request-issueidorkey-transition-post)",
|
|
13
|
-
version: "0.1.
|
|
13
|
+
version: "0.1.5",
|
|
14
14
|
type: "action",
|
|
15
15
|
ai: "optimized",
|
|
16
16
|
annotations: {
|
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
+ " `fields` is a JSON object of field name-value pairs."
|
|
12
12
|
+ " Example: `{\"summary\": \"Updated title\", \"priority\": {\"name\": \"High\"}}`."
|
|
13
13
|
+ " [See the documentation](https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/#api-rest-api-3-issue-issueidorkey-put)",
|
|
14
|
-
version: "0.1.
|
|
14
|
+
version: "0.1.5",
|
|
15
15
|
type: "action",
|
|
16
16
|
ai: "optimized",
|
|
17
17
|
annotations: {
|
package/common/constants.mjs
CHANGED
|
@@ -7,6 +7,18 @@
|
|
|
7
7
|
// https://developer.atlassian.com/cloud/jira/service-desk/rest/intro/#pagination
|
|
8
8
|
const PAGE_SIZE = 100;
|
|
9
9
|
|
|
10
|
+
// Atlassian's documented default page size for `/rest/api/3/user/search`.
|
|
11
|
+
const USER_SEARCH_PAGE_SIZE = 50;
|
|
12
|
+
|
|
13
|
+
// `/rest/api/3/user/search` serves nothing past the thousandth match, and answers
|
|
14
|
+
// an offset at or beyond it with an empty page whether or not more matches exist.
|
|
15
|
+
const USER_SEARCH_MAX_OFFSET = 1000;
|
|
16
|
+
|
|
17
|
+
// The service desk customer resource is experimental and 412s without this.
|
|
18
|
+
const EXPERIMENTAL_API_HEADER = {
|
|
19
|
+
"X-ExperimentalApi": "opt-in",
|
|
20
|
+
};
|
|
21
|
+
|
|
10
22
|
// Ceiling on how many items a single action run will collect across pages.
|
|
11
23
|
const MAX_RESULTS_DEFAULT = 100;
|
|
12
24
|
const MAX_RESULTS_MIN = 1;
|
|
@@ -27,6 +39,9 @@ const MAX_ATTACHMENT_SIZE_BYTES = 2 * 1024 * 1024 * 1024;
|
|
|
27
39
|
|
|
28
40
|
export default {
|
|
29
41
|
PAGE_SIZE,
|
|
42
|
+
USER_SEARCH_PAGE_SIZE,
|
|
43
|
+
USER_SEARCH_MAX_OFFSET,
|
|
44
|
+
EXPERIMENTAL_API_HEADER,
|
|
30
45
|
MAX_RESULTS_DEFAULT,
|
|
31
46
|
MAX_RESULTS_MIN,
|
|
32
47
|
MAX_RESULTS_MAX,
|
|
@@ -33,6 +33,11 @@ export default {
|
|
|
33
33
|
label: "Issue ID or Key",
|
|
34
34
|
description: "The ID or key of the Jira Service Desk request (e.g. `IT-42` or `10001`). Use **List My Requests** to find the `issueKey` of a request (in its `requests` array).",
|
|
35
35
|
},
|
|
36
|
+
query: {
|
|
37
|
+
type: "string",
|
|
38
|
+
label: "Query",
|
|
39
|
+
description: "Name or email address to search for, e.g. `Joseph Wilson` or `joseph@example.com`. Matched against `displayName` and `emailAddress`. A full name or full email address gives the tightest result set.",
|
|
40
|
+
},
|
|
36
41
|
maxResults: {
|
|
37
42
|
type: "integer",
|
|
38
43
|
label: "Max Results",
|
|
@@ -73,7 +78,7 @@ export default {
|
|
|
73
78
|
* items and whether the API still had more to give when collection stopped.
|
|
74
79
|
*/
|
|
75
80
|
async _paginate({
|
|
76
|
-
$, path, params, maxResults = constants.MAX_RESULTS_DEFAULT,
|
|
81
|
+
$, path, params, headers, maxResults = constants.MAX_RESULTS_DEFAULT,
|
|
77
82
|
}) {
|
|
78
83
|
const results = [];
|
|
79
84
|
let start = 0;
|
|
@@ -83,6 +88,7 @@ export default {
|
|
|
83
88
|
const response = await this._makeRequest({
|
|
84
89
|
$,
|
|
85
90
|
path,
|
|
91
|
+
headers,
|
|
86
92
|
params: {
|
|
87
93
|
...params,
|
|
88
94
|
start,
|
|
@@ -173,6 +179,61 @@ export default {
|
|
|
173
179
|
path: `/ex/jira/${cloudId}/rest/servicedeskapi/request/${requestId}/comment`,
|
|
174
180
|
});
|
|
175
181
|
},
|
|
182
|
+
// Site-wide user search. Returns a bare array, not the `values`/`isLastPage`
|
|
183
|
+
// envelope `_paginate` expects, so it pages by offset here instead.
|
|
184
|
+
async searchUsers({
|
|
185
|
+
$, cloudId, query, maxResults = constants.MAX_RESULTS_DEFAULT,
|
|
186
|
+
}) {
|
|
187
|
+
const results = [];
|
|
188
|
+
let startAt = 0;
|
|
189
|
+
// One row past the cap separates "cap equals match count" from "more exist".
|
|
190
|
+
const ceiling = maxResults + 1;
|
|
191
|
+
|
|
192
|
+
while (results.length < ceiling) {
|
|
193
|
+
const limit = Math.min(
|
|
194
|
+
ceiling - results.length,
|
|
195
|
+
constants.USER_SEARCH_PAGE_SIZE,
|
|
196
|
+
);
|
|
197
|
+
const users = await this._makeRequest({
|
|
198
|
+
$,
|
|
199
|
+
path: `/ex/jira/${cloudId}/rest/api/3/user/search`,
|
|
200
|
+
params: {
|
|
201
|
+
query,
|
|
202
|
+
startAt,
|
|
203
|
+
maxResults: limit,
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Only an empty page ends it: a short page may just be a clamped page.
|
|
208
|
+
if (!users?.length) {
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
results.push(...users);
|
|
213
|
+
startAt += users.length;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
results: results.slice(0, maxResults),
|
|
218
|
+
// Reaching Atlassian's offset ceiling is indistinguishable from running out
|
|
219
|
+
// of matches, so report it as more-to-come rather than claim completeness.
|
|
220
|
+
hasMore: results.length > maxResults
|
|
221
|
+
|| startAt >= constants.USER_SEARCH_MAX_OFFSET,
|
|
222
|
+
};
|
|
223
|
+
},
|
|
224
|
+
async searchServiceDeskCustomers({
|
|
225
|
+
$, cloudId, serviceDeskId, query, maxResults,
|
|
226
|
+
}) {
|
|
227
|
+
return this._paginate({
|
|
228
|
+
$,
|
|
229
|
+
path: `/ex/jira/${cloudId}/rest/servicedeskapi/servicedesk/${serviceDeskId}/customer`,
|
|
230
|
+
params: {
|
|
231
|
+
query,
|
|
232
|
+
},
|
|
233
|
+
headers: constants.EXPERIMENTAL_API_HEADER,
|
|
234
|
+
maxResults,
|
|
235
|
+
});
|
|
236
|
+
},
|
|
176
237
|
async getCurrentUser({ $ } = {}) {
|
|
177
238
|
return this._makeRequest({
|
|
178
239
|
$,
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
name: "New Request Created",
|
|
7
7
|
description:
|
|
8
8
|
"Emit new event when a customer request is created. [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/#api-rest-servicedeskapi-request-get)",
|
|
9
|
-
version: "0.1.
|
|
9
|
+
version: "0.1.4",
|
|
10
10
|
type: "source",
|
|
11
11
|
dedupe: "unique",
|
|
12
12
|
methods: {
|
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
name: "Request Status Updated",
|
|
7
7
|
description:
|
|
8
8
|
"Emit new event when a customer request is updated. [See the documentation](https://developer.atlassian.com/cloud/jira/service-desk/rest/#api-rest-servicedeskapi-request-get)",
|
|
9
|
-
version: "0.1.
|
|
9
|
+
version: "0.1.4",
|
|
10
10
|
type: "source",
|
|
11
11
|
dedupe: "unique",
|
|
12
12
|
methods: {
|