@pipedream/zendesk 0.8.1 → 0.8.3
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/add-ticket-tags/add-ticket-tags.mjs +1 -1
- package/actions/create-ticket/create-ticket.mjs +1 -1
- package/actions/delete-ticket/delete-ticket.mjs +1 -1
- package/actions/get-ticket-info/get-ticket-info.mjs +1 -1
- package/actions/get-user-info/get-user-info.mjs +1 -1
- package/actions/list-locales/list-locales.mjs +1 -1
- package/actions/list-macros/list-macros.mjs +1 -1
- package/actions/list-ticket-comments/list-ticket-comments.mjs +1 -1
- package/actions/list-tickets/list-tickets.mjs +1 -1
- package/actions/remove-ticket-tags/remove-ticket-tags.mjs +1 -1
- package/actions/search-tickets/search-tickets.mjs +1 -1
- package/actions/set-ticket-tags/set-ticket-tags.mjs +1 -1
- package/actions/update-ticket/update-ticket.mjs +77 -8
- package/package.json +4 -3
- package/sources/locale-updated/locale-updated.mjs +1 -1
- package/sources/new-ticket/new-ticket.mjs +1 -1
- package/sources/new-ticket-comment-added/new-ticket-comment-added.mjs +1 -1
- package/sources/ticket-added-to-view/ticket-added-to-view.mjs +1 -1
- package/sources/ticket-closed/ticket-closed.mjs +1 -1
- package/sources/ticket-pended/ticket-pended.mjs +1 -1
- package/sources/ticket-solved/ticket-solved.mjs +1 -1
- package/sources/ticket-updated/ticket-updated.mjs +1 -1
- package/zendesk.app.mjs +134 -0
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
name: "Add Ticket Tags",
|
|
6
6
|
description: "Add tags to a ticket (appends to existing tags). [See the documentation](https://developer.zendesk.com/api-reference/ticketing/ticket-management/tags/#add-tags).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.4",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
ticketId: {
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
name: "Create Ticket",
|
|
6
6
|
description: "Creates a ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#create-ticket).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.1.
|
|
8
|
+
version: "0.1.8",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
ticketCommentBody: {
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
name: "Delete Ticket",
|
|
6
6
|
description: "Deletes a ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#delete-ticket).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.1.
|
|
8
|
+
version: "0.1.8",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
ticketId: {
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
name: "Get Ticket Info",
|
|
6
6
|
description: "Retrieves information about a specific ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#show-ticket).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.6",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
ticketId: {
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "zendesk-get-user-info",
|
|
5
5
|
name: "Get User Info",
|
|
6
6
|
description: "Retrieves information about a specific user. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/users/users/#show-user).",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.3",
|
|
8
8
|
type: "action",
|
|
9
9
|
props: {
|
|
10
10
|
zendesk,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "zendesk-list-locales",
|
|
5
5
|
name: "List Locales",
|
|
6
6
|
description: "Retrieves all locales. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/account-configuration/locales/).",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.3",
|
|
8
8
|
type: "action",
|
|
9
9
|
props: {
|
|
10
10
|
zendesk,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "zendesk-list-macros",
|
|
5
5
|
name: "List Macros",
|
|
6
6
|
description: "Retrieves all macros. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/business-rules/macros/#list-macros).",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.3",
|
|
8
8
|
type: "action",
|
|
9
9
|
props: {
|
|
10
10
|
zendesk,
|
|
@@ -4,7 +4,7 @@ export default {
|
|
|
4
4
|
key: "zendesk-list-ticket-comments",
|
|
5
5
|
name: "List Ticket Comments",
|
|
6
6
|
description: "Retrieves all comments for a specific ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_comments/#list-comments).",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.3",
|
|
8
8
|
type: "action",
|
|
9
9
|
props: {
|
|
10
10
|
zendesk,
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
name: "List Tickets",
|
|
6
6
|
description: "Retrieves a list of tickets. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#list-tickets).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.6",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
sortBy: {
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
name: "Remove Ticket Tags",
|
|
6
6
|
description: "Remove specific tags from a ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/ticket-management/tags/#remove-tags).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.4",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
ticketId: {
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
name: "Search Tickets",
|
|
6
6
|
description: "Searches for tickets using Zendesk's search API. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/ticket-management/search/#search-tickets).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.7",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
query: {
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
name: "Set Ticket Tags",
|
|
6
6
|
description: "Set tags on a ticket (replaces all existing tags). [See the documentation](https://developer.zendesk.com/api-reference/ticketing/ticket-management/tags/#set-tags).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.4",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
ticketId: {
|
|
@@ -3,9 +3,9 @@ import app from "../../zendesk.app.mjs";
|
|
|
3
3
|
export default {
|
|
4
4
|
key: "zendesk-update-ticket",
|
|
5
5
|
name: "Update Ticket",
|
|
6
|
-
description: "Updates a ticket
|
|
6
|
+
description: "Updates a ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#update-ticket).",
|
|
7
7
|
type: "action",
|
|
8
|
-
version: "0.1
|
|
8
|
+
version: "0.2.1",
|
|
9
9
|
props: {
|
|
10
10
|
app,
|
|
11
11
|
ticketId: {
|
|
@@ -56,6 +56,12 @@ export default {
|
|
|
56
56
|
"customSubdomain",
|
|
57
57
|
],
|
|
58
58
|
},
|
|
59
|
+
attachments: {
|
|
60
|
+
propDefinition: [
|
|
61
|
+
app,
|
|
62
|
+
"attachments",
|
|
63
|
+
],
|
|
64
|
+
},
|
|
59
65
|
ticketTags: {
|
|
60
66
|
propDefinition: [
|
|
61
67
|
app,
|
|
@@ -83,6 +89,18 @@ export default {
|
|
|
83
89
|
optional: true,
|
|
84
90
|
default: "set",
|
|
85
91
|
},
|
|
92
|
+
assigneeId: {
|
|
93
|
+
propDefinition: [
|
|
94
|
+
app,
|
|
95
|
+
"assigneeId",
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
assigneeEmail: {
|
|
99
|
+
propDefinition: [
|
|
100
|
+
app,
|
|
101
|
+
"assigneeEmail",
|
|
102
|
+
],
|
|
103
|
+
},
|
|
86
104
|
},
|
|
87
105
|
methods: {
|
|
88
106
|
updateTicket({
|
|
@@ -104,8 +122,11 @@ export default {
|
|
|
104
122
|
ticketStatus,
|
|
105
123
|
ticketCommentPublic,
|
|
106
124
|
customSubdomain,
|
|
125
|
+
attachments,
|
|
107
126
|
ticketTags,
|
|
108
127
|
tagAction,
|
|
128
|
+
assigneeId,
|
|
129
|
+
assigneeEmail,
|
|
109
130
|
} = this;
|
|
110
131
|
|
|
111
132
|
const ticketComment = ticketCommentBodyIsHTML
|
|
@@ -118,20 +139,68 @@ export default {
|
|
|
118
139
|
|
|
119
140
|
ticketComment.public = ticketCommentPublic;
|
|
120
141
|
|
|
142
|
+
// Upload attachments if provided
|
|
143
|
+
if (attachments && attachments.length > 0) {
|
|
144
|
+
try {
|
|
145
|
+
const uploadTokens = await this.app.uploadFiles({
|
|
146
|
+
attachments,
|
|
147
|
+
customSubdomain,
|
|
148
|
+
step,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
if (uploadTokens.length > 0) {
|
|
152
|
+
ticketComment.uploads = uploadTokens;
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
step.export("$summary", `Failed to upload attachments: ${error.message}`);
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Build ticket data object
|
|
161
|
+
const ticketData = {
|
|
162
|
+
comment: ticketComment,
|
|
163
|
+
priority: ticketPriority,
|
|
164
|
+
subject: ticketSubject,
|
|
165
|
+
status: ticketStatus,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Add assignee fields if provided
|
|
169
|
+
if (assigneeId) {
|
|
170
|
+
ticketData.assignee_id = assigneeId;
|
|
171
|
+
}
|
|
172
|
+
if (assigneeEmail) {
|
|
173
|
+
ticketData.assignee_email = assigneeEmail;
|
|
174
|
+
}
|
|
175
|
+
|
|
121
176
|
const response = await this.updateTicket({
|
|
122
177
|
step,
|
|
123
178
|
ticketId,
|
|
124
179
|
customSubdomain,
|
|
125
180
|
data: {
|
|
126
|
-
ticket:
|
|
127
|
-
comment: ticketComment,
|
|
128
|
-
priority: ticketPriority,
|
|
129
|
-
subject: ticketSubject,
|
|
130
|
-
status: ticketStatus,
|
|
131
|
-
},
|
|
181
|
+
ticket: ticketData,
|
|
132
182
|
},
|
|
133
183
|
});
|
|
134
184
|
|
|
185
|
+
const attachmentCount = ticketComment.uploads?.length || 0;
|
|
186
|
+
const assigneeUpdated = assigneeId || assigneeEmail;
|
|
187
|
+
|
|
188
|
+
let summary = `Successfully updated ticket with ID ${response.ticket.id}`;
|
|
189
|
+
|
|
190
|
+
const updates = [];
|
|
191
|
+
if (attachmentCount > 0) {
|
|
192
|
+
updates.push(`${attachmentCount} attachment(s)`);
|
|
193
|
+
}
|
|
194
|
+
if (assigneeUpdated) {
|
|
195
|
+
updates.push("assignee");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (updates.length > 0) {
|
|
199
|
+
summary += ` with ${updates.join(" and ")}`;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
step.export("$summary", summary);
|
|
203
|
+
|
|
135
204
|
// Handle tag operations if tags are provided
|
|
136
205
|
if (ticketTags && ticketTags.length > 0) {
|
|
137
206
|
let tagResponse;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipedream/zendesk",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "Pipedream Zendesk Components",
|
|
5
5
|
"main": "zendesk.app.mjs",
|
|
6
6
|
"keywords": [
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@pipedream/platform": "^3.0
|
|
18
|
-
"crypto": "^1.0.1"
|
|
17
|
+
"@pipedream/platform": "^3.1.0",
|
|
18
|
+
"crypto": "^1.0.1",
|
|
19
|
+
"path": "^0.12.7"
|
|
19
20
|
}
|
|
20
21
|
}
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
key: "zendesk-ticket-added-to-view",
|
|
6
6
|
name: "New Ticket Added to View (Instant)",
|
|
7
7
|
description: "Emit new event when a ticket is added to the specified view",
|
|
8
|
-
version: "0.0.
|
|
8
|
+
version: "0.0.8",
|
|
9
9
|
type: "source",
|
|
10
10
|
dedupe: "unique",
|
|
11
11
|
props: {
|
package/zendesk.app.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { axios } from "@pipedream/platform";
|
|
2
2
|
import constants from "./common/constants.mjs";
|
|
3
|
+
import { getFileStreamAndMetadata } from "@pipedream/platform";
|
|
4
|
+
import path from "path";
|
|
3
5
|
|
|
4
6
|
export default {
|
|
5
7
|
type: "app",
|
|
@@ -260,12 +262,56 @@ export default {
|
|
|
260
262
|
description: "For Enterprise Zendesk accounts: optionally specify the subdomain to use. This will override the subdomain that was provided when connecting your Zendesk account to Pipedream. For example, if you Zendesk URL is https://examplehelp.zendesk.com, your subdomain is `examplehelp`",
|
|
261
263
|
optional: true,
|
|
262
264
|
},
|
|
265
|
+
attachments: {
|
|
266
|
+
type: "string[]",
|
|
267
|
+
label: "Attachments",
|
|
268
|
+
description: "File paths or URLs to attach to the ticket. Multiple files can be attached.",
|
|
269
|
+
optional: true,
|
|
270
|
+
},
|
|
263
271
|
ticketTags: {
|
|
264
272
|
type: "string[]",
|
|
265
273
|
label: "Tags",
|
|
266
274
|
description: "Array of tags to apply to the ticket. These will replace any existing tags on the ticket.",
|
|
267
275
|
optional: true,
|
|
268
276
|
},
|
|
277
|
+
assigneeId: {
|
|
278
|
+
type: "string",
|
|
279
|
+
label: "Assignee ID",
|
|
280
|
+
description: "The ID of the agent to assign the ticket to",
|
|
281
|
+
optional: true,
|
|
282
|
+
async options({ prevContext }) {
|
|
283
|
+
const { afterCursor } = prevContext;
|
|
284
|
+
|
|
285
|
+
const {
|
|
286
|
+
users,
|
|
287
|
+
meta,
|
|
288
|
+
} = await this.listUsers({
|
|
289
|
+
params: {
|
|
290
|
+
[constants.PAGE_SIZE_PARAM]: constants.DEFAULT_LIMIT,
|
|
291
|
+
[constants.PAGE_AFTER_PARAM]: afterCursor,
|
|
292
|
+
role: "agent",
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
context: {
|
|
298
|
+
afterCursor: meta.after_cursor,
|
|
299
|
+
},
|
|
300
|
+
options: users.map(({
|
|
301
|
+
id, name,
|
|
302
|
+
}) => ({
|
|
303
|
+
label: name,
|
|
304
|
+
value: id,
|
|
305
|
+
})),
|
|
306
|
+
};
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
assigneeEmail: {
|
|
310
|
+
type: "string",
|
|
311
|
+
label: "Assignee Email",
|
|
312
|
+
description: "The email address of the agent to assign the ticket to",
|
|
313
|
+
optional: true,
|
|
314
|
+
},
|
|
269
315
|
},
|
|
270
316
|
methods: {
|
|
271
317
|
getUrl(path, customSubdomain) {
|
|
@@ -369,6 +415,94 @@ export default {
|
|
|
369
415
|
...args,
|
|
370
416
|
});
|
|
371
417
|
},
|
|
418
|
+
streamToBuffer(stream) {
|
|
419
|
+
return new Promise((resolve, reject) => {
|
|
420
|
+
const chunks = [];
|
|
421
|
+
stream.on("data", (chunk) => chunks.push(chunk));
|
|
422
|
+
stream.on("end", () => resolve(Buffer.concat(chunks)));
|
|
423
|
+
stream.on("error", reject);
|
|
424
|
+
});
|
|
425
|
+
},
|
|
426
|
+
/**
|
|
427
|
+
* Upload a single file (local path or http(s) URL) to Zendesk Uploads API.
|
|
428
|
+
* @param {Object} params
|
|
429
|
+
* @param {string} params.filePath - Local filesystem path or http(s) URL.
|
|
430
|
+
* @param {string} [params.filename] - Optional filename override for the upload.
|
|
431
|
+
* @param {string} [params.customSubdomain]
|
|
432
|
+
* @param {*} [params.step]
|
|
433
|
+
*/
|
|
434
|
+
async uploadFile({
|
|
435
|
+
filePath, filename, customSubdomain, step,
|
|
436
|
+
}) {
|
|
437
|
+
if (!filePath || typeof filePath !== "string") {
|
|
438
|
+
throw new Error("uploadFile: 'filePath' (string) is required");
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const {
|
|
442
|
+
stream, metadata,
|
|
443
|
+
} = await getFileStreamAndMetadata(filePath);
|
|
444
|
+
const fileBinary = await this.streamToBuffer(stream);
|
|
445
|
+
|
|
446
|
+
if (!filename) {
|
|
447
|
+
filename = path.basename(filePath);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return this.makeRequest({
|
|
451
|
+
step,
|
|
452
|
+
method: "post",
|
|
453
|
+
path: `/uploads?filename=${encodeURIComponent(filename)}`,
|
|
454
|
+
customSubdomain,
|
|
455
|
+
headers: {
|
|
456
|
+
"Content-Type": metadata.contentType,
|
|
457
|
+
"Content-Length": metadata.size,
|
|
458
|
+
"Accept": "application/json",
|
|
459
|
+
},
|
|
460
|
+
data: Buffer.from(fileBinary, "binary"),
|
|
461
|
+
});
|
|
462
|
+
},
|
|
463
|
+
async uploadFiles({
|
|
464
|
+
attachments, customSubdomain, step,
|
|
465
|
+
} = {}) {
|
|
466
|
+
if (!attachments || !attachments.length) {
|
|
467
|
+
return [];
|
|
468
|
+
}
|
|
469
|
+
const files = attachments
|
|
470
|
+
.map((a) => (typeof a === "string"
|
|
471
|
+
? a.trim()
|
|
472
|
+
: a))
|
|
473
|
+
.filter(Boolean);
|
|
474
|
+
|
|
475
|
+
const settled = await Promise.allSettled(
|
|
476
|
+
files.map((attachment) =>
|
|
477
|
+
this.uploadFile({
|
|
478
|
+
filePath: attachment,
|
|
479
|
+
customSubdomain,
|
|
480
|
+
step,
|
|
481
|
+
})),
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
const tokens = [];
|
|
485
|
+
const errors = [];
|
|
486
|
+
settled.forEach((res, i) => {
|
|
487
|
+
const attachment = files[i];
|
|
488
|
+
if (res.status === "fulfilled") {
|
|
489
|
+
const token = res.value?.upload?.token;
|
|
490
|
+
if (!token) {
|
|
491
|
+
errors.push(`Upload API returned no token for ${attachment}`);
|
|
492
|
+
} else {
|
|
493
|
+
tokens.push(token);
|
|
494
|
+
}
|
|
495
|
+
} else {
|
|
496
|
+
const reason = res.reason?.message || String(res.reason || "Unknown error");
|
|
497
|
+
errors.push(`${attachment}: ${reason}`);
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
if (errors.length) {
|
|
502
|
+
throw new Error(`Failed to upload ${errors.length}/${files.length} attachment(s): ${errors.join("; ")}`);
|
|
503
|
+
}
|
|
504
|
+
return tokens;
|
|
505
|
+
},
|
|
372
506
|
listTicketComments({
|
|
373
507
|
ticketId, ...args
|
|
374
508
|
} = {}) {
|