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,33 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.base.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-apollo
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-apollo` to build the library.
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@activepieces/piece-apollo",
|
||||
"version": "0.0.8"
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "pieces-apollo",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/apollo/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/apollo",
|
||||
"tsConfig": "packages/pieces/community/apollo/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/apollo/package.json",
|
||||
"main": "packages/pieces/community/apollo/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/apollo/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/apollo/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"command": "node tools/scripts/publish.mjs pieces-apollo {args.ver} {args.tag}",
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/apollo",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Match Person": "Match-Person",
|
||||
"Enrich Company": "Firma bereichern",
|
||||
"Email": "E-Mail",
|
||||
"Cache Response": "Cache-Antwort",
|
||||
"Domain": "Domäne",
|
||||
"Store the response in the project store for future use.": "Speichern Sie die Antwort im Projektspeicher für zukünftige Nutzung."
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Match Person": "Persona de partida",
|
||||
"Enrich Company": "Enriquecer empresa",
|
||||
"Email": "E-mail",
|
||||
"Cache Response": "Respuesta de caché",
|
||||
"Domain": "Dominio",
|
||||
"Store the response in the project store for future use.": "Almacena la respuesta en la tienda de proyectos para su uso futuro."
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Match Person": "Personne correspondante",
|
||||
"Enrich Company": "Enrichir la société",
|
||||
"Email": "Courriel",
|
||||
"Cache Response": "Mettre en cache la réponse",
|
||||
"Domain": "Domaine",
|
||||
"Store the response in the project store for future use.": "Stockez la réponse dans la boutique du projet pour une utilisation future."
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Match Person": "人と一致",
|
||||
"Enrich Company": "Enrich Company",
|
||||
"Email": "Eメールアドレス",
|
||||
"Cache Response": "キャッシュ応答",
|
||||
"Domain": "ドメイン",
|
||||
"Store the response in the project store for future use.": "今後使用するためにプロジェクトストアに応答を保存します。"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Match Person": "Wedstrijd persoon",
|
||||
"Enrich Company": "Bedrijf verrijken",
|
||||
"Email": "E-mail",
|
||||
"Cache Response": "Cache antwoord",
|
||||
"Domain": "Domein",
|
||||
"Store the response in the project store for future use.": "Sla het antwoord op in de projectopslag op voor toekomstig gebruik."
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Match Person": "Correspondência de pessoa",
|
||||
"Enrich Company": "Enriquecer empresa",
|
||||
"Email": "e-mail",
|
||||
"Cache Response": "Resposta em cache",
|
||||
"Domain": "Domínio",
|
||||
"Store the response in the project store for future use.": "Armazene a resposta na loja do projeto para uso futuro."
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Apollo": "Аполло",
|
||||
"Match Person": "Лицо матча",
|
||||
"Enrich Company": "Расширить компанию",
|
||||
"Email": "Почта",
|
||||
"Cache Response": "Ответ кэша",
|
||||
"Domain": "Домен",
|
||||
"Store the response in the project store for future use.": "Сохранять ответ в магазине проекта для последующего использования."
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Match Person": "Match Person",
|
||||
"Enrich Company": "Enrich Company",
|
||||
"Email": "Email",
|
||||
"Cache Response": "Cache Response",
|
||||
"Domain": "Domain",
|
||||
"Store the response in the project store for future use.": "Store the response in the project store for future use."
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Apollo": "Apollo",
|
||||
"Match Person": "Match Person",
|
||||
"Enrich Company": "Enrich Company",
|
||||
"Email": "Email",
|
||||
"Cache Response": "Cache Response",
|
||||
"Domain": "Domain",
|
||||
"Store the response in the project store for future use.": "Store the response in the project store for future use."
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Match Person": "Match Person",
|
||||
"Enrich Company": "Enrich Company",
|
||||
"Email": "电子邮件地址",
|
||||
"Cache Response": "Cache Response",
|
||||
"Domain": "Domain",
|
||||
"Store the response in the project store for future use.": "Store the response in the project store for future use."
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { matchPerson } from './lib/actions/match-person';
|
||||
import { enrichCompany } from './lib/actions/enrich-company';
|
||||
import { newsArticlesSearch } from './lib/actions/news-articles-search';
|
||||
import { organizationJobPostings } from './lib/actions/organization-job-postings';
|
||||
import { organizationSearch } from './lib/actions/organization-search';
|
||||
import { peopleSearch } from './lib/actions/people-search';
|
||||
import { createCustomApiCallAction } from '@activepieces/pieces-common';
|
||||
|
||||
export const apolloAuth = PieceAuth.SecretText({
|
||||
displayName: 'API Key',
|
||||
description: `
|
||||
To create your Apollo API key:
|
||||
|
||||
1. Go to **Settings** > **[Integrations](https://app.apollo.io/#/settings/integrations)** in Apollo
|
||||
2. Click **Connect** beside Apollo API
|
||||
3. Click **API Keys** > **Create new key**
|
||||
4. Enter a name and description, then select the endpoints you need (or toggle **Set as master key** for full access)
|
||||
5. Click **Create API key** and copy it to a secure location
|
||||
|
||||
**Note:** Some endpoints require a master API key. Keep your API keys secure and be careful with whom you share access.
|
||||
|
||||
[Learn more about creating API keys](https://docs.apollo.io/docs/create-api-key)
|
||||
`,
|
||||
required: true,
|
||||
});
|
||||
|
||||
export const apollo = createPiece({
|
||||
displayName: 'Apollo',
|
||||
auth: apolloAuth,
|
||||
description:
|
||||
'AI sales platform for prospecting, lead gen, and deal automation. Close more deals, faster, with smart data.',
|
||||
minimumSupportedRelease: '0.30.0',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/apollo.png',
|
||||
authors: ['abuaboud', 'sanket-a11y'],
|
||||
actions: [
|
||||
matchPerson,
|
||||
enrichCompany,
|
||||
newsArticlesSearch,
|
||||
organizationJobPostings,
|
||||
organizationSearch,
|
||||
peopleSearch,
|
||||
createCustomApiCallAction({
|
||||
auth: apolloAuth,
|
||||
baseUrl: () => 'https://api.apollo.io/api/v1',
|
||||
authMapping: async (auth) => {
|
||||
return {
|
||||
'x-api-key': auth.secret_text,
|
||||
};
|
||||
},
|
||||
}),
|
||||
],
|
||||
triggers: [],
|
||||
});
|
||||
@@ -0,0 +1,57 @@
|
||||
import { apolloAuth } from '../../';
|
||||
import {
|
||||
Property,
|
||||
StoreScope,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
|
||||
export const enrichCompany = createAction({
|
||||
name: 'enrichCompany',
|
||||
description: '',
|
||||
displayName: 'Enrich Company',
|
||||
props: {
|
||||
domain: Property.ShortText({
|
||||
displayName: 'Domain',
|
||||
description: '',
|
||||
required: true,
|
||||
}),
|
||||
cacheResponse: Property.Checkbox({
|
||||
displayName: 'Cache Response',
|
||||
description: 'Store the response in the project store for future use.',
|
||||
required: false,
|
||||
defaultValue: true,
|
||||
}),
|
||||
},
|
||||
auth: apolloAuth,
|
||||
async run({ propsValue, auth, store }) {
|
||||
if (propsValue.cacheResponse) {
|
||||
const cachedResult = await store.get(
|
||||
`_apollo_org_${propsValue.domain}`,
|
||||
StoreScope.PROJECT
|
||||
);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
}
|
||||
const result = await httpClient.sendRequest<{
|
||||
organization: Record<string, unknown>;
|
||||
}>({
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.apollo.io/v1/organizations/enrich?domain=${propsValue.domain}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': `${auth.secret_text}`,
|
||||
},
|
||||
});
|
||||
const resultOrg = result.body.organization || {};
|
||||
if (propsValue.cacheResponse) {
|
||||
await store.put(
|
||||
`_apollo_org_${propsValue.domain}`,
|
||||
resultOrg,
|
||||
StoreScope.PROJECT
|
||||
);
|
||||
}
|
||||
return resultOrg;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
import { apolloAuth } from '../../';
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
import {
|
||||
Property,
|
||||
StoreScope,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
|
||||
export const matchPerson = createAction({
|
||||
name: 'matchPerson',
|
||||
displayName: 'Match Person',
|
||||
description: 'Enrich a persons details using their email address',
|
||||
props: {
|
||||
email: Property.ShortText({
|
||||
displayName: 'Email',
|
||||
description: ' The email address of the person to be matched',
|
||||
required: true,
|
||||
}),
|
||||
cacheResponse: Property.Checkbox({
|
||||
displayName: 'Cache Response',
|
||||
description: 'Store the response in the project store for future use.',
|
||||
required: false,
|
||||
defaultValue: true,
|
||||
}),
|
||||
},
|
||||
auth: apolloAuth,
|
||||
async run({ propsValue, auth, store }) {
|
||||
if (propsValue.cacheResponse) {
|
||||
const cachedResult = await store.get(
|
||||
`_apollo_person_${propsValue.email}`,
|
||||
StoreScope.PROJECT
|
||||
);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
}
|
||||
const result = await httpClient.sendRequest<{
|
||||
person: Record<string, unknown>;
|
||||
}>({
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.apollo.io/v1/people/match`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'x-api-key': `${auth.secret_text}`,
|
||||
},
|
||||
body: {
|
||||
|
||||
email: propsValue.email,
|
||||
},
|
||||
});
|
||||
const personResult = result.body.person || {};
|
||||
if (propsValue.cacheResponse) {
|
||||
await store.put(
|
||||
`_apollo_person_${propsValue.email}`,
|
||||
personResult,
|
||||
StoreScope.PROJECT
|
||||
);
|
||||
}
|
||||
return personResult;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
import { apolloAuth } from '../../';
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
import {
|
||||
Property,
|
||||
StoreScope,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
|
||||
export const newsArticlesSearch = createAction({
|
||||
auth: apolloAuth,
|
||||
name: 'newsArticlesSearch',
|
||||
displayName: 'News Articles Search',
|
||||
description:
|
||||
'Search for news articles related to companies in the Apollo database',
|
||||
props: {
|
||||
organization_ids: Property.Array({
|
||||
displayName: 'Organization IDs',
|
||||
description:
|
||||
'The Apollo IDs for the companies you want to include in your search results. To find IDs, call the Organization Search endpoint.',
|
||||
required: true,
|
||||
}),
|
||||
categories: Property.Array({
|
||||
displayName: 'Categories',
|
||||
description:
|
||||
'Filter your search to include only certain categories or sub-categories of news (e.g., hires, investment, contract)',
|
||||
required: false,
|
||||
}),
|
||||
published_at_min: Property.ShortText({
|
||||
displayName: 'Published Date Min',
|
||||
description: 'Lower bound of the date range (YYYY-MM-DD format)',
|
||||
required: false,
|
||||
}),
|
||||
published_at_max: Property.ShortText({
|
||||
displayName: 'Published Date Max',
|
||||
description: 'Upper bound of the date range (YYYY-MM-DD format)',
|
||||
required: false,
|
||||
}),
|
||||
cacheResponse: Property.Checkbox({
|
||||
displayName: 'Cache Response',
|
||||
description: 'Store the response in the project store for future use.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run({ propsValue, auth, store }) {
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
if (propsValue.organization_ids && propsValue.organization_ids.length > 0) {
|
||||
propsValue.organization_ids.forEach((id: unknown) => {
|
||||
queryParams.append('organization_ids[]', id as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (propsValue.categories && propsValue.categories.length > 0) {
|
||||
propsValue.categories.forEach((category: unknown) => {
|
||||
queryParams.append('categories[]', category as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (propsValue.published_at_min) {
|
||||
queryParams.append('published_at[min]', propsValue.published_at_min);
|
||||
}
|
||||
|
||||
if (propsValue.published_at_max) {
|
||||
queryParams.append('published_at[max]', propsValue.published_at_max);
|
||||
}
|
||||
|
||||
const cacheKey = `_apollo_news_${queryParams.toString()}`;
|
||||
|
||||
if (propsValue.cacheResponse) {
|
||||
const cachedResult = await store.get(cacheKey, StoreScope.PROJECT);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
}
|
||||
|
||||
const result = await httpClient.sendRequest<{
|
||||
news_articles: Record<string, unknown>[];
|
||||
pagination: Record<string, unknown>;
|
||||
}>({
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.apollo.io/api/v1/news_articles/search?${queryParams.toString()}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache',
|
||||
'x-api-key': `${auth.secret_text}`,
|
||||
},
|
||||
});
|
||||
|
||||
const response = {
|
||||
news_articles: result.body.news_articles || [],
|
||||
pagination: result.body.pagination || {},
|
||||
};
|
||||
|
||||
if (propsValue.cacheResponse) {
|
||||
await store.put(cacheKey, response, StoreScope.PROJECT);
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import { apolloAuth } from '../../';
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
import {
|
||||
Property,
|
||||
StoreScope,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
|
||||
export const organizationJobPostings = createAction({
|
||||
auth: apolloAuth,
|
||||
name: 'organizationJobPostings',
|
||||
displayName: 'Organization Job Postings',
|
||||
description: 'Retrieve current job postings for a company to identify growing headcount areas',
|
||||
props: {
|
||||
organization_id: Property.ShortText({
|
||||
displayName: 'Organization ID',
|
||||
description: 'The Apollo ID of the organization to get job postings for',
|
||||
required: true,
|
||||
}),
|
||||
cacheResponse: Property.Checkbox({
|
||||
displayName: 'Cache Response',
|
||||
description: 'Store the response in the project store for future use.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run({ propsValue, auth, store }) {
|
||||
const cacheKey = `_apollo_job_postings_${propsValue.organization_id}`;
|
||||
|
||||
if (propsValue.cacheResponse) {
|
||||
const cachedResult = await store.get(cacheKey, StoreScope.PROJECT);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
}
|
||||
|
||||
const result = await httpClient.sendRequest<{
|
||||
organization_job_postings: Record<string, unknown>[];
|
||||
pagination: Record<string, unknown>;
|
||||
}>({
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.apollo.io/api/v1/organizations/${propsValue.organization_id}/job_postings`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache',
|
||||
'x-api-key': `${auth.secret_text}`,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (propsValue.cacheResponse) {
|
||||
await store.put(cacheKey, result.body.organization_job_postings || [], StoreScope.PROJECT);
|
||||
}
|
||||
|
||||
return result.body.organization_job_postings || [];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,145 @@
|
||||
import { apolloAuth } from '../../';
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
import {
|
||||
Property,
|
||||
StoreScope,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
|
||||
export const organizationSearch = createAction({
|
||||
auth: apolloAuth,
|
||||
name: 'organizationSearch',
|
||||
displayName: 'Organization Search',
|
||||
description:
|
||||
'Search for companies in the Apollo database with various filters',
|
||||
props: {
|
||||
q_organization_name: Property.ShortText({
|
||||
displayName: 'Organization Name',
|
||||
description: 'Search by organization name',
|
||||
required: false,
|
||||
}),
|
||||
organization_locations: Property.Array({
|
||||
displayName: 'Organization Locations',
|
||||
description: 'Filter by locations (e.g., texas, tokyo)',
|
||||
required: false,
|
||||
}),
|
||||
organization_not_locations: Property.Array({
|
||||
displayName: 'Exclude Locations',
|
||||
description: 'Exclude specific locations (e.g., minnesota)',
|
||||
required: false,
|
||||
}),
|
||||
organization_num_employees_ranges: Property.Array({
|
||||
displayName: 'Employee Count Ranges',
|
||||
description: 'Filter by employee count ranges (e.g., "1,10", "250,500")',
|
||||
required: false,
|
||||
}),
|
||||
organization_ids: Property.Array({
|
||||
displayName: 'Organization IDs',
|
||||
description: 'Filter by specific organization IDs',
|
||||
required: false,
|
||||
}),
|
||||
q_organization_domains: Property.Array({
|
||||
displayName: 'Domains',
|
||||
description: 'Filter by organization domains',
|
||||
required: false,
|
||||
}),
|
||||
organization_industry_tag_ids: Property.Array({
|
||||
displayName: 'Industry Tag IDs',
|
||||
description: 'Filter by industry tag IDs',
|
||||
required: false,
|
||||
}),
|
||||
cacheResponse: Property.Checkbox({
|
||||
displayName: 'Cache Response',
|
||||
description: 'Store the response in the project store for future use.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run({ propsValue, auth, store }) {
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
if (propsValue.q_organization_name) {
|
||||
queryParams.append('q_organization_name', propsValue.q_organization_name);
|
||||
}
|
||||
if (
|
||||
propsValue.organization_locations &&
|
||||
propsValue.organization_locations.length > 0
|
||||
) {
|
||||
propsValue.organization_locations.forEach((location: unknown) => {
|
||||
queryParams.append('organization_locations[]', location as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
propsValue.organization_not_locations &&
|
||||
propsValue.organization_not_locations.length > 0
|
||||
) {
|
||||
propsValue.organization_not_locations.forEach((location: unknown) => {
|
||||
queryParams.append('organization_not_locations[]', location as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
propsValue.organization_num_employees_ranges &&
|
||||
propsValue.organization_num_employees_ranges.length > 0
|
||||
) {
|
||||
propsValue.organization_num_employees_ranges.forEach((range: unknown) => {
|
||||
queryParams.append(
|
||||
'organization_num_employees_ranges[]',
|
||||
range as string
|
||||
);
|
||||
});
|
||||
}
|
||||
if (propsValue.organization_ids && propsValue.organization_ids.length > 0) {
|
||||
propsValue.organization_ids.forEach((id: unknown) => {
|
||||
queryParams.append('organization_ids[]', id as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
propsValue.q_organization_domains &&
|
||||
propsValue.q_organization_domains.length > 0
|
||||
) {
|
||||
propsValue.q_organization_domains.forEach((domain: unknown) => {
|
||||
queryParams.append('q_organization_domains[]', domain as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
propsValue.organization_industry_tag_ids &&
|
||||
propsValue.organization_industry_tag_ids.length > 0
|
||||
) {
|
||||
propsValue.organization_industry_tag_ids.forEach((tagId: unknown) => {
|
||||
queryParams.append('organization_industry_tag_ids[]', tagId as string);
|
||||
});
|
||||
}
|
||||
|
||||
const cacheKey = `_apollo_org_search_${queryParams.toString()}`;
|
||||
|
||||
if (propsValue.cacheResponse) {
|
||||
const cachedResult = await store.get(cacheKey, StoreScope.PROJECT);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
}
|
||||
|
||||
const result = await httpClient.sendRequest<{
|
||||
organizations: Record<string, unknown>[];
|
||||
pagination: Record<string, unknown>;
|
||||
}>({
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.apollo.io/api/v1/mixed_companies/search?${queryParams.toString()}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache',
|
||||
'x-api-key': `${auth.secret_text}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (propsValue.cacheResponse) {
|
||||
await store.put(cacheKey, result.body, StoreScope.PROJECT);
|
||||
}
|
||||
|
||||
return result.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,161 @@
|
||||
import { apolloAuth } from '../../';
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
import {
|
||||
Property,
|
||||
StoreScope,
|
||||
createAction,
|
||||
} from '@activepieces/pieces-framework';
|
||||
|
||||
export const peopleSearch = createAction({
|
||||
auth: apolloAuth,
|
||||
name: 'peopleSearch',
|
||||
displayName: 'People Search',
|
||||
description:
|
||||
'Search for people in the Apollo database (does not return email/phone, use enrichment for that)',
|
||||
props: {
|
||||
q_keywords: Property.ShortText({
|
||||
displayName: 'Keywords',
|
||||
description: 'Search keywords for people',
|
||||
required: false,
|
||||
}),
|
||||
person_titles: Property.Array({
|
||||
displayName: 'Person Titles',
|
||||
description: 'Filter by job titles (e.g., "CEO", "Sales Manager")',
|
||||
required: false,
|
||||
}),
|
||||
person_locations: Property.Array({
|
||||
displayName: 'Person Locations',
|
||||
description: 'Filter by person locations',
|
||||
required: false,
|
||||
}),
|
||||
person_seniorities: Property.Array({
|
||||
displayName: 'Person Seniorities',
|
||||
description:
|
||||
'Filter by seniority levels (e.g., "senior", "manager", "director")',
|
||||
required: false,
|
||||
}),
|
||||
organization_ids: Property.Array({
|
||||
displayName: 'Organization IDs',
|
||||
description: 'Filter by specific organization IDs',
|
||||
required: false,
|
||||
}),
|
||||
organization_num_employees_ranges: Property.Array({
|
||||
displayName: 'Organization Employee Ranges',
|
||||
description:
|
||||
'Filter by organization employee count ranges (e.g., "1,10", "250,500")',
|
||||
required: false,
|
||||
}),
|
||||
q_organization_domains: Property.Array({
|
||||
displayName: 'Organization Domains',
|
||||
description: 'Filter by organization domains',
|
||||
required: false,
|
||||
}),
|
||||
organization_locations: Property.Array({
|
||||
displayName: 'Organization Locations',
|
||||
description: 'Filter by organization locations',
|
||||
required: false,
|
||||
}),
|
||||
|
||||
cacheResponse: Property.Checkbox({
|
||||
displayName: 'Cache Response',
|
||||
description: 'Store the response in the project store for future use.',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run({ propsValue, auth, store }) {
|
||||
const queryParams = new URLSearchParams();
|
||||
|
||||
if (propsValue.q_keywords) {
|
||||
queryParams.append('q_keywords', propsValue.q_keywords);
|
||||
}
|
||||
|
||||
if (propsValue.person_titles && propsValue.person_titles.length > 0) {
|
||||
propsValue.person_titles.forEach((title: unknown) => {
|
||||
queryParams.append('person_titles[]', title as string);
|
||||
});
|
||||
}
|
||||
if (propsValue.person_locations && propsValue.person_locations.length > 0) {
|
||||
propsValue.person_locations.forEach((location: unknown) => {
|
||||
queryParams.append('person_locations[]', location as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
propsValue.person_seniorities &&
|
||||
propsValue.person_seniorities.length > 0
|
||||
) {
|
||||
propsValue.person_seniorities.forEach((seniority: unknown) => {
|
||||
queryParams.append('person_seniorities[]', seniority as string);
|
||||
});
|
||||
}
|
||||
if (propsValue.organization_ids && propsValue.organization_ids.length > 0) {
|
||||
propsValue.organization_ids.forEach((id: unknown) => {
|
||||
queryParams.append('organization_ids[]', id as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
propsValue.organization_num_employees_ranges &&
|
||||
propsValue.organization_num_employees_ranges.length > 0
|
||||
) {
|
||||
propsValue.organization_num_employees_ranges.forEach((range: unknown) => {
|
||||
queryParams.append(
|
||||
'organization_num_employees_ranges[]',
|
||||
range as string
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
propsValue.q_organization_domains &&
|
||||
propsValue.q_organization_domains.length > 0
|
||||
) {
|
||||
propsValue.q_organization_domains.forEach((domain: unknown) => {
|
||||
queryParams.append('q_organization_domains[]', domain as string);
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
propsValue.organization_locations &&
|
||||
propsValue.organization_locations.length > 0
|
||||
) {
|
||||
propsValue.organization_locations.forEach((location: unknown) => {
|
||||
queryParams.append('organization_locations[]', location as string);
|
||||
});
|
||||
}
|
||||
|
||||
const cacheKey = `_apollo_people_search_${queryParams.toString()}`;
|
||||
|
||||
if (propsValue.cacheResponse) {
|
||||
const cachedResult = await store.get(cacheKey, StoreScope.PROJECT);
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
}
|
||||
|
||||
const result = await httpClient.sendRequest<{
|
||||
people: Record<string, unknown>[];
|
||||
pagination: Record<string, unknown>;
|
||||
}>({
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.apollo.io/api/v1/mixed_people/api_search?${queryParams.toString()}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'no-cache',
|
||||
'x-api-key': `${auth.secret_text}`,
|
||||
},
|
||||
});
|
||||
|
||||
const response = {
|
||||
people: result.body.people || [],
|
||||
pagination: result.body.pagination || {},
|
||||
};
|
||||
|
||||
if (propsValue.cacheResponse) {
|
||||
await store.put(cacheKey, response, StoreScope.PROJECT);
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user