chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveCreateActivityParams,
|
||||
PipedriveCreateActivityResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveCreateActivity')
|
||||
|
||||
export const pipedriveCreateActivityTool: ToolConfig<
|
||||
PipedriveCreateActivityParams,
|
||||
PipedriveCreateActivityResponse
|
||||
> = {
|
||||
id: 'pipedrive_create_activity',
|
||||
name: 'Create Activity in Pipedrive',
|
||||
description: 'Create a new activity (task) in Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
subject: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The subject/title of the activity (e.g., "Follow up call with John")',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Activity type: call, meeting, task, deadline, email, lunch',
|
||||
},
|
||||
due_date: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Due date in YYYY-MM-DD format (e.g., "2025-03-15")',
|
||||
},
|
||||
due_time: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Due time in HH:MM format (e.g., "14:30")',
|
||||
},
|
||||
duration: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Duration in HH:MM format (e.g., "01:00" for 1 hour)',
|
||||
},
|
||||
deal_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the deal to associate with (e.g., "123")',
|
||||
},
|
||||
person_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the person to associate with (e.g., "456")',
|
||||
},
|
||||
org_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the organization to associate with (e.g., "789")',
|
||||
},
|
||||
note: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Notes for the activity',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: () => 'https://api.pipedrive.com/v1/activities',
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
},
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
subject: params.subject,
|
||||
type: params.type,
|
||||
due_date: params.due_date,
|
||||
}
|
||||
|
||||
if (params.due_time) body.due_time = params.due_time
|
||||
if (params.duration) body.duration = params.duration
|
||||
if (params.deal_id) body.deal_id = Number(params.deal_id)
|
||||
if (params.person_id) body.person_id = Number(params.person_id)
|
||||
if (params.org_id) body.org_id = Number(params.org_id)
|
||||
if (params.note) body.note = params.note
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to create activity in Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
activity: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
activity: { type: 'object', description: 'The created activity object', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveCreateDealParams,
|
||||
PipedriveCreateDealResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveCreateDeal')
|
||||
|
||||
export const pipedriveCreateDealTool: ToolConfig<
|
||||
PipedriveCreateDealParams,
|
||||
PipedriveCreateDealResponse
|
||||
> = {
|
||||
id: 'pipedrive_create_deal',
|
||||
name: 'Create Deal in Pipedrive',
|
||||
description: 'Create a new deal in Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The title of the deal (e.g., "Enterprise Software License")',
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The monetary value of the deal (e.g., "5000")',
|
||||
},
|
||||
currency: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Currency code (e.g., "USD", "EUR", "GBP")',
|
||||
},
|
||||
person_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the person this deal is associated with (e.g., "456")',
|
||||
},
|
||||
org_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the organization this deal is associated with (e.g., "789")',
|
||||
},
|
||||
pipeline_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the pipeline this deal should be placed in (e.g., "1")',
|
||||
},
|
||||
stage_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the stage this deal should be placed in (e.g., "2")',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Status of the deal: open, won, lost',
|
||||
},
|
||||
expected_close_date: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Expected close date in YYYY-MM-DD format (e.g., "2025-06-30")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: () => 'https://api.pipedrive.com/api/v2/deals',
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
},
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
title: params.title,
|
||||
}
|
||||
|
||||
if (params.value) body.value = Number(params.value)
|
||||
if (params.currency) body.currency = params.currency
|
||||
if (params.person_id) body.person_id = Number(params.person_id)
|
||||
if (params.org_id) body.org_id = Number(params.org_id)
|
||||
if (params.pipeline_id) body.pipeline_id = Number(params.pipeline_id)
|
||||
if (params.stage_id) body.stage_id = Number(params.stage_id)
|
||||
if (params.status) body.status = params.status
|
||||
if (params.expected_close_date) body.expected_close_date = params.expected_close_date
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to create deal in Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
deal: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
deal: { type: 'object', description: 'The created deal object', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveCreateLeadParams,
|
||||
PipedriveCreateLeadResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveCreateLead')
|
||||
|
||||
export const pipedriveCreateLeadTool: ToolConfig<
|
||||
PipedriveCreateLeadParams,
|
||||
PipedriveCreateLeadResponse
|
||||
> = {
|
||||
id: 'pipedrive_create_lead',
|
||||
name: 'Create Lead in Pipedrive',
|
||||
description: 'Create a new lead in Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'pipedrive',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The name of the lead (e.g., "Acme Corp - Website Redesign")',
|
||||
},
|
||||
person_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the person (REQUIRED unless organization_id is provided) (e.g., "456")',
|
||||
},
|
||||
organization_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the organization (REQUIRED unless person_id is provided) (e.g., "789")',
|
||||
},
|
||||
owner_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'ID of the user who will own the lead (e.g., "123")',
|
||||
},
|
||||
value_amount: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Potential value amount (e.g., "10000")',
|
||||
},
|
||||
value_currency: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Currency code (e.g., "USD", "EUR", "GBP")',
|
||||
},
|
||||
expected_close_date: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Expected close date in YYYY-MM-DD format (e.g., "2025-04-15")',
|
||||
},
|
||||
visible_to: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Visibility: 1 (Owner & followers), 3 (Entire company)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: () => 'https://api.pipedrive.com/v1/leads',
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
},
|
||||
body: (params) => {
|
||||
if (!params.person_id && !params.organization_id) {
|
||||
throw new Error('Either person_id or organization_id is required to create a lead')
|
||||
}
|
||||
|
||||
const body: Record<string, any> = {
|
||||
title: params.title,
|
||||
}
|
||||
|
||||
if (params.person_id) body.person_id = Number(params.person_id)
|
||||
if (params.organization_id) body.organization_id = Number(params.organization_id)
|
||||
if (params.owner_id) body.owner_id = Number(params.owner_id)
|
||||
|
||||
// Build value object if both amount and currency are provided
|
||||
if (params.value_amount && params.value_currency) {
|
||||
body.value = {
|
||||
amount: Number(params.value_amount),
|
||||
currency: params.value_currency,
|
||||
}
|
||||
}
|
||||
|
||||
if (params.expected_close_date) body.expected_close_date = params.expected_close_date
|
||||
if (params.visible_to) body.visible_to = Number(params.visible_to)
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to create lead in Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
lead: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
lead: { type: 'object', description: 'The created lead object', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveCreateProjectParams,
|
||||
PipedriveCreateProjectResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveCreateProject')
|
||||
|
||||
export const pipedriveCreateProjectTool: ToolConfig<
|
||||
PipedriveCreateProjectParams,
|
||||
PipedriveCreateProjectResponse
|
||||
> = {
|
||||
id: 'pipedrive_create_project',
|
||||
name: 'Create Project in Pipedrive',
|
||||
description: 'Create a new project in Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The title of the project (e.g., "Q2 Marketing Campaign")',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Description of the project',
|
||||
},
|
||||
start_date: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Project start date in YYYY-MM-DD format (e.g., "2025-04-01")',
|
||||
},
|
||||
end_date: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Project end date in YYYY-MM-DD format (e.g., "2025-06-30")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: () => 'https://api.pipedrive.com/v1/projects',
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
},
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
title: params.title,
|
||||
}
|
||||
|
||||
if (params.description) body.description = params.description
|
||||
if (params.start_date) body.start_date = params.start_date
|
||||
if (params.end_date) body.end_date = params.end_date
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to create project in Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
project: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
project: { type: 'object', description: 'The created project object', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveDeleteLeadParams,
|
||||
PipedriveDeleteLeadResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveDeleteLead')
|
||||
|
||||
export const pipedriveDeleteLeadTool: ToolConfig<
|
||||
PipedriveDeleteLeadParams,
|
||||
PipedriveDeleteLeadResponse
|
||||
> = {
|
||||
id: 'pipedrive_delete_lead',
|
||||
name: 'Delete Lead from Pipedrive',
|
||||
description: 'Delete a specific lead from Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'pipedrive',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
lead_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the lead to delete (e.g., "abc123-def456-ghi789")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pipedrive.com/v1/leads/${params.lead_id}`,
|
||||
method: 'DELETE',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to delete lead from Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
data: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
data: { type: 'object', description: 'Deletion confirmation data', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveGetActivitiesParams,
|
||||
PipedriveGetActivitiesResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import { PIPEDRIVE_ACTIVITY_OUTPUT_PROPERTIES } from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetActivities')
|
||||
|
||||
export const pipedriveGetActivitiesTool: ToolConfig<
|
||||
PipedriveGetActivitiesParams,
|
||||
PipedriveGetActivitiesResponse
|
||||
> = {
|
||||
id: 'pipedrive_get_activities',
|
||||
name: 'Get Activities from Pipedrive',
|
||||
description: 'Retrieve activities (tasks) from Pipedrive with optional filters',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
user_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter activities by user ID (e.g., "123")',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by activity type (call, meeting, task, deadline, email, lunch)',
|
||||
},
|
||||
done: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by completion status: 0 for not done, 1 for done',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||
},
|
||||
start: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = 'https://api.pipedrive.com/v1/activities'
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
if (params.user_id) queryParams.append('user_id', params.user_id)
|
||||
if (params.type) queryParams.append('type', params.type)
|
||||
if (params.done) queryParams.append('done', params.done)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.start) queryParams.append('start', params.start)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch activities from Pipedrive')
|
||||
}
|
||||
|
||||
const activities = data.data || []
|
||||
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
activities,
|
||||
total_items: activities.length,
|
||||
has_more: hasMore,
|
||||
next_start: nextStart,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
activities: {
|
||||
type: 'array',
|
||||
description: 'Array of activity objects from Pipedrive',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: PIPEDRIVE_ACTIVITY_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
total_items: { type: 'number', description: 'Total number of activities returned' },
|
||||
has_more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more activities are available',
|
||||
optional: true,
|
||||
},
|
||||
next_start: {
|
||||
type: 'number',
|
||||
description: 'Offset for fetching the next page',
|
||||
optional: true,
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveGetAllDealsParams,
|
||||
PipedriveGetAllDealsResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import {
|
||||
PIPEDRIVE_DEAL_OUTPUT_PROPERTIES,
|
||||
PIPEDRIVE_METADATA_OUTPUT_PROPERTIES,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetAllDeals')
|
||||
|
||||
export const pipedriveGetAllDealsTool: ToolConfig<
|
||||
PipedriveGetAllDealsParams,
|
||||
PipedriveGetAllDealsResponse
|
||||
> = {
|
||||
id: 'pipedrive_get_all_deals',
|
||||
name: 'Get All Deals from Pipedrive',
|
||||
description: 'Retrieve all deals from Pipedrive with optional filters',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Only fetch deals with a specific status. Values: open, won, lost. If omitted, all not deleted deals are returned',
|
||||
},
|
||||
person_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'If supplied, only deals linked to the specified person are returned (e.g., "456")',
|
||||
},
|
||||
org_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'If supplied, only deals linked to the specified organization are returned (e.g., "789")',
|
||||
},
|
||||
pipeline_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'If supplied, only deals in the specified pipeline are returned (e.g., "1")',
|
||||
},
|
||||
updated_since: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'If set, only deals updated after this time are returned. Format: 2025-01-01T10:20:00Z',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'For pagination, the marker representing the first item on the next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = 'https://api.pipedrive.com/api/v2/deals'
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
// Add optional parameters to query string if they exist
|
||||
if (params.status) queryParams.append('status', params.status)
|
||||
if (params.person_id) queryParams.append('person_id', params.person_id)
|
||||
if (params.org_id) queryParams.append('org_id', params.org_id)
|
||||
if (params.pipeline_id) queryParams.append('pipeline_id', params.pipeline_id)
|
||||
if (params.updated_since) queryParams.append('updated_since', params.updated_since)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response, params?: PipedriveGetAllDealsParams) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch deals from Pipedrive')
|
||||
}
|
||||
|
||||
const deals = data.data || []
|
||||
const nextCursor = data.additional_data?.next_cursor ?? null
|
||||
const hasMore = nextCursor !== null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
deals,
|
||||
metadata: {
|
||||
total_items: deals.length,
|
||||
has_more: hasMore,
|
||||
next_cursor: nextCursor,
|
||||
},
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
deals: {
|
||||
type: 'array',
|
||||
description: 'Array of deal objects from Pipedrive',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: PIPEDRIVE_DEAL_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Pagination metadata for the response',
|
||||
properties: PIPEDRIVE_METADATA_OUTPUT_PROPERTIES,
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { PipedriveGetDealParams, PipedriveGetDealResponse } from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetDeal')
|
||||
|
||||
export const pipedriveGetDealTool: ToolConfig<PipedriveGetDealParams, PipedriveGetDealResponse> = {
|
||||
id: 'pipedrive_get_deal',
|
||||
name: 'Get Deal Details from Pipedrive',
|
||||
description: 'Retrieve detailed information about a specific deal',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
deal_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the deal to retrieve (e.g., "123")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pipedrive.com/api/v2/deals/${params.deal_id}`,
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch deal from Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
deal: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
deal: { type: 'object', description: 'Deal object with full details', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import type { PipedriveGetFilesParams, PipedriveGetFilesResponse } from '@/tools/pipedrive/types'
|
||||
import { PIPEDRIVE_FILE_OUTPUT_PROPERTIES } from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const pipedriveGetFilesTool: ToolConfig<PipedriveGetFilesParams, PipedriveGetFilesResponse> =
|
||||
{
|
||||
id: 'pipedrive_get_files',
|
||||
name: 'Get Files from Pipedrive',
|
||||
description: 'Retrieve files from Pipedrive with optional filters',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
sort: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Sort files by field (supported: "id", "update_time")',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return (e.g., "50", default: 100, max: 100)',
|
||||
},
|
||||
start: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||
},
|
||||
downloadFiles: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Download file contents into file outputs',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/pipedrive/get-files',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => ({
|
||||
accessToken: params.accessToken,
|
||||
sort: params.sort,
|
||||
limit: params.limit,
|
||||
start: params.start,
|
||||
downloadFiles: params.downloadFiles,
|
||||
}),
|
||||
},
|
||||
|
||||
outputs: {
|
||||
files: {
|
||||
type: 'array',
|
||||
description: 'Array of file objects from Pipedrive',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: PIPEDRIVE_FILE_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
downloadedFiles: {
|
||||
type: 'file[]',
|
||||
description: 'Downloaded files from Pipedrive',
|
||||
optional: true,
|
||||
},
|
||||
total_items: { type: 'number', description: 'Total number of files returned' },
|
||||
has_more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more files are available',
|
||||
optional: true,
|
||||
},
|
||||
next_start: {
|
||||
type: 'number',
|
||||
description: 'Offset for fetching the next page',
|
||||
optional: true,
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type { PipedriveGetLeadsParams, PipedriveGetLeadsResponse } from '@/tools/pipedrive/types'
|
||||
import { PIPEDRIVE_LEAD_OUTPUT_PROPERTIES } from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetLeads')
|
||||
|
||||
export const pipedriveGetLeadsTool: ToolConfig<PipedriveGetLeadsParams, PipedriveGetLeadsResponse> =
|
||||
{
|
||||
id: 'pipedrive_get_leads',
|
||||
name: 'Get Leads from Pipedrive',
|
||||
description: 'Retrieve all leads or a specific lead from Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'pipedrive',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
lead_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Optional: ID of a specific lead to retrieve (e.g., "abc123-def456-ghi789")',
|
||||
},
|
||||
archived: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Get archived leads instead of active ones (e.g., "true" or "false")',
|
||||
},
|
||||
owner_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by owner user ID (e.g., "123")',
|
||||
},
|
||||
person_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by person ID (e.g., "456")',
|
||||
},
|
||||
organization_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by organization ID (e.g., "789")',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||
},
|
||||
start: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
// If lead_id is provided, get specific lead
|
||||
if (params.lead_id) {
|
||||
return `https://api.pipedrive.com/v1/leads/${params.lead_id}`
|
||||
}
|
||||
|
||||
// Get archived or active leads with optional filters
|
||||
const baseUrl =
|
||||
params.archived === 'true'
|
||||
? 'https://api.pipedrive.com/v1/leads/archived'
|
||||
: 'https://api.pipedrive.com/v1/leads'
|
||||
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
if (params.owner_id) queryParams.append('owner_id', params.owner_id)
|
||||
if (params.person_id) queryParams.append('person_id', params.person_id)
|
||||
if (params.organization_id) queryParams.append('organization_id', params.organization_id)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.start) queryParams.append('start', params.start)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response, params) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch lead(s) from Pipedrive')
|
||||
}
|
||||
|
||||
// If lead_id was provided, return single lead
|
||||
if (params?.lead_id) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
lead: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, return list of leads
|
||||
const leads = data.data || []
|
||||
// Leads endpoint puts pagination fields directly on additional_data (no .pagination wrapper)
|
||||
const hasMore = data.additional_data?.more_items_in_collection || false
|
||||
const currentStart = data.additional_data?.start ?? 0
|
||||
const currentLimit = data.additional_data?.limit ?? leads.length
|
||||
const nextStart = hasMore ? currentStart + currentLimit : null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
leads,
|
||||
total_items: leads.length,
|
||||
has_more: hasMore,
|
||||
next_start: nextStart,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
leads: {
|
||||
type: 'array',
|
||||
description: 'Array of lead objects (when listing all)',
|
||||
optional: true,
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: PIPEDRIVE_LEAD_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
lead: {
|
||||
type: 'object',
|
||||
description: 'Single lead object (when lead_id is provided)',
|
||||
optional: true,
|
||||
properties: PIPEDRIVE_LEAD_OUTPUT_PROPERTIES,
|
||||
},
|
||||
total_items: {
|
||||
type: 'number',
|
||||
description: 'Total number of leads returned',
|
||||
optional: true,
|
||||
},
|
||||
has_more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more leads are available',
|
||||
optional: true,
|
||||
},
|
||||
next_start: {
|
||||
type: 'number',
|
||||
description: 'Offset for fetching the next page',
|
||||
optional: true,
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveGetMailMessagesParams,
|
||||
PipedriveGetMailMessagesResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetMailMessages')
|
||||
|
||||
export const pipedriveGetMailMessagesTool: ToolConfig<
|
||||
PipedriveGetMailMessagesParams,
|
||||
PipedriveGetMailMessagesResponse
|
||||
> = {
|
||||
id: 'pipedrive_get_mail_messages',
|
||||
name: 'Get Mail Threads from Pipedrive',
|
||||
description: 'Retrieve mail threads from Pipedrive mailbox',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'pipedrive',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
folder: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by folder: inbox, drafts, sent, archive (default: inbox)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return (e.g., "25", default: 50)',
|
||||
},
|
||||
start: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = 'https://api.pipedrive.com/v1/mailbox/mailThreads'
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
if (params.folder) queryParams.append('folder', params.folder)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.start) queryParams.append('start', params.start)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch mail threads from Pipedrive')
|
||||
}
|
||||
|
||||
const threads = data.data || []
|
||||
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
messages: threads,
|
||||
total_items: threads.length,
|
||||
has_more: hasMore,
|
||||
next_start: nextStart,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
messages: { type: 'array', description: 'Array of mail thread objects from Pipedrive mailbox' },
|
||||
total_items: { type: 'number', description: 'Total number of mail threads returned' },
|
||||
has_more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more messages are available',
|
||||
optional: true,
|
||||
},
|
||||
next_start: {
|
||||
type: 'number',
|
||||
description: 'Offset for fetching the next page',
|
||||
optional: true,
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveGetMailThreadParams,
|
||||
PipedriveGetMailThreadResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetMailThread')
|
||||
|
||||
export const pipedriveGetMailThreadTool: ToolConfig<
|
||||
PipedriveGetMailThreadParams,
|
||||
PipedriveGetMailThreadResponse
|
||||
> = {
|
||||
id: 'pipedrive_get_mail_thread',
|
||||
name: 'Get Mail Thread Messages from Pipedrive',
|
||||
description: 'Retrieve all messages from a specific mail thread',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'pipedrive',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
thread_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the mail thread (e.g., "12345")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) =>
|
||||
`https://api.pipedrive.com/v1/mailbox/mailThreads/${params.thread_id}/mailMessages`,
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response, params) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch mail thread from Pipedrive')
|
||||
}
|
||||
|
||||
const messages = data.data || []
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
messages,
|
||||
metadata: {
|
||||
thread_id: params?.thread_id || '',
|
||||
total_items: messages.length,
|
||||
},
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
messages: { type: 'array', description: 'Array of mail message objects from the thread' },
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Thread and pagination metadata',
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveGetPipelineDealsParams,
|
||||
PipedriveGetPipelineDealsResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetPipelineDeals')
|
||||
|
||||
export const pipedriveGetPipelineDealsTool: ToolConfig<
|
||||
PipedriveGetPipelineDealsParams,
|
||||
PipedriveGetPipelineDealsResponse
|
||||
> = {
|
||||
id: 'pipedrive_get_pipeline_deals',
|
||||
name: 'Get Pipeline Deals from Pipedrive',
|
||||
description: 'Retrieve all deals in a specific pipeline',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
pipeline_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the pipeline (e.g., "1")',
|
||||
},
|
||||
stage_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by specific stage within the pipeline (e.g., "2")',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||
},
|
||||
start: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = `https://api.pipedrive.com/v1/pipelines/${params.pipeline_id}/deals`
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
if (params.stage_id) queryParams.append('stage_id', params.stage_id)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.start) queryParams.append('start', params.start)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response, params) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch pipeline deals from Pipedrive')
|
||||
}
|
||||
|
||||
const deals = data.data || []
|
||||
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
deals,
|
||||
metadata: {
|
||||
pipeline_id: params?.pipeline_id || '',
|
||||
total_items: deals.length,
|
||||
has_more: hasMore,
|
||||
next_start: nextStart,
|
||||
},
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
deals: { type: 'array', description: 'Array of deal objects from the pipeline' },
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Pipeline and pagination metadata',
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveGetPipelinesParams,
|
||||
PipedriveGetPipelinesResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import { PIPEDRIVE_PIPELINE_OUTPUT_PROPERTIES } from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetPipelines')
|
||||
|
||||
export const pipedriveGetPipelinesTool: ToolConfig<
|
||||
PipedriveGetPipelinesParams,
|
||||
PipedriveGetPipelinesResponse
|
||||
> = {
|
||||
id: 'pipedrive_get_pipelines',
|
||||
name: 'Get Pipelines from Pipedrive',
|
||||
description: 'Retrieve all pipelines from Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
sort_by: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Field to sort by: id, update_time, add_time (default: id)',
|
||||
},
|
||||
sort_direction: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Sorting direction: asc, desc (default: asc)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||
},
|
||||
start: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const baseUrl = 'https://api.pipedrive.com/v1/pipelines'
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
if (params.sort_by) queryParams.append('sort_by', params.sort_by)
|
||||
if (params.sort_direction) queryParams.append('sort_direction', params.sort_direction)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.start) queryParams.append('start', params.start)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch pipelines from Pipedrive')
|
||||
}
|
||||
|
||||
const pipelines = data.data || []
|
||||
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
pipelines,
|
||||
total_items: pipelines.length,
|
||||
has_more: hasMore,
|
||||
next_start: nextStart,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
pipelines: {
|
||||
type: 'array',
|
||||
description: 'Array of pipeline objects from Pipedrive',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: PIPEDRIVE_PIPELINE_OUTPUT_PROPERTIES,
|
||||
},
|
||||
},
|
||||
total_items: { type: 'number', description: 'Total number of pipelines returned' },
|
||||
has_more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more pipelines are available',
|
||||
optional: true,
|
||||
},
|
||||
next_start: {
|
||||
type: 'number',
|
||||
description: 'Offset for fetching the next page',
|
||||
optional: true,
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveGetProjectsParams,
|
||||
PipedriveGetProjectsResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveGetProjects')
|
||||
|
||||
export const pipedriveGetProjectsTool: ToolConfig<
|
||||
PipedriveGetProjectsParams,
|
||||
PipedriveGetProjectsResponse
|
||||
> = {
|
||||
id: 'pipedrive_get_projects',
|
||||
name: 'Get Projects from Pipedrive',
|
||||
description: 'Retrieve all projects or a specific project from Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
project_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Optional: ID of a specific project to retrieve (e.g., "123")',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by project status: open, completed, deleted (only for listing all)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Number of results to return (e.g., "50", default: 100, max: 500, only for listing all)',
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'For pagination, the marker representing the first item on the next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
// If project_id is provided, get specific project
|
||||
if (params.project_id) {
|
||||
return `https://api.pipedrive.com/v1/projects/${params.project_id}`
|
||||
}
|
||||
|
||||
// Otherwise, get all projects with optional filters
|
||||
const baseUrl = 'https://api.pipedrive.com/v1/projects'
|
||||
const queryParams = new URLSearchParams()
|
||||
|
||||
if (params.status) queryParams.append('status', params.status)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||
|
||||
const queryString = queryParams.toString()
|
||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response, params) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to fetch project(s) from Pipedrive')
|
||||
}
|
||||
|
||||
// If project_id was provided, return single project
|
||||
if (params?.project_id) {
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
project: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, return list of projects
|
||||
const projects = data.data || []
|
||||
const nextCursor = data.additional_data?.next_cursor ?? null
|
||||
const hasMore = nextCursor !== null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
projects,
|
||||
total_items: projects.length,
|
||||
has_more: hasMore,
|
||||
next_cursor: nextCursor,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
projects: {
|
||||
type: 'array',
|
||||
description: 'Array of project objects (when listing all)',
|
||||
optional: true,
|
||||
},
|
||||
project: {
|
||||
type: 'object',
|
||||
description: 'Single project object (when project_id is provided)',
|
||||
optional: true,
|
||||
},
|
||||
total_items: {
|
||||
type: 'number',
|
||||
description: 'Total number of projects returned',
|
||||
optional: true,
|
||||
},
|
||||
has_more: {
|
||||
type: 'boolean',
|
||||
description: 'Whether more projects are available',
|
||||
optional: true,
|
||||
},
|
||||
next_cursor: {
|
||||
type: 'string',
|
||||
description: 'Cursor for fetching the next page',
|
||||
optional: true,
|
||||
},
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Deal operations
|
||||
|
||||
export { pipedriveCreateActivityTool } from '@/tools/pipedrive/create_activity'
|
||||
export { pipedriveCreateDealTool } from '@/tools/pipedrive/create_deal'
|
||||
export { pipedriveCreateLeadTool } from '@/tools/pipedrive/create_lead'
|
||||
export { pipedriveCreateProjectTool } from '@/tools/pipedrive/create_project'
|
||||
export { pipedriveDeleteLeadTool } from '@/tools/pipedrive/delete_lead'
|
||||
// Activity operations
|
||||
export { pipedriveGetActivitiesTool } from '@/tools/pipedrive/get_activities'
|
||||
export { pipedriveGetAllDealsTool } from '@/tools/pipedrive/get_all_deals'
|
||||
export { pipedriveGetDealTool } from '@/tools/pipedrive/get_deal'
|
||||
// File operations
|
||||
export { pipedriveGetFilesTool } from '@/tools/pipedrive/get_files'
|
||||
// Lead operations
|
||||
export { pipedriveGetLeadsTool } from '@/tools/pipedrive/get_leads'
|
||||
// Mail operations
|
||||
export { pipedriveGetMailMessagesTool } from '@/tools/pipedrive/get_mail_messages'
|
||||
export { pipedriveGetMailThreadTool } from '@/tools/pipedrive/get_mail_thread'
|
||||
export { pipedriveGetPipelineDealsTool } from '@/tools/pipedrive/get_pipeline_deals'
|
||||
// Pipeline operations
|
||||
export { pipedriveGetPipelinesTool } from '@/tools/pipedrive/get_pipelines'
|
||||
// Project operations
|
||||
export { pipedriveGetProjectsTool } from '@/tools/pipedrive/get_projects'
|
||||
export { pipedriveUpdateActivityTool } from '@/tools/pipedrive/update_activity'
|
||||
export { pipedriveUpdateDealTool } from '@/tools/pipedrive/update_deal'
|
||||
export { pipedriveUpdateLeadTool } from '@/tools/pipedrive/update_lead'
|
||||
@@ -0,0 +1,758 @@
|
||||
import type { OutputProperty, ToolFileData, ToolResponse } from '@/tools/types'
|
||||
|
||||
/**
|
||||
* Output property definitions for Pipedrive API responses.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1
|
||||
*/
|
||||
|
||||
/**
|
||||
* Output definition for lead value objects.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1/Leads
|
||||
*/
|
||||
export const PIPEDRIVE_LEAD_VALUE_OUTPUT_PROPERTIES = {
|
||||
amount: { type: 'number', description: 'Value amount' },
|
||||
currency: { type: 'string', description: 'Currency code (e.g., USD, EUR)' },
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
/**
|
||||
* Output definition for lead objects.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1/Leads
|
||||
*/
|
||||
export const PIPEDRIVE_LEAD_OUTPUT_PROPERTIES = {
|
||||
id: { type: 'string', description: 'Lead ID (UUID)' },
|
||||
title: { type: 'string', description: 'Lead title' },
|
||||
person_id: { type: 'number', description: 'ID of the associated person', optional: true },
|
||||
organization_id: {
|
||||
type: 'number',
|
||||
description: 'ID of the associated organization',
|
||||
optional: true,
|
||||
},
|
||||
owner_id: { type: 'number', description: 'ID of the lead owner' },
|
||||
value: {
|
||||
type: 'object',
|
||||
description: 'Lead value',
|
||||
optional: true,
|
||||
properties: PIPEDRIVE_LEAD_VALUE_OUTPUT_PROPERTIES,
|
||||
},
|
||||
expected_close_date: {
|
||||
type: 'string',
|
||||
description: 'Expected close date (YYYY-MM-DD)',
|
||||
optional: true,
|
||||
},
|
||||
is_archived: { type: 'boolean', description: 'Whether the lead is archived' },
|
||||
was_seen: { type: 'boolean', description: 'Whether the lead was seen' },
|
||||
add_time: { type: 'string', description: 'When the lead was created (ISO 8601)' },
|
||||
update_time: { type: 'string', description: 'When the lead was last updated (ISO 8601)' },
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
/**
|
||||
* Complete lead output definition
|
||||
*/
|
||||
export const PIPEDRIVE_LEAD_OUTPUT: OutputProperty = {
|
||||
type: 'object',
|
||||
description: 'Pipedrive lead object',
|
||||
properties: PIPEDRIVE_LEAD_OUTPUT_PROPERTIES,
|
||||
}
|
||||
|
||||
/**
|
||||
* Output definition for deal objects.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1/Deals
|
||||
*/
|
||||
export const PIPEDRIVE_DEAL_OUTPUT_PROPERTIES = {
|
||||
id: { type: 'number', description: 'Deal ID' },
|
||||
title: { type: 'string', description: 'Deal title' },
|
||||
value: { type: 'number', description: 'Deal value' },
|
||||
currency: { type: 'string', description: 'Currency code' },
|
||||
status: { type: 'string', description: 'Deal status (open, won, lost, deleted)' },
|
||||
stage_id: { type: 'number', description: 'Pipeline stage ID' },
|
||||
pipeline_id: { type: 'number', description: 'Pipeline ID' },
|
||||
person_id: { type: 'number', description: 'Associated person ID', optional: true },
|
||||
org_id: { type: 'number', description: 'Associated organization ID', optional: true },
|
||||
owner_id: { type: 'number', description: 'Deal owner user ID' },
|
||||
add_time: { type: 'string', description: 'When the deal was created (ISO 8601)' },
|
||||
update_time: { type: 'string', description: 'When the deal was last updated (ISO 8601)' },
|
||||
won_time: { type: 'string', description: 'When the deal was won', optional: true },
|
||||
lost_time: { type: 'string', description: 'When the deal was lost', optional: true },
|
||||
close_time: { type: 'string', description: 'When the deal was closed', optional: true },
|
||||
expected_close_date: { type: 'string', description: 'Expected close date', optional: true },
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
/**
|
||||
* Complete deal output definition
|
||||
*/
|
||||
export const PIPEDRIVE_DEAL_OUTPUT: OutputProperty = {
|
||||
type: 'object',
|
||||
description: 'Pipedrive deal object',
|
||||
properties: PIPEDRIVE_DEAL_OUTPUT_PROPERTIES,
|
||||
}
|
||||
|
||||
/**
|
||||
* Output definition for activity objects.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1/Activities
|
||||
*/
|
||||
export const PIPEDRIVE_ACTIVITY_OUTPUT_PROPERTIES = {
|
||||
id: { type: 'number', description: 'Activity ID' },
|
||||
subject: { type: 'string', description: 'Activity subject' },
|
||||
type: { type: 'string', description: 'Activity type (call, meeting, task, etc.)' },
|
||||
due_date: { type: 'string', description: 'Due date (YYYY-MM-DD)' },
|
||||
due_time: { type: 'string', description: 'Due time (HH:MM)' },
|
||||
duration: { type: 'string', description: 'Duration (HH:MM)' },
|
||||
deal_id: { type: 'number', description: 'Associated deal ID', optional: true },
|
||||
person_id: { type: 'number', description: 'Associated person ID', optional: true },
|
||||
org_id: { type: 'number', description: 'Associated organization ID', optional: true },
|
||||
done: { type: 'boolean', description: 'Whether the activity is done' },
|
||||
note: { type: 'string', description: 'Activity note' },
|
||||
add_time: { type: 'string', description: 'When the activity was created' },
|
||||
update_time: { type: 'string', description: 'When the activity was last updated' },
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
/**
|
||||
* Complete activity output definition
|
||||
*/
|
||||
export const PIPEDRIVE_ACTIVITY_OUTPUT: OutputProperty = {
|
||||
type: 'object',
|
||||
description: 'Pipedrive activity object',
|
||||
properties: PIPEDRIVE_ACTIVITY_OUTPUT_PROPERTIES,
|
||||
}
|
||||
|
||||
/**
|
||||
* Output definition for file objects.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1/Files
|
||||
*/
|
||||
export const PIPEDRIVE_FILE_OUTPUT_PROPERTIES = {
|
||||
id: { type: 'number', description: 'File ID' },
|
||||
name: { type: 'string', description: 'File name' },
|
||||
file_type: { type: 'string', description: 'File type/extension' },
|
||||
file_size: { type: 'number', description: 'File size in bytes' },
|
||||
add_time: { type: 'string', description: 'When the file was uploaded' },
|
||||
update_time: { type: 'string', description: 'When the file was last updated' },
|
||||
deal_id: { type: 'number', description: 'Associated deal ID', optional: true },
|
||||
person_id: { type: 'number', description: 'Associated person ID', optional: true },
|
||||
org_id: { type: 'number', description: 'Associated organization ID', optional: true },
|
||||
url: { type: 'string', description: 'File download URL' },
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
/**
|
||||
* Complete file output definition
|
||||
*/
|
||||
export const PIPEDRIVE_FILE_OUTPUT: OutputProperty = {
|
||||
type: 'object',
|
||||
description: 'Pipedrive file object',
|
||||
properties: PIPEDRIVE_FILE_OUTPUT_PROPERTIES,
|
||||
}
|
||||
|
||||
/**
|
||||
* Output definition for pipeline objects.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1/Pipelines
|
||||
*/
|
||||
export const PIPEDRIVE_PIPELINE_OUTPUT_PROPERTIES = {
|
||||
id: { type: 'number', description: 'Pipeline ID' },
|
||||
name: { type: 'string', description: 'Pipeline name' },
|
||||
url_title: { type: 'string', description: 'URL-friendly title' },
|
||||
order_nr: { type: 'number', description: 'Pipeline order number' },
|
||||
active: { type: 'boolean', description: 'Whether the pipeline is active' },
|
||||
deal_probability: { type: 'boolean', description: 'Whether deal probability is enabled' },
|
||||
add_time: { type: 'string', description: 'When the pipeline was created' },
|
||||
update_time: { type: 'string', description: 'When the pipeline was last updated' },
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
/**
|
||||
* Complete pipeline output definition
|
||||
*/
|
||||
export const PIPEDRIVE_PIPELINE_OUTPUT: OutputProperty = {
|
||||
type: 'object',
|
||||
description: 'Pipedrive pipeline object',
|
||||
properties: PIPEDRIVE_PIPELINE_OUTPUT_PROPERTIES,
|
||||
}
|
||||
|
||||
/**
|
||||
* Output definition for project objects.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1/Projects
|
||||
*/
|
||||
export const PIPEDRIVE_PROJECT_OUTPUT_PROPERTIES = {
|
||||
id: { type: 'number', description: 'Project ID' },
|
||||
title: { type: 'string', description: 'Project title' },
|
||||
description: { type: 'string', description: 'Project description', optional: true },
|
||||
status: { type: 'string', description: 'Project status' },
|
||||
owner_id: { type: 'number', description: 'Project owner user ID' },
|
||||
start_date: { type: 'string', description: 'Project start date', optional: true },
|
||||
end_date: { type: 'string', description: 'Project end date', optional: true },
|
||||
add_time: { type: 'string', description: 'When the project was created' },
|
||||
update_time: { type: 'string', description: 'When the project was last updated' },
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
/**
|
||||
* Complete project output definition
|
||||
*/
|
||||
export const PIPEDRIVE_PROJECT_OUTPUT: OutputProperty = {
|
||||
type: 'object',
|
||||
description: 'Pipedrive project object',
|
||||
properties: PIPEDRIVE_PROJECT_OUTPUT_PROPERTIES,
|
||||
}
|
||||
|
||||
/**
|
||||
* Output definition for mail message objects.
|
||||
* @see https://developers.pipedrive.com/docs/api/v1/Mailbox
|
||||
*/
|
||||
export const PIPEDRIVE_MAIL_MESSAGE_OUTPUT_PROPERTIES = {
|
||||
id: { type: 'number', description: 'Message ID' },
|
||||
subject: { type: 'string', description: 'Email subject' },
|
||||
snippet: { type: 'string', description: 'Email snippet/preview' },
|
||||
mail_thread_id: { type: 'number', description: 'Mail thread ID' },
|
||||
from_address: { type: 'string', description: 'Sender email address' },
|
||||
to_addresses: {
|
||||
type: 'array',
|
||||
description: 'Recipient email addresses',
|
||||
items: { type: 'string', description: 'Email address' },
|
||||
},
|
||||
cc_addresses: {
|
||||
type: 'array',
|
||||
description: 'CC email addresses',
|
||||
optional: true,
|
||||
items: { type: 'string', description: 'Email address' },
|
||||
},
|
||||
bcc_addresses: {
|
||||
type: 'array',
|
||||
description: 'BCC email addresses',
|
||||
optional: true,
|
||||
items: { type: 'string', description: 'Email address' },
|
||||
},
|
||||
timestamp: { type: 'string', description: 'Message timestamp' },
|
||||
item_type: { type: 'string', description: 'Item type' },
|
||||
deal_id: { type: 'number', description: 'Associated deal ID', optional: true },
|
||||
person_id: { type: 'number', description: 'Associated person ID', optional: true },
|
||||
org_id: { type: 'number', description: 'Associated organization ID', optional: true },
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
/**
|
||||
* Complete mail message output definition
|
||||
*/
|
||||
export const PIPEDRIVE_MAIL_MESSAGE_OUTPUT: OutputProperty = {
|
||||
type: 'object',
|
||||
description: 'Pipedrive mail message object',
|
||||
properties: PIPEDRIVE_MAIL_MESSAGE_OUTPUT_PROPERTIES,
|
||||
}
|
||||
|
||||
/**
|
||||
* List metadata output properties
|
||||
*/
|
||||
export const PIPEDRIVE_METADATA_OUTPUT_PROPERTIES = {
|
||||
total_items: { type: 'number', description: 'Total number of items' },
|
||||
has_more: { type: 'boolean', description: 'Whether more items are available', optional: true },
|
||||
next_cursor: {
|
||||
type: 'string',
|
||||
description: 'Cursor for fetching the next page (v2 endpoints)',
|
||||
optional: true,
|
||||
},
|
||||
next_start: {
|
||||
type: 'number',
|
||||
description: 'Offset for fetching the next page (v1 endpoints)',
|
||||
optional: true,
|
||||
},
|
||||
} as const satisfies Record<string, OutputProperty>
|
||||
|
||||
// Common Pipedrive types
|
||||
interface PipedriveLead {
|
||||
id: string
|
||||
title: string
|
||||
person_id?: number
|
||||
organization_id?: number
|
||||
owner_id: number
|
||||
value?: {
|
||||
amount: number
|
||||
currency: string
|
||||
}
|
||||
expected_close_date?: string
|
||||
is_archived: boolean
|
||||
was_seen: boolean
|
||||
add_time: string
|
||||
update_time: string
|
||||
}
|
||||
|
||||
interface PipedriveDeal {
|
||||
id: number
|
||||
title: string
|
||||
value: number
|
||||
currency: string
|
||||
status: string
|
||||
stage_id: number
|
||||
pipeline_id: number
|
||||
person_id?: number
|
||||
org_id?: number
|
||||
owner_id: number
|
||||
add_time: string
|
||||
update_time: string
|
||||
won_time?: string
|
||||
lost_time?: string
|
||||
close_time?: string
|
||||
expected_close_date?: string
|
||||
}
|
||||
|
||||
interface PipedriveActivity {
|
||||
id: number
|
||||
subject: string
|
||||
type: string
|
||||
due_date: string
|
||||
due_time: string
|
||||
duration: string
|
||||
deal_id?: number
|
||||
person_id?: number
|
||||
org_id?: number
|
||||
done: boolean
|
||||
note: string
|
||||
add_time: string
|
||||
update_time: string
|
||||
}
|
||||
|
||||
interface PipedriveFile {
|
||||
id: number
|
||||
name: string
|
||||
file_type: string
|
||||
file_size: number
|
||||
add_time: string
|
||||
update_time: string
|
||||
deal_id?: number
|
||||
person_id?: number
|
||||
org_id?: number
|
||||
url: string
|
||||
}
|
||||
|
||||
interface PipedrivePipeline {
|
||||
id: number
|
||||
name: string
|
||||
url_title: string
|
||||
order_nr: number
|
||||
active: boolean
|
||||
deal_probability: boolean
|
||||
add_time: string
|
||||
update_time: string
|
||||
}
|
||||
|
||||
interface PipedriveProject {
|
||||
id: number
|
||||
title: string
|
||||
description?: string
|
||||
status: string
|
||||
owner_id: number
|
||||
start_date?: string
|
||||
end_date?: string
|
||||
add_time: string
|
||||
update_time: string
|
||||
}
|
||||
|
||||
interface PipedriveMailMessage {
|
||||
id: number
|
||||
subject: string
|
||||
snippet: string
|
||||
mail_thread_id: number
|
||||
from_address: string
|
||||
to_addresses: string[]
|
||||
cc_addresses?: string[]
|
||||
bcc_addresses?: string[]
|
||||
timestamp: string
|
||||
item_type: string
|
||||
deal_id?: number
|
||||
person_id?: number
|
||||
org_id?: number
|
||||
}
|
||||
|
||||
// GET All Deals
|
||||
export interface PipedriveGetAllDealsParams {
|
||||
accessToken: string
|
||||
status?: string
|
||||
person_id?: string
|
||||
org_id?: string
|
||||
pipeline_id?: string
|
||||
updated_since?: string
|
||||
limit?: string
|
||||
cursor?: string
|
||||
}
|
||||
|
||||
interface PipedriveGetAllDealsOutput {
|
||||
deals: PipedriveDeal[]
|
||||
metadata: {
|
||||
total_items: number
|
||||
has_more: boolean
|
||||
next_cursor?: string
|
||||
}
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetAllDealsResponse extends ToolResponse {
|
||||
output: PipedriveGetAllDealsOutput
|
||||
}
|
||||
|
||||
// GET Deal
|
||||
export interface PipedriveGetDealParams {
|
||||
accessToken: string
|
||||
deal_id: string
|
||||
}
|
||||
|
||||
interface PipedriveGetDealOutput {
|
||||
deal: PipedriveDeal
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetDealResponse extends ToolResponse {
|
||||
output: PipedriveGetDealOutput
|
||||
}
|
||||
|
||||
// CREATE Deal
|
||||
export interface PipedriveCreateDealParams {
|
||||
accessToken: string
|
||||
title: string
|
||||
value?: string
|
||||
currency?: string
|
||||
person_id?: string
|
||||
org_id?: string
|
||||
pipeline_id?: string
|
||||
stage_id?: string
|
||||
status?: string
|
||||
expected_close_date?: string
|
||||
}
|
||||
|
||||
interface PipedriveCreateDealOutput {
|
||||
deal: PipedriveDeal
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveCreateDealResponse extends ToolResponse {
|
||||
output: PipedriveCreateDealOutput
|
||||
}
|
||||
|
||||
// UPDATE Deal
|
||||
export interface PipedriveUpdateDealParams {
|
||||
accessToken: string
|
||||
deal_id: string
|
||||
title?: string
|
||||
value?: string
|
||||
status?: string
|
||||
stage_id?: string
|
||||
expected_close_date?: string
|
||||
}
|
||||
|
||||
interface PipedriveUpdateDealOutput {
|
||||
deal: PipedriveDeal
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveUpdateDealResponse extends ToolResponse {
|
||||
output: PipedriveUpdateDealOutput
|
||||
}
|
||||
|
||||
// GET Files
|
||||
export interface PipedriveGetFilesParams {
|
||||
accessToken: string
|
||||
sort?: string
|
||||
limit?: string
|
||||
start?: string
|
||||
downloadFiles?: boolean
|
||||
}
|
||||
|
||||
interface PipedriveGetFilesOutput {
|
||||
files: PipedriveFile[]
|
||||
downloadedFiles?: ToolFileData[]
|
||||
total_items: number
|
||||
has_more?: boolean
|
||||
next_start?: number
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetFilesResponse extends ToolResponse {
|
||||
output: PipedriveGetFilesOutput
|
||||
}
|
||||
|
||||
export interface PipedriveGetMailMessagesParams {
|
||||
accessToken: string
|
||||
folder?: string
|
||||
limit?: string
|
||||
start?: string
|
||||
}
|
||||
|
||||
interface PipedriveGetMailMessagesOutput {
|
||||
messages: PipedriveMailMessage[]
|
||||
total_items: number
|
||||
has_more?: boolean
|
||||
next_start?: number
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetMailMessagesResponse extends ToolResponse {
|
||||
output: PipedriveGetMailMessagesOutput
|
||||
}
|
||||
|
||||
// GET Mail Thread
|
||||
export interface PipedriveGetMailThreadParams {
|
||||
accessToken: string
|
||||
thread_id: string
|
||||
}
|
||||
|
||||
interface PipedriveGetMailThreadOutput {
|
||||
messages: PipedriveMailMessage[]
|
||||
metadata: {
|
||||
thread_id: string
|
||||
total_items: number
|
||||
}
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetMailThreadResponse extends ToolResponse {
|
||||
output: PipedriveGetMailThreadOutput
|
||||
}
|
||||
|
||||
// GET All Pipelines
|
||||
export interface PipedriveGetPipelinesParams {
|
||||
accessToken: string
|
||||
sort_by?: string
|
||||
sort_direction?: string
|
||||
limit?: string
|
||||
start?: string
|
||||
}
|
||||
|
||||
interface PipedriveGetPipelinesOutput {
|
||||
pipelines: PipedrivePipeline[]
|
||||
total_items: number
|
||||
has_more?: boolean
|
||||
next_start?: number
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetPipelinesResponse extends ToolResponse {
|
||||
output: PipedriveGetPipelinesOutput
|
||||
}
|
||||
|
||||
// GET Pipeline Deals
|
||||
export interface PipedriveGetPipelineDealsParams {
|
||||
accessToken: string
|
||||
pipeline_id: string
|
||||
stage_id?: string
|
||||
limit?: string
|
||||
start?: string
|
||||
}
|
||||
|
||||
interface PipedriveGetPipelineDealsOutput {
|
||||
deals: PipedriveDeal[]
|
||||
metadata: {
|
||||
pipeline_id: string
|
||||
total_items: number
|
||||
has_more?: boolean
|
||||
next_start?: number
|
||||
}
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetPipelineDealsResponse extends ToolResponse {
|
||||
output: PipedriveGetPipelineDealsOutput
|
||||
}
|
||||
|
||||
// GET All Projects (or single project if project_id provided)
|
||||
export interface PipedriveGetProjectsParams {
|
||||
accessToken: string
|
||||
project_id?: string
|
||||
status?: string
|
||||
limit?: string
|
||||
cursor?: string
|
||||
}
|
||||
|
||||
interface PipedriveGetProjectsOutput {
|
||||
projects?: PipedriveProject[]
|
||||
project?: PipedriveProject
|
||||
total_items?: number
|
||||
has_more?: boolean
|
||||
next_cursor?: string
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetProjectsResponse extends ToolResponse {
|
||||
output: PipedriveGetProjectsOutput
|
||||
}
|
||||
|
||||
// CREATE Project
|
||||
export interface PipedriveCreateProjectParams {
|
||||
accessToken: string
|
||||
title: string
|
||||
description?: string
|
||||
start_date?: string
|
||||
end_date?: string
|
||||
}
|
||||
|
||||
interface PipedriveCreateProjectOutput {
|
||||
project: PipedriveProject
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveCreateProjectResponse extends ToolResponse {
|
||||
output: PipedriveCreateProjectOutput
|
||||
}
|
||||
|
||||
// GET All Activities
|
||||
export interface PipedriveGetActivitiesParams {
|
||||
accessToken: string
|
||||
user_id?: string
|
||||
type?: string
|
||||
done?: string
|
||||
limit?: string
|
||||
start?: string
|
||||
}
|
||||
|
||||
interface PipedriveGetActivitiesOutput {
|
||||
activities: PipedriveActivity[]
|
||||
total_items: number
|
||||
has_more?: boolean
|
||||
next_start?: number
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetActivitiesResponse extends ToolResponse {
|
||||
output: PipedriveGetActivitiesOutput
|
||||
}
|
||||
|
||||
// CREATE Activity
|
||||
export interface PipedriveCreateActivityParams {
|
||||
accessToken: string
|
||||
subject: string
|
||||
type: string
|
||||
due_date: string
|
||||
due_time?: string
|
||||
duration?: string
|
||||
deal_id?: string
|
||||
person_id?: string
|
||||
org_id?: string
|
||||
note?: string
|
||||
}
|
||||
|
||||
interface PipedriveCreateActivityOutput {
|
||||
activity: PipedriveActivity
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveCreateActivityResponse extends ToolResponse {
|
||||
output: PipedriveCreateActivityOutput
|
||||
}
|
||||
|
||||
// UPDATE Activity
|
||||
export interface PipedriveUpdateActivityParams {
|
||||
accessToken: string
|
||||
activity_id: string
|
||||
subject?: string
|
||||
due_date?: string
|
||||
due_time?: string
|
||||
duration?: string
|
||||
done?: string
|
||||
note?: string
|
||||
}
|
||||
|
||||
interface PipedriveUpdateActivityOutput {
|
||||
activity: PipedriveActivity
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveUpdateActivityResponse extends ToolResponse {
|
||||
output: PipedriveUpdateActivityOutput
|
||||
}
|
||||
|
||||
// GET Leads
|
||||
export interface PipedriveGetLeadsParams {
|
||||
accessToken: string
|
||||
lead_id?: string
|
||||
archived?: string
|
||||
owner_id?: string
|
||||
person_id?: string
|
||||
organization_id?: string
|
||||
limit?: string
|
||||
start?: string
|
||||
}
|
||||
|
||||
interface PipedriveGetLeadsOutput {
|
||||
leads?: PipedriveLead[]
|
||||
lead?: PipedriveLead
|
||||
total_items?: number
|
||||
has_more?: boolean
|
||||
next_start?: number
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveGetLeadsResponse extends ToolResponse {
|
||||
output: PipedriveGetLeadsOutput
|
||||
}
|
||||
|
||||
// CREATE Lead
|
||||
export interface PipedriveCreateLeadParams {
|
||||
accessToken: string
|
||||
title: string
|
||||
person_id?: string
|
||||
organization_id?: string
|
||||
owner_id?: string
|
||||
value_amount?: string
|
||||
value_currency?: string
|
||||
expected_close_date?: string
|
||||
visible_to?: string
|
||||
}
|
||||
|
||||
interface PipedriveCreateLeadOutput {
|
||||
lead: PipedriveLead
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveCreateLeadResponse extends ToolResponse {
|
||||
output: PipedriveCreateLeadOutput
|
||||
}
|
||||
|
||||
// UPDATE Lead
|
||||
export interface PipedriveUpdateLeadParams {
|
||||
accessToken: string
|
||||
lead_id: string
|
||||
title?: string
|
||||
person_id?: string
|
||||
organization_id?: string
|
||||
owner_id?: string
|
||||
value_amount?: string
|
||||
value_currency?: string
|
||||
expected_close_date?: string
|
||||
is_archived?: string
|
||||
}
|
||||
|
||||
interface PipedriveUpdateLeadOutput {
|
||||
lead: PipedriveLead
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveUpdateLeadResponse extends ToolResponse {
|
||||
output: PipedriveUpdateLeadOutput
|
||||
}
|
||||
|
||||
// DELETE Lead
|
||||
export interface PipedriveDeleteLeadParams {
|
||||
accessToken: string
|
||||
lead_id: string
|
||||
}
|
||||
|
||||
interface PipedriveDeleteLeadOutput {
|
||||
data: any
|
||||
success: boolean
|
||||
}
|
||||
|
||||
export interface PipedriveDeleteLeadResponse extends ToolResponse {
|
||||
output: PipedriveDeleteLeadOutput
|
||||
}
|
||||
|
||||
// Union type of all responses
|
||||
export type PipedriveResponse =
|
||||
| PipedriveGetAllDealsResponse
|
||||
| PipedriveGetDealResponse
|
||||
| PipedriveCreateDealResponse
|
||||
| PipedriveUpdateDealResponse
|
||||
| PipedriveGetFilesResponse
|
||||
| PipedriveGetMailMessagesResponse
|
||||
| PipedriveGetMailThreadResponse
|
||||
| PipedriveGetPipelinesResponse
|
||||
| PipedriveGetPipelineDealsResponse
|
||||
| PipedriveGetProjectsResponse
|
||||
| PipedriveCreateProjectResponse
|
||||
| PipedriveGetActivitiesResponse
|
||||
| PipedriveCreateActivityResponse
|
||||
| PipedriveUpdateActivityResponse
|
||||
| PipedriveGetLeadsResponse
|
||||
| PipedriveCreateLeadResponse
|
||||
| PipedriveUpdateLeadResponse
|
||||
| PipedriveDeleteLeadResponse
|
||||
@@ -0,0 +1,119 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveUpdateActivityParams,
|
||||
PipedriveUpdateActivityResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveUpdateActivity')
|
||||
|
||||
export const pipedriveUpdateActivityTool: ToolConfig<
|
||||
PipedriveUpdateActivityParams,
|
||||
PipedriveUpdateActivityResponse
|
||||
> = {
|
||||
id: 'pipedrive_update_activity',
|
||||
name: 'Update Activity in Pipedrive',
|
||||
description: 'Update an existing activity (task) in Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
activity_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the activity to update (e.g., "12345")',
|
||||
},
|
||||
subject: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New subject/title for the activity (e.g., "Updated meeting with client")',
|
||||
},
|
||||
due_date: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New due date in YYYY-MM-DD format (e.g., "2025-03-20")',
|
||||
},
|
||||
due_time: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New due time in HH:MM format (e.g., "15:00")',
|
||||
},
|
||||
duration: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New duration in HH:MM format (e.g., "00:30" for 30 minutes)',
|
||||
},
|
||||
done: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Mark as done: 0 for not done, 1 for done',
|
||||
},
|
||||
note: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New notes for the activity',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pipedrive.com/v1/activities/${params.activity_id}`,
|
||||
method: 'PUT',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
},
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {}
|
||||
|
||||
if (params.subject) body.subject = params.subject
|
||||
if (params.due_date) body.due_date = params.due_date
|
||||
if (params.due_time) body.due_time = params.due_time
|
||||
if (params.duration) body.duration = params.duration
|
||||
if (params.done !== undefined) body.done = params.done === '1' ? 1 : 0
|
||||
if (params.note) body.note = params.note
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to update activity in Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
activity: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
activity: { type: 'object', description: 'The updated activity object', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveUpdateDealParams,
|
||||
PipedriveUpdateDealResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveUpdateDeal')
|
||||
|
||||
export const pipedriveUpdateDealTool: ToolConfig<
|
||||
PipedriveUpdateDealParams,
|
||||
PipedriveUpdateDealResponse
|
||||
> = {
|
||||
id: 'pipedrive_update_deal',
|
||||
name: 'Update Deal in Pipedrive',
|
||||
description: 'Update an existing deal in Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
deal_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the deal to update (e.g., "123")',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New title for the deal (e.g., "Updated Enterprise License")',
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New monetary value for the deal (e.g., "7500")',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New status: open, won, lost',
|
||||
},
|
||||
stage_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New stage ID for the deal (e.g., "3")',
|
||||
},
|
||||
expected_close_date: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New expected close date in YYYY-MM-DD format (e.g., "2025-07-15")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pipedrive.com/api/v2/deals/${params.deal_id}`,
|
||||
method: 'PATCH',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
},
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {}
|
||||
|
||||
if (params.title) body.title = params.title
|
||||
if (params.value) body.value = Number(params.value)
|
||||
if (params.status) body.status = params.status
|
||||
if (params.stage_id) body.stage_id = Number(params.stage_id)
|
||||
if (params.expected_close_date) body.expected_close_date = params.expected_close_date
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to update deal in Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
deal: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
deal: { type: 'object', description: 'The updated deal object', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
import { createLogger } from '@sim/logger'
|
||||
import type {
|
||||
PipedriveUpdateLeadParams,
|
||||
PipedriveUpdateLeadResponse,
|
||||
} from '@/tools/pipedrive/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
const logger = createLogger('PipedriveUpdateLead')
|
||||
|
||||
export const pipedriveUpdateLeadTool: ToolConfig<
|
||||
PipedriveUpdateLeadParams,
|
||||
PipedriveUpdateLeadResponse
|
||||
> = {
|
||||
id: 'pipedrive_update_lead',
|
||||
name: 'Update Lead in Pipedrive',
|
||||
description: 'Update an existing lead in Pipedrive',
|
||||
version: '1.0.0',
|
||||
|
||||
oauth: {
|
||||
required: true,
|
||||
provider: 'pipedrive',
|
||||
},
|
||||
|
||||
params: {
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'hidden',
|
||||
description: 'The access token for the Pipedrive API',
|
||||
},
|
||||
lead_id: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the lead to update (e.g., "abc123-def456-ghi789")',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New name for the lead (e.g., "Updated Lead - Premium Package")',
|
||||
},
|
||||
person_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New person ID (e.g., "456")',
|
||||
},
|
||||
organization_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New organization ID (e.g., "789")',
|
||||
},
|
||||
owner_id: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New owner user ID (e.g., "123")',
|
||||
},
|
||||
value_amount: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New value amount (e.g., "15000")',
|
||||
},
|
||||
value_currency: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New currency code (e.g., "USD", "EUR", "GBP")',
|
||||
},
|
||||
expected_close_date: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'New expected close date in YYYY-MM-DD format (e.g., "2025-05-01")',
|
||||
},
|
||||
is_archived: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Archive the lead: true or false',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.pipedrive.com/v1/leads/${params.lead_id}`,
|
||||
method: 'PATCH',
|
||||
headers: (params) => {
|
||||
if (!params.accessToken) {
|
||||
throw new Error('Access token is required')
|
||||
}
|
||||
|
||||
return {
|
||||
Authorization: `Bearer ${params.accessToken}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
},
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {}
|
||||
|
||||
if (params.title) body.title = params.title
|
||||
if (params.person_id) body.person_id = Number(params.person_id)
|
||||
if (params.organization_id) body.organization_id = Number(params.organization_id)
|
||||
if (params.owner_id) body.owner_id = Number(params.owner_id)
|
||||
|
||||
// Build value object if both amount and currency are provided
|
||||
if (params.value_amount && params.value_currency) {
|
||||
body.value = {
|
||||
amount: Number(params.value_amount),
|
||||
currency: params.value_currency,
|
||||
}
|
||||
}
|
||||
|
||||
if (params.expected_close_date) body.expected_close_date = params.expected_close_date
|
||||
if (params.is_archived) body.is_archived = params.is_archived === 'true'
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
logger.error('Pipedrive API request failed', { data })
|
||||
throw new Error(data.error || 'Failed to update lead in Pipedrive')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
lead: data.data ?? null,
|
||||
success: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
lead: { type: 'object', description: 'The updated lead object', optional: true },
|
||||
success: { type: 'boolean', description: 'Operation success status' },
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user