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:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,18 @@
{
"extends": ["../../../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@@ -0,0 +1,7 @@
# pieces-constant-contact
This library was generated with [Nx](https://nx.dev).
## Running lint
Run `nx lint pieces-constant-contact` to execute the lint via [ESLint](https://eslint.org/).

View File

@@ -0,0 +1,4 @@
{
"name": "@activepieces/piece-constant-contact",
"version": "0.1.10"
}

View File

@@ -0,0 +1,51 @@
{
"name": "pieces-constant-contact",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/pieces/community/constant-contact/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": [
"{options.outputPath}"
],
"options": {
"outputPath": "dist/packages/pieces/community/constant-contact",
"tsConfig": "packages/pieces/community/constant-contact/tsconfig.lib.json",
"packageJson": "packages/pieces/community/constant-contact/package.json",
"main": "packages/pieces/community/constant-contact/src/index.ts",
"assets": [
"packages/pieces/community/constant-contact/*.md",
{
"input": "packages/pieces/community/constant-contact/src/i18n",
"output": "./src/i18n",
"glob": "**/!(i18n.json)"
}
],
"buildableProjectDepsInPackageJsonType": "dependencies",
"updateBuildableProjectDepsInPackageJson": true
},
"dependsOn": [
"^build",
"prebuild"
]
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}"
]
},
"prebuild": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/pieces/community/constant-contact",
"command": "bun install --no-save --silent"
},
"dependsOn": [
"^build"
]
}
},
"tags": []
}

View File

@@ -0,0 +1,36 @@
{
"Email marketing for small businesses": "E-Mail-Marketing für kleine Unternehmen",
"Create or Update Contact": "Kontakt erstellen oder aktualisieren",
"Custom API Call": "Eigener API-Aufruf",
"Create or Update a contact in Constant Contact": "Erstellen oder Aktualisieren eines Kontakts in Konstanten",
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
"List": "Liste",
"Email": "E-Mail",
"First Name": "Vorname",
"Last Name": "Nachname",
"Job Title": "Job Titel",
"Company Name": "Firmenname",
"Phone Number": "Telefonnummer",
"Method": "Methode",
"Headers": "Kopfzeilen",
"Query Parameters": "Abfrageparameter",
"Body": "Körper",
"Response is Binary ?": "Antwort ist binär?",
"No Error on Failure": "Kein Fehler bei Fehler",
"Timeout (in seconds)": "Timeout (in Sekunden)",
"The list of the contact": "Die Liste des Kontakts",
"The email of the contact": "Die E-Mail des Kontakts",
"The first name of the contact": "Der Vorname des Kontakts",
"The last name of the contact": "Der Nachname des Kontakts",
"The job title of the contact": "Der Jobtitel des Kontakts",
"The company name of the contact": "Der Firmenname des Kontakts",
"The phone number of the contact": "Die Telefonnummer des Kontakts",
"Authorization headers are injected automatically from your connection.": "Autorisierungs-Header werden automatisch von Ihrer Verbindung injiziert.",
"Enable for files like PDFs, images, etc..": "Aktivieren für Dateien wie PDFs, Bilder, etc..",
"GET": "ERHALTEN",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "LÖSCHEN",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,36 @@
{
"Email marketing for small businesses": "Marketing por correo electrónico para pequeñas empresas",
"Create or Update Contact": "Crear o actualizar contacto",
"Custom API Call": "Llamada API personalizada",
"Create or Update a contact in Constant Contact": "Crear o actualizar un contacto en Contacto Constante",
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
"List": "Lista",
"Email": "E-mail",
"First Name": "Nombre",
"Last Name": "Apellido",
"Job Title": "Trabajo",
"Company Name": "Nombre De La Empresa",
"Phone Number": "Número de teléfono",
"Method": "Método",
"Headers": "Encabezados",
"Query Parameters": "Parámetros de consulta",
"Body": "Cuerpo",
"Response is Binary ?": "¿Respuesta es binaria?",
"No Error on Failure": "No hay ningún error en fallo",
"Timeout (in seconds)": "Tiempo de espera (en segundos)",
"The list of the contact": "La lista del contacto",
"The email of the contact": "El email del contacto",
"The first name of the contact": "El nombre del contacto",
"The last name of the contact": "El apellido del contacto",
"The job title of the contact": "El título del trabajo del contacto",
"The company name of the contact": "El nombre de la empresa del contacto",
"The phone number of the contact": "El número de teléfono del contacto",
"Authorization headers are injected automatically from your connection.": "Las cabeceras de autorización se inyectan automáticamente desde tu conexión.",
"Enable for files like PDFs, images, etc..": "Activar para archivos como PDFs, imágenes, etc.",
"GET": "RECOGER",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "BORRAR",
"HEAD": "LIMPIO"
}

View File

@@ -0,0 +1,36 @@
{
"Email marketing for small businesses": "Marketing par e-mail pour les petites entreprises",
"Create or Update Contact": "Créer ou mettre à jour le contact",
"Custom API Call": "Appel API personnalisé",
"Create or Update a contact in Constant Contact": "Créer ou mettre à jour un contact dans Constant Contact",
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
"List": "Liste",
"Email": "Courriel",
"First Name": "First Name",
"Last Name": "Last Name",
"Job Title": "Titre du poste",
"Company Name": "Nom de lentreprise",
"Phone Number": "Numéro de téléphone",
"Method": "Méthode",
"Headers": "En-têtes",
"Query Parameters": "Paramètres de requête",
"Body": "Corps",
"Response is Binary ?": "La réponse est Binaire ?",
"No Error on Failure": "Aucune erreur en cas d'échec",
"Timeout (in seconds)": "Délai d'attente (en secondes)",
"The list of the contact": "La liste des contacts",
"The email of the contact": "L'e-mail du contact",
"The first name of the contact": "Le prénom du contact",
"The last name of the contact": "Le nom de famille du contact",
"The job title of the contact": "Le titre du poste du contact",
"The company name of the contact": "Le nom de la société du contact",
"The phone number of the contact": "Le numéro de téléphone du contact",
"Authorization headers are injected automatically from your connection.": "Les en-têtes d'autorisation sont injectés automatiquement à partir de votre connexion.",
"Enable for files like PDFs, images, etc..": "Activer pour les fichiers comme les PDFs, les images, etc.",
"GET": "OBTENIR",
"POST": "POSTER",
"PATCH": "PATCH",
"PUT": "EFFACER",
"DELETE": "SUPPRIMER",
"HEAD": "TÊTE"
}

View File

@@ -0,0 +1,36 @@
{
"Email marketing for small businesses": "中小企業向けのメールマーケティング",
"Create or Update Contact": "連絡先を作成または更新",
"Custom API Call": "カスタムAPI通話",
"Create or Update a contact in Constant Contact": "Constant Contact で連絡先を作成または更新する",
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
"List": "リスト",
"Email": "Eメールアドレス",
"First Name": "名",
"Last Name": "姓",
"Job Title": "役職名",
"Company Name": "会社名",
"Phone Number": "電話番号",
"Method": "方法",
"Headers": "ヘッダー",
"Query Parameters": "クエリパラメータ",
"Body": "本文",
"Response is Binary ?": "応答はバイナリですか?",
"No Error on Failure": "失敗時にエラーはありません",
"Timeout (in seconds)": "タイムアウト(秒)",
"The list of the contact": "連絡先のリスト",
"The email of the contact": "連絡先のメールアドレス",
"The first name of the contact": "連絡先の名",
"The last name of the contact": "連絡先の姓",
"The job title of the contact": "連絡先の職名",
"The company name of the contact": "連絡先の会社名",
"The phone number of the contact": "連絡先の電話番号",
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
"GET": "取得",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "削除",
"HEAD": "頭"
}

View File

@@ -0,0 +1,36 @@
{
"Email marketing for small businesses": "E-mailmarketing voor kleine bedrijven",
"Create or Update Contact": "Maken of bijwerken van contactpersoon",
"Custom API Call": "Custom API Call",
"Create or Update a contact in Constant Contact": "Maak of update een contact in Constante Contact",
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
"List": "Klantenlijst",
"Email": "E-mail",
"First Name": "Voornaam",
"Last Name": "Achternaam",
"Job Title": "Job titel",
"Company Name": "Bedrijfsnaam",
"Phone Number": "Telefoon nummer",
"Method": "Methode",
"Headers": "Kopteksten",
"Query Parameters": "Query parameters",
"Body": "Lichaam",
"Response is Binary ?": "Antwoord is binair?",
"No Error on Failure": "Geen fout bij fout",
"Timeout (in seconds)": "Time-out (in seconden)",
"The list of the contact": "De lijst van de contactpersoon",
"The email of the contact": "Het e-mailadres van de contactpersoon",
"The first name of the contact": "De voornaam van het contact",
"The last name of the contact": "De achternaam van de contactpersoon",
"The job title of the contact": "De job titel van de contactpersoon",
"The company name of the contact": "De bedrijfsnaam van de contactpersoon",
"The phone number of the contact": "Het telefoonnummer van de contactpersoon",
"Authorization headers are injected automatically from your connection.": "Autorisatie headers worden automatisch geïnjecteerd vanuit uw verbinding.",
"Enable for files like PDFs, images, etc..": "Inschakelen voor bestanden zoals PDF's, afbeeldingen etc..",
"GET": "KRIJG",
"POST": "POSTE",
"PATCH": "BEKIJK",
"PUT": "PUT",
"DELETE": "VERWIJDEREN",
"HEAD": "HOOFD"
}

View File

@@ -0,0 +1,36 @@
{
"Email marketing for small businesses": "Marketing por e-mail para pequenas empresas",
"Create or Update Contact": "Criar ou atualizar contato",
"Custom API Call": "Chamada de API personalizada",
"Create or Update a contact in Constant Contact": "Criar ou atualizar um contato em constante contato",
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
"List": "Lista",
"Email": "e-mail",
"First Name": "Nome",
"Last Name": "Sobrenome",
"Job Title": "Título do Cargo",
"Company Name": "Nome da Empresa",
"Phone Number": "Número de telefone",
"Method": "Método",
"Headers": "Cabeçalhos",
"Query Parameters": "Parâmetros da consulta",
"Body": "Conteúdo",
"Response is Binary ?": "A resposta é binária ?",
"No Error on Failure": "Nenhum erro no Failure",
"Timeout (in seconds)": "Tempo limite (em segundos)",
"The list of the contact": "A lista de contatos",
"The email of the contact": "O e-mail do contato",
"The first name of the contact": "O primeiro nome do contato",
"The last name of the contact": "O último nome do contato",
"The job title of the contact": "O título do cargo do contato",
"The company name of the contact": "O nome da empresa do contato",
"The phone number of the contact": "O número de telefone do contato",
"Authorization headers are injected automatically from your connection.": "Os cabeçalhos de autorização são inseridos automaticamente a partir da sua conexão.",
"Enable for files like PDFs, images, etc..": "Habilitar para arquivos como PDFs, imagens, etc..",
"GET": "OBTER",
"POST": "POSTAR",
"PATCH": "COMPRAR",
"PUT": "COLOCAR",
"DELETE": "EXCLUIR",
"HEAD": "CABEÇA"
}

View File

@@ -0,0 +1,35 @@
{
"Constant Contact": "Постоянный контакт",
"Email marketing for small businesses": "Почтовый маркетинг для малых предприятий",
"Create or Update Contact": "Создать или обновить контакт",
"Custom API Call": "Пользовательский вызов API",
"Create or Update a contact in Constant Contact": "Создать или обновить контакт в постоянном контакте",
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
"List": "Список",
"Email": "Почта",
"First Name": "First Name",
"Last Name": "Фамилия",
"Job Title": "Заголовок",
"Company Name": "Название компании",
"Phone Number": "Номер телефона",
"Method": "Метод",
"Headers": "Заголовки",
"Query Parameters": "Параметры запроса",
"Body": "Тело",
"No Error on Failure": "Нет ошибок при ошибке",
"Timeout (in seconds)": "Таймаут (в секундах)",
"The list of the contact": "Список контактов",
"The email of the contact": "Email контакта",
"The first name of the contact": "Имя контакта",
"The last name of the contact": "Фамилия контакта",
"The job title of the contact": "Должность контакта",
"The company name of the contact": "Название компании контакта",
"The phone number of the contact": "Номер телефона контакта",
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
"GET": "ПОЛУЧИТЬ",
"POST": "ПОСТ",
"PATCH": "ПАТЧ",
"PUT": "ПОКУПИТЬ",
"DELETE": "УДАЛИТЬ",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,36 @@
{
"Email marketing for small businesses": "Email marketing for small businesses",
"Create or Update Contact": "Create or Update Contact",
"Custom API Call": "Custom API Call",
"Create or Update a contact in Constant Contact": "Create or Update a contact in Constant Contact",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"List": "List",
"Email": "Email",
"First Name": "First Name",
"Last Name": "Last Name",
"Job Title": "Job Title",
"Company Name": "Company Name",
"Phone Number": "Phone Number",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"The list of the contact": "The list of the contact",
"The email of the contact": "The email of the contact",
"The first name of the contact": "The first name of the contact",
"The last name of the contact": "The last name of the contact",
"The job title of the contact": "The job title of the contact",
"The company name of the contact": "The company name of the contact",
"The phone number of the contact": "The phone number of the contact",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,35 @@
{
"Constant Contact": "Constant Contact",
"Email marketing for small businesses": "Email marketing for small businesses",
"Create or Update Contact": "Create or Update Contact",
"Custom API Call": "Custom API Call",
"Create or Update a contact in Constant Contact": "Create or Update a contact in Constant Contact",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"List": "List",
"Email": "Email",
"First Name": "First Name",
"Last Name": "Last Name",
"Job Title": "Job Title",
"Company Name": "Tên công ty",
"Phone Number": "Phone Number",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"The list of the contact": "The list of the contact",
"The email of the contact": "The email of the contact",
"The first name of the contact": "The first name of the contact",
"The last name of the contact": "The last name of the contact",
"The job title of the contact": "The job title of the contact",
"The company name of the contact": "The company name of the contact",
"The phone number of the contact": "The phone number of the contact",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,36 @@
{
"Email marketing for small businesses": "Email marketing for small businesses",
"Create or Update Contact": "Create or Update Contact",
"Custom API Call": "自定义 API 呼叫",
"Create or Update a contact in Constant Contact": "Create or Update a contact in Constant Contact",
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
"List": "List",
"Email": "电子邮件地址",
"First Name": "名字",
"Last Name": "名字",
"Job Title": "Job Title",
"Company Name": "Company Name",
"Phone Number": "Phone Number",
"Method": "方法",
"Headers": "信头",
"Query Parameters": "查询参数",
"Body": "正文内容",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "失败时没有错误",
"Timeout (in seconds)": "超时(秒)",
"The list of the contact": "The list of the contact",
"The email of the contact": "The email of the contact",
"The first name of the contact": "The first name of the contact",
"The last name of the contact": "The last name of the contact",
"The job title of the contact": "The job title of the contact",
"The company name of the contact": "The company name of the contact",
"The phone number of the contact": "The phone number of the contact",
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"GET": "获取",
"POST": "帖子",
"PATCH": "PATCH",
"PUT": "弹出",
"DELETE": "删除",
"HEAD": "黑色"
}

View File

@@ -0,0 +1,37 @@
import { createCustomApiCallAction } from '@activepieces/pieces-common';
import {
OAuth2PropertyValue,
PieceAuth,
createPiece,
} from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { createOrUpdateContact } from './lib/actions/create-or-update-contact';
export const constantContactAuth = PieceAuth.OAuth2({
required: true,
tokenUrl: 'https://authz.constantcontact.com/oauth2/default/v1/token',
authUrl: 'https://authz.constantcontact.com/oauth2/default/v1/authorize',
scope: ['contact_data'],
});
export const constantContact = createPiece({
displayName: 'Constant Contact',
description: 'Email marketing for small businesses',
minimumSupportedRelease: '0.30.0',
logoUrl: 'https://cdn.activepieces.com/pieces/constant-contact.png',
categories: [PieceCategory.MARKETING],
authors: ["kishanprmr","MoShizzle","khaledmashaly","abuaboud"],
auth: constantContactAuth,
actions: [
createOrUpdateContact,
createCustomApiCallAction({
baseUrl: () => 'https://api.cc.email/v3', // Replace with the actual base URL
auth: constantContactAuth,
authMapping: async (auth) => ({
Authorization: `Bearer ${auth.access_token}`,
}),
}),
],
triggers: [],
});

View File

@@ -0,0 +1,108 @@
import {
OAuth2PropertyValue,
Property,
createAction,
} from '@activepieces/pieces-framework';
import {
AuthenticationType,
httpClient,
HttpMethod,
} from '@activepieces/pieces-common';
import { constantContactAuth } from '../../';
export const createOrUpdateContact = createAction({
auth: constantContactAuth,
name: 'create_or_update_contact',
displayName: 'Create or Update Contact',
description: 'Create or Update a contact in Constant Contact',
props: {
list: Property.MultiSelectDropdown({
auth: constantContactAuth,
displayName: 'List',
description: 'The list of the contact',
required: true,
refreshers: [],
options: async ({ auth }) => {
if (!auth) {
return {
options: [],
placeholder: 'Connect to Constant Contact to see the lists',
disabled: true,
};
}
return {
placeholder: 'Select a list',
disabled: false,
options: (
await httpClient.sendRequest<{
lists: { list_id: string; name: string }[];
}>({
url: 'https://api.cc.email/v3/contact_lists',
method: HttpMethod.GET,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: (auth)['access_token'],
},
})
).body.lists.map((list) => {
return {
value: list.list_id,
label: list.name,
};
}),
};
},
}),
email_address: Property.ShortText({
displayName: 'Email',
description: 'The email of the contact',
required: true,
}),
first_name: Property.ShortText({
displayName: 'First Name',
description: 'The first name of the contact',
required: false,
}),
last_name: Property.ShortText({
displayName: 'Last Name',
description: 'The last name of the contact',
required: false,
}),
job_title: Property.ShortText({
displayName: 'Job Title',
description: 'The job title of the contact',
required: false,
}),
company_name: Property.ShortText({
displayName: 'Company Name',
description: 'The company name of the contact',
required: false,
}),
phoner_number: Property.ShortText({
displayName: 'Phone Number',
description: 'The phone number of the contact',
required: false,
}),
},
run: async ({ auth, propsValue }) => {
return (
await httpClient.sendRequest({
url: 'https://api.cc.email/v3/contacts/sign_up_form',
method: HttpMethod.POST,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: auth.access_token,
},
body: {
email_address: propsValue.email_address,
first_name: propsValue.first_name,
last_name: propsValue.last_name,
job_title: propsValue.job_title,
company_name: propsValue.company_name,
phoner_number: propsValue.phoner_number,
list_memberships: propsValue.list,
},
})
).body;
},
});

View File

@@ -0,0 +1,16 @@
{
"extends": "../../../../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
],
"compilerOptions": {
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
}
}

View File

@@ -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"]
}