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,76 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const enrichCompanyBasicBulk = createAction({
|
||||
name: 'enrichCompanyBasicBulk',
|
||||
auth: villageAuth,
|
||||
displayName: 'Enrich Company - Bulk',
|
||||
description: 'Enrich multiple company profiles (max 10) with basic information including employee size, industry, and founding details.',
|
||||
props: {
|
||||
identifiers: Property.Array({
|
||||
displayName: 'Identifiers',
|
||||
description: 'Add companies to enrich (max 10)',
|
||||
properties: {
|
||||
identifierType: Property.StaticDropdown({
|
||||
displayName: 'Identifier Type',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Village ID', value: 'village_id' },
|
||||
{ label: 'LinkedIn URL', value: 'linkedin_url' },
|
||||
{ label: 'Domain', value: 'domain' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
identifierValue: Property.ShortText({
|
||||
displayName: 'Identifier Value',
|
||||
description: 'Enter the Village ID, LinkedIn URL, or Domain',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { identifiers, user_identifier } = context.propsValue;
|
||||
|
||||
if (!identifiers || identifiers.length === 0) {
|
||||
throw new Error('At least one identifier is required');
|
||||
}
|
||||
|
||||
if (identifiers.length > 10) {
|
||||
throw new Error('Maximum of 10 identifiers allowed per request');
|
||||
}
|
||||
|
||||
// Transform the array data to match API format
|
||||
const formattedIdentifiers = identifiers.map((item: any) => ({
|
||||
[item.identifierType]: item.identifierValue
|
||||
}));
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: 'https://api.village.do/v1/companies/enrich/basic/bulk',
|
||||
headers,
|
||||
body: {
|
||||
identifiers: formattedIdentifiers,
|
||||
},
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const enrichCompanyBasic = createAction({
|
||||
name: 'enrichCompanyBasic',
|
||||
auth: villageAuth,
|
||||
displayName: 'Enrich Company',
|
||||
description: 'Enrich a single company profile with basic information including employee size, industry, and founding details',
|
||||
props: {
|
||||
village_id: Property.ShortText({
|
||||
displayName: 'Village ID',
|
||||
description: 'Village internal company ID',
|
||||
required: false,
|
||||
}),
|
||||
domain: Property.ShortText({
|
||||
displayName: 'Domain',
|
||||
description: 'Company domain name',
|
||||
required: false,
|
||||
}),
|
||||
linkedin_url: Property.ShortText({
|
||||
displayName: 'LinkedIn URL',
|
||||
description: 'LinkedIn company page URL',
|
||||
required: false,
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { village_id, domain, linkedin_url, user_identifier } = context.propsValue;
|
||||
|
||||
// At least one identifier is required
|
||||
if (!village_id && !domain && !linkedin_url) {
|
||||
throw new Error('At least one identifier (village_id, domain, or linkedin_url) is required');
|
||||
}
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
// Build query parameters
|
||||
const queryParams = new URLSearchParams();
|
||||
if (village_id) queryParams.append('village_id', village_id);
|
||||
if (domain) queryParams.append('domain', domain);
|
||||
if (linkedin_url) queryParams.append('linkedin_url', linkedin_url);
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.village.do/v1/companies/enrich/basic?${queryParams.toString()}`,
|
||||
headers,
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const getCompanyPaths = createAction({
|
||||
name: 'getCompanyPaths',
|
||||
auth: villageAuth,
|
||||
displayName: 'Get Company Paths',
|
||||
description: 'Returns connection paths to a company using either its LinkedIn URL or domain URL',
|
||||
props: {
|
||||
company_url: Property.ShortText({
|
||||
displayName: 'Company URL',
|
||||
description: 'LinkedIn URL or domain URL of the target company (URL encoded)',
|
||||
required: true,
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { company_url, user_identifier } = context.propsValue;
|
||||
|
||||
// Encode the URL for use in the path
|
||||
const encodedUrl = encodeURIComponent(company_url);
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.village.do/v1/companies/paths/${encodedUrl}`,
|
||||
headers,
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const sortCompanies = createAction({
|
||||
name: 'sortCompanies',
|
||||
auth: villageAuth,
|
||||
displayName: 'Sort Companies',
|
||||
description: 'Sort a list of companies by relationship strength with the user',
|
||||
props: {
|
||||
companies: Property.Array({
|
||||
displayName: 'Company URLs',
|
||||
description: 'Array of company LinkedIn URLs or domain URLs',
|
||||
required: true,
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { companies, user_identifier } = context.propsValue;
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: 'https://api.village.do/v1/companies/sort',
|
||||
headers,
|
||||
body: {
|
||||
companies,
|
||||
},
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const enrichEmail = createAction({
|
||||
name: 'enrichEmail',
|
||||
auth: villageAuth,
|
||||
displayName: 'Enrich Email',
|
||||
description: 'Enrich a single LinkedIn profile or Village ID with an email address',
|
||||
props: {
|
||||
identifier: Property.ShortText({
|
||||
displayName: 'Identifier',
|
||||
description: 'LinkedIn URL or Village ID',
|
||||
required: true,
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { identifier, user_identifier } = context.propsValue;
|
||||
|
||||
// Encode the identifier for use in the path
|
||||
const encodedIdentifier = encodeURIComponent(identifier);
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.village.do/v1/people/enrich/emails/${encodedIdentifier}`,
|
||||
headers,
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const enrichEmailsBulk = createAction({
|
||||
name: 'enrichEmailsBulk',
|
||||
auth: villageAuth,
|
||||
displayName: 'Enrich Emails (Bulk)',
|
||||
description: 'Enrich multiple LinkedIn profiles or Village IDs with email addresses',
|
||||
props: {
|
||||
identifiers: Property.Array({
|
||||
displayName: 'Identifiers',
|
||||
description: 'Semicolon-separated list of LinkedIn URLs or Village IDs',
|
||||
required: true,
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { identifiers, user_identifier } = context.propsValue;
|
||||
|
||||
if (!identifiers || identifiers.length === 0) {
|
||||
throw new Error('At least one identifier is required');
|
||||
}
|
||||
|
||||
// Join identifiers with semicolon and encode for URL
|
||||
const identifiersString = identifiers.join(';');
|
||||
const encodedIdentifiers = encodeURIComponent(identifiersString);
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.village.do/v1/people/enrich/emails/bulk/${encodedIdentifiers}`,
|
||||
headers,
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,76 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const enrichPersonBasicBulk = createAction({
|
||||
name: 'enrichPersonBasicBulk',
|
||||
auth: villageAuth,
|
||||
displayName: 'Enrich Profile - Bulk',
|
||||
description: 'Enrich multiple person profiles (max 10) with basic professional information and work history.',
|
||||
props: {
|
||||
identifiers: Property.Array({
|
||||
displayName: 'Identifiers',
|
||||
description: 'Add people to enrich (max 10)',
|
||||
properties: {
|
||||
identifierType: Property.StaticDropdown({
|
||||
displayName: 'Identifier Type',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Village ID', value: 'village_id' },
|
||||
{ label: 'LinkedIn URL', value: 'linkedin_url' },
|
||||
{ label: 'Email', value: 'email' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
identifierValue: Property.ShortText({
|
||||
displayName: 'Identifier Value',
|
||||
description: 'Enter the Village ID, LinkedIn URL, or Email',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
required: true,
|
||||
defaultValue: [],
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { identifiers, user_identifier } = context.propsValue;
|
||||
|
||||
if (!identifiers || identifiers.length === 0) {
|
||||
throw new Error('At least one identifier is required');
|
||||
}
|
||||
|
||||
if (identifiers.length > 10) {
|
||||
throw new Error('Maximum of 10 identifiers allowed per request');
|
||||
}
|
||||
|
||||
// Transform the array data to match API format
|
||||
const formattedIdentifiers = identifiers.map((item: any) => ({
|
||||
[item.identifierType]: item.identifierValue
|
||||
}));
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: 'https://api.village.do/v1/people/enrich/basic/bulk',
|
||||
headers,
|
||||
body: {
|
||||
identifiers: formattedIdentifiers,
|
||||
},
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const enrichPersonBasic = createAction({
|
||||
name: 'enrichPersonBasic',
|
||||
auth: villageAuth,
|
||||
displayName: 'Enrich Profile',
|
||||
description: 'Enrich a single person profile with basic professional information and work history',
|
||||
props: {
|
||||
village_id: Property.ShortText({
|
||||
displayName: 'Village ID',
|
||||
description: 'Village internal user ID',
|
||||
required: false,
|
||||
}),
|
||||
linkedin_url: Property.ShortText({
|
||||
displayName: 'LinkedIn URL',
|
||||
description: 'LinkedIn profile URL',
|
||||
required: false,
|
||||
}),
|
||||
email: Property.ShortText({
|
||||
displayName: 'Email',
|
||||
description: 'Email address',
|
||||
required: false,
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { village_id, linkedin_url, email, user_identifier } = context.propsValue;
|
||||
|
||||
// At least one identifier is required
|
||||
if (!village_id && !linkedin_url && !email) {
|
||||
throw new Error('At least one identifier (village_id, linkedin_url, or email) is required');
|
||||
}
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
// Build query parameters
|
||||
const queryParams = new URLSearchParams();
|
||||
if (village_id) queryParams.append('village_id', village_id);
|
||||
if (linkedin_url) queryParams.append('linkedin_url', linkedin_url);
|
||||
if (email) queryParams.append('email', email);
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.village.do/v1/people/enrich/basic?${queryParams.toString()}`,
|
||||
headers,
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const getPersonPaths = createAction({
|
||||
name: 'getPersonPaths',
|
||||
auth: villageAuth,
|
||||
displayName: 'Get Person Paths',
|
||||
description: 'Returns connection paths and warmth score to a LinkedIn profile',
|
||||
props: {
|
||||
linkedin_url: Property.ShortText({
|
||||
displayName: 'LinkedIn URL',
|
||||
description: 'LinkedIn URL of the target person',
|
||||
required: true,
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { linkedin_url, user_identifier } = context.propsValue;
|
||||
|
||||
// Encode the URL for use in the path
|
||||
const encodedUrl = encodeURIComponent(linkedin_url);
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.village.do/v1/people/paths/${encodedUrl}`,
|
||||
headers,
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { villageAuth } from '../../..';
|
||||
|
||||
export const sortPeople = createAction({
|
||||
name: 'sortPeople',
|
||||
auth: villageAuth,
|
||||
displayName: 'Sort People',
|
||||
description: 'Sort a list of LinkedIn profiles by relationship strength with the user',
|
||||
props: {
|
||||
people: Property.Array({
|
||||
displayName: 'People URLs',
|
||||
description: 'Array of LinkedIn URLs',
|
||||
required: true,
|
||||
}),
|
||||
user_identifier: Property.ShortText({
|
||||
displayName: 'User Identifier',
|
||||
description: 'Specify the user making the request. This identifier should match the one you used when integrating the user with Village.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { people, user_identifier } = context.propsValue;
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
'secret-key': context.auth.secret_text,
|
||||
};
|
||||
|
||||
if (user_identifier) {
|
||||
headers['user-identifier'] = user_identifier;
|
||||
}
|
||||
|
||||
const res = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: 'https://api.village.do/v1/people/sort',
|
||||
headers,
|
||||
body: {
|
||||
people,
|
||||
},
|
||||
});
|
||||
|
||||
return res.body;
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user