Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { makeRequest } from '../common';
|
||||
import { kommoAuth } from '../../index';
|
||||
import { userDropdown } from '../common/props';
|
||||
|
||||
interface KommoCustomFieldValue {
|
||||
field_id?: number;
|
||||
field_code?: string;
|
||||
values: Array<{ value: string | number; enum_id?: number }>;
|
||||
}
|
||||
|
||||
export const createContactAction = createAction({
|
||||
auth: kommoAuth,
|
||||
name: 'create_contact',
|
||||
displayName: 'Create New Contact',
|
||||
description: 'Add a new contact.',
|
||||
props: {
|
||||
name: Property.ShortText({
|
||||
displayName: 'Full Name',
|
||||
required: true,
|
||||
}),
|
||||
first_name: Property.ShortText({
|
||||
displayName: 'First Name',
|
||||
required: false,
|
||||
}),
|
||||
last_name: Property.ShortText({
|
||||
displayName: 'Last Name',
|
||||
required: false,
|
||||
}),
|
||||
email: Property.ShortText({
|
||||
displayName: 'Email',
|
||||
required: false,
|
||||
}),
|
||||
phone: Property.ShortText({
|
||||
displayName: 'Phone',
|
||||
required: false,
|
||||
}),
|
||||
responsible_user_id: userDropdown(),
|
||||
tags_to_add: Property.Array({
|
||||
displayName: 'Tags to Add',
|
||||
required: false,
|
||||
})
|
||||
},
|
||||
async run(context) {
|
||||
const {
|
||||
name,
|
||||
first_name,
|
||||
last_name,
|
||||
email,
|
||||
phone,
|
||||
responsible_user_id,
|
||||
} = context.propsValue;
|
||||
const tagsToAdd = context.propsValue.tags_to_add ?? [];
|
||||
|
||||
|
||||
const { subdomain, apiToken } = context.auth.props
|
||||
|
||||
const customFields: KommoCustomFieldValue[] = [];
|
||||
|
||||
if (email) {
|
||||
customFields.push({
|
||||
field_code: 'EMAIL',
|
||||
values: [{ value: email }],
|
||||
});
|
||||
}
|
||||
|
||||
if (phone) {
|
||||
customFields.push({
|
||||
field_code: 'PHONE',
|
||||
values: [{ value: phone }],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const contactPayload: Record<string, any> = {
|
||||
...(customFields.length > 0 ? { custom_fields_values: customFields } : {}),
|
||||
};
|
||||
|
||||
|
||||
if (name) contactPayload['name'] = name;
|
||||
if (first_name) contactPayload['first_name'] = first_name;
|
||||
if (last_name) contactPayload['last_name'] = last_name;
|
||||
if (responsible_user_id) contactPayload['responsible_user_id'] = responsible_user_id;
|
||||
|
||||
|
||||
if (tagsToAdd.length > 0) {
|
||||
contactPayload['tags_to_add'] = tagsToAdd.map((tag) => ({ name: tag }))
|
||||
}
|
||||
|
||||
const result = await makeRequest(
|
||||
{ apiToken, subdomain },
|
||||
HttpMethod.POST,
|
||||
`/contacts`,
|
||||
[contactPayload]
|
||||
);
|
||||
|
||||
return result;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { makeRequest } from '../common';
|
||||
import { kommoAuth } from '../../index';
|
||||
import {
|
||||
pipelineDropdown,
|
||||
statusDropdown,
|
||||
userDropdown,
|
||||
lossReasonDropdown,
|
||||
} from '../common/props';
|
||||
|
||||
export const createLeadAction = createAction({
|
||||
auth: kommoAuth,
|
||||
name: 'create_lead',
|
||||
displayName: 'Create New Lead',
|
||||
description: 'Creates a new lead.',
|
||||
props: {
|
||||
name: Property.ShortText({
|
||||
displayName: 'Lead Name',
|
||||
required: true,
|
||||
}),
|
||||
price: Property.Number({
|
||||
displayName: 'Price',
|
||||
required: false,
|
||||
}),
|
||||
pipelineId: pipelineDropdown(true),
|
||||
statusId: statusDropdown(true),
|
||||
responsible_user_id: userDropdown(),
|
||||
loss_reason_id: lossReasonDropdown(),
|
||||
tags_to_add: Property.Array({
|
||||
displayName: 'Tags to Add',
|
||||
description: 'List of tags to add.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { name, price, statusId, pipelineId, loss_reason_id, responsible_user_id } =
|
||||
context.propsValue;
|
||||
|
||||
const tagsToAdd = context.propsValue.tags_to_add ?? [];
|
||||
|
||||
const { apiToken, subdomain } = context.auth.props;
|
||||
|
||||
const body: Record<string, unknown> = {
|
||||
name,
|
||||
};
|
||||
|
||||
if (price) body['price'] = price;
|
||||
if (statusId) body['status_id'] = statusId;
|
||||
if (pipelineId) body['pipeline_id'] = pipelineId;
|
||||
if (loss_reason_id) body['loss_reason_id'] = loss_reason_id;
|
||||
if (responsible_user_id) body['responsible_user_id'] = responsible_user_id;
|
||||
|
||||
if (tagsToAdd.length > 0) {
|
||||
body['tags_to_add'] = tagsToAdd.map((tag) => ({ name: tag }));
|
||||
}
|
||||
|
||||
const response = await makeRequest({ apiToken, subdomain }, HttpMethod.POST, '/leads', [body]);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { makeRequest } from '../common';
|
||||
import { kommoAuth } from '../../index';
|
||||
|
||||
export const findCompanyAction = createAction({
|
||||
auth: kommoAuth,
|
||||
name: 'find_company',
|
||||
displayName: 'Find Company',
|
||||
description: 'Find an existing company.',
|
||||
props: {
|
||||
query: Property.ShortText({
|
||||
displayName: 'Query',
|
||||
required: true,
|
||||
description: 'Search query (Searches through the filled fields of the company).'
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { query } = context.propsValue;
|
||||
const { subdomain, apiToken } = context.auth.props
|
||||
|
||||
const result = await makeRequest(
|
||||
{ apiToken, subdomain },
|
||||
HttpMethod.GET,
|
||||
`/companies?query=${encodeURIComponent(query || '')}`
|
||||
);
|
||||
|
||||
const companies = result?._embedded?.companies ?? [];
|
||||
|
||||
return {
|
||||
found: companies.length > 0,
|
||||
result: companies
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { kommoAuth } from '../../index';
|
||||
import { makeRequest } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const findContactAction = createAction({
|
||||
auth: kommoAuth,
|
||||
name: 'find_contact',
|
||||
displayName: 'Find Contact',
|
||||
description: 'Finds an existing contact.',
|
||||
props: {
|
||||
query: Property.ShortText({
|
||||
displayName: 'Query',
|
||||
required: true,
|
||||
description: 'Search query (Searches through the filled fields of the contact).'
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { query } = context.propsValue;
|
||||
const { subdomain, apiToken } = context.auth.props
|
||||
|
||||
const result = await makeRequest(
|
||||
{ apiToken, subdomain },
|
||||
HttpMethod.GET,
|
||||
`/contacts?query=${encodeURIComponent(query)}`
|
||||
);
|
||||
|
||||
const contacts = result?._embedded?.contacts ?? [];
|
||||
|
||||
return {
|
||||
found: contacts.length > 0,
|
||||
result: contacts
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { makeRequest } from '../common';
|
||||
import { kommoAuth } from '../../index';
|
||||
|
||||
export const findLeadAction = createAction({
|
||||
auth: kommoAuth,
|
||||
name: 'find_lead',
|
||||
displayName: 'Find Lead',
|
||||
description: "Finds an existing lead.",
|
||||
props: {
|
||||
query: Property.ShortText({
|
||||
displayName: 'Query',
|
||||
required: true,
|
||||
description: 'Search query (Searches through the filled fields of the lead).'
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { subdomain, apiToken } = context.auth.props
|
||||
|
||||
const result = await makeRequest(
|
||||
{ apiToken, subdomain },
|
||||
HttpMethod.GET,
|
||||
`/leads?query=${encodeURIComponent(context.propsValue.query)}`
|
||||
);
|
||||
|
||||
const leads = result?._embedded?.leads ?? [];
|
||||
|
||||
return {
|
||||
found: leads.length > 0,
|
||||
result: leads
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { findLeadAction } from './find-lead';
|
||||
import { updateContactAction } from './update-contact';
|
||||
import { createLeadAction } from './create-new-lead';
|
||||
import { createContactAction } from './create-new-contact';
|
||||
import { findContactAction } from './find-contact';
|
||||
import { findCompanyAction } from './find-company';
|
||||
import { updateLeadAction } from './update-lead'
|
||||
|
||||
export { findLeadAction, updateContactAction, createLeadAction, createContactAction, findContactAction, findCompanyAction, updateLeadAction };
|
||||
@@ -0,0 +1,110 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { kommoAuth } from '../../index';
|
||||
import { makeRequest } from '../common';
|
||||
import { contactDropdown, userDropdown } from '../common/props';
|
||||
|
||||
interface KommoCustomFieldValue {
|
||||
field_id?: number;
|
||||
field_code?: string;
|
||||
values: Array<{ value: string | number; enum_id?: number }>;
|
||||
}
|
||||
|
||||
export const updateContactAction = createAction({
|
||||
auth: kommoAuth,
|
||||
name: 'update_contact',
|
||||
displayName: 'Update Contact',
|
||||
description: 'Updates an existing contact.',
|
||||
props: {
|
||||
contactId: contactDropdown,
|
||||
name: Property.ShortText({
|
||||
displayName: 'Full Name',
|
||||
required: false,
|
||||
}),
|
||||
first_name: Property.ShortText({
|
||||
displayName: 'First Name',
|
||||
required: false,
|
||||
}),
|
||||
last_name: Property.ShortText({
|
||||
displayName: 'Last Name',
|
||||
required: false,
|
||||
}),
|
||||
email: Property.ShortText({
|
||||
displayName: 'Email',
|
||||
required: false,
|
||||
}),
|
||||
phone: Property.ShortText({
|
||||
displayName: 'Phone',
|
||||
required: false,
|
||||
}),
|
||||
responsible_user_id: userDropdown(),
|
||||
tags_to_add: Property.Array({
|
||||
displayName: 'Tags to Add',
|
||||
description: 'List of tag names or IDs to add.',
|
||||
required: false,
|
||||
}),
|
||||
tags_to_delete: Property.Array({
|
||||
displayName: 'Tags to Delete',
|
||||
description: 'List of tag names or IDs to remove.',
|
||||
required: false,
|
||||
})
|
||||
},
|
||||
async run(context) {
|
||||
const {
|
||||
contactId,
|
||||
name,
|
||||
first_name,
|
||||
last_name,
|
||||
email,
|
||||
phone,
|
||||
responsible_user_id,
|
||||
} = context.propsValue;
|
||||
|
||||
const tagsToAdd = context.propsValue.tags_to_add ?? [];
|
||||
const tagsToDelete = context.propsValue.tags_to_delete ?? [];
|
||||
|
||||
const { subdomain, apiToken } = context.auth.props;
|
||||
|
||||
const customFields: KommoCustomFieldValue[] = [];
|
||||
|
||||
if (email) {
|
||||
customFields.push({
|
||||
field_code: 'EMAIL',
|
||||
values: [{ value: email }],
|
||||
});
|
||||
}
|
||||
|
||||
if (phone) {
|
||||
customFields.push({
|
||||
field_code: 'PHONE',
|
||||
values: [{ value: phone }],
|
||||
});
|
||||
}
|
||||
|
||||
const updatePayload: Record<string, any> = {
|
||||
...(customFields.length > 0 ? { custom_fields_values: customFields } : {}),
|
||||
};
|
||||
|
||||
if (name) updatePayload['name'] = name;
|
||||
if (first_name) updatePayload['first_name'] = first_name;
|
||||
if (last_name) updatePayload['last_name'] = last_name;
|
||||
if (responsible_user_id) updatePayload['responsible_user_id'] = responsible_user_id;
|
||||
|
||||
if (tagsToAdd.length > 0) {
|
||||
updatePayload['tags_to_add'] = tagsToAdd.map((tag) => ({ name: tag }))
|
||||
}
|
||||
|
||||
if (tagsToDelete.length > 0) {
|
||||
updatePayload['tags_to_delete'] = tagsToDelete.map((tag) => ({ name: tag }))
|
||||
}
|
||||
|
||||
const result = await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.PATCH,
|
||||
`/contacts/${contactId}`,
|
||||
updatePayload
|
||||
);
|
||||
|
||||
return result;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { makeRequest } from '../common';
|
||||
import { kommoAuth } from '../../index';
|
||||
import { pipelineDropdown, statusDropdown, userDropdown, lossReasonDropdown, leadDropdown } from '../common/props';
|
||||
|
||||
export const updateLeadAction = createAction({
|
||||
auth: kommoAuth,
|
||||
name: 'update_lead',
|
||||
displayName: 'Update Lead',
|
||||
description: 'Update existing lead info.',
|
||||
props: {
|
||||
leadId: leadDropdown,
|
||||
name: Property.ShortText({
|
||||
displayName: 'Name',
|
||||
required: false,
|
||||
}),
|
||||
price: Property.Number({
|
||||
displayName: 'Price',
|
||||
required: false,
|
||||
}),
|
||||
pipelineId: pipelineDropdown(false),
|
||||
statusId: statusDropdown(false),
|
||||
responsible_user_id: userDropdown(false),
|
||||
loss_reason_id: lossReasonDropdown(false),
|
||||
tags_to_add: Property.Array({
|
||||
displayName: 'Tags to Add',
|
||||
required: false,
|
||||
}),
|
||||
tags_to_delete: Property.Array({
|
||||
displayName: 'Tags to Delete',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const {
|
||||
leadId,
|
||||
name,
|
||||
price,
|
||||
statusId,
|
||||
pipelineId,
|
||||
responsible_user_id,
|
||||
loss_reason_id,
|
||||
} = context.propsValue;
|
||||
|
||||
const tagsToAdd = context.propsValue.tags_to_add ?? [];
|
||||
const tagsToDelete = context.propsValue.tags_to_delete ?? [];
|
||||
|
||||
|
||||
const { subdomain, apiToken } = context.auth.props;
|
||||
|
||||
const updatePayload: Record<string, any> = {};
|
||||
|
||||
if (name) updatePayload['name'] = name;
|
||||
if (price) updatePayload['price'] = price;
|
||||
if (statusId) updatePayload['status_id'] = statusId;
|
||||
if (pipelineId) updatePayload['pipeline_id'] = pipelineId;
|
||||
if (loss_reason_id) updatePayload['loss_reason_id'] = loss_reason_id;
|
||||
if (responsible_user_id) updatePayload['responsible_user_id'] = responsible_user_id;
|
||||
|
||||
if (tagsToAdd.length > 0) {
|
||||
updatePayload['tags_to_add'] = tagsToAdd.map((tag) => ({ name: tag }))
|
||||
}
|
||||
|
||||
if (tagsToDelete.length > 0) {
|
||||
updatePayload['tags_to_delete'] = tagsToDelete.map((tag) => ({ name: tag }))
|
||||
}
|
||||
|
||||
const result = await makeRequest(
|
||||
{ apiToken, subdomain },
|
||||
HttpMethod.PATCH,
|
||||
`/leads/${leadId}`,
|
||||
updatePayload
|
||||
);
|
||||
|
||||
return result;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
|
||||
interface KommoAuth {
|
||||
subdomain: string;
|
||||
apiToken: string;
|
||||
}
|
||||
|
||||
export async function makeRequest(
|
||||
auth: KommoAuth,
|
||||
method: HttpMethod,
|
||||
path: string,
|
||||
body?: unknown
|
||||
) {
|
||||
const url = `https://${auth.subdomain}.kommo.com/api/v4${path}`;
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method,
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.apiToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body,
|
||||
});
|
||||
|
||||
return response.body;
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
import { Property, DropdownOption } from '@activepieces/pieces-framework';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { makeRequest } from './index';
|
||||
import { kommoAuth } from '../..';
|
||||
|
||||
interface KommoAuth {
|
||||
subdomain: string;
|
||||
apiToken: string;
|
||||
}
|
||||
|
||||
export const pipelineDropdown = (required = false) => Property.Dropdown({
|
||||
auth: kommoAuth,
|
||||
displayName: 'Pipeline',
|
||||
required,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Kommo account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const { subdomain, apiToken } = auth.props;
|
||||
const pipelines = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/leads/pipelines');
|
||||
|
||||
const options: DropdownOption<number>[] = (pipelines._embedded?.pipelines || []).map(
|
||||
(pipeline: any) => ({
|
||||
label: pipeline.name,
|
||||
value: pipeline.id
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const statusDropdown = (required = false) => Property.Dropdown({
|
||||
auth: kommoAuth,
|
||||
displayName: 'Status',
|
||||
required,
|
||||
refreshers: ['pipelineId'],
|
||||
options: async ({ auth, pipelineId }) => {
|
||||
if (!auth || !pipelineId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Select a pipeline first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const { subdomain, apiToken } = auth.props;
|
||||
const statuses = await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.GET,
|
||||
`/leads/pipelines/${pipelineId}/statuses`
|
||||
);
|
||||
|
||||
const options: DropdownOption<number>[] = (statuses._embedded?.statuses || []).map(
|
||||
(status: any) => ({
|
||||
label: status.name,
|
||||
value: status.id,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const userDropdown = (required = false) => Property.Dropdown({
|
||||
auth: kommoAuth,
|
||||
displayName: 'Unique identified of a responsible user',
|
||||
required,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Kommo account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const { subdomain, apiToken } = auth.props;
|
||||
const users = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/users');
|
||||
|
||||
const options: DropdownOption<number>[] = (users._embedded?.users || []).map((user: any) => ({
|
||||
label: `${user.name} (${user.email})`,
|
||||
value: user.id,
|
||||
}));
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const lossReasonDropdown = (required = false) => Property.Dropdown({
|
||||
auth: kommoAuth,
|
||||
displayName: 'Loss Reason',
|
||||
required,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Kommo account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const { subdomain, apiToken } = auth.props;
|
||||
const reasons = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/leads/loss_reasons');
|
||||
|
||||
const options: DropdownOption<number>[] = (reasons._embedded?.loss_reasons || []).map(
|
||||
(reason: any) => ({
|
||||
label: reason.name,
|
||||
value: reason.id,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const leadDropdown = Property.Dropdown({
|
||||
auth: kommoAuth,
|
||||
displayName: 'Lead',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Kommo account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const { subdomain, apiToken } = auth.props;
|
||||
const leads = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/leads');
|
||||
|
||||
const options: DropdownOption<number>[] = (leads._embedded?.leads || []).map((lead: any) => ({
|
||||
label: lead.name,
|
||||
value: lead.id,
|
||||
}));
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const companyDropdown = Property.Dropdown({
|
||||
auth: kommoAuth,
|
||||
displayName: 'Company',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Kommo account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const { subdomain, apiToken } = auth.props;
|
||||
const companies = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/companies');
|
||||
|
||||
const options: DropdownOption<string>[] = (companies._embedded?.companies || []).map(
|
||||
(company: any) => ({
|
||||
label: company.name,
|
||||
value: company.id.toString(),
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const contactDropdown = Property.Dropdown({
|
||||
auth: kommoAuth,
|
||||
displayName: 'Contact',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Kommo account',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const { subdomain, apiToken } = auth.props;
|
||||
const contacts = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/contacts');
|
||||
|
||||
const options: DropdownOption<number>[] = (contacts._embedded?.contacts || []).map(
|
||||
(contact: any) => ({
|
||||
label: contact.name,
|
||||
value: contact.id,
|
||||
})
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
import { leadStatusChangedTrigger } from './lead-status-changed';
|
||||
import { newContactAddedTrigger } from './new-contact-added';
|
||||
import { newLeadCreatedTrigger } from './new-lead-created';
|
||||
import { newTaskCreatedTrigger } from './new-task-created';
|
||||
|
||||
export { leadStatusChangedTrigger, newContactAddedTrigger, newLeadCreatedTrigger, newTaskCreatedTrigger };
|
||||
@@ -0,0 +1,102 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { kommoAuth } from '../../index';
|
||||
import { makeRequest } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const leadStatusChangedTrigger = createTrigger({
|
||||
auth: kommoAuth,
|
||||
name: 'lead_status_changed',
|
||||
displayName: 'Lead Status Changed',
|
||||
description: 'Triggers when a lead status is changed.',
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
props: {},
|
||||
async onEnable(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
|
||||
const webhook = await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.POST,
|
||||
`/webhooks`,
|
||||
{
|
||||
destination: context.webhookUrl,
|
||||
settings: ['status_lead']
|
||||
}
|
||||
);
|
||||
|
||||
await context.store.put('webhookId', webhook.id);
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
const webhookId = await context.store.get('webhookId');
|
||||
|
||||
if (webhookId) {
|
||||
await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.DELETE,
|
||||
`/webhooks`,
|
||||
{destination:context.webhookUrl}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
|
||||
const payload = context.payload.body as { leads: { status: { id: string }[] } }
|
||||
const leadId = payload.leads.status[0].id;
|
||||
if (!leadId) return [];
|
||||
|
||||
const response = await makeRequest({ apiToken, subdomain }, HttpMethod.GET, `/leads/${leadId}`)
|
||||
return [response]
|
||||
},
|
||||
async test(context) {
|
||||
const { subdomain, apiToken } = context.auth.props;
|
||||
|
||||
const response = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/leads?limit=5&order[updated_at]=desc');
|
||||
|
||||
const leads = response?._embedded?.leads ?? [];
|
||||
|
||||
return leads;
|
||||
},
|
||||
sampleData: {
|
||||
"id": 256988,
|
||||
"name": "John Doe",
|
||||
"price": 100,
|
||||
"responsible_user_id": 13290567,
|
||||
"group_id": 0,
|
||||
"status_id": 86521115,
|
||||
"pipeline_id": 11273979,
|
||||
"loss_reason_id": null,
|
||||
"created_by": 13290567,
|
||||
"updated_by": 13290567,
|
||||
"created_at": 1748800059,
|
||||
"updated_at": 1748800060,
|
||||
"closed_at": null,
|
||||
"closest_task_at": null,
|
||||
"is_deleted": false,
|
||||
"custom_fields_values": null,
|
||||
"score": null,
|
||||
"account_id": 34678947,
|
||||
"labor_cost": null,
|
||||
"is_price_computed": false,
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": ""
|
||||
}
|
||||
},
|
||||
"_embedded": {
|
||||
"tags": [],
|
||||
"companies": [
|
||||
{
|
||||
"id": 722828,
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,98 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { kommoAuth } from '../../index';
|
||||
import { makeRequest } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const newContactAddedTrigger = createTrigger({
|
||||
auth: kommoAuth,
|
||||
name: 'new_contact_added',
|
||||
displayName: 'New Contact Added',
|
||||
description: 'Triggers when a new contact is added.',
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
props: {},
|
||||
async onEnable(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
|
||||
const webhook = await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.POST,
|
||||
`/webhooks`,
|
||||
{
|
||||
destination: context.webhookUrl,
|
||||
settings: ['add_contact']
|
||||
}
|
||||
);
|
||||
|
||||
await context.store.put('webhookId', webhook.id);
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
const { subdomain, apiToken } = context.auth.props;
|
||||
const webhookId = await context.store.get('webhookId');
|
||||
|
||||
if (webhookId) {
|
||||
await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.DELETE,
|
||||
`/webhooks`,
|
||||
{destination:context.webhookUrl}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
|
||||
const payload = context.payload.body as { contacts: { add: { id: string }[] } }
|
||||
const contactId = payload.contacts.add[0].id;
|
||||
if (!contactId) return [];
|
||||
|
||||
|
||||
const response = await makeRequest({ apiToken, subdomain }, HttpMethod.GET, `/contacts/${contactId}`)
|
||||
return [response]
|
||||
},
|
||||
async test(context) {
|
||||
const { subdomain, apiToken } = context.auth.props;
|
||||
|
||||
const response = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/contacts?limit=5&order[updated_at]=desc');
|
||||
|
||||
const contacts = response?._embedded?.contacts ?? [];
|
||||
|
||||
return contacts;
|
||||
},
|
||||
sampleData: {
|
||||
"id": 722830,
|
||||
"name": "John Doe",
|
||||
"first_name": "",
|
||||
"last_name": "",
|
||||
"responsible_user_id": 13290567,
|
||||
"group_id": 0,
|
||||
"created_by": 13290567,
|
||||
"updated_by": 13290567,
|
||||
"created_at": 1748800060,
|
||||
"updated_at": 1748800060,
|
||||
"closest_task_at": null,
|
||||
"is_deleted": false,
|
||||
"is_unsorted": false,
|
||||
"custom_fields_values": null,
|
||||
"account_id": 34678947,
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": ""
|
||||
}
|
||||
},
|
||||
"_embedded": {
|
||||
"tags": [],
|
||||
"companies": [
|
||||
{
|
||||
"id": 722828,
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { kommoAuth } from '../../index';
|
||||
import { makeRequest } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const newLeadCreatedTrigger = createTrigger({
|
||||
auth: kommoAuth,
|
||||
name: 'new_lead_created',
|
||||
displayName: 'New Lead Created',
|
||||
description: 'Triggers when a new lead is created.',
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
props: {},
|
||||
async onEnable(context) {
|
||||
const { subdomain, apiToken } = context.auth.props;
|
||||
|
||||
const webhook = await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.POST,
|
||||
`/webhooks`,
|
||||
{
|
||||
destination: context.webhookUrl,
|
||||
settings: ['add_lead']
|
||||
}
|
||||
);
|
||||
|
||||
await context.store.put('webhookId', webhook.id);
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
const { subdomain, apiToken } = context.auth.props;
|
||||
const webhookId = await context.store.get('webhookId');
|
||||
|
||||
if (webhookId) {
|
||||
await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.DELETE,
|
||||
`/webhooks`,
|
||||
{destination:context.webhookUrl}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
|
||||
const payload = context.payload.body as { leads: { add: { id: string }[] } }
|
||||
const leadId = payload.leads.add[0].id;
|
||||
if (!leadId) return [];
|
||||
|
||||
|
||||
const response = await makeRequest({ apiToken, subdomain }, HttpMethod.GET, `/leads/${leadId}`)
|
||||
return [response]
|
||||
},
|
||||
async test(context) {
|
||||
const { subdomain, apiToken } = context.auth.props;
|
||||
|
||||
const response = await makeRequest({ subdomain, apiToken }, HttpMethod.GET, '/leads?limit=5&order[updated_at]=desc');
|
||||
|
||||
const leads = response?._embedded?.leads ?? [];
|
||||
|
||||
return leads;
|
||||
},
|
||||
sampleData: {
|
||||
"id": 256988,
|
||||
"name": "John Doe",
|
||||
"price": 100,
|
||||
"responsible_user_id": 13290567,
|
||||
"group_id": 0,
|
||||
"status_id": 86521115,
|
||||
"pipeline_id": 11273979,
|
||||
"loss_reason_id": null,
|
||||
"created_by": 13290567,
|
||||
"updated_by": 13290567,
|
||||
"created_at": 1748800059,
|
||||
"updated_at": 1748800060,
|
||||
"closed_at": null,
|
||||
"closest_task_at": null,
|
||||
"is_deleted": false,
|
||||
"custom_fields_values": null,
|
||||
"score": null,
|
||||
"account_id": 34678947,
|
||||
"labor_cost": null,
|
||||
"is_price_computed": false,
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": ""
|
||||
}
|
||||
},
|
||||
"_embedded": {
|
||||
"tags": [],
|
||||
"companies": [
|
||||
{
|
||||
"id": 722828,
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { kommoAuth } from '../../index';
|
||||
import { makeRequest } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const newTaskCreatedTrigger = createTrigger({
|
||||
auth: kommoAuth,
|
||||
name: 'new_task_created',
|
||||
displayName: 'New Task Created',
|
||||
description: 'Triggered when a new task is created.',
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
props: {},
|
||||
async onEnable(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
|
||||
const webhook = await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.POST,
|
||||
`/webhooks`,
|
||||
{
|
||||
destination: context.webhookUrl,
|
||||
settings: ['add_task']
|
||||
}
|
||||
);
|
||||
|
||||
await context.store.put('webhookId', webhook.id);
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
const webhookId = await context.store.get('webhookId');
|
||||
|
||||
if (webhookId) {
|
||||
await makeRequest(
|
||||
{ subdomain, apiToken },
|
||||
HttpMethod.DELETE,
|
||||
`/webhooks`,
|
||||
{destination:context.webhookUrl}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
const { subdomain, apiToken } = context.auth.props as { subdomain: string; apiToken: string };
|
||||
|
||||
const payload = context.payload.body as { task: { add: { id: number }[] } }
|
||||
const taskId = payload.task.add[0].id;
|
||||
if (!taskId) return [];
|
||||
|
||||
|
||||
const response = await makeRequest({ apiToken, subdomain }, HttpMethod.GET, `/tasks/${taskId}`)
|
||||
return [response]
|
||||
},
|
||||
sampleData: {
|
||||
"id": 12040,
|
||||
"created_by": 13290567,
|
||||
"updated_by": 13290567,
|
||||
"created_at": 1748805952,
|
||||
"updated_at": 1748805952,
|
||||
"responsible_user_id": 13290567,
|
||||
"group_id": 0,
|
||||
"entity_id": 722830,
|
||||
"entity_type": "contacts",
|
||||
"duration": 0,
|
||||
"is_completed": false,
|
||||
"task_type_id": 1,
|
||||
"text": "Test",
|
||||
"result": [],
|
||||
"complete_till": 1748975340,
|
||||
"account_id": 34678947,
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user