From 5fc12699f9c0c82677f23ff8abaf62dbd5022266 Mon Sep 17 00:00:00 2001 From: Jorge Cortes Date: Tue, 18 Jun 2024 09:41:46 -0500 Subject: [PATCH] Migration is complete with tested components (#12429) --- .../actions/create-item/create-item.mjs | 72 ++- .../actions/create-message/create-message.mjs | 52 +- .../actions/create-project/create-project.mjs | 62 ++- .../actions/create-user/create-user.mjs | 68 ++- .../onedesk/actions/find-item/find-item.mjs | 125 ++--- .../actions/find-project/find-project.mjs | 125 +++-- .../actions/update-item/update-item.mjs | 83 ++- components/onedesk/common/constants.mjs | 33 +- components/onedesk/common/utils.mjs | 26 + components/onedesk/onedesk.app.mjs | 514 +++++++++++------- components/onedesk/package.json | 6 +- .../onedesk/sources/common/activity-types.mjs | 85 +++ components/onedesk/sources/common/common.mjs | 52 -- components/onedesk/sources/common/polling.mjs | 104 ++++ .../new-item-created/new-item-created.mjs | 36 +- .../sources/new-item-created/test-event.mjs | 11 + .../new-item-updated/new-item-updated.mjs | 35 -- .../new-project-created.mjs | 36 +- .../new-project-created/test-event.mjs | 11 + .../new-project-updated.mjs | 36 -- .../new-public-message-created.mjs | 35 -- .../new-timesheet-created.mjs | 37 +- .../new-timesheet-created/test-event.mjs | 11 + .../new-user-created/new-user-created.mjs | 36 +- .../sources/new-user-created/test-event.mjs | 11 + pnpm-lock.yaml | 8 +- 26 files changed, 1024 insertions(+), 686 deletions(-) create mode 100644 components/onedesk/common/utils.mjs create mode 100644 components/onedesk/sources/common/activity-types.mjs delete mode 100644 components/onedesk/sources/common/common.mjs create mode 100644 components/onedesk/sources/common/polling.mjs create mode 100644 components/onedesk/sources/new-item-created/test-event.mjs delete mode 100644 components/onedesk/sources/new-item-updated/new-item-updated.mjs create mode 100644 components/onedesk/sources/new-project-created/test-event.mjs delete mode 100644 components/onedesk/sources/new-project-updated/new-project-updated.mjs delete mode 100644 components/onedesk/sources/new-public-message-created/new-public-message-created.mjs create mode 100644 components/onedesk/sources/new-timesheet-created/test-event.mjs create mode 100644 components/onedesk/sources/new-user-created/test-event.mjs diff --git a/components/onedesk/actions/create-item/create-item.mjs b/components/onedesk/actions/create-item/create-item.mjs index 22aa48ba697e6..e635583807301 100644 --- a/components/onedesk/actions/create-item/create-item.mjs +++ b/components/onedesk/actions/create-item/create-item.mjs @@ -1,57 +1,75 @@ -import onedesk from "../../onedesk.app.mjs"; +import app from "../../onedesk.app.mjs"; export default { key: "onedesk-create-item", name: "Create Item", - description: "Creates a new item. [See the docs](https://www.onedesk.com/developers/#_create_work_item)", - version: "0.0.1", + description: "Creates a new item. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "action", props: { - onedesk, + app, + name: { + propDefinition: [ + app, + "itemName", + ], + }, type: { propDefinition: [ - onedesk, + app, "itemType", ], }, - name: { - type: "string", - label: "Name", - description: "Name of the item", - }, description: { - type: "string", - label: "Description", - description: "Description of the item", - optional: true, + propDefinition: [ + app, + "itemDescription", + ], }, - spaceId: { + projectExternalId: { propDefinition: [ - onedesk, - "spaceId", + app, + "projectId", ], }, priority: { propDefinition: [ - onedesk, + app, "priority", ], }, }, + methods: { + createItem(args = {}) { + return this.app.post({ + path: "/items/", + ...args, + }); + }, + }, async run({ $ }) { - const { data } = await this.onedesk.createItem({ + const { + createItem, + name, + type, + description, + projectExternalId, + priority, + } = this; + + const response = await createItem({ + $, data: { - type: this.type, - name: this.name, - description: this.description, - spaceId: this.spaceId, - priority: this.priority, + name, + type, + description, + projectExternalId, + priority, }, - $, }); - $.export("$summary", `Successfully created item with ID ${data.id}.`); + $.export("$summary", `Successfully created item with ID \`${response.data}\`.`); - return data; + return response; }, }; diff --git a/components/onedesk/actions/create-message/create-message.mjs b/components/onedesk/actions/create-message/create-message.mjs index 729e38b3fb764..981e5fcc908bc 100644 --- a/components/onedesk/actions/create-message/create-message.mjs +++ b/components/onedesk/actions/create-message/create-message.mjs @@ -1,44 +1,50 @@ -import onedesk from "../../onedesk.app.mjs"; +import app from "../../onedesk.app.mjs"; export default { key: "onedesk-create-message", name: "Create Message", - description: "Creates a message or comment. [See the docs](https://www.onedesk.com/developers/#_create_comment)", - version: "0.0.1", + description: "Creates a message or comment. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "action", props: { - onedesk, - itemId: { + app, + conversationExternalId: { propDefinition: [ - onedesk, - "itemId", + app, + "conversationExternalId", ], }, - description: { + content: { type: "string", - label: "Description", - description: "Content of the message", + label: "Content", + description: "Content of the conversation message", }, - postType: { - propDefinition: [ - onedesk, - "postType", - ], + }, + methods: { + createMessage(args = {}) { + return this.app.post({ + path: "/conversation-messages/", + ...args, + }); }, }, async run({ $ }) { - const { data } = await this.onedesk.createComment({ + const { + createMessage, + conversationExternalId, + content, + } = this; + + const response = await createMessage({ + $, data: { - itemId: this.itemId, - description: this.description, - postType: this.postType, - token: this.onedesk._authToken(), + conversationExternalId, + content, }, - $, }); - $.export("$summary", `Successfully created comment with ID ${data}.`); + $.export("$summary", `Successfully created message with ID \`${response.data}\`.`); - return data; + return response; }, }; diff --git a/components/onedesk/actions/create-project/create-project.mjs b/components/onedesk/actions/create-project/create-project.mjs index acfd7b1cbe199..4524c6e00588b 100644 --- a/components/onedesk/actions/create-project/create-project.mjs +++ b/components/onedesk/actions/create-project/create-project.mjs @@ -1,50 +1,68 @@ -import onedesk from "../../onedesk.app.mjs"; +import app from "../../onedesk.app.mjs"; export default { key: "onedesk-create-project", name: "Create Project", - description: "Creates a project/space. [See the docs](https://www.onedesk.com/developers/#_create_space)", - version: "0.0.1", + description: "Creates a project/space. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "action", props: { - onedesk, + app, + name: { + type: "string", + label: "Name", + description: "Name of the project.", + }, type: { + label: "Project Type", + description: "Type of the project.", propDefinition: [ - onedesk, + app, "containerType", ], }, - name: { - type: "string", - label: "Name", - description: "Name of the project/space", - }, description: { type: "string", label: "Description", - description: "Description of the project/space", + description: "Description of the project", optional: true, }, - parentIds: { + parentPortfolioExternalIds: { propDefinition: [ - onedesk, - "parentIds", + app, + "parentPortfolioExternalIds", ], }, }, + methods: { + createProject(args = {}) { + return this.app.post({ + path: "/projects/", + ...args, + }); + }, + }, async run({ $ }) { - const { data } = await this.onedesk.createSpace({ + const { + createProject, + type, + name, + description, + parentPortfolioExternalIds, + } = this; + + const response = await createProject({ + $, data: { - containerType: this.type, - name: this.name, - description: this.description, - parentIds: this.parentIds, + type, + name, + description, + parentPortfolioExternalIds, }, - $, }); - $.export("$summary", `Successfully created project with ID ${data.id}.`); + $.export("$summary", `Successfully created project with ID \`${response.data}\`.`); - return data; + return response; }, }; diff --git a/components/onedesk/actions/create-user/create-user.mjs b/components/onedesk/actions/create-user/create-user.mjs index a2e1bc79ad521..d76e553cc5c90 100644 --- a/components/onedesk/actions/create-user/create-user.mjs +++ b/components/onedesk/actions/create-user/create-user.mjs @@ -1,62 +1,84 @@ -import onedesk from "../../onedesk.app.mjs"; +import app from "../../onedesk.app.mjs"; export default { key: "onedesk-create-user", name: "Create User", - description: "Creates a user or a customer. [See the docs](https://www.onedesk.com/developers/#_create_user)", - version: "0.0.1", + description: "Creates a user or a customer. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "action", props: { - onedesk, + app, + email: { + type: "string", + label: "Email", + description: "The new user email", + }, firstName: { type: "string", label: "First Name", description: "The first name of the new user", + optional: true, }, lastName: { type: "string", label: "Last Name", description: "The last name of the new user", - }, - email: { - type: "string", - label: "Email", - description: "The new user email", + optional: true, }, type: { propDefinition: [ - onedesk, + app, "userType", ], }, - teamId: { + teams: { + type: "string[]", + label: "Team IDs", propDefinition: [ - onedesk, + app, "teamId", ], }, - isAdministrator: { + isAdmin: { type: "boolean", label: "Is Administrator", description: "Set to `true` if the new user should be an administrator", optional: true, }, }, + methods: { + createUser(args = {}) { + return this.app.post({ + path: "/users/", + ...args, + }); + }, + }, async run({ $ }) { - const { data } = await this.onedesk.createUser({ + const { + createUser, + email, + firstName, + lastName, + type, + teams, + isAdmin, + } = this; + + const response = await createUser({ + $, data: { - firstName: this.firstName, - lastName: this.lastName, - email: this.email, - type: this.type, - teamId: this.teamId, - isAdministrator: this.isAdministrator, + email, + firstName, + lastName, + type, + teams, + isAdmin, }, - $, }); - $.export("$summary", `Successfully created user with ID ${data.id}.`); + $.export("$summary", `Successfully created user with ID \`${response.data}\`.`); - return data; + return response; }, }; diff --git a/components/onedesk/actions/find-item/find-item.mjs b/components/onedesk/actions/find-item/find-item.mjs index eea117d637349..2916018a81f47 100644 --- a/components/onedesk/actions/find-item/find-item.mjs +++ b/components/onedesk/actions/find-item/find-item.mjs @@ -1,97 +1,90 @@ -import onedesk from "../../onedesk.app.mjs"; -import { ConfigurationError } from "@pipedream/platform"; +import app from "../../onedesk.app.mjs"; +import constants from "../../common/constants.mjs"; export default { key: "onedesk-find-item", name: "Find Item", - description: "Search for an existing item. [See the docs](https://www.onedesk.com/developers/#_search_items)", - version: "0.0.1", + description: "Search for an existing item. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "action", props: { - onedesk, - itemId: { + app, + itemType: { + optional: false, propDefinition: [ - onedesk, - "itemId", + app, + "itemType", ], + }, + creationTimeValue: { + type: "string", + label: "Creation Time Value", + description: "Item creation date. Eg. `2024-01-28`", optional: true, }, - spaceName: { - propDefinition: [ - onedesk, - "spaceName", + creationTimeOperator: { + type: "string", + label: "Creation Time Operator", + description: "Item creation date operator", + optional: true, + options: [ + { + label: "Equal", + value: "EQ", + }, + constants.DATE_OPERATOR.GT, + constants.DATE_OPERATOR.LT, ], }, name: { type: "string", label: "Item Name", description: "Name of the item", - optional: true, - }, - exactMatch: { - type: "boolean", - label: "Exact Match", - description: "The item name search should be an exact match", - optional: true, - default: false, }, }, async run({ $ }) { const { - itemId, - spaceName, + app, + itemType, + creationTimeValue, + creationTimeOperator, name, - exactMatch, } = this; - if (!itemId && !spaceName && !name) { - throw new ConfigurationError("Must enter `itemId`, `spaceName` or `name`."); - } - - const data = { - filters: [], - }; + const properties = [ + { + property: "name", + operation: "CONTAINS", + value: name, + }, + { + property: "creationTime", + operation: creationTimeOperator || constants.DATE_OPERATOR.LT.value, + value: creationTimeValue, + }, + ]; - if (itemId) { - data.itemIds = [ - itemId, - ]; - } - - if (spaceName) { - data.filters.push({ - propertyName: "spaceName", - operation: "EQ", - value: spaceName, - }); - } - - const { data: { items } } = await this.onedesk.searchItems({ - data, - $, - }); - - let results = []; - for (const workItemId of items) { - const { data: itemWithData } = await this.onedesk.getItem({ - params: { - workItemId, - }, + const results = await app.paginate({ + resourcesFn: app.filterItemDetails, + resourcesFnArgs: { $, - }); - results.push(itemWithData); - } + data: { + properties: properties.filter(({ value }) => value), + isAsc: false, + itemType: [ + itemType, + ], + }, + }, + resourceName: "data", + }); - if (name) { - const lowerCaseName = name.toLowerCase(); - results = results.filter((item) => - exactMatch - ? item.name === name - : item.name.toLowerCase().includes(lowerCaseName)); + if (!results.length) { + $.export("$summary", "No items found."); + } else { + $.export("$summary", `Found \`${results.length}\` matching item(s).`); } - $.export("$summary", `Found ${results.length} matching item(s).`); - return results; }, }; diff --git a/components/onedesk/actions/find-project/find-project.mjs b/components/onedesk/actions/find-project/find-project.mjs index d662a8b54686a..d6d7bd612dc97 100644 --- a/components/onedesk/actions/find-project/find-project.mjs +++ b/components/onedesk/actions/find-project/find-project.mjs @@ -1,87 +1,94 @@ -import onedesk from "../../onedesk.app.mjs"; -import { ConfigurationError } from "@pipedream/platform"; +import app from "../../onedesk.app.mjs"; +import constants from "../../common/constants.mjs"; export default { key: "onedesk-find-project", name: "Find Project", - description: "Search for a project/space by name or ID. [See the docs](https://www.onedesk.com/developers/#_search_spaces)", - version: "0.0.1", + description: "Search for a project/space by name or ID. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "action", props: { - onedesk, - spaceId: { + app, + creationTimeValue: { + type: "string", + label: "Creation Time Value", + description: "Project creation date. Eg. `2024-01-28`", + }, + creationTimeOperator: { + type: "string", + label: "Creation Time Operator", + description: "Project creation date operator", + optional: true, + options: Object.values(constants.DATE_OPERATOR), + }, + invoiceType: { + label: "Invoice Type", + description: "Type of invoice. Eg. `flat fee`", propDefinition: [ - onedesk, - "spaceId", + app, + "invoice", ], }, - name: { + dueDateValue: { type: "string", - label: "Name", - description: "Name of the project/space", + label: "Due Date Value", + description: "Due date of project. Eg. `2024-01-28`", optional: true, }, - exactMatch: { - type: "boolean", - label: "Exact Match", - description: "The project name search should be an exact match", + dueDateOperator: { + type: "string", + label: "Due Date Operator", + description: "Due date of project operator", optional: true, - default: false, + options: Object.values(constants.DATE_OPERATOR), }, }, async run({ $ }) { const { - spaceId, - name, - exactMatch, + app, + creationTimeValue, + creationTimeOperator, + invoiceType, + dueDateValue, + dueDateOperator, } = this; - if (!spaceId && !name) { - throw new ConfigurationError("Must enter `spaceId` or `name`."); - } - - const data = {}; - - if (spaceId) { - data.itemIds = [ - spaceId, - ]; - } - - if (name && exactMatch) { - data.filters = [ - { - propertyName: "name", - operation: "EQ", - value: name, - }, - ]; - } - - const { data: { items: projects } } = await this.onedesk.searchSpaces({ - data, - $, - }); + const properties = [ + { + property: "creationTime", + operation: creationTimeOperator || constants.DATE_OPERATOR.LT.value, + value: creationTimeValue, + }, + { + property: "invoiceType", + operation: "EQ", + value: invoiceType, + }, + { + property: "dueDate", + operation: dueDateOperator || constants.DATE_OPERATOR.LT.value, + value: dueDateValue, + }, + ]; - let results = []; - for (const projectId of projects) { - const { data: projectWithData } = await this.onedesk.getSpace({ + const results = await app.paginate({ + resourcesFn: app.filterProjectDetails, + resourcesFnArgs: { + $, data: { - id: projectId, + properties: properties.filter(({ value }) => value), + isAsc: false, }, - $, - }); - results.push(projectWithData); - } + }, + resourceName: "data", + }); - if (name && !exactMatch) { - const lowerCaseName = name.toLowerCase(); - results = results.filter((project) => - project.name.toLowerCase().includes(lowerCaseName)); + if (!results.length) { + $.export("$summary", "No projects found."); + } else { + $.export("$summary", `Found \`${results.length}\` matching project(s).`); } - $.export("$summary", `Found ${results.length} matching project(s).`); - return results; }, }; diff --git a/components/onedesk/actions/update-item/update-item.mjs b/components/onedesk/actions/update-item/update-item.mjs index ba2362f1dee42..2e03833727725 100644 --- a/components/onedesk/actions/update-item/update-item.mjs +++ b/components/onedesk/actions/update-item/update-item.mjs @@ -1,62 +1,89 @@ -import onedesk from "../../onedesk.app.mjs"; -import pickBy from "lodash.pickby"; +import app from "../../onedesk.app.mjs"; export default { key: "onedesk-update-item", name: "Update Item", - description: "Updates an existing item. [See the docs](https://www.onedesk.com/developers/#_update_work_item)", - version: "0.0.1", + description: "Updates an existing item. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "action", props: { - onedesk, + app, + itemType: { + optional: false, + propDefinition: [ + app, + "itemType", + ], + }, itemId: { propDefinition: [ - onedesk, + app, "itemId", + ({ itemType }) => ({ + itemType, + }), ], - description: "", }, name: { - type: "string", - label: "Name", - description: "Name of the item", optional: true, + propDefinition: [ + app, + "itemName", + ], }, description: { - type: "string", - label: "Description", - description: "Description of the item", - optional: true, + propDefinition: [ + app, + "itemDescription", + ], }, priority: { propDefinition: [ - onedesk, + app, "priority", ], - optional: true, }, - progress: { + percentComplete: { type: "integer", label: "Progress", - description: "Progress of the item between 1 and 100", + description: "Progress of the item between `1` and `100`", max: 100, optional: true, }, }, + methods: { + updateItem({ + itemId, ...args + } = {}) { + return this.app.post({ + path: `/items/id/${itemId}`, + ...args, + }); + }, + }, async run({ $ }) { - const { data } = await this.onedesk.updateItem({ - data: pickBy({ - itemId: this.itemId, - name: this.name, - spaceId: this.spaceId, - priority: this.priority, - progress: this.progress, - }), + const { + updateItem, + itemId, + name, + description, + priority, + percentComplete, + } = this; + + const response = await updateItem({ $, + itemId, + data: { + name, + description, + priority, + percentComplete, + }, }); - $.export("$summary", `Successfully updated item with ID ${data.id}.`); + $.export("$summary", `Successfully updated item with code \`${response}\`.`); - return data; + return response; }, }; diff --git a/components/onedesk/common/constants.mjs b/components/onedesk/common/constants.mjs index c76a8f8e2a629..44d42a43f1aae 100644 --- a/components/onedesk/common/constants.mjs +++ b/components/onedesk/common/constants.mjs @@ -25,13 +25,34 @@ const PRIORITY_OPTIONS = [ }, ]; -const POST_TYPES = [ - "OLD_REQUESTER_ONLY_POST", - "PUBLIC_DISCUSSION_POST", - "PRIVATE_DISCUSSION_POST", -]; +const DEFAULT_LIMIT = 20; +const DEFAULT_MAX = 100; + +const DATE_OPERATOR = { + LE: { + label: "Less Than or Equal", + value: "LE", + }, + LT: { + label: "Less Than", + value: "LT", + }, + GT: { + label: "Greater Than", + value: "GT", + }, + GE: { + label: "Greater Than or Equal", + value: "GE", + }, +}; + +const LAST_CREATION_DATE = "lastCreationDate"; export default { PRIORITY_OPTIONS, - POST_TYPES, + DEFAULT_LIMIT, + DEFAULT_MAX, + DATE_OPERATOR, + LAST_CREATION_DATE, }; diff --git a/components/onedesk/common/utils.mjs b/components/onedesk/common/utils.mjs new file mode 100644 index 0000000000000..fa76a8907af05 --- /dev/null +++ b/components/onedesk/common/utils.mjs @@ -0,0 +1,26 @@ +async function iterate(iterations) { + const items = []; + for await (const item of iterations) { + items.push(item); + } + return items; +} + +function getDateOnly(date) { + const dateStr = date instanceof Date + ? date.toISOString() + : date; + return dateStr.split("T")[0]; +} + +function getDateAfterToday(days = 1) { + const dateAfterToday = new Date(); + dateAfterToday.setDate(dateAfterToday.getDate() + days); + return getDateOnly(dateAfterToday); +} + +export default { + iterate, + getDateOnly, + getDateAfterToday, +}; diff --git a/components/onedesk/onedesk.app.mjs b/components/onedesk/onedesk.app.mjs index 61b7af6896aea..6b921511bf8bc 100644 --- a/components/onedesk/onedesk.app.mjs +++ b/components/onedesk/onedesk.app.mjs @@ -1,138 +1,221 @@ import { axios } from "@pipedream/platform"; import constants from "./common/constants.mjs"; +import utils from "./common/utils.mjs"; export default { type: "app", app: "onedesk", propDefinitions: { - userType: { + containerType: { type: "string", - label: "User Type", - description: "Type of user or customer", + label: "Container Type", + description: "Type of the container", optional: true, - async options() { - const { data: { userTypes } } = await this.getOrgInfo(); - return userTypes.map((type) => ({ - label: type.name, - value: type.userType, - })); + async options({ + filter = ({ visible }) => visible, + mapper = ({ label }) => label, + }) { + const { data: containerTypes } = await this.getContainerTypes(); + return containerTypes + .filter(filter) + .map(mapper); }, }, - itemType: { - type: "string", - label: "Item Type", - description: "Type of the item", - async options() { - const { data: { itemTypes } } = await this.getOrgInfo(); - return itemTypes.map((type) => ({ - label: type.name, - value: type.itemType, - })); + parentPortfolioExternalIds: { + type: "string[]", + label: "Parent Portfolio External IDs", + description: "Array of parent portfolio external IDs. Type the name of the parent portfolio to search for it.", + useQuery: true, + optional: true, + async options({ + query, prevContext: { offset = 0 }, + }) { + const { data } = await this.filterPortfolioDetails({ + data: { + properties: [ + { + property: "name", + operation: "CONTAINS", + value: query, + }, + ], + isAsc: false, + limit: constants.DEFAULT_LIMIT, + offset, + }, + }); + + return { + options: data.map(({ + name: label, + externalId: value, + }) => ({ + label, + value, + })), + context: { + offset: offset + constants.DEFAULT_LIMIT, + }, + }; }, }, - containerType: { + userType: { type: "string", - label: "Container Type", - description: "Type of the space", + label: "User Type", + description: "Type of user or customer", + optional: true, async options() { - const { data: { containerTypes } } = await this.getOrgInfo(); - return containerTypes.map((type) => ({ - label: type.name, - value: type.containerType, - })); + const { data: userTypes } = await this.getUserTypes(); + return userTypes.map(({ label }) => label); }, }, teamId: { type: "string", label: "Team ID", description: "The ID of the team", + useQuery: true, optional: true, - async options() { - const { data } = await this.listTeams(); - return data.map((team) => ({ - label: team.name, - value: team.id, - })); + async options({ + query, prevContext: { offset = 0 }, + }) { + const { data } = await this.filterTeamDetails({ + data: { + properties: [ + { + property: "name", + operation: "CONTAINS", + value: query, + }, + ], + isAsc: false, + limit: constants.DEFAULT_LIMIT, + offset, + }, + }); + + return { + options: data.map(({ + name: label, + externalId: value, + }) => ({ + label, + value, + })), + context: { + offset: offset + constants.DEFAULT_LIMIT, + }, + }; }, }, - itemId: { + invoice: { type: "string", - label: "Item ID", - description: "Id of the work item to post a comment on", - async options() { - const { data: { items } } = await this.searchItems(); - const { data: { items: workspaceItems } } = await this.getItemsByIds({ + label: "Invoice", + description: "The invoice to search for", + optional: true, + async options({ + prevContext: { offset = 0 }, + mapper = ({ type }) => type, + }) { + const { data } = await this.filterInvoiceDetails({ data: { - workItemIds: items, + properties: [ + { + property: "creationTime", + operation: constants.DATE_OPERATOR.LT.value, + value: utils.getDateAfterToday(), + }, + ], + isAsc: false, + limit: constants.DEFAULT_LIMIT, + offset, }, }); - return workspaceItems.map((workspaceItem) => ({ - label: workspaceItem.name, - value: workspaceItem.id, - })); + + return { + options: data.map(mapper), + context: { + offset: offset + constants.DEFAULT_LIMIT, + }, + }; }, }, - spaceId: { + conversationExternalId: { type: "string", - label: "Space ID", - description: "The ID of the space or project", - optional: true, - async options() { - const spaces = []; - const { data: { items } } = await this.searchSpaces(); - for (const item of items) { - const { data: space } = await this.getSpace({ - data: { - id: item, - }, - }); - spaces.push({ - label: space.name, - value: space.id, - }); - } - return spaces; + label: "Conversation External ID", + description: "The external ID of the conversation", + async options({ prevContext: { offset = 0 } }) { + const { data } = await this.filterConversationDetails({ + data: { + properties: [ + { + property: "createdTime", + operation: constants.DATE_OPERATOR.LT.value, + value: utils.getDateAfterToday(), + }, + ], + isAsc: false, + limit: constants.DEFAULT_LIMIT, + offset, + }, + }); + + return { + options: data.map(({ + conversationId: value, + content: label, + }) => ({ + label, + value, + })), + context: { + offset: offset + constants.DEFAULT_LIMIT, + }, + }; }, }, - spaceName: { + itemType: { type: "string", - label: "Space Name", - description: "The name of the space or project", + label: "Item Type", + description: "Type of the item", optional: true, async options() { - const spaces = []; - const { data: { items } } = await this.searchSpaces(); - for (const item of items) { - const { data: space } = await this.getSpace({ - data: { - id: item, - }, - }); - spaces.push(space.name); - } - return spaces; + const { data: itemTypes } = await this.getItemTypes(); + return itemTypes.map(({ label }) => label); }, }, - parentIds: { - type: "string[]", - label: "Parent IDs", - description: "Array of parent/portfolio IDs", + projectId: { + type: "string", + label: "Project ID", + description: "The ID of the project", optional: true, - async options() { - const portfolios = []; - const { data: { items } } = await this.searchPortfolios(); - for (const item of items) { - const { data: portfolio } = await this.getPortfolio({ - data: { - id: item, - }, - }); - portfolios.push({ - label: portfolio.name, - value: portfolio.id, - }); - } - return portfolios; + async options({ prevContext: { offset = 0 } }) { + const { data } = await this.filterProjectDetails({ + data: { + properties: [ + { + property: "creationTime", + operation: constants.DATE_OPERATOR.LT.value, + value: utils.getDateAfterToday(), + }, + ], + isAsc: false, + limit: constants.DEFAULT_LIMIT, + offset, + }, + }); + + return { + options: data.map(({ + name: label, + externalId: value, + }) => ({ + label, + value, + })), + context: { + offset: offset + constants.DEFAULT_LIMIT, + }, + }; }, }, priority: { @@ -142,154 +225,209 @@ export default { optional: true, options: constants.PRIORITY_OPTIONS, }, - postType: { + itemId: { + type: "integer", + label: "Item ID", + description: "Id of the item", + useQuery: true, + async options({ + query, prevContext: { offset = 0 }, itemType, + }) { + const properties = [ + { + property: "creationTime", + operation: constants.DATE_OPERATOR.LT.value, + value: utils.getDateAfterToday(), + }, + { + property: "name", + operation: "CONTAINS", + value: query, + }, + ]; + + const { data } = await this.filterItemDetails({ + data: { + properties: properties.filter(({ value }) => value), + isAsc: false, + limit: constants.DEFAULT_LIMIT, + offset, + itemType: [ + itemType, + ], + }, + }); + + return { + options: data.map(({ + name: label, + id: value, + }) => ({ + label, + value, + })), + context: { + offset: offset + constants.DEFAULT_LIMIT, + }, + }; + }, + }, + itemName: { type: "string", - label: "Post Type", - description: "Type of comment", - options: constants.POST_TYPES, + label: "Name", + description: "Name of the item", + }, + itemDescription: { + type: "string", + label: "Description", + description: "Description of the item", + optional: true, }, }, methods: { _baseUrl() { - return "https://app.onedesk.com/rest/2.0"; + return "https://app.onedesk.com/rest/public"; }, _authToken() { return this.$auth.oauth_access_token; }, - _buildAuth(method, data, params) { - if (method === "POST") { - return { - data: { - ...data, - authenticationToken: this._authToken(), - }, - }; - } + getHeaders(headers) { return { - params: { - ...params, - token: this._authToken(), - }, + ...headers, + "OD-Public-API-Key": `${this.$auth.api_key}`, }; }, async _makeRequest({ - $ = this, - path, - method = "GET", - data, - params, - ...args - }) { - const config = { + $ = this, path, headers, ...args + } = {}) { + const response = await axios($, { url: `${this._baseUrl()}${path}`, - method, - ...this._buildAuth(method, data, params), - ...args, - }; - return axios($, config); - }, - getItemUpdates(args = {}) { - return this._makeRequest({ - path: "/history/getItemUpdates", - method: "POST", - ...args, - }); - }, - getOrgInfo(args = {}) { - return this._makeRequest({ - path: "/organization/getOrgInfo", + headers: this.getHeaders(headers), ...args, }); + + if (response?.data === null) { + throw new Error(`No data returned from the API ${JSON.stringify(response, null, 2)}`); + } + + if (response?.status === 429) { + throw new Error("API rate limit exceeded"); + } + + return response; }, - getSpace(args = {}) { + post(args = {}) { return this._makeRequest({ - path: "/space/getItemById", method: "POST", ...args, }); }, - getItem(args = {}) { + getContainerTypes(args = {}) { return this._makeRequest({ - path: "/workitem/getItemDetails", + path: "/organization/containerTypes", ...args, }); }, - getPortfolio(args = {}) { + getUserTypes(args = {}) { return this._makeRequest({ - path: "/portfolio/getItemById", - method: "POST", + path: "/organization/userTypes", ...args, }); }, - getItemsByIds(args = {}) { + getItemTypes(args = {}) { return this._makeRequest({ - path: "/workitem/getItems", - method: "POST", + path: "/organization/itemTypes", ...args, }); }, - listTeams(args = {}) { - return this._makeRequest({ - path: "/userteam/get", - method: "POST", + filterPortfolioDetails(args = {}) { + return this.post({ + path: "/portfolios/filter/details", ...args, }); }, - createUser(args = {}) { - return this._makeRequest({ - path: "/user/create", - method: "POST", + filterTeamDetails(args = {}) { + return this.post({ + path: "/teams/filter/details", ...args, }); }, - createItem(args = {}) { - return this._makeRequest({ - path: "/workitem/createWorkItem", - method: "POST", + filterInvoiceDetails(args = {}) { + return this.post({ + path: "/invoices/filter/details", ...args, }); }, - createSpace(args = {}) { - return this._makeRequest({ - path: "/space/create", - method: "POST", + filterProjectDetails(args = {}) { + return this.post({ + path: "/projects/filter/details", ...args, }); }, - createComment(args = {}) { - return this._makeRequest({ - path: "/workitem/createComment", - method: "POST", + filterConversationDetails(args = {}) { + return this.post({ + path: "/conversation-messages/filter/details", ...args, }); }, - searchSpaces(args = {}) { - return this._makeRequest({ - path: "/space/search", - method: "POST", + filterItemDetails(args = {}) { + return this.post({ + path: "/items/filter/details", ...args, }); }, - searchPortfolios(args = {}) { - return this._makeRequest({ - path: "/portfolio/search", - method: "POST", + filterActivityDetails(args = {}) { + return this.post({ + debug: true, + path: "/activities/filter/details", ...args, }); }, - searchItems(args = {}) { - return this._makeRequest({ - path: "/workitem/searchItems", - method: "POST", - ...args, - }); + async *getIterations({ + resourcesFn, resourcesFnArgs, resourceName, + max = constants.DEFAULT_MAX, + }) { + let offset = 0; + let resourcesCount = 0; + + while (true) { + const response = + await resourcesFn({ + ...resourcesFnArgs, + data: { + ...resourcesFnArgs?.data, + limit: constants.DEFAULT_LIMIT, + offset, + }, + }); + + const nextResources = resourceName && response[resourceName] || response; + + if (!nextResources?.length) { + console.log("No more resources found"); + return; + } + + for (const resource of nextResources) { + yield resource; + resourcesCount += 1; + + if (resourcesCount >= max) { + console.log("Reached max resources"); + return; + } + } + + if (nextResources.length < constants.DEFAULT_LIMIT) { + console.log("No next page found"); + return; + } + + offset += constants.DEFAULT_LIMIT; + } }, - updateItem(args = {}) { - return this._makeRequest({ - path: "/workitem/updateWorkItem", - method: "POST", - ...args, - }); + paginate(args = {}) { + return utils.iterate(this.getIterations(args)); }, }, }; diff --git a/components/onedesk/package.json b/components/onedesk/package.json index e54e8bba32810..325bf2f0c3cf4 100644 --- a/components/onedesk/package.json +++ b/components/onedesk/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/onedesk", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream OneDesk Components", "main": "onedesk.app.mjs", "keywords": [ @@ -13,8 +13,6 @@ "access": "public" }, "dependencies": { - "@pipedream/platform": "^1.3.0", - "lodash.pickby": "^4.6.0", - "uuid": "^9.0.0" + "@pipedream/platform": "^3.0.0" } } diff --git a/components/onedesk/sources/common/activity-types.mjs b/components/onedesk/sources/common/activity-types.mjs new file mode 100644 index 0000000000000..49a406a20a556 --- /dev/null +++ b/components/onedesk/sources/common/activity-types.mjs @@ -0,0 +1,85 @@ +// The following are the activity types that are available in OneDesk according to the Support team. +export default { + ADDED_CUSTOMER_REPLY: "added a Customer Reply", + REMOVED_CUSTOMER_REPLY: "removed a Customer Reply", + CHANGED_CUSTOMER_REPLY: "changed a Customer Reply", + REMOVED_CUSTOM_FIELD: "removed the custom field", + PROJECT_ARCHIVED: "project archived", + UPDATE_ORGANIZATION_FINANCIAL: "update organization financial", + ADDED_ATTACHMENT: "added an attachment", + REMOVED_ATTACHMENT: "attachment(s) removed", + ADDED_ASSIGNEE: "added an assignee", + REMOVED_ASSIGNEE: "removed an assignee", + ADDED_TEAM_ASSIGNMENT: "added a team assignment", + REMOVED_TEAM_ASSIGNMENT: "removed a team assignment", + ADDED_LINK_TO_ITEM: "added a link to an item", + REMOVED_LINK_TO_ITEM: "removed a link to an item", + SENT_EMAIL: "sent email", + EMAIL_SENT: "email sent", + LOGGED_IN: "logged in", + LOGGED_OUT: "logged out", + FIRST_NAME_UPDATED: "first name updated", + LAST_NAME_UPDATED: "last name updated", + ADDED_FOLLOWER: "added follower", + REMOVED_FOLLOWER: "removed follower", + CREATED_WORK_ITEM: "created work item", + DELETED_WORK_ITEM: "deleted work item", + CREATED_PROJECT: "created project", + DELETED_PROJECT: "deleted project", + CREATED_PORTFOLIO: "created portfolio", + DELETED_PORTFOLIO: "deleted portfolio", + CREATED_MARKER: "created marker", + DELETED_MARKER: "deleted marker", + USER_JOINED_PROJECT: "user joined project", + USER_LEFT_PROJECT: "user left project", + CREATED_USER: "created user", + DEACTIVATED_USER: "deactivated user", + REACTIVATED_USER: "reactivated user", + ASSIGNED_TO_SLA: "assigned to SLA", + CHANGED_SLA: "changed the SLA", + ADDED_PROJECT_FOLLOWER: "added project follower", + REMOVED_PROJECT_FOLLOWER: "removed project follower", + CREATE_INVOICE: "create invoice", + UPDATE_INVOICE: "update invoice", + NUMBER_OF_USER_LICENSES_UPDATED: "number of user licenses updated", + COMPLETE_UPDATED: "complete updated", + ACTUAL_COST_UPDATED: "actual cost updated", + ACTUAL_FINISH_DATE_UPDATED: "actual finish date updated", + ACTUAL_START_DATE_UPDATED: "actual start date updated", + // This was given by OneDesk Support team however it returns 500 when used so the correct + // one right now is `changed the actual work` + // ACTUAL_WORK_UPDATED: "actual work updated", + ACTUAL_WORK_UPDATED: "changed the actual work", + ADDED_INTERNAL_MESSAGE: "added a Internal message", + AGILE_POINTS_CAPACITY_UPDATED: "agile points capacity updated", + AGILE_POINTS_UPDATED: "agile points updated", + CHANGED_INTERNAL_MESSAGE: "changed a Internal message", + CUSTOM_FIELD_UPDATED: "custom field updated", + DELETED_USER: "deleted user", + DESCRIPTION_UPDATED: "description updated", + ESTIMATION_TYPE_UPDATED: "estimation type updated", + LIFECYCLE_STATUS_UPDATED: "lifecycle status updated", + NAME_UPDATED: "name updated", + ONE_TIME_ACCESS_GRANTED: "one-time access granted", + ONE_TIME_ACCESS_REVOKED: "one-time access revoked", + PLANNED_CONSTRAINT_DATE_UPDATED: "planned constraint date updated", + PLANNED_CONSTRAINT_TYPE_UPDATED: "planned constraint type updated", + PLANNED_COST_UPDATED: "planned cost updated", + PLANNED_DURATION_AMOUNT_UPDATED: "planned duration amount updated", + PLANNED_DURATION_UNIT_UPDATED: "planned duration unit updated", + PLANNED_ESTIMATED_REVENUE_UPDATED: "planned estimated revenue updated", + PLANNED_FINISH_DATE_UPDATED: "planned finish date updated", + PLANNED_START_DATE_UPDATED: "planned start date updated", + PLANNED_WORK_AMOUNT_UPDATED: "planned work amount updated", + PLANNED_WORK_UNIT_UPDATED: "planned work unit updated", + PRIORITY_UPDATED: "priority updated", + PROJECT_PLANNED_START_DATE_UPDATED: "project planned start date updated", + PROJECT_PRIVACY_UPDATED: "project privacy updated", + PROJECT_UPDATED: "project updated", + PUBLISHED_STATE_UPDATED: "published state updated", + REMOVED_INTERNAL_MESSAGE: "removed a Internal message", + SCHEDULED_FOR_DELETION: "scheduled for deletion", + SUPPORT_TEAM_LOGGED_IN: "support team logged in", + TYPE_UPDATED: "type updated", + UPDATED_REMAINING_PREPAID_HOURS: "updated remaining prepaid hours", +}; diff --git a/components/onedesk/sources/common/common.mjs b/components/onedesk/sources/common/common.mjs deleted file mode 100644 index 42110a5ab9cd5..0000000000000 --- a/components/onedesk/sources/common/common.mjs +++ /dev/null @@ -1,52 +0,0 @@ -import onedesk from "../../onedesk.app.mjs"; -import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; -import { v4 as uuidv4 } from "uuid"; - -export default { - props: { - onedesk, - db: "$.service.db", - timer: { - type: "$.interface.timer", - default: { - intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, - }, - }, - }, - hooks: { - async deploy() { - await this.resetApplicationId(); - }, - }, - methods: { - getApplicationId() { - return this.db.get("applicationId"); - }, - setApplicationId(applicationId) { - this.db.set("applicationId", applicationId); - }, - async resetApplicationId() { - const applicationId = uuidv4(); - await this.getUpdates(applicationId); - this.setApplicationId(applicationId); - }, - getUpdates() { - throw new Error("getUpdates is not implemented"); - }, - generateMeta() { - throw new Error("generateMeta is not implemented"); - }, - }, - async run() { - const applicationId = this.getApplicationId(); - - const results = await this.getUpdates(applicationId); - - await this.resetApplicationId(); - - for (const result of results) { - const meta = this.generateMeta(result); - this.$emit(result, meta); - } - }, -}; diff --git a/components/onedesk/sources/common/polling.mjs b/components/onedesk/sources/common/polling.mjs new file mode 100644 index 0000000000000..31a25e615494e --- /dev/null +++ b/components/onedesk/sources/common/polling.mjs @@ -0,0 +1,104 @@ +import { + DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + ConfigurationError, +} from "@pipedream/platform"; +import app from "../../onedesk.app.mjs"; +import constants from "../../common/constants.mjs"; +import utils from "../../common/utils.mjs"; + +export default { + props: { + app, + db: "$.service.db", + timer: { + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + }, + methods: { + setLastCreationDate(value) { + this.db.set(constants.LAST_CREATION_DATE, value); + }, + getLastCreationDate() { + return this.db.get(constants.LAST_CREATION_DATE); + }, + getActivityTypeProperties() { + throw new ConfigurationError("getActivityTypeProperties is not implemented"); + }, + generateMeta() { + throw new ConfigurationError("generateMeta is not implemented"); + }, + getResourceName() { + return "data"; + }, + getResourcesFn() { + return this.app.filterActivityDetails; + }, + getResourcesFnArgs() { + const lastCreationDate = this.getLastCreationDate(); + + const creationDateFilter = lastCreationDate + ? { + property: "createdDate", + operation: "GE", + value: utils.getDateOnly(lastCreationDate), + } + : { + property: "createdDate", + operation: "LT", + value: utils.getDateAfterToday(), + }; + + return { + data: { + properties: [ + creationDateFilter, + ...this.getActivityTypeProperties(), + ], + isAsc: false, + }, + }; + }, + processResource(resource) { + const meta = this.generateMeta(resource); + this.$emit(resource, meta); + }, + async processResources(resources) { + const { + setLastCreationDate, + processResource, + } = this; + + const [ + lastResource, + ] = resources; + + if (lastResource?.timestamp) { + setLastCreationDate(lastResource.timestamp); + } + + Array.from(resources) + .reverse() + .forEach(processResource); + }, + }, + async run() { + const { + app, + getResourcesFn, + getResourcesFnArgs, + getResourceName, + processResources, + } = this; + + const resources = await app.paginate({ + resourcesFn: getResourcesFn(), + resourcesFnArgs: getResourcesFnArgs(), + resourceName: getResourceName(), + }); + + processResources(resources); + }, +}; diff --git a/components/onedesk/sources/new-item-created/new-item-created.mjs b/components/onedesk/sources/new-item-created/new-item-created.mjs index 1b6db28366577..add5c8f359500 100644 --- a/components/onedesk/sources/new-item-created/new-item-created.mjs +++ b/components/onedesk/sources/new-item-created/new-item-created.mjs @@ -1,35 +1,33 @@ -import common from "../common/common.mjs"; +import common from "../common/polling.mjs"; +import activityTypes from "../common/activity-types.mjs"; +import sampleEmit from "./test-event.mjs"; export default { ...common, key: "onedesk-new-item-created", name: "New Item Created", - description: "Emit new event when a new item is created. [See the docs](https://www.onedesk.com/developers/#_get_item_updates)", - version: "0.0.1", + description: "Emit new event when a new item is created. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "source", dedupe: "unique", methods: { ...common.methods, - async getUpdates(applicationId) { - const { data } = await this.onedesk.getItemUpdates({ - data: { - applicationId, - itemTypes: [ - "ProjectTask", - ], - operations: [ - "CREATE", - ], + getActivityTypeProperties() { + return [ + { + property: "types", + operation: "EQ", + value: activityTypes.CREATED_WORK_ITEM, }, - }); - return data; + ]; }, - generateMeta(item) { + generateMeta(resource) { return { - id: item.itemId, - summary: item.itemName || `New Item ID ${item.itemId}`, - ts: Date.parse(item.collectedTimestamp), + id: resource.itemExternalId, + summary: `New Item Created: ${resource.itemName || resource.itemExternalId}`, + ts: Date.parse(resource.timestamp), }; }, }, + sampleEmit, }; diff --git a/components/onedesk/sources/new-item-created/test-event.mjs b/components/onedesk/sources/new-item-created/test-event.mjs new file mode 100644 index 0000000000000..cb1bbb5c3e44a --- /dev/null +++ b/components/onedesk/sources/new-item-created/test-event.mjs @@ -0,0 +1,11 @@ +export default { + "projectExternalId": "91d899c0-e3c4-46c3-9cc2-97b6ea2a708b", + "authorExternalId": "d5ef5e78-a82b-477f-be9c-a17b04283648", + "itemExternalId": "26ecb43a-69b1-4550-962f-616bbdc5476c", + "activityType": "created work item", + "automationTypeName": null, + "timestamp": "2024-06-12T22:20:06.598+00:00", + "itemType": "Item", + "itemName": null, + "newValue": null +} diff --git a/components/onedesk/sources/new-item-updated/new-item-updated.mjs b/components/onedesk/sources/new-item-updated/new-item-updated.mjs deleted file mode 100644 index 2afa94c7caa9f..0000000000000 --- a/components/onedesk/sources/new-item-updated/new-item-updated.mjs +++ /dev/null @@ -1,35 +0,0 @@ -import common from "../common/common.mjs"; - -export default { - ...common, - key: "onedesk-new-item-updated", - name: "New Item Updated", - description: "Emit new event when an item is updated. [See the docs](https://www.onedesk.com/developers/#_get_item_updates)", - version: "0.0.1", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - async getUpdates(applicationId) { - const { data } = await this.onedesk.getItemUpdates({ - data: { - applicationId, - itemTypes: [ - "ProjectTask", - ], - operations: [ - "PROPERTY_UPDATE", - ], - }, - }); - return data; - }, - generateMeta(item) { - return { - id: item.itemId, - summary: item.itemName || `New Item ID ${item.itemId}`, - ts: Date.parse(item.collectedTimestamp), - }; - }, - }, -}; diff --git a/components/onedesk/sources/new-project-created/new-project-created.mjs b/components/onedesk/sources/new-project-created/new-project-created.mjs index 29d818f5c6fc5..ec5493dad0f74 100644 --- a/components/onedesk/sources/new-project-created/new-project-created.mjs +++ b/components/onedesk/sources/new-project-created/new-project-created.mjs @@ -1,35 +1,33 @@ -import common from "../common/common.mjs"; +import common from "../common/polling.mjs"; +import activityTypes from "../common/activity-types.mjs"; +import sampleEmit from "./test-event.mjs"; export default { ...common, key: "onedesk-new-project-created", name: "New Project Created", - description: "Emit new event when a new project is created. [See the docs](https://www.onedesk.com/developers/#_get_item_updates)", - version: "0.0.1", + description: "Emit new event when a new project is created. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "source", dedupe: "unique", methods: { ...common.methods, - async getUpdates(applicationId) { - const { data } = await this.onedesk.getItemUpdates({ - data: { - applicationId, - itemTypes: [ - "ProjectVariables", - ], - operations: [ - "CREATE", - ], + getActivityTypeProperties() { + return [ + { + property: "types", + operation: "EQ", + value: activityTypes.CREATED_PROJECT, }, - }); - return data; + ]; }, - generateMeta(project) { + generateMeta(resource) { return { - id: project.itemId, - summary: project.itemName, - ts: Date.parse(project.collectedTimestamp), + id: resource.itemExternalId, + summary: `New Project Created: ${resource.itemName}`, + ts: Date.parse(resource.timestamp), }; }, }, + sampleEmit, }; diff --git a/components/onedesk/sources/new-project-created/test-event.mjs b/components/onedesk/sources/new-project-created/test-event.mjs new file mode 100644 index 0000000000000..7e5928602e7c1 --- /dev/null +++ b/components/onedesk/sources/new-project-created/test-event.mjs @@ -0,0 +1,11 @@ +export default { + "projectExternalId": "99f6ea5e-da59-48c1-8a61-15cde4a11cf3", + "authorExternalId": "d5ef5e78-a82b-477f-be9c-a17b04283648", + "itemExternalId": "99f6ea5e-da59-48c1-8a61-15cde4a11cf3", + "activityType": "created project", + "automationTypeName": null, + "timestamp": "2024-06-12T20:43:10.770+00:00", + "itemType": "Project", + "itemName": "Test 100", + "newValue": null +} diff --git a/components/onedesk/sources/new-project-updated/new-project-updated.mjs b/components/onedesk/sources/new-project-updated/new-project-updated.mjs deleted file mode 100644 index 074083a0b0e6a..0000000000000 --- a/components/onedesk/sources/new-project-updated/new-project-updated.mjs +++ /dev/null @@ -1,36 +0,0 @@ -import common from "../common/common.mjs"; - -export default { - ...common, - key: "onedesk-new-project-updated", - name: "New Project Updated", - description: "Emit new event when a project is updated. [See the docs](https://www.onedesk.com/developers/#_get_item_updates)", - version: "0.0.1", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - async getUpdates(applicationId) { - const { data } = await this.onedesk.getItemUpdates({ - data: { - applicationId, - itemTypes: [ - "Space", - ], - operations: [ - "PROPERTY_UPDATE", - ], - }, - }); - return data; - }, - generateMeta(project) { - const ts = Date.parse(project.collectedTimestamp); - return { - id: `${project.itemId}${ts}`, - summary: project.itemName, - ts, - }; - }, - }, -}; diff --git a/components/onedesk/sources/new-public-message-created/new-public-message-created.mjs b/components/onedesk/sources/new-public-message-created/new-public-message-created.mjs deleted file mode 100644 index 81354fe6d4088..0000000000000 --- a/components/onedesk/sources/new-public-message-created/new-public-message-created.mjs +++ /dev/null @@ -1,35 +0,0 @@ -import common from "../common/common.mjs"; - -export default { - ...common, - key: "onedesk-new-public-message-created", - name: "New Public Message Created", - description: "Emit new event when a new public message is created. [See the docs](https://www.onedesk.com/developers/#_get_item_updates)", - version: "0.0.1", - type: "source", - dedupe: "unique", - methods: { - ...common.methods, - async getUpdates(applicationId) { - const { data } = await this.onedesk.getItemUpdates({ - data: { - applicationId, - itemTypes: [ - "ConversationMessageActivity", - ], - operations: [ - "CREATE", - ], - }, - }); - return data; - }, - generateMeta(item) { - return { - id: item.itemId, - summary: `New Message Activity ID ${item.itemId}`, - ts: Date.parse(item.collectedTimestamp), - }; - }, - }, -}; diff --git a/components/onedesk/sources/new-timesheet-created/new-timesheet-created.mjs b/components/onedesk/sources/new-timesheet-created/new-timesheet-created.mjs index 78fc22b66d2f9..abdf902fa2819 100644 --- a/components/onedesk/sources/new-timesheet-created/new-timesheet-created.mjs +++ b/components/onedesk/sources/new-timesheet-created/new-timesheet-created.mjs @@ -1,35 +1,34 @@ -import common from "../common/common.mjs"; +import common from "../common/polling.mjs"; +import activityTypes from "../common/activity-types.mjs"; +import sampleEmit from "./test-event.mjs"; export default { ...common, key: "onedesk-new-timesheet-created", name: "New Timesheet Created", - description: "Emit new event when a new timesheet is created. [See the docs](https://www.onedesk.com/developers/#_get_item_updates)", - version: "0.0.1", + description: "Emit new event when a new timesheet is created. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "source", dedupe: "unique", methods: { ...common.methods, - async getUpdates(applicationId) { - const { data } = await this.onedesk.getItemUpdates({ - data: { - applicationId, - itemTypes: [ - "ProjectTaskTimesheet", - ], - operations: [ - "CREATE", - ], + getActivityTypeProperties() { + return [ + { + property: "types", + operation: "EQ", + value: activityTypes.ACTUAL_WORK_UPDATED, }, - }); - return data; + ]; }, - generateMeta(item) { + generateMeta(resource) { + const ts = Date.parse(resource.timestamp); return { - id: item.itemId, - summary: `New Timesheet ID ${item.itemId}`, - ts: Date.parse(item.collectedTimestamp), + id: `${resource.itemExternalId}-${ts}`, + summary: `New Timesheet: ${resource.itemName || resource.itemExternalId}`, + ts, }; }, }, + sampleEmit, }; diff --git a/components/onedesk/sources/new-timesheet-created/test-event.mjs b/components/onedesk/sources/new-timesheet-created/test-event.mjs new file mode 100644 index 0000000000000..2664e0b4d32fc --- /dev/null +++ b/components/onedesk/sources/new-timesheet-created/test-event.mjs @@ -0,0 +1,11 @@ +export default { + "projectExternalId": "91d899c0-e3c4-46c3-9cc2-97b6ea2a708b", + "authorExternalId": "471cb72b-c56a-4413-8a51-abb2ffac0a2f", + "itemExternalId": "20bf477b-5aa4-45aa-b08d-e403e17c4c75", + "activityType": "changed the actual work", + "automationTypeName": null, + "timestamp": "2024-06-17T15:43:27.201+00:00", + "itemType": "Item", + "itemName": "Sample TICKET in Project", + "newValue": null +}; diff --git a/components/onedesk/sources/new-user-created/new-user-created.mjs b/components/onedesk/sources/new-user-created/new-user-created.mjs index ef3464de0618d..e4b0a4e692e9d 100644 --- a/components/onedesk/sources/new-user-created/new-user-created.mjs +++ b/components/onedesk/sources/new-user-created/new-user-created.mjs @@ -1,35 +1,33 @@ -import common from "../common/common.mjs"; +import common from "../common/polling.mjs"; +import activityTypes from "../common/activity-types.mjs"; +import sampleEmit from "./test-event.mjs"; export default { ...common, key: "onedesk-new-user-created", name: "New User Created", - description: "Emit new event when a new user is created. [See the docs](https://www.onedesk.com/developers/#_get_item_updates)", - version: "0.0.1", + description: "Emit new event when a new user is created. [See the documentation](https://www.onedesk.com/dev/).", + version: "0.0.2", type: "source", dedupe: "unique", methods: { ...common.methods, - async getUpdates(applicationId) { - const { data } = await this.onedesk.getItemUpdates({ - data: { - applicationId, - itemTypes: [ - "User", - ], - operations: [ - "CREATE", - ], + getActivityTypeProperties() { + return [ + { + property: "types", + operation: "EQ", + value: activityTypes.CREATED_USER, }, - }); - return data; + ]; }, - generateMeta(item) { + generateMeta(resource) { return { - id: item.itemId, - summary: item.itemName, - ts: Date.parse(item.collectedTimestamp), + id: resource.itemExternalId, + summary: `New User Created: ${resource.itemName}`, + ts: Date.parse(resource.timestamp), }; }, }, + sampleEmit, }; diff --git a/components/onedesk/sources/new-user-created/test-event.mjs b/components/onedesk/sources/new-user-created/test-event.mjs new file mode 100644 index 0000000000000..f5f69421ba1a6 --- /dev/null +++ b/components/onedesk/sources/new-user-created/test-event.mjs @@ -0,0 +1,11 @@ +export default { + "projectExternalId": null, + "authorExternalId": "d5ef5e78-a82b-477f-be9c-a17b04283648", + "itemExternalId": "0fd310cb-2eda-4a22-899a-2830990fabfc", + "activityType": "created user", + "automationTypeName": null, + "timestamp": "2024-06-12T20:45:19.623+00:00", + "itemType": "User", + "itemName": "Test 10 Test 10", + "newValue": null +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11f87f863f3cc..86d6b0bf5237f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5970,13 +5970,9 @@ importers: components/onedesk: specifiers: - '@pipedream/platform': ^1.3.0 - lodash.pickby: ^4.6.0 - uuid: ^9.0.0 + '@pipedream/platform': ^3.0.0 dependencies: - '@pipedream/platform': 1.5.1 - lodash.pickby: 4.6.0 - uuid: 9.0.1 + '@pipedream/platform': 3.0.0 components/onenote: specifiers: