diff --git a/components/zendesk/actions/add-ticket-tags/add-ticket-tags.mjs b/components/zendesk/actions/add-ticket-tags/add-ticket-tags.mjs index d663c7e657d6f..c171ca1259755 100644 --- a/components/zendesk/actions/add-ticket-tags/add-ticket-tags.mjs +++ b/components/zendesk/actions/add-ticket-tags/add-ticket-tags.mjs @@ -5,7 +5,7 @@ export default { name: "Add Ticket Tags", 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).", type: "action", - version: "0.0.2", + version: "0.0.3", props: { app, ticketId: { diff --git a/components/zendesk/actions/create-ticket/create-ticket.mjs b/components/zendesk/actions/create-ticket/create-ticket.mjs index 65d06b6480984..a0e396a0be85a 100644 --- a/components/zendesk/actions/create-ticket/create-ticket.mjs +++ b/components/zendesk/actions/create-ticket/create-ticket.mjs @@ -5,7 +5,7 @@ export default { name: "Create Ticket", description: "Creates a ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#create-ticket).", type: "action", - version: "0.1.6", + version: "0.1.7", props: { app, ticketCommentBody: { diff --git a/components/zendesk/actions/delete-ticket/delete-ticket.mjs b/components/zendesk/actions/delete-ticket/delete-ticket.mjs index 6c6de189374df..bef6c225f95f0 100644 --- a/components/zendesk/actions/delete-ticket/delete-ticket.mjs +++ b/components/zendesk/actions/delete-ticket/delete-ticket.mjs @@ -5,7 +5,7 @@ export default { name: "Delete Ticket", description: "Deletes a ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#delete-ticket).", type: "action", - version: "0.1.6", + version: "0.1.7", props: { app, ticketId: { diff --git a/components/zendesk/actions/get-ticket-info/get-ticket-info.mjs b/components/zendesk/actions/get-ticket-info/get-ticket-info.mjs index fc9e0d2adbfcc..4d841013e3fe7 100644 --- a/components/zendesk/actions/get-ticket-info/get-ticket-info.mjs +++ b/components/zendesk/actions/get-ticket-info/get-ticket-info.mjs @@ -5,7 +5,7 @@ export default { name: "Get Ticket Info", description: "Retrieves information about a specific ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#show-ticket).", type: "action", - version: "0.0.4", + version: "0.0.5", props: { app, ticketId: { diff --git a/components/zendesk/actions/get-user-info/get-user-info.mjs b/components/zendesk/actions/get-user-info/get-user-info.mjs index 8f6e03b94a6f5..c0dd22f32a66e 100644 --- a/components/zendesk/actions/get-user-info/get-user-info.mjs +++ b/components/zendesk/actions/get-user-info/get-user-info.mjs @@ -4,7 +4,7 @@ export default { key: "zendesk-get-user-info", name: "Get User Info", description: "Retrieves information about a specific user. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/users/users/#show-user).", - version: "0.0.1", + version: "0.0.2", type: "action", props: { zendesk, diff --git a/components/zendesk/actions/list-locales/list-locales.mjs b/components/zendesk/actions/list-locales/list-locales.mjs index 035f86e3d56b5..e6e0050650a43 100644 --- a/components/zendesk/actions/list-locales/list-locales.mjs +++ b/components/zendesk/actions/list-locales/list-locales.mjs @@ -4,7 +4,7 @@ export default { key: "zendesk-list-locales", name: "List Locales", description: "Retrieves all locales. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/account-configuration/locales/).", - version: "0.0.1", + version: "0.0.2", type: "action", props: { zendesk, diff --git a/components/zendesk/actions/list-macros/list-macros.mjs b/components/zendesk/actions/list-macros/list-macros.mjs index d5b4ae4f412cb..2d2d3cb1cac79 100644 --- a/components/zendesk/actions/list-macros/list-macros.mjs +++ b/components/zendesk/actions/list-macros/list-macros.mjs @@ -4,7 +4,7 @@ export default { key: "zendesk-list-macros", name: "List Macros", description: "Retrieves all macros. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/business-rules/macros/#list-macros).", - version: "0.0.1", + version: "0.0.2", type: "action", props: { zendesk, diff --git a/components/zendesk/actions/list-ticket-comments/list-ticket-comments.mjs b/components/zendesk/actions/list-ticket-comments/list-ticket-comments.mjs index 2554eef62d59c..be82b6c26e703 100644 --- a/components/zendesk/actions/list-ticket-comments/list-ticket-comments.mjs +++ b/components/zendesk/actions/list-ticket-comments/list-ticket-comments.mjs @@ -4,7 +4,7 @@ export default { key: "zendesk-list-ticket-comments", name: "List Ticket Comments", description: "Retrieves all comments for a specific ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_comments/#list-comments).", - version: "0.0.1", + version: "0.0.2", type: "action", props: { zendesk, diff --git a/components/zendesk/actions/list-tickets/list-tickets.mjs b/components/zendesk/actions/list-tickets/list-tickets.mjs index 03355f0b3088e..26ef649461123 100644 --- a/components/zendesk/actions/list-tickets/list-tickets.mjs +++ b/components/zendesk/actions/list-tickets/list-tickets.mjs @@ -5,7 +5,7 @@ export default { name: "List Tickets", description: "Retrieves a list of tickets. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#list-tickets).", type: "action", - version: "0.0.4", + version: "0.0.5", props: { app, sortBy: { diff --git a/components/zendesk/actions/remove-ticket-tags/remove-ticket-tags.mjs b/components/zendesk/actions/remove-ticket-tags/remove-ticket-tags.mjs index b1ebf6e18b302..17b81b1626c4d 100644 --- a/components/zendesk/actions/remove-ticket-tags/remove-ticket-tags.mjs +++ b/components/zendesk/actions/remove-ticket-tags/remove-ticket-tags.mjs @@ -5,7 +5,7 @@ export default { name: "Remove Ticket Tags", description: "Remove specific tags from a ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/ticket-management/tags/#remove-tags).", type: "action", - version: "0.0.2", + version: "0.0.3", props: { app, ticketId: { diff --git a/components/zendesk/actions/search-tickets/search-tickets.mjs b/components/zendesk/actions/search-tickets/search-tickets.mjs index c64d59beceaa3..a4bc5c4981490 100644 --- a/components/zendesk/actions/search-tickets/search-tickets.mjs +++ b/components/zendesk/actions/search-tickets/search-tickets.mjs @@ -5,7 +5,7 @@ export default { name: "Search Tickets", description: "Searches for tickets using Zendesk's search API. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/ticket-management/search/#search-tickets).", type: "action", - version: "0.0.5", + version: "0.0.6", props: { app, query: { diff --git a/components/zendesk/actions/set-ticket-tags/set-ticket-tags.mjs b/components/zendesk/actions/set-ticket-tags/set-ticket-tags.mjs index 5f6c50746f457..2a584a38128d8 100644 --- a/components/zendesk/actions/set-ticket-tags/set-ticket-tags.mjs +++ b/components/zendesk/actions/set-ticket-tags/set-ticket-tags.mjs @@ -5,7 +5,7 @@ export default { name: "Set Ticket Tags", 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).", type: "action", - version: "0.0.2", + version: "0.0.3", props: { app, ticketId: { diff --git a/components/zendesk/actions/update-ticket/update-ticket.mjs b/components/zendesk/actions/update-ticket/update-ticket.mjs index 6a97199349ddf..75708ec495e3f 100644 --- a/components/zendesk/actions/update-ticket/update-ticket.mjs +++ b/components/zendesk/actions/update-ticket/update-ticket.mjs @@ -3,9 +3,9 @@ import app from "../../zendesk.app.mjs"; export default { key: "zendesk-update-ticket", name: "Update Ticket", - description: "Updates a ticket and optionally manages tags. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#update-ticket).", + description: "Updates a ticket. [See the documentation](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#update-ticket).", type: "action", - version: "0.1.6", + version: "0.2.0", props: { app, ticketId: { @@ -56,6 +56,12 @@ export default { "customSubdomain", ], }, + attachments: { + propDefinition: [ + app, + "attachments", + ], + }, ticketTags: { propDefinition: [ app, @@ -104,6 +110,7 @@ export default { ticketStatus, ticketCommentPublic, customSubdomain, + attachments, ticketTags, tagAction, } = this; @@ -118,6 +125,24 @@ export default { ticketComment.public = ticketCommentPublic; + // Upload attachments if provided + if (attachments && attachments.length > 0) { + try { + const uploadTokens = await this.app.uploadFiles({ + attachments, + customSubdomain, + step, + }); + + if (uploadTokens.length > 0) { + ticketComment.uploads = uploadTokens; + } + } catch (error) { + step.export("$summary", `Failed to upload attachments: ${error.message}`); + throw error; + } + } + const response = await this.updateTicket({ step, ticketId, @@ -132,6 +157,13 @@ export default { }, }); + const attachmentCount = ticketComment.uploads?.length || 0; + const summary = attachmentCount > 0 + ? `Successfully updated ticket with ID ${response.ticket.id} with ${attachmentCount} attachment(s)` + : `Successfully updated ticket with ID ${response.ticket.id}`; + + step.export("$summary", summary); + // Handle tag operations if tags are provided if (ticketTags && ticketTags.length > 0) { let tagResponse; diff --git a/components/zendesk/package.json b/components/zendesk/package.json index 4b96e930e3505..4c1206e7c0f68 100644 --- a/components/zendesk/package.json +++ b/components/zendesk/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/zendesk", - "version": "0.8.1", + "version": "0.8.2", "description": "Pipedream Zendesk Components", "main": "zendesk.app.mjs", "keywords": [ @@ -14,7 +14,8 @@ "access": "public" }, "dependencies": { - "@pipedream/platform": "^3.0.3", - "crypto": "^1.0.1" + "@pipedream/platform": "^3.1.0", + "crypto": "^1.0.1", + "path": "^0.12.7" } } diff --git a/components/zendesk/sources/locale-updated/locale-updated.mjs b/components/zendesk/sources/locale-updated/locale-updated.mjs index 855aade43155f..edf4439a54a4f 100644 --- a/components/zendesk/sources/locale-updated/locale-updated.mjs +++ b/components/zendesk/sources/locale-updated/locale-updated.mjs @@ -6,7 +6,7 @@ export default { name: "Locale Updated", type: "source", description: "Emit new event when a locale has been updated", - version: "0.0.1", + version: "0.0.2", dedupe: "unique", async run() { const lastTs = this._getLastTs(); diff --git a/components/zendesk/sources/new-ticket-comment-added/new-ticket-comment-added.mjs b/components/zendesk/sources/new-ticket-comment-added/new-ticket-comment-added.mjs index eb9cfdafb6876..b760f5e740890 100644 --- a/components/zendesk/sources/new-ticket-comment-added/new-ticket-comment-added.mjs +++ b/components/zendesk/sources/new-ticket-comment-added/new-ticket-comment-added.mjs @@ -7,7 +7,7 @@ export default { key: "zendesk-new-ticket-comment-added", type: "source", description: "Emit new event when a ticket comment has been added", - version: "0.0.1", + version: "0.0.2", dedupe: "unique", props: { app, diff --git a/components/zendesk/sources/new-ticket/new-ticket.mjs b/components/zendesk/sources/new-ticket/new-ticket.mjs index 8e00bac4ca314..afbefcb407383 100644 --- a/components/zendesk/sources/new-ticket/new-ticket.mjs +++ b/components/zendesk/sources/new-ticket/new-ticket.mjs @@ -6,7 +6,7 @@ export default { key: "zendesk-new-ticket", type: "source", description: "Emit new event when a ticket is created", - version: "0.2.6", + version: "0.2.7", dedupe: "unique", methods: { ...common.methods, diff --git a/components/zendesk/sources/ticket-added-to-view/ticket-added-to-view.mjs b/components/zendesk/sources/ticket-added-to-view/ticket-added-to-view.mjs index ae785d533baec..0dc8ce8ace2c0 100644 --- a/components/zendesk/sources/ticket-added-to-view/ticket-added-to-view.mjs +++ b/components/zendesk/sources/ticket-added-to-view/ticket-added-to-view.mjs @@ -5,7 +5,7 @@ export default { key: "zendesk-ticket-added-to-view", name: "New Ticket Added to View (Instant)", description: "Emit new event when a ticket is added to the specified view", - version: "0.0.6", + version: "0.0.7", type: "source", dedupe: "unique", props: { diff --git a/components/zendesk/sources/ticket-closed/ticket-closed.mjs b/components/zendesk/sources/ticket-closed/ticket-closed.mjs index 9f50d86ebf726..f77aa1444b38e 100644 --- a/components/zendesk/sources/ticket-closed/ticket-closed.mjs +++ b/components/zendesk/sources/ticket-closed/ticket-closed.mjs @@ -6,7 +6,7 @@ export default { key: "zendesk-ticket-closed", type: "source", description: "Emit new event when a ticket has changed to closed status", - version: "0.2.6", + version: "0.2.7", dedupe: "unique", methods: { ...common.methods, diff --git a/components/zendesk/sources/ticket-pended/ticket-pended.mjs b/components/zendesk/sources/ticket-pended/ticket-pended.mjs index 8b0bd503bc9b1..48a1f0b901980 100644 --- a/components/zendesk/sources/ticket-pended/ticket-pended.mjs +++ b/components/zendesk/sources/ticket-pended/ticket-pended.mjs @@ -6,7 +6,7 @@ export default { key: "zendesk-ticket-pended", type: "source", description: "Emit new event when a ticket has changed to pending status", - version: "0.2.6", + version: "0.2.7", dedupe: "unique", methods: { ...common.methods, diff --git a/components/zendesk/sources/ticket-solved/ticket-solved.mjs b/components/zendesk/sources/ticket-solved/ticket-solved.mjs index 6d87a69d986ec..206007e0390b6 100644 --- a/components/zendesk/sources/ticket-solved/ticket-solved.mjs +++ b/components/zendesk/sources/ticket-solved/ticket-solved.mjs @@ -6,7 +6,7 @@ export default { key: "zendesk-ticket-solved", type: "source", description: "Emit new event when a ticket has changed to solved status", - version: "0.2.6", + version: "0.2.7", dedupe: "unique", methods: { ...common.methods, diff --git a/components/zendesk/sources/ticket-updated/ticket-updated.mjs b/components/zendesk/sources/ticket-updated/ticket-updated.mjs index 253d5e92d6233..24a0c3edc7780 100644 --- a/components/zendesk/sources/ticket-updated/ticket-updated.mjs +++ b/components/zendesk/sources/ticket-updated/ticket-updated.mjs @@ -6,7 +6,7 @@ export default { key: "zendesk-ticket-updated", type: "source", description: "Emit new event when a ticket has been updated", - version: "0.2.6", + version: "0.2.7", dedupe: "unique", methods: { ...common.methods, diff --git a/components/zendesk/zendesk.app.mjs b/components/zendesk/zendesk.app.mjs index e81bf805e991d..40c1ab4d8bc6f 100644 --- a/components/zendesk/zendesk.app.mjs +++ b/components/zendesk/zendesk.app.mjs @@ -1,5 +1,7 @@ import { axios } from "@pipedream/platform"; import constants from "./common/constants.mjs"; +import { getFileStreamAndMetadata } from "@pipedream/platform"; +import path from "path"; export default { type: "app", @@ -260,6 +262,12 @@ export default { 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`", optional: true, }, + attachments: { + type: "string[]", + label: "Attachments", + description: "File paths or URLs to attach to the ticket. Multiple files can be attached.", + optional: true, + }, ticketTags: { type: "string[]", label: "Tags", @@ -369,6 +377,94 @@ export default { ...args, }); }, + streamToBuffer(stream) { + return new Promise((resolve, reject) => { + const chunks = []; + stream.on("data", (chunk) => chunks.push(chunk)); + stream.on("end", () => resolve(Buffer.concat(chunks))); + stream.on("error", reject); + }); + }, + /** + * Upload a single file (local path or http(s) URL) to Zendesk Uploads API. + * @param {Object} params + * @param {string} params.filePath - Local filesystem path or http(s) URL. + * @param {string} [params.filename] - Optional filename override for the upload. + * @param {string} [params.customSubdomain] + * @param {*} [params.step] + */ + async uploadFile({ + filePath, filename, customSubdomain, step, + }) { + if (!filePath || typeof filePath !== "string") { + throw new Error("uploadFile: 'filePath' (string) is required"); + } + + const { + stream, metadata, + } = await getFileStreamAndMetadata(filePath); + const fileBinary = await this.streamToBuffer(stream); + + if (!filename) { + filename = path.basename(filePath); + } + + return this.makeRequest({ + step, + method: "post", + path: `/uploads?filename=${encodeURIComponent(filename)}`, + customSubdomain, + headers: { + "Content-Type": metadata.contentType, + "Content-Length": metadata.size, + "Accept": "application/json", + }, + data: Buffer.from(fileBinary, "binary"), + }); + }, + async uploadFiles({ + attachments, customSubdomain, step, + } = {}) { + if (!attachments || !attachments.length) { + return []; + } + const files = attachments + .map((a) => (typeof a === "string" + ? a.trim() + : a)) + .filter(Boolean); + + const settled = await Promise.allSettled( + files.map((attachment) => + this.uploadFile({ + filePath: attachment, + customSubdomain, + step, + })), + ); + + const tokens = []; + const errors = []; + settled.forEach((res, i) => { + const attachment = files[i]; + if (res.status === "fulfilled") { + const token = res.value?.upload?.token; + if (!token) { + errors.push(`Upload API returned no token for ${attachment}`); + } else { + tokens.push(token); + } + } else { + const reason = res.reason?.message || String(res.reason || "Unknown error"); + errors.push(`${attachment}: ${reason}`); + } + }); + + if (errors.length) { + throw new Error(`Failed to upload ${errors.length}/${files.length} attachment(s): ${errors.join("; ")}`); + } + return tokens; + }, listTicketComments({ ticketId, ...args } = {}) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e7845895295a9..3e716d5e9c8fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3453,8 +3453,7 @@ importers: components/danny_test_app: {} - components/dante_ai: - specifiers: {} + components/dante_ai: {} components/dappier: {} @@ -16096,11 +16095,14 @@ importers: components/zendesk: dependencies: '@pipedream/platform': - specifier: ^3.0.3 - version: 3.0.3 + specifier: ^3.1.0 + version: 3.1.0 crypto: specifier: ^1.0.1 version: 1.0.1 + path: + specifier: ^0.12.7 + version: 0.12.7 components/zendesk_sell: dependencies: