From 312f1c785d8557869868c159ec224b4b4ce1883c Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Mon, 9 Jun 2025 14:00:54 -0400 Subject: [PATCH 1/7] new actions --- .../actions/add-activity/add-activity.mjs | 2 +- .../pipedrive/actions/add-deal/add-deal.mjs | 2 +- .../pipedrive/actions/add-lead/add-lead.mjs | 2 +- .../pipedrive/actions/add-note/add-note.mjs | 2 +- .../add-organization/add-organization.mjs | 2 +- .../actions/add-person/add-person.mjs | 2 +- .../remove-duplicate-notes.mjs | 145 ++++++++++++++ .../actions/search-notes/search-notes.mjs | 179 ++++++++++++++++++ .../actions/search-persons/search-persons.mjs | 2 +- .../actions/update-deal/update-deal.mjs | 2 +- .../actions/update-person/update-person.mjs | 2 +- components/pipedrive/package.json | 2 +- components/pipedrive/pipedrive.app.mjs | 44 +++++ .../new-deal-instant/new-deal-instant.mjs | 2 +- .../new-person-instant/new-person-instant.mjs | 2 +- .../updated-deal-instant.mjs | 2 +- .../updated-person-instant.mjs | 2 +- 17 files changed, 382 insertions(+), 14 deletions(-) create mode 100644 components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs create mode 100644 components/pipedrive/actions/search-notes/search-notes.mjs diff --git a/components/pipedrive/actions/add-activity/add-activity.mjs b/components/pipedrive/actions/add-activity/add-activity.mjs index d38b160d1c405..2c96278c47155 100644 --- a/components/pipedrive/actions/add-activity/add-activity.mjs +++ b/components/pipedrive/actions/add-activity/add-activity.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-add-activity", name: "Add Activity", description: "Adds a new activity. Includes `more_activities_scheduled_in_context` property in response's `additional_data` which indicates whether there are more undone activities scheduled with the same deal, person or organization (depending on the supplied data). See the Pipedrive API docs for Activities [here](https://developers.pipedrive.com/docs/api/v1/#!/Activities). For info on [adding an activity in Pipedrive](https://developers.pipedrive.com/docs/api/v1/Activities#addActivity)", - version: "0.1.9", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-deal/add-deal.mjs b/components/pipedrive/actions/add-deal/add-deal.mjs index f7bee4947d332..fe13f92baa689 100644 --- a/components/pipedrive/actions/add-deal/add-deal.mjs +++ b/components/pipedrive/actions/add-deal/add-deal.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-deal", name: "Add Deal", description: "Adds a new deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#addDeal)", - version: "0.1.9", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-lead/add-lead.mjs b/components/pipedrive/actions/add-lead/add-lead.mjs index fc2c15086c0b1..850ed90947eee 100644 --- a/components/pipedrive/actions/add-lead/add-lead.mjs +++ b/components/pipedrive/actions/add-lead/add-lead.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-add-lead", name: "Add Lead", description: "Create a new lead in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Leads#addLead)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { pipedrive, diff --git a/components/pipedrive/actions/add-note/add-note.mjs b/components/pipedrive/actions/add-note/add-note.mjs index bf14955954144..2f33e6e7384d3 100644 --- a/components/pipedrive/actions/add-note/add-note.mjs +++ b/components/pipedrive/actions/add-note/add-note.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-note", name: "Add Note", description: "Adds a new note. For info on [adding an note in Pipedrive](https://developers.pipedrive.com/docs/api/v1/Notes#addNote)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-organization/add-organization.mjs b/components/pipedrive/actions/add-organization/add-organization.mjs index 8db9b9f9f9e1e..55d5f0ba5e9f1 100644 --- a/components/pipedrive/actions/add-organization/add-organization.mjs +++ b/components/pipedrive/actions/add-organization/add-organization.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-add-organization", name: "Add Organization", description: "Adds a new organization. See the Pipedrive API docs for Organizations [here](https://developers.pipedrive.com/docs/api/v1/Organizations#addOrganization)", - version: "0.1.9", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/add-person/add-person.mjs b/components/pipedrive/actions/add-person/add-person.mjs index 2c1b102620aeb..1d3bbc901ee71 100644 --- a/components/pipedrive/actions/add-person/add-person.mjs +++ b/components/pipedrive/actions/add-person/add-person.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-add-person", name: "Add Person", description: "Adds a new person. See the Pipedrive API docs for People [here](https://developers.pipedrive.com/docs/api/v1/Persons#addPerson)", - version: "0.1.9", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs new file mode 100644 index 0000000000000..3bf02889daa3c --- /dev/null +++ b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs @@ -0,0 +1,145 @@ +import pipedriveApp from "../../pipedrive.app.mjs"; + +export default { + key: "pipedrive-remove-duplicate-notes", + name: "Remove Duplicate Notes", + description: "Remove duplicate notes from an object in Pipedrive. See the documentation for [getting notes](https://developers.pipedrive.com/docs/api/v1/Notes#getNotes) and [deleting notes](https://developers.pipedrive.com/docs/api/v1/Notes#deleteNote)", + version: "0.0.1", + type: "action", + props: { + pipedriveApp, + leadId: { + propDefinition: [ + pipedriveApp, + "leadId", + ], + description: "The ID of the lead that the notes are attached to", + }, + dealId: { + propDefinition: [ + pipedriveApp, + "dealId", + ], + description: "The ID of the deal that the notes are attached to", + }, + personId: { + propDefinition: [ + pipedriveApp, + "personId", + ], + description: "The ID of the person that the notes are attached to", + }, + organizationId: { + propDefinition: [ + pipedriveApp, + "organizationId", + ], + description: "The ID of the organization that the notes are attached to", + }, + userId: { + propDefinition: [ + pipedriveApp, + "userId", + ], + description: "The ID of the user that the notes are attached to", + }, + projectId: { + propDefinition: [ + pipedriveApp, + "projectId", + ], + description: "The ID of the project that the notes are attached to", + }, + keyword: { + type: "string", + label: "Keyword", + description: "Only remove duplicate notes that contain the specified keyword(s)", + optional: true, + }, + }, + methods: { + getDuplicateNotes(notes) { + const seenContent = new Map(); + const uniqueNotes = []; + const duplicates = []; + + // Sort notes by add_time (ascending) to keep the oldest duplicate + const sortedNotes = notes.sort((a, b) => { + const dateA = new Date(a.add_time); + const dateB = new Date(b.add_time); + return dateA - dateB; + }); + + for (const note of sortedNotes) { + // Normalize content by removing extra whitespace and converting to lowercase + const normalizedContent = note.content?.trim().toLowerCase(); + + if (!normalizedContent) { + // Skip notes with empty content + continue; + } + + if (seenContent.has(normalizedContent)) { + // This is a duplicate + duplicates.push({ + duplicate: note, + original: seenContent.get(normalizedContent), + }); + } else { + // This is the first occurrence + seenContent.set(normalizedContent, note); + uniqueNotes.push(note); + } + } + + return { + uniqueNotes, + duplicates, + duplicateCount: duplicates.length, + }; + }, + }, + async run({ $ }) { + let notes = await this.pipedriveApp.getPaginatedResources({ + fn: this.pipedriveApp.getNotes, + params: { + user_id: this.userId, + lead_id: this.leadId, + deal_id: this.dealId, + person_id: this.personId, + org_id: this.organizationId, + project_id: this.projectId, + }, + }); + + if (this.keyword) { + notes = notes.filter((note) => + note.content.toLowerCase().includes(this.keyword.toLowerCase())); + } + + let result = { + notes, + totalNotes: notes.length, + }; + + const { + uniqueNotes, duplicates, duplicateCount, + } = this.getDuplicateNotes(notes); + + for (const note of duplicates) { + await this.pipedriveApp.deleteNote(note.duplicate.id); + } + + result = { + notes: uniqueNotes, + totalNotes: uniqueNotes.length, + duplicatesFound: duplicateCount, + duplicates: duplicates, + originalCount: notes.length, + }; + + $.export("$summary", `Found ${notes.length} total note(s), removed ${duplicateCount} duplicate(s), returning ${uniqueNotes.length} unique note(s)`); + + return result; + }, +}; diff --git a/components/pipedrive/actions/search-notes/search-notes.mjs b/components/pipedrive/actions/search-notes/search-notes.mjs new file mode 100644 index 0000000000000..d66b7da41c4f5 --- /dev/null +++ b/components/pipedrive/actions/search-notes/search-notes.mjs @@ -0,0 +1,179 @@ +import pipedriveApp from "../../pipedrive.app.mjs"; + +export default { + key: "pipedrive-search-notes", + name: "Search Notes", + description: "Search for notes in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Notes#getNotes)", + version: "0.0.1", + type: "action", + props: { + pipedriveApp, + searchTerm: { + type: "string", + label: "Search Term", + description: "The term to search for in the note content", + optional: true, + }, + leadId: { + propDefinition: [ + pipedriveApp, + "leadId", + ], + description: "The ID of the lead that the note is attached to", + }, + dealId: { + propDefinition: [ + pipedriveApp, + "dealId", + ], + description: "The ID of the deal that the note is attached to", + }, + personId: { + propDefinition: [ + pipedriveApp, + "personId", + ], + description: "The ID of the person that the note is attached to", + }, + organizationId: { + propDefinition: [ + pipedriveApp, + "organizationId", + ], + description: "The ID of the organization that the note is attached to", + }, + userId: { + propDefinition: [ + pipedriveApp, + "userId", + ], + description: "The ID of the user that the note is attached to", + }, + projectId: { + propDefinition: [ + pipedriveApp, + "projectId", + ], + description: "The ID of the project that the note is attached to", + }, + sortField: { + type: "string", + label: "Sort Field", + description: "The field name to sort by", + options: [ + "id", + "user_id", + "deal_id", + "org_id", + "person_id", + "content", + "add_time", + "update_time", + ], + optional: true, + }, + sortDirection: { + type: "string", + label: "Sort Direction", + description: "The direction to sort the results in", + options: [ + "ASC", + "DESC", + ], + default: "DESC", + optional: true, + }, + startDate: { + type: "string", + label: "Start Date", + description: "The date in format of YYYY-MM-DD from which notes to fetch", + optional: true, + }, + endDate: { + type: "string", + label: "End Date", + description: "The date in format of YYYY-MM-DD until which notes to fetch to", + optional: true, + }, + pinnedToLeadFlag: { + type: "boolean", + label: "Pinned to Lead Flag", + description: "If `true`, the results are filtered by note to lead pinning state", + optional: true, + }, + pinnedToDealFlag: { + type: "boolean", + label: "Pinned to Deal Flag", + description: "If `true`, the results are filtered by note to deal pinning state", + optional: true, + }, + pinnedToOrganizationFlag: { + type: "boolean", + label: "Pinned to Organization Flag", + description: "If `true`, the results are filtered by note to organization pinning state", + optional: true, + }, + pinnedToPersonFlag: { + type: "boolean", + label: "Pinned to Person Flag", + description: "If `true`, the results are filtered by note to person pinning state", + optional: true, + }, + pinnedToProjectFlag: { + type: "boolean", + label: "Pinned to Project Flag", + description: "If `true`, the results are filtered by note to project pinning state", + optional: true, + }, + maxResults: { + type: "integer", + label: "Max Results", + description: "The maximum number of results to return", + optional: true, + }, + }, + async run({ $ }) { + let notes = await this.pipedriveApp.getPaginatedResources({ + fn: this.pipedriveApp.getNotes, + params: { + user_id: this.userId, + lead_id: this.leadId, + deal_id: this.dealId, + person_id: this.personId, + org_id: this.organizationId, + project_id: this.projectId, + sort: this.sortField + ? `${this.sortField} ${this.sortDirection}` + : undefined, + pinned_to_lead_flag: this.pinnedToLeadFlag + ? 1 + : 0, + pinned_to_deal_flag: this.pinnedToDealFlag + ? 1 + : 0, + pinned_to_organization_flag: this.pinnedToOrganizationFlag + ? 1 + : 0, + pinned_to_person_flag: this.pinnedToPersonFlag + ? 1 + : 0, + pinned_to_project_flag: this.pinnedToProjectFlag + ? 1 + : 0, + start_date: this.startDate, + end_date: this.endDate, + }, + max: this.maxResults, + }); + + if (this.searchTerm) { + notes = notes.filter((note) => + note.content.toLowerCase().includes(this.searchTerm.toLowerCase())); + } + + $.export("$summary", `Successfully found ${notes.length} note${notes.length === 1 + ? "" + : "s"}`); + return notes; + }, +}; diff --git a/components/pipedrive/actions/search-persons/search-persons.mjs b/components/pipedrive/actions/search-persons/search-persons.mjs index a47ddb53a0108..c1b47f7700785 100644 --- a/components/pipedrive/actions/search-persons/search-persons.mjs +++ b/components/pipedrive/actions/search-persons/search-persons.mjs @@ -7,7 +7,7 @@ export default { key: "pipedrive-search-persons", name: "Search persons", description: "Searches all Persons by `name`, `email`, `phone`, `notes` and/or custom fields. This endpoint is a wrapper of `/v1/itemSearch` with a narrower OAuth scope. Found Persons can be filtered by Organization ID. See the Pipedrive API docs [here](https://developers.pipedrive.com/docs/api/v1/Persons#searchPersons)", - version: "0.1.9", + version: "0.1.10", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/update-deal/update-deal.mjs b/components/pipedrive/actions/update-deal/update-deal.mjs index cbebcbde1b339..e1ef1d03977af 100644 --- a/components/pipedrive/actions/update-deal/update-deal.mjs +++ b/components/pipedrive/actions/update-deal/update-deal.mjs @@ -5,7 +5,7 @@ export default { key: "pipedrive-update-deal", name: "Update Deal", description: "Updates the properties of a deal. See the Pipedrive API docs for Deals [here](https://developers.pipedrive.com/docs/api/v1/Deals#updateDeal)", - version: "0.1.11", + version: "0.1.12", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/actions/update-person/update-person.mjs b/components/pipedrive/actions/update-person/update-person.mjs index 39608512fb703..13f447d3030ce 100644 --- a/components/pipedrive/actions/update-person/update-person.mjs +++ b/components/pipedrive/actions/update-person/update-person.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-update-person", name: "Update Person", description: "Updates an existing person in Pipedrive. [See the documentation](https://developers.pipedrive.com/docs/api/v1/Persons#updatePerson)", - version: "0.0.1", + version: "0.0.2", type: "action", props: { pipedriveApp, diff --git a/components/pipedrive/package.json b/components/pipedrive/package.json index 193b0be48bae4..158b3ae2760f4 100644 --- a/components/pipedrive/package.json +++ b/components/pipedrive/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/pipedrive", - "version": "0.5.1", + "version": "0.6.0", "description": "Pipedream Pipedrive Components", "main": "pipedrive.app.mjs", "keywords": [ diff --git a/components/pipedrive/pipedrive.app.mjs b/components/pipedrive/pipedrive.app.mjs index d90fafbe6f780..bd1c6fc332f81 100644 --- a/components/pipedrive/pipedrive.app.mjs +++ b/components/pipedrive/pipedrive.app.mjs @@ -355,6 +355,10 @@ export default { const leadLabelsApi = this.api("LeadLabelsApi"); return leadLabelsApi.getLeadLabels(opts); }, + getNotes(opts = {}) { + const notesApi = this.api("NotesApi"); + return notesApi.getNotes(opts); + }, addActivity(opts = {}) { const activityApi = this.api("ActivitiesApi", "v2"); return activityApi.addActivity({ @@ -425,5 +429,45 @@ export default { UpdatePersonRequest: opts, }); }, + deleteNote(noteId) { + const notesApi = this.api("NotesApi"); + return notesApi.deleteNote({ + id: noteId, + }); + }, + async *paginate({ + fn, params, max, + }) { + params = { + ...params, + start: 0, + limit: 100, + }; + let hasMore, count = 0;; + do { + const { + data, additional_data: additionalData, + } = await fn(params); + if (!data?.length) { + return; + } + for (const item of data) { + yield item; + if (max && ++count >= max) { + return; + } + } + params.start += params.limit; + hasMore = additionalData.pagination.more_items_in_collection; + } while (hasMore); + }, + async getPaginatedResources(opts) { + const results = []; + const resources = this.paginate(opts); + for await (const resource of resources) { + results.push(resource); + } + return results; + }, }, }; diff --git a/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs b/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs index 437f92de339e1..881bda6ffdd18 100644 --- a/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs +++ b/components/pipedrive/sources/new-deal-instant/new-deal-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-new-deal-instant", name: "New Deal (Instant)", description: "Emit new event when a new deal is created.", - version: "0.0.5", + version: "0.0.6", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/new-person-instant/new-person-instant.mjs b/components/pipedrive/sources/new-person-instant/new-person-instant.mjs index ddbb174757caa..210aac876d859 100644 --- a/components/pipedrive/sources/new-person-instant/new-person-instant.mjs +++ b/components/pipedrive/sources/new-person-instant/new-person-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-new-person-instant", name: "New Person (Instant)", description: "Emit new event when a new person is created.", - version: "0.0.5", + version: "0.0.6", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs b/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs index 89aa2b8eb8bf7..69b221e2e9168 100644 --- a/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs +++ b/components/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-updated-deal-instant", name: "New Deal Update (Instant)", description: "Emit new event when a deal is updated.", - version: "0.0.5", + version: "0.0.6", type: "source", dedupe: "unique", methods: { diff --git a/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs b/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs index 6b808b8d12f63..cb09964ece5a7 100644 --- a/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs +++ b/components/pipedrive/sources/updated-person-instant/updated-person-instant.mjs @@ -6,7 +6,7 @@ export default { key: "pipedrive-updated-person-instant", name: "Updated Person (Instant)", description: "Emit new event when a person is updated.", - version: "0.0.5", + version: "0.0.6", type: "source", dedupe: "unique", methods: { From bbe30b434130140f4e09b7238ff371064c03029e Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Mon, 9 Jun 2025 14:01:31 -0400 Subject: [PATCH 2/7] pnpm-lock.yaml --- pnpm-lock.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 57e31305818d9..a90ad1a79335d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15639,14 +15639,6 @@ importers: specifier: ^6.0.0 version: 6.2.0 - modelcontextprotocol/node_modules2/@modelcontextprotocol/sdk/dist/cjs: {} - - modelcontextprotocol/node_modules2/@modelcontextprotocol/sdk/dist/esm: {} - - modelcontextprotocol/node_modules2/zod-to-json-schema/dist/cjs: {} - - modelcontextprotocol/node_modules2/zod-to-json-schema/dist/esm: {} - packages/ai: dependencies: '@pipedream/sdk': From f23c3b1f290e78d6c24e84a0d9c316ac5488456b Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Mon, 9 Jun 2025 14:14:44 -0400 Subject: [PATCH 3/7] updates --- .../remove-duplicate-notes.mjs | 2 +- .../actions/search-notes/search-notes.mjs | 22 +++++++++---------- components/pipedrive/pipedrive.app.mjs | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs index 3bf02889daa3c..7169279dd3221 100644 --- a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs +++ b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs @@ -114,7 +114,7 @@ export default { if (this.keyword) { notes = notes.filter((note) => - note.content.toLowerCase().includes(this.keyword.toLowerCase())); + note.content?.toLowerCase().includes(this.keyword.toLowerCase())); } let result = { diff --git a/components/pipedrive/actions/search-notes/search-notes.mjs b/components/pipedrive/actions/search-notes/search-notes.mjs index d66b7da41c4f5..9f76f363c3773 100644 --- a/components/pipedrive/actions/search-notes/search-notes.mjs +++ b/components/pipedrive/actions/search-notes/search-notes.mjs @@ -145,21 +145,21 @@ export default { sort: this.sortField ? `${this.sortField} ${this.sortDirection}` : undefined, - pinned_to_lead_flag: this.pinnedToLeadFlag + pinned_to_lead_flag: this.pinnedToLeadFlag === true ? 1 - : 0, - pinned_to_deal_flag: this.pinnedToDealFlag + : undefined, + pinned_to_deal_flag: this.pinnedToDealFlag === true ? 1 - : 0, - pinned_to_organization_flag: this.pinnedToOrganizationFlag + : undefined, + pinned_to_organization_flag: this.pinnedToOrganizationFlag === true ? 1 - : 0, - pinned_to_person_flag: this.pinnedToPersonFlag + : undefined, + pinned_to_person_flag: this.pinnedToPersonFlag === true ? 1 - : 0, - pinned_to_project_flag: this.pinnedToProjectFlag + : undefined, + pinned_to_project_flag: this.pinnedToProjectFlag === true ? 1 - : 0, + : undefined, start_date: this.startDate, end_date: this.endDate, }, @@ -168,7 +168,7 @@ export default { if (this.searchTerm) { notes = notes.filter((note) => - note.content.toLowerCase().includes(this.searchTerm.toLowerCase())); + note.content?.toLowerCase().includes(this.searchTerm.toLowerCase())); } $.export("$summary", `Successfully found ${notes.length} note${notes.length === 1 diff --git a/components/pipedrive/pipedrive.app.mjs b/components/pipedrive/pipedrive.app.mjs index bd1c6fc332f81..8c985902defd0 100644 --- a/components/pipedrive/pipedrive.app.mjs +++ b/components/pipedrive/pipedrive.app.mjs @@ -443,7 +443,7 @@ export default { start: 0, limit: 100, }; - let hasMore, count = 0;; + let hasMore, count = 0; do { const { data, additional_data: additionalData, From cdd06b8d93d3d6bd8409d5e4f72fae8f9eb2d833 Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Wed, 11 Jun 2025 13:11:33 -0400 Subject: [PATCH 4/7] update --- .../remove-duplicate-notes.mjs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs index 7169279dd3221..69496c799d9e8 100644 --- a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs +++ b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs @@ -71,23 +71,19 @@ export default { }); for (const note of sortedNotes) { - // Normalize content by removing extra whitespace and converting to lowercase - const normalizedContent = note.content?.trim().toLowerCase(); - - if (!normalizedContent) { - // Skip notes with empty content + if (!note.content) { continue; } - if (seenContent.has(normalizedContent)) { + if (seenContent.has(note.content)) { // This is a duplicate duplicates.push({ duplicate: note, - original: seenContent.get(normalizedContent), + original: seenContent.get(note.content), }); } else { // This is the first occurrence - seenContent.set(normalizedContent, note); + seenContent.set(note.content, note); uniqueNotes.push(note); } } From 36f6ebb0e2cca82fc8fde403b4e72415267af269 Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Wed, 11 Jun 2025 13:31:18 -0400 Subject: [PATCH 5/7] update --- .../remove-duplicate-notes.mjs | 16 ++++++++++++---- components/pipedrive/package.json | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs index 69496c799d9e8..ec7f0a9edee11 100644 --- a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs +++ b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs @@ -1,4 +1,5 @@ import pipedriveApp from "../../pipedrive.app.mjs"; +import { decode } from "html-entities"; export default { key: "pipedrive-remove-duplicate-notes", @@ -71,19 +72,26 @@ export default { }); for (const note of sortedNotes) { - if (!note.content) { + // Normalize content by removing extra whitespace and converting to lowercase + const decodedContent = decode(note.content || ""); + const normalizedContent = decodedContent?.replace(/^\s*|\s*$/gi, "").trim() + .toLowerCase(); + console.log(normalizedContent); + + if (!normalizedContent) { + // Skip notes with empty content continue; } - if (seenContent.has(note.content)) { + if (seenContent.has(normalizedContent)) { // This is a duplicate duplicates.push({ duplicate: note, - original: seenContent.get(note.content), + original: seenContent.get(normalizedContent), }); } else { // This is the first occurrence - seenContent.set(note.content, note); + seenContent.set(normalizedContent, note); uniqueNotes.push(note); } } diff --git a/components/pipedrive/package.json b/components/pipedrive/package.json index 158b3ae2760f4..79cbd3091f598 100644 --- a/components/pipedrive/package.json +++ b/components/pipedrive/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@pipedream/platform": "^3.0.3", + "html-entities": "^2.6.0", "pipedrive": "^24.1.1" } } From ff566762275d77f8e107b27ed0309b6ea0233350 Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Wed, 11 Jun 2025 13:32:22 -0400 Subject: [PATCH 6/7] pnpm-lock.yaml --- pnpm-lock.yaml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a90ad1a79335d..523e19a1d572d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10030,6 +10030,9 @@ importers: '@pipedream/platform': specifier: ^3.0.3 version: 3.0.3 + html-entities: + specifier: ^2.6.0 + version: 2.6.0 pipedrive: specifier: ^24.1.1 version: 24.1.1 @@ -24601,8 +24604,8 @@ packages: html-entities@1.4.0: resolution: {integrity: sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==} - html-entities@2.5.2: - resolution: {integrity: sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==} + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -34324,7 +34327,7 @@ snapshots: fast-xml-parser: 4.5.0 gaxios: 6.7.1 google-auth-library: 9.15.0 - html-entities: 2.5.2 + html-entities: 2.6.0 mime: 3.0.0 p-limit: 3.1.0 retry-request: 7.0.2 @@ -43004,8 +43007,7 @@ snapshots: html-entities@1.4.0: {} - html-entities@2.5.2: - optional: true + html-entities@2.6.0: {} html-escaper@2.0.2: {} From 52270ef572ca12929707096dfc54a4742843b539 Mon Sep 17 00:00:00 2001 From: Michelle Bergeron Date: Wed, 11 Jun 2025 13:41:44 -0400 Subject: [PATCH 7/7] remove console.log --- .../actions/remove-duplicate-notes/remove-duplicate-notes.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs index ec7f0a9edee11..c8114ffe86ace 100644 --- a/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs +++ b/components/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjs @@ -76,7 +76,6 @@ export default { const decodedContent = decode(note.content || ""); const normalizedContent = decodedContent?.replace(/^\s*|\s*$/gi, "").trim() .toLowerCase(); - console.log(normalizedContent); if (!normalizedContent) { // Skip notes with empty content