Skip to content

Commit cd4ae8b

Browse files
committed
fix(pipedrive): move activity writes and pipeline listing to API v2, send lead visible_to as a string, guard path ids
1 parent 9c70bf9 commit cd4ae8b

14 files changed

Lines changed: 71 additions & 39 deletions

‎apps/sim/blocks/blocks/pipedrive.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
399399
placeholder: 'Pagination cursor from previous response',
400400
condition: {
401401
field: 'operation',
402-
value: ['get_all_deals', 'get_projects'],
402+
value: ['get_all_deals', 'get_projects', 'get_pipelines'],
403403
},
404404
},
405405
{
@@ -415,7 +415,6 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
415415
'get_files',
416416
'get_pipeline_deals',
417417
'get_mail_messages',
418-
'get_pipelines',
419418
],
420419
},
421420
},
@@ -448,6 +447,7 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
448447
{ label: 'All', id: '' },
449448
{ label: 'Open', id: 'open' },
450449
{ label: 'Completed', id: 'completed' },
450+
{ label: 'Canceled', id: 'canceled' },
451451
],
452452
value: () => '',
453453
condition: { field: 'operation', value: ['get_projects'] },

‎apps/sim/tools/pipedrive/create_activity.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export const pipedriveCreateActivityTool: ToolConfig<
7676
type: 'string',
7777
required: false,
7878
visibility: 'user-or-llm',
79-
description: 'ID of the person to associate with (e.g., "456")',
79+
description: 'ID of the person to associate with as the primary participant (e.g., "456")',
8080
},
8181
org_id: {
8282
type: 'string',
@@ -93,7 +93,7 @@ export const pipedriveCreateActivityTool: ToolConfig<
9393
},
9494

9595
request: {
96-
url: () => 'https://api.pipedrive.com/v1/activities',
96+
url: () => 'https://api.pipedrive.com/api/v2/activities',
9797
method: 'POST',
9898
headers: (params) => ({
9999
...getPipedriveAuthHeaders(params),
@@ -109,7 +109,9 @@ export const pipedriveCreateActivityTool: ToolConfig<
109109
if (params.due_time) body.due_time = params.due_time
110110
if (params.duration) body.duration = params.duration
111111
if (params.deal_id) body.deal_id = Number(params.deal_id)
112-
if (params.person_id) body.person_id = Number(params.person_id)
112+
if (params.person_id) {
113+
body.participants = [{ person_id: Number(params.person_id), primary: true }]
114+
}
113115
if (params.org_id) body.org_id = Number(params.org_id)
114116
if (params.note) body.note = params.note
115117

‎apps/sim/tools/pipedrive/create_lead.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ export const pipedriveCreateLeadTool: ToolConfig<
8282
type: 'string',
8383
required: false,
8484
visibility: 'user-or-llm',
85-
description: 'Visibility: 1 (Owner & followers), 3 (Entire company)',
85+
description:
86+
"Visibility group: 1 (owner only / owner & followers), 3 (owner's visibility group / entire company), 5 (owner's group and sub-groups), 7 (entire company); 5 and 7 are Premium/Ultimate only",
8687
},
8788
},
8889

@@ -115,7 +116,7 @@ export const pipedriveCreateLeadTool: ToolConfig<
115116
}
116117

117118
if (params.expected_close_date) body.expected_close_date = params.expected_close_date
118-
if (params.visible_to) body.visible_to = Number(params.visible_to)
119+
if (params.visible_to) body.visible_to = String(params.visible_to)
119120

120121
return body
121122
},

‎apps/sim/tools/pipedrive/delete_lead.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
} from '@/tools/pipedrive/types'
66
import { getPipedriveAuthHeaders } from '@/tools/pipedrive/utils'
77
import type { ToolConfig } from '@/tools/types'
8+
import { safeUrlPathSegment } from '@/tools/url-path'
89

910
const logger = createLogger('PipedriveDeleteLead')
1011

@@ -45,7 +46,8 @@ export const pipedriveDeleteLeadTool: ToolConfig<
4546
},
4647

4748
request: {
48-
url: (params) => `https://api.pipedrive.com/v1/leads/${params.lead_id}`,
49+
url: (params) =>
50+
`https://api.pipedrive.com/v1/leads/${safeUrlPathSegment(params.lead_id, 'lead_id')}`,
4951
method: 'DELETE',
5052
headers: (params) => getPipedriveAuthHeaders(params),
5153
},

‎apps/sim/tools/pipedrive/get_deal.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createLogger } from '@sim/logger'
22
import type { PipedriveGetDealParams, PipedriveGetDealResponse } from '@/tools/pipedrive/types'
33
import { getPipedriveAuthHeaders } from '@/tools/pipedrive/utils'
44
import type { ToolConfig } from '@/tools/types'
5+
import { safeUrlPathSegment } from '@/tools/url-path'
56

67
const logger = createLogger('PipedriveGetDeal')
78

@@ -39,7 +40,8 @@ export const pipedriveGetDealTool: ToolConfig<PipedriveGetDealParams, PipedriveG
3940
},
4041

4142
request: {
42-
url: (params) => `https://api.pipedrive.com/api/v2/deals/${params.deal_id}`,
43+
url: (params) =>
44+
`https://api.pipedrive.com/api/v2/deals/${safeUrlPathSegment(params.deal_id, 'deal_id')}`,
4345
method: 'GET',
4446
headers: (params) => getPipedriveAuthHeaders(params),
4547
},

‎apps/sim/tools/pipedrive/get_leads.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { PipedriveGetLeadsParams, PipedriveGetLeadsResponse } from '@/tools
33
import { PIPEDRIVE_LEAD_OUTPUT_PROPERTIES } from '@/tools/pipedrive/types'
44
import { getPipedriveAuthHeaders } from '@/tools/pipedrive/utils'
55
import type { ToolConfig } from '@/tools/types'
6+
import { safeUrlPathSegment } from '@/tools/url-path'
67

78
const logger = createLogger('PipedriveGetLeads')
89

@@ -80,7 +81,7 @@ export const pipedriveGetLeadsTool: ToolConfig<PipedriveGetLeadsParams, Pipedriv
8081
url: (params) => {
8182
// If lead_id is provided, get specific lead
8283
if (params.lead_id) {
83-
return `https://api.pipedrive.com/v1/leads/${params.lead_id}`
84+
return `https://api.pipedrive.com/v1/leads/${safeUrlPathSegment(params.lead_id, 'lead_id')}`
8485
}
8586

8687
// Get archived or active leads with optional filters

‎apps/sim/tools/pipedrive/get_mail_thread.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
} from '@/tools/pipedrive/types'
66
import { getPipedriveAuthHeaders } from '@/tools/pipedrive/utils'
77
import type { ToolConfig } from '@/tools/types'
8+
import { safeUrlPathSegment } from '@/tools/url-path'
89

910
const logger = createLogger('PipedriveGetMailThread')
1011

@@ -46,7 +47,7 @@ export const pipedriveGetMailThreadTool: ToolConfig<
4647

4748
request: {
4849
url: (params) =>
49-
`https://api.pipedrive.com/v1/mailbox/mailThreads/${params.thread_id}/mailMessages`,
50+
`https://api.pipedrive.com/v1/mailbox/mailThreads/${safeUrlPathSegment(params.thread_id, 'thread_id')}/mailMessages`,
5051
method: 'GET',
5152
headers: (params) => getPipedriveAuthHeaders(params),
5253
},

‎apps/sim/tools/pipedrive/get_pipeline_deals.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
} from '@/tools/pipedrive/types'
66
import { getPipedriveAuthHeaders } from '@/tools/pipedrive/utils'
77
import type { ToolConfig } from '@/tools/types'
8+
import { safeUrlPathSegment } from '@/tools/url-path'
89

910
const logger = createLogger('PipedriveGetPipelineDeals')
1011

@@ -64,7 +65,7 @@ export const pipedriveGetPipelineDealsTool: ToolConfig<
6465

6566
request: {
6667
url: (params) => {
67-
const baseUrl = `https://api.pipedrive.com/v1/pipelines/${params.pipeline_id}/deals`
68+
const baseUrl = `https://api.pipedrive.com/v1/pipelines/${safeUrlPathSegment(params.pipeline_id, 'pipeline_id')}/deals`
6869
const queryParams = new URLSearchParams()
6970

7071
if (params.stage_id) queryParams.append('stage_id', params.stage_id)

‎apps/sim/tools/pipedrive/get_pipelines.ts‎

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,28 @@ export const pipedriveGetPipelinesTool: ToolConfig<
5656
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
5757
},
5858
start: {
59+
type: 'string',
60+
required: false,
61+
visibility: 'user-only',
62+
description: 'Ignored: Pipedrive API v2 pages pipelines with cursor instead of an offset',
63+
},
64+
cursor: {
5965
type: 'string',
6066
required: false,
6167
visibility: 'user-or-llm',
62-
description: 'Pagination start offset (0-based index of the first item to return)',
68+
description: 'For pagination, the marker representing the first item on the next page',
6369
},
6470
},
6571

6672
request: {
6773
url: (params) => {
68-
const baseUrl = 'https://api.pipedrive.com/v1/pipelines'
74+
const baseUrl = 'https://api.pipedrive.com/api/v2/pipelines'
6975
const queryParams = new URLSearchParams()
7076

7177
if (params.sort_by) queryParams.append('sort_by', params.sort_by)
7278
if (params.sort_direction) queryParams.append('sort_direction', params.sort_direction)
7379
if (params.limit) queryParams.append('limit', params.limit)
74-
if (params.start) queryParams.append('start', params.start)
80+
if (params.cursor) queryParams.append('cursor', params.cursor)
7581

7682
const queryString = queryParams.toString()
7783
return queryString ? `${baseUrl}?${queryString}` : baseUrl
@@ -89,16 +95,16 @@ export const pipedriveGetPipelinesTool: ToolConfig<
8995
}
9096

9197
const pipelines = data.data || []
92-
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
93-
const nextStart = data.additional_data?.pagination?.next_start ?? null
98+
const nextCursor = data.additional_data?.next_cursor ?? null
9499

95100
return {
96101
success: true,
97102
output: {
98103
pipelines,
99104
total_items: pipelines.length,
100-
has_more: hasMore,
101-
next_start: nextStart,
105+
has_more: nextCursor !== null,
106+
next_start: null,
107+
next_cursor: nextCursor,
102108
success: true,
103109
},
104110
}
@@ -121,7 +127,12 @@ export const pipedriveGetPipelinesTool: ToolConfig<
121127
},
122128
next_start: {
123129
type: 'number',
124-
description: 'Offset for fetching the next page',
130+
description: 'Always null: API v2 pages with next_cursor instead of an offset',
131+
optional: true,
132+
},
133+
next_cursor: {
134+
type: 'string',
135+
description: 'Cursor for fetching the next page',
125136
optional: true,
126137
},
127138
success: { type: 'boolean', description: 'Operation success status' },

‎apps/sim/tools/pipedrive/get_projects.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
} from '@/tools/pipedrive/types'
66
import { getPipedriveAuthHeaders } from '@/tools/pipedrive/utils'
77
import type { ToolConfig } from '@/tools/types'
8+
import { safeUrlPathSegment } from '@/tools/url-path'
89

910
const logger = createLogger('PipedriveGetProjects')
1011

@@ -46,7 +47,8 @@ export const pipedriveGetProjectsTool: ToolConfig<
4647
type: 'string',
4748
required: false,
4849
visibility: 'user-or-llm',
49-
description: 'Filter by project status: open, completed, deleted (only for listing all)',
50+
description:
51+
'Filter by project status: open, completed, canceled, deleted (only for listing all)',
5052
},
5153
limit: {
5254
type: 'string',
@@ -67,7 +69,7 @@ export const pipedriveGetProjectsTool: ToolConfig<
6769
url: (params) => {
6870
// If project_id is provided, get specific project
6971
if (params.project_id) {
70-
return `https://api.pipedrive.com/v1/projects/${params.project_id}`
72+
return `https://api.pipedrive.com/v1/projects/${safeUrlPathSegment(params.project_id, 'project_id')}`
7173
}
7274

7375
// Otherwise, get all projects with optional filters

0 commit comments

Comments
 (0)