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-capsule-crm
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-capsule-crm` to build the library.
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@activepieces/piece-capsule-crm",
|
||||
"version": "0.0.2",
|
||||
"type": "commonjs",
|
||||
"main": "./src/index.js",
|
||||
"types": "./src/index.d.ts",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "pieces-capsule-crm",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/capsule-crm/src",
|
||||
"projectType": "library",
|
||||
"release": {
|
||||
"version": {
|
||||
"manifestRootsToUpdate": [
|
||||
"dist/{projectRoot}"
|
||||
],
|
||||
"currentVersionResolver": "git-tag",
|
||||
"fallbackCurrentVersionResolver": "disk"
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/capsule-crm",
|
||||
"tsConfig": "packages/pieces/community/capsule-crm/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/capsule-crm/package.json",
|
||||
"main": "packages/pieces/community/capsule-crm/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/capsule-crm/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/capsule-crm/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"nx-release-publish": {
|
||||
"options": {
|
||||
"packageRoot": "dist/{projectRoot}"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/capsule-crm",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.": "\n Zur Authentifizierung mit Capsule CRM:\n 1. Gehen Sie zu Ihren Capsule CRM Benutzereinstellungen.\n 2. Navigieren Sie zu \"Meine Einstellungen\" > \"API-Authentifizierungs-Tokens\".\n 3. Registrieren Sie eine neue Anwendung, um eine Client ID und Client Secret zu erhalten.\n 4. Fügen Sie https://cloud hinzu. ctivepieces.com/redirect zu den autorisierten Weiterleitungs-URIs.\n 5. Verwenden Sie den OAuth2-Fluss unten.",
|
||||
"Create Contact": "Kontakt erstellen",
|
||||
"Update Contact": "Kontakt aktualisieren",
|
||||
"Create Opportunity": "Verkaufschance erstellen",
|
||||
"Create Project": "Projekt erstellen",
|
||||
"Create Task": "Aufgabe erstellen",
|
||||
"Update Opportunity": "Update-Verkaufschance",
|
||||
"Add Note to Entity": "Notiz zu Entität hinzufügen",
|
||||
"Find Contact": "Kontakt finden",
|
||||
"Find Project": "Projekt finden",
|
||||
"Find Opportunity": "Verkaufschance suchen",
|
||||
"Create a new Person or Organisation in Capsule CRM.": "Erstellen Sie eine neue Person oder Organisation in Capsule CRM.",
|
||||
"Update fields on an existing Person or Organisation.": "Felder einer bestehenden Person oder Organisation aktualisieren.",
|
||||
"Create a new Opportunity in Capsule CRM.": "Erstellen Sie eine neue Verkaufschance in Capsule CRM.",
|
||||
"Create a new Project in Capsule CRM.": "Erstellen Sie ein neues Projekt in Capsule CRM.",
|
||||
"Create a new Task in Capsule CRM.": "Erstellen Sie eine neue Aufgabe in Capsule CRM.",
|
||||
"Update an existing Opportunity in Capsule CRM.": "Aktualisieren Sie eine vorhandene Verkaufschance in Capsule CRM.",
|
||||
"Add a comment/note to an entity (e.g., contact, opportunity, project).": "Kommentar/Notiz zu einer Entität hinzufügen (z. B. Kontakt, Chance, Projekt).",
|
||||
"Find a Person by search criteria.": "Finden Sie eine Person nach Suchkriterien.",
|
||||
"Find a Project by search criteria.": "Suchen Sie ein Projekt nach Suchkriterien.",
|
||||
"Find an Opportunity by search criteria.": "Finden Sie eine Verkaufschance anhand von Suchkriterien.",
|
||||
"Contact Type": "Kontakttyp",
|
||||
"Details": "Details",
|
||||
"About": "Über",
|
||||
"Owner": "Besitzer",
|
||||
"Team": "Team",
|
||||
"Tags": "Tags",
|
||||
"Custom Fields": "Eigene Felder",
|
||||
"Email Addresses": "E-Mail-Adressen",
|
||||
"Phone Numbers": "Telefonnummern",
|
||||
"Addresses": "Adressen",
|
||||
"Websites": "Webseiten",
|
||||
"Contact": "Kontakt",
|
||||
"Party": "Gruppe",
|
||||
"Name": "Name",
|
||||
"Description": "Beschreibung",
|
||||
"Milestone": "Meilenstein",
|
||||
"Currency": "Währung",
|
||||
"Amount": "Betrag",
|
||||
"Expected Close Date": "Erwartetes Enddatum",
|
||||
"Probability": "Wahrscheinlichkeit",
|
||||
"Duration Basis": "Dauer",
|
||||
"Duration": "Dauer",
|
||||
"Opportunity": "Verkaufschance",
|
||||
"Stage": "Teil",
|
||||
"Status": "Status",
|
||||
"Due Date": "Fälligkeitsdatum",
|
||||
"Due Time": "Fällige Zeit",
|
||||
"Link To": "Link zu",
|
||||
"Linked Entity": "Verknüpfte Entität",
|
||||
"Category": "Kategorie",
|
||||
"Note Content": "Notiz Inhalt",
|
||||
"Entity Type": "Entitätstyp",
|
||||
"Entity": "Entität",
|
||||
"Activity Type": "Aktivitätstyp",
|
||||
"Search Term": "Suchbegriff",
|
||||
"Filter": "Filtern",
|
||||
"The type of contact to create.": "Die Art des zu erstellenden Kontakts.",
|
||||
"The contact (Person or Organisation) to select.": "Der zu wählende Kontakt (Person oder Organisation).",
|
||||
"The user to assign the task to.": "Der Benutzer, dem die Aufgabe zugewiesen wird.",
|
||||
"The team to assign the contact to.": "Das Team, dem der Kontakt zugewiesen werden soll.",
|
||||
"Update the biography or description for the contact.": "Aktualisieren Sie die Biographie oder Beschreibung für den Kontakt.",
|
||||
"A short description of the opportunity.": "Eine kurze Beschreibung der Möglichkeit.",
|
||||
"More details about the opportunity.": "Mehr Details zur Chance.",
|
||||
"The currency for the opportunity value (e.g., USD, GBP).": "Die Währung für den Opportunity-Wert (z.B. USD, GBP).",
|
||||
"The numerical value of the opportunity.": "Der numerische Wert der Chance.",
|
||||
"The expected closing date for the opportunity.": "Das erwartete Enddatum für die Chance.",
|
||||
"The probability of winning the opportunity.": "Die Wahrscheinlichkeit, die Chance zu gewinnen.",
|
||||
"The basis of the duration of the opportunity.": "Die Grundlage für die Dauer der Möglichkeit.",
|
||||
"The duration of the opportunity.": "Die Dauer der Möglichkeit.",
|
||||
"The user the opportunity is assigned to.": "Der Benutzer, dem die Chance zugewiesen wurde.",
|
||||
"The team the opportunity is assigned to.": "Das Team, dem die Gelegenheit zugewiesen ist.",
|
||||
"The main contact for this project.": "Der Hauptkontakt für dieses Projekt.",
|
||||
"The name of this project.": "Der Name dieses Projekts.",
|
||||
"The description of this project.": "Die Beschreibung dieses Projekts.",
|
||||
"An optional link to the opportunity that this project was created to support.": "Ein optionaler Link zu der Möglichkeit, die dieses Projekt zur Unterstützung erstellt hat.",
|
||||
"The stage that this project is on.": "Die Phase, in der sich dieses Projekt befindet.",
|
||||
"The status of the project.": "Der Status des Projekts.",
|
||||
"The expected close date of this project.": "Das erwartete Enddatum dieses Projekts.",
|
||||
"The user this project is assigned to.": "Der Benutzer, dem dieses Projekt zugewiesen ist.",
|
||||
"The team this project is assigned to.": "Das Team, dem dieses Projekt zugewiesen ist.",
|
||||
"An array of tags that are added to this project.": "Ein Array von Tags, die diesem Projekt hinzugefügt werden.",
|
||||
"An array of custom fields that are defined for this project.": "Ein Array von benutzerdefinierten Feldern, die für dieses Projekt definiert sind.",
|
||||
"A short description of the task.": "Eine kurze Beschreibung der Aufgabe.",
|
||||
"The date when this task is due.": "Das Datum, an dem diese Aufgabe fällig ist.",
|
||||
"More details about the task.": "Mehr Details zur Aufgabe.",
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.": "Die Zeit, zu der diese Aufgabe fällig ist (z.B. 18:00:00). Hinweis: Die Zeit ist in der Zeitzone des Benutzers.",
|
||||
"The entity this task is linked to. Only one can be selected.": "Die Entität, mit der diese Aufgabe verknüpft ist. Nur eine kann ausgewählt werden.",
|
||||
"The category of this task.": "Die Kategorie dieser Aufgabe.",
|
||||
"The user this task is assigned to.": "Der Benutzer, dem diese Aufgabe zugewiesen ist.",
|
||||
"The body of the note.": "Der Text der Notiz.",
|
||||
"The type of entity to add the note to.": "Der Typ der Entität, der die Notiz hinzugefügt werden soll.",
|
||||
"The activity type for this entry. Defaults to \"Note\".": "Der Aktivitätstyp für diesen Eintrag. Standard ist \"Notiz\".",
|
||||
"The value to search for (e.g., a name or email).": "Der zu suchende Wert (z.B. Name oder E-Mail).",
|
||||
"The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.": "Die strukturierte Filterabfrage. Siehe die [documentation](https://capsulecrm.com/developer/api-v2/filters/) für Beispiele.",
|
||||
"Person": "Person",
|
||||
"Organisation": "Organisation",
|
||||
"Fixed": "Feste",
|
||||
"Hour": "Stunde",
|
||||
"Day": "Tag",
|
||||
"Week": "Woche",
|
||||
"Month": "Monat",
|
||||
"Quarter": "Quartal",
|
||||
"Year": "Jahr",
|
||||
"Open": "Öffnen",
|
||||
"Closed": "Geschlossen",
|
||||
"Party (Contact)": "Gruppe (Kontakt)",
|
||||
"Project": "Projekt",
|
||||
"New Case": "Neuer Fall",
|
||||
"New Opportunity": "Neue Verkaufschance",
|
||||
"New Task": "Neue Aufgabe",
|
||||
"New Project": "Neues Projekt",
|
||||
"Fires when a new case (project) is created in Capsule CRM.": "Feuert ab, wenn ein neuer Fall (Projekt) in Capsule CRM erstellt wird.",
|
||||
"Fires when a new opportunity is created.": "Feuert ab, wenn eine neue Chance geschaffen wird.",
|
||||
"Fires when a new task is created.": "Feuert ab, wenn eine neue Aufgabe erstellt wird.",
|
||||
"Fires when a project is created.": "Feuert ab, wenn ein Projekt erstellt wird."
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.": "\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.",
|
||||
"Create Contact": "Crear contacto",
|
||||
"Update Contact": "Actualizar contacto",
|
||||
"Create Opportunity": "Crear Oportunidad",
|
||||
"Create Project": "Crear proyecto",
|
||||
"Create Task": "Crear tarea",
|
||||
"Update Opportunity": "Actualizar Oportunidad",
|
||||
"Add Note to Entity": "Añadir Nota a Entidad",
|
||||
"Find Contact": "Encontrar contacto",
|
||||
"Find Project": "Buscar proyecto",
|
||||
"Find Opportunity": "Buscar Oportunidad",
|
||||
"Create a new Person or Organisation in Capsule CRM.": "Crear una nueva persona u organización en Capsule CRM.",
|
||||
"Update fields on an existing Person or Organisation.": "Actualizar campos en una persona u organización existente.",
|
||||
"Create a new Opportunity in Capsule CRM.": "Crear una nueva oportunidad en Cápsula CRM.",
|
||||
"Create a new Project in Capsule CRM.": "Crear un nuevo proyecto en Cápsula CRM.",
|
||||
"Create a new Task in Capsule CRM.": "Crear una nueva tarea en Cápsula CRM.",
|
||||
"Update an existing Opportunity in Capsule CRM.": "Actualizar una Oportunidad existente en Cápsula CRM.",
|
||||
"Add a comment/note to an entity (e.g., contact, opportunity, project).": "Añadir un comentario/nota a una entidad (por ejemplo, contacto, oportunidad, proyecto).",
|
||||
"Find a Person by search criteria.": "Encuentre una Persona por criterios de búsqueda.",
|
||||
"Find a Project by search criteria.": "Buscar un proyecto por criterios de búsqueda.",
|
||||
"Find an Opportunity by search criteria.": "Encuentre una Oportunidad por criterios de búsqueda.",
|
||||
"Contact Type": "Tipo de contacto",
|
||||
"Details": "Detalles",
|
||||
"About": "Acerca de",
|
||||
"Owner": "Propietario",
|
||||
"Team": "Equipo",
|
||||
"Tags": "Etiquetas",
|
||||
"Custom Fields": "Campos personalizados",
|
||||
"Email Addresses": "Direcciones de email",
|
||||
"Phone Numbers": "Números de teléfono",
|
||||
"Addresses": "Direcciones",
|
||||
"Websites": "Sitios web",
|
||||
"Contact": "Contacto",
|
||||
"Party": "Fiesta",
|
||||
"Name": "Nombre",
|
||||
"Description": "Descripción",
|
||||
"Milestone": "Hito",
|
||||
"Currency": "Moneda",
|
||||
"Amount": "Cantidad",
|
||||
"Expected Close Date": "Fecha de cierre esperada",
|
||||
"Probability": "Probabilidad",
|
||||
"Duration Basis": "Duración base",
|
||||
"Duration": "Duración",
|
||||
"Opportunity": "Oportunidad",
|
||||
"Stage": "Etapa",
|
||||
"Status": "Estado",
|
||||
"Due Date": "Fecha de fin",
|
||||
"Due Time": "Hora límite",
|
||||
"Link To": "Enlace a",
|
||||
"Linked Entity": "Entidad vinculada",
|
||||
"Category": "Categoría",
|
||||
"Note Content": "Contenido de Nota",
|
||||
"Entity Type": "Tipo de entidad",
|
||||
"Entity": "Entidad",
|
||||
"Activity Type": "Tipo de actividad",
|
||||
"Search Term": "Buscar término",
|
||||
"Filter": "Filtro",
|
||||
"The type of contact to create.": "El tipo de contacto a crear.",
|
||||
"The contact (Person or Organisation) to select.": "El contacto (Persona u Organización) para seleccionar.",
|
||||
"The user to assign the task to.": "El usuario al que asignar la tarea.",
|
||||
"The team to assign the contact to.": "El equipo al que asignar el contacto.",
|
||||
"Update the biography or description for the contact.": "Actualizar la biografía o descripción del contacto.",
|
||||
"A short description of the opportunity.": "Una breve descripción de la oportunidad.",
|
||||
"More details about the opportunity.": "Más detalles sobre la oportunidad.",
|
||||
"The currency for the opportunity value (e.g., USD, GBP).": "La moneda para el valor de oportunidad (por ejemplo, USD, GBP).",
|
||||
"The numerical value of the opportunity.": "El valor numérico de la oportunidad.",
|
||||
"The expected closing date for the opportunity.": "La fecha de cierre prevista para la oportunidad.",
|
||||
"The probability of winning the opportunity.": "La probabilidad de ganar la oportunidad.",
|
||||
"The basis of the duration of the opportunity.": "La base de la duración de la oportunidad.",
|
||||
"The duration of the opportunity.": "La duración de la oportunidad.",
|
||||
"The user the opportunity is assigned to.": "El usuario al que se ha asignado la oportunidad.",
|
||||
"The team the opportunity is assigned to.": "El equipo al que se ha asignado la oportunidad.",
|
||||
"The main contact for this project.": "El contacto principal para este proyecto.",
|
||||
"The name of this project.": "El nombre de este proyecto.",
|
||||
"The description of this project.": "La descripción de este proyecto.",
|
||||
"An optional link to the opportunity that this project was created to support.": "Un enlace opcional a la oportunidad que este proyecto fue creado para apoyar.",
|
||||
"The stage that this project is on.": "La fase en la que se encuentra este proyecto.",
|
||||
"The status of the project.": "El estado del proyecto.",
|
||||
"The expected close date of this project.": "La fecha prevista de cierre de este proyecto.",
|
||||
"The user this project is assigned to.": "El usuario al que este proyecto está asignado.",
|
||||
"The team this project is assigned to.": "El equipo al que este proyecto está asignado.",
|
||||
"An array of tags that are added to this project.": "Un array de etiquetas que se añaden a este proyecto.",
|
||||
"An array of custom fields that are defined for this project.": "Un array de campos personalizados que están definidos para este proyecto.",
|
||||
"A short description of the task.": "Una breve descripción de la tarea.",
|
||||
"The date when this task is due.": "La fecha en que esta tarea es vencida.",
|
||||
"More details about the task.": "Más detalles sobre la tarea.",
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.": "El tiempo en que esta tarea es debido (por ejemplo, 18:00:00). Nota: La hora está en la zona horaria del usuario.",
|
||||
"The entity this task is linked to. Only one can be selected.": "La entidad a la que esta tarea está vinculada. Sólo una puede ser seleccionada.",
|
||||
"The category of this task.": "La categoría de esta tarea.",
|
||||
"The user this task is assigned to.": "El usuario al que esta tarea está asignada.",
|
||||
"The body of the note.": "El cuerpo de la nota.",
|
||||
"The type of entity to add the note to.": "El tipo de entidad a la que agregar la nota.",
|
||||
"The activity type for this entry. Defaults to \"Note\".": "El tipo de actividad para esta entrada. Por defecto es \"Nota\".",
|
||||
"The value to search for (e.g., a name or email).": "El valor a buscar (por ejemplo, un nombre o correo electrónico).",
|
||||
"The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.": "La consulta de filtro estructurado. Vea la [documentation](https://capsulecrm.com/developer/api-v2/filters/) para ver ejemplos.",
|
||||
"Person": "Persona",
|
||||
"Organisation": "Organisation",
|
||||
"Fixed": "Fijado",
|
||||
"Hour": "Hora",
|
||||
"Day": "Día",
|
||||
"Week": "Semana",
|
||||
"Month": "Mes",
|
||||
"Quarter": "Triturador",
|
||||
"Year": "Año",
|
||||
"Open": "Abrir",
|
||||
"Closed": "Cerrado",
|
||||
"Party (Contact)": "Fiesta (Contacto)",
|
||||
"Project": "Projekt",
|
||||
"New Case": "Nuevo Caso",
|
||||
"New Opportunity": "Nueva oportunidad",
|
||||
"New Task": "Nueva tarea",
|
||||
"New Project": "Nuevo proyecto",
|
||||
"Fires when a new case (project) is created in Capsule CRM.": "Dispara cuando se crea un nuevo caso (proyecto) en Cápsula CRM.",
|
||||
"Fires when a new opportunity is created.": "Dispara cuando se crea una nueva oportunidad.",
|
||||
"Fires when a new task is created.": "Dispara cuando se crea una nueva tarea.",
|
||||
"Fires when a project is created.": "Dispara cuando se crea un proyecto."
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.": "\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.",
|
||||
"Create Contact": "Créer un contact",
|
||||
"Update Contact": "Mettre à jour le contact",
|
||||
"Create Opportunity": "Créer une Affaire",
|
||||
"Create Project": "Créer un projet",
|
||||
"Create Task": "Créer une tâche",
|
||||
"Update Opportunity": "Mettre à jour l'Affaire",
|
||||
"Add Note to Entity": "Ajouter une note à l'entité",
|
||||
"Find Contact": "Trouver un contact",
|
||||
"Find Project": "Trouver un projet",
|
||||
"Find Opportunity": "Trouver une opportunité",
|
||||
"Create a new Person or Organisation in Capsule CRM.": "Créer une nouvelle Personne ou Organisation dans Capsule CRM.",
|
||||
"Update fields on an existing Person or Organisation.": "Mettre à jour les champs sur une personne ou une organisation existante.",
|
||||
"Create a new Opportunity in Capsule CRM.": "Créer une nouvelle opportunité dans Capsule CRM.",
|
||||
"Create a new Project in Capsule CRM.": "Créer un nouveau projet dans Capsule CRM.",
|
||||
"Create a new Task in Capsule CRM.": "Créer une nouvelle tâche dans Capsule CRM.",
|
||||
"Update an existing Opportunity in Capsule CRM.": "Mettre à jour une opportunité existante dans Capsule CRM.",
|
||||
"Add a comment/note to an entity (e.g., contact, opportunity, project).": "Ajouter un commentaire/note à une entité (par exemple, contact, opportunité, projet).",
|
||||
"Find a Person by search criteria.": "Trouver une personne par critère de recherche.",
|
||||
"Find a Project by search criteria.": "Trouver un projet par critères de recherche.",
|
||||
"Find an Opportunity by search criteria.": "Trouver une Opportunité par critères de recherche.",
|
||||
"Contact Type": "Type de contact",
|
||||
"Details": "Détails",
|
||||
"About": "À propos de",
|
||||
"Owner": "Propriétaire",
|
||||
"Team": "Équipe",
|
||||
"Tags": "Tags",
|
||||
"Custom Fields": "Champs personnalisés",
|
||||
"Email Addresses": "Adresses e-mail",
|
||||
"Phone Numbers": "Numéros de téléphone",
|
||||
"Addresses": "Adresses",
|
||||
"Websites": "Sites web",
|
||||
"Contact": "Contacter",
|
||||
"Party": "Soirée",
|
||||
"Name": "Nom",
|
||||
"Description": "Libellé",
|
||||
"Milestone": "Jalon",
|
||||
"Currency": "Devise",
|
||||
"Amount": "Montant",
|
||||
"Expected Close Date": "Date de clôture prévue",
|
||||
"Probability": "Probabilité",
|
||||
"Duration Basis": "Durée de la base",
|
||||
"Duration": "Durée",
|
||||
"Opportunity": "Opportunité",
|
||||
"Stage": "Étape",
|
||||
"Status": "Statut",
|
||||
"Due Date": "Date de fin",
|
||||
"Due Time": "Heure d'échéance",
|
||||
"Link To": "Lien vers",
|
||||
"Linked Entity": "Entité liée",
|
||||
"Category": "Catégorie",
|
||||
"Note Content": "Contenu de la note",
|
||||
"Entity Type": "Type d'entité",
|
||||
"Entity": "Entité",
|
||||
"Activity Type": "Type d'activité",
|
||||
"Search Term": "Terme de recherche",
|
||||
"Filter": "Filtre",
|
||||
"The type of contact to create.": "Le type de contact à créer.",
|
||||
"The contact (Person or Organisation) to select.": "Le contact (Personne ou Organisation) à sélectionner.",
|
||||
"The user to assign the task to.": "L'utilisateur à assigner la tâche.",
|
||||
"The team to assign the contact to.": "L'équipe à laquelle il faut assigner le contact.",
|
||||
"Update the biography or description for the contact.": "Mettre à jour la biographie ou la description du contact.",
|
||||
"A short description of the opportunity.": "Une courte description de l'opportunité.",
|
||||
"More details about the opportunity.": "Plus de détails sur l'opportunité.",
|
||||
"The currency for the opportunity value (e.g., USD, GBP).": "La devise de la valeur de l'opportunité (par exemple, USD, GBP).",
|
||||
"The numerical value of the opportunity.": "La valeur numérique de l'opportunité.",
|
||||
"The expected closing date for the opportunity.": "La date de clôture prévue pour l'occasion.",
|
||||
"The probability of winning the opportunity.": "La probabilité de gagner l'occasion.",
|
||||
"The basis of the duration of the opportunity.": "La base de la durée de l'opportunité.",
|
||||
"The duration of the opportunity.": "La durée de l'opportunité.",
|
||||
"The user the opportunity is assigned to.": "L'utilisateur auquel cette opportunité est assignée.",
|
||||
"The team the opportunity is assigned to.": "L’équipe à laquelle cette opportunité est assignée.",
|
||||
"The main contact for this project.": "Le contact principal pour ce projet.",
|
||||
"The name of this project.": "Le nom de ce projet.",
|
||||
"The description of this project.": "La description de ce projet.",
|
||||
"An optional link to the opportunity that this project was created to support.": "Un lien facultatif vers l'opportunité que ce projet a été créé pour soutenir.",
|
||||
"The stage that this project is on.": "Le stade où ce projet est en cours.",
|
||||
"The status of the project.": "Le statut du projet.",
|
||||
"The expected close date of this project.": "La date de clôture prévue de ce projet.",
|
||||
"The user this project is assigned to.": "L'utilisateur auquel ce projet est assigné.",
|
||||
"The team this project is assigned to.": "L'équipe à laquelle ce projet est assigné.",
|
||||
"An array of tags that are added to this project.": "Un tableau de balises qui sont ajoutées à ce projet.",
|
||||
"An array of custom fields that are defined for this project.": "Un tableau de champs personnalisés qui sont définis pour ce projet.",
|
||||
"A short description of the task.": "Une courte description de la tâche.",
|
||||
"The date when this task is due.": "La date à laquelle cette tâche est due.",
|
||||
"More details about the task.": "Plus de détails sur la tâche.",
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.": "L'heure à laquelle cette tâche est due (par exemple, 18:00:00). Note: L'heure est dans le fuseau horaire de l'utilisateur.",
|
||||
"The entity this task is linked to. Only one can be selected.": "L'entité à laquelle cette tâche est liée. Une seule peut être sélectionnée.",
|
||||
"The category of this task.": "La catégorie de cette tâche.",
|
||||
"The user this task is assigned to.": "L'utilisateur auquel cette tâche est assignée.",
|
||||
"The body of the note.": "Le corps de la note.",
|
||||
"The type of entity to add the note to.": "Le type d'entité auquel ajouter la note.",
|
||||
"The activity type for this entry. Defaults to \"Note\".": "Le type d'activité pour cette entrée. Par défaut, \"Note\".",
|
||||
"The value to search for (e.g., a name or email).": "La valeur à rechercher (par exemple, un nom ou un e-mail).",
|
||||
"The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.": "La requête de filtre structuré. Voir la [documentation](https://capsulecrm.com/developer/api-v2/filters/) pour des exemples.",
|
||||
"Person": "Personne",
|
||||
"Organisation": "Organisation",
|
||||
"Fixed": "Fixe",
|
||||
"Hour": "Heure",
|
||||
"Day": "Jour",
|
||||
"Week": "Semaine",
|
||||
"Month": "Mois",
|
||||
"Quarter": "Trimestre",
|
||||
"Year": "Année",
|
||||
"Open": "Ouvert",
|
||||
"Closed": "Fermé",
|
||||
"Party (Contact)": "Groupe (Contact)",
|
||||
"Project": "Votre compte",
|
||||
"New Case": "Nouveau Cas",
|
||||
"New Opportunity": "Nouvelle opportunité",
|
||||
"New Task": "Nouvelle tâche",
|
||||
"New Project": "Nouveau projet",
|
||||
"Fires when a new case (project) is created in Capsule CRM.": "Se déclenche lorsqu'un nouveau cas (projet) est créé dans Capsule CRM.",
|
||||
"Fires when a new opportunity is created.": "Tire quand une nouvelle opportunité est créée.",
|
||||
"Fires when a new task is created.": "Tire quand une nouvelle tâche est créée.",
|
||||
"Fires when a project is created.": "Se déclenche lorsqu'un projet est créé."
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.": "\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.",
|
||||
"Create Contact": "連絡先を作成",
|
||||
"Update Contact": "連絡先を更新",
|
||||
"Create Opportunity": "案件を作成",
|
||||
"Create Project": "プロジェクトを作成",
|
||||
"Create Task": "タスクを作成",
|
||||
"Update Opportunity": "商談を更新",
|
||||
"Add Note to Entity": "エンティティにメモを追加",
|
||||
"Find Contact": "連絡先を探す",
|
||||
"Find Project": "プロジェクトを検索",
|
||||
"Find Opportunity": "商談を探す",
|
||||
"Create a new Person or Organisation in Capsule CRM.": "Capsule CRM に新しい人または組織を作成します。",
|
||||
"Update fields on an existing Person or Organisation.": "既存の個人または組織のフィールドを更新します。",
|
||||
"Create a new Opportunity in Capsule CRM.": "Capsule CRM に新しい機会を作成します。",
|
||||
"Create a new Project in Capsule CRM.": "Capsule CRM に新しいプロジェクトを作成します。",
|
||||
"Create a new Task in Capsule CRM.": "Capsule CRM に新しいタスクを作成します。",
|
||||
"Update an existing Opportunity in Capsule CRM.": "Capsule CRM 内の既存の機会を更新します。",
|
||||
"Add a comment/note to an entity (e.g., contact, opportunity, project).": "エンティティにコメント/メモを追加 (取引先責任者、商談、プロジェクトなど)。",
|
||||
"Find a Person by search criteria.": "検索条件で人を検索します。",
|
||||
"Find a Project by search criteria.": "検索条件でプロジェクトを検索します。",
|
||||
"Find an Opportunity by search criteria.": "検索条件で商談を検索します。",
|
||||
"Contact Type": "連絡先の種類",
|
||||
"Details": "詳細",
|
||||
"About": "About",
|
||||
"Owner": "所有者",
|
||||
"Team": "Team",
|
||||
"Tags": "タグ",
|
||||
"Custom Fields": "カスタムフィールド",
|
||||
"Email Addresses": "メールアドレス",
|
||||
"Phone Numbers": "電話番号",
|
||||
"Addresses": "アドレス",
|
||||
"Websites": "ウェブサイト",
|
||||
"Contact": "お問い合わせ",
|
||||
"Party": "パーティー",
|
||||
"Name": "Name",
|
||||
"Description": "説明",
|
||||
"Milestone": "マイルストーン",
|
||||
"Currency": "通貨",
|
||||
"Amount": "金額",
|
||||
"Expected Close Date": "終了予定日",
|
||||
"Probability": "可能性",
|
||||
"Duration Basis": "Duration Basis",
|
||||
"Duration": "期間",
|
||||
"Opportunity": "機会",
|
||||
"Stage": "ステージ",
|
||||
"Status": "Status",
|
||||
"Due Date": "締切日",
|
||||
"Due Time": "締切日時",
|
||||
"Link To": "リンク先",
|
||||
"Linked Entity": "リンクされたエンティティ",
|
||||
"Category": "カテゴリ",
|
||||
"Note Content": "ノートコンテンツ",
|
||||
"Entity Type": "エンティティタイプ",
|
||||
"Entity": "エンティティ",
|
||||
"Activity Type": "活動タイプ",
|
||||
"Search Term": "検索用語",
|
||||
"Filter": "フィルター",
|
||||
"The type of contact to create.": "作成する連絡先の種類",
|
||||
"The contact (Person or Organisation) to select.": "選択する連絡先 (個人または組織) 。",
|
||||
"The user to assign the task to.": "タスクを割り当てるユーザー",
|
||||
"The team to assign the contact to.": "連絡先を割り当てるチーム。",
|
||||
"Update the biography or description for the contact.": "連絡先の伝記または説明を更新します。",
|
||||
"A short description of the opportunity.": "機会の簡単な説明。",
|
||||
"More details about the opportunity.": "機会についての詳細。",
|
||||
"The currency for the opportunity value (e.g., USD, GBP).": "商談値の通貨(例:USD、GBP)。",
|
||||
"The numerical value of the opportunity.": "機会の数値。",
|
||||
"The expected closing date for the opportunity.": "案件の終了予定日。",
|
||||
"The probability of winning the opportunity.": "チャンスを勝ち取る確率。",
|
||||
"The basis of the duration of the opportunity.": "機会の持続時間の基礎。",
|
||||
"The duration of the opportunity.": "機会の持続時間。",
|
||||
"The user the opportunity is assigned to.": "商談が割り当てられているユーザー。",
|
||||
"The team the opportunity is assigned to.": "商談が割り当てられているチーム。",
|
||||
"The main contact for this project.": "このプロジェクトの主な連絡先。",
|
||||
"The name of this project.": "このプロジェクトの名前",
|
||||
"The description of this project.": "このプロジェクトの説明",
|
||||
"An optional link to the opportunity that this project was created to support.": "このプロジェクトをサポートするために作成された商談へのオプションのリンク。",
|
||||
"The stage that this project is on.": "このプロジェクトが進行中の段階。",
|
||||
"The status of the project.": "プロジェクトのステータス。",
|
||||
"The expected close date of this project.": "このプロジェクトの終了予定日。",
|
||||
"The user this project is assigned to.": "このプロジェクトに割り当てられているユーザー。",
|
||||
"The team this project is assigned to.": "このプロジェクトに割り当てられているチーム",
|
||||
"An array of tags that are added to this project.": "このプロジェクトに追加されたタグの配列。",
|
||||
"An array of custom fields that are defined for this project.": "このプロジェクトで定義されているカスタムフィールドの配列。",
|
||||
"A short description of the task.": "タスクの簡単な説明。",
|
||||
"The date when this task is due.": "このタスクの期日です。",
|
||||
"More details about the task.": "タスクの詳細。",
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.": "このタスクが期限切れの時刻(例:18:00)。注:時刻はユーザのタイムゾーンにあります。",
|
||||
"The entity this task is linked to. Only one can be selected.": "このタスクがリンクされているエンティティ。1つだけ選択できます。",
|
||||
"The category of this task.": "このタスクのカテゴリ",
|
||||
"The user this task is assigned to.": "このタスクに割り当てられているユーザー。",
|
||||
"The body of the note.": "メモの本文。",
|
||||
"The type of entity to add the note to.": "メモを追加するエンティティの種類",
|
||||
"The activity type for this entry. Defaults to \"Note\".": "このエントリのアクティビティタイプ。デフォルトは\"Note\"です。",
|
||||
"The value to search for (e.g., a name or email).": "検索する値 (名前やメールなど)。",
|
||||
"The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.": "構造化されたフィルタクエリ。例については、 [documentation](https://capsulecrm.com/developer/api-v2/filters/) を参照してください。",
|
||||
"Person": "人",
|
||||
"Organisation": "Organisation",
|
||||
"Fixed": "固定",
|
||||
"Hour": "時間",
|
||||
"Day": "日",
|
||||
"Week": "週",
|
||||
"Month": "月",
|
||||
"Quarter": "四半期ごと",
|
||||
"Year": "年",
|
||||
"Open": "開く",
|
||||
"Closed": "クローズ済み",
|
||||
"Party (Contact)": "パーティー (連絡先)",
|
||||
"Project": "プロジェクト",
|
||||
"New Case": "新規ケース",
|
||||
"New Opportunity": "新しい機会",
|
||||
"New Task": "新しいタスク",
|
||||
"New Project": "新規プロジェクト",
|
||||
"Fires when a new case (project) is created in Capsule CRM.": "Capsule CRM に新しいケース (プロジェクト) が作成されたときに発生します。",
|
||||
"Fires when a new opportunity is created.": "新しい商談が作成されたときに発火します。",
|
||||
"Fires when a new task is created.": "新しいタスクが作成されたときに発生します。",
|
||||
"Fires when a project is created.": "プロジェクトが作成されたときに発生します。"
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.": "\n Om te verifiëren met Capsule CRM:\n 1. Ga naar uw Capsule CRM-instellingen.\n 2. Navigeer naar \"Mijn Voorkeuren\" > \"API Authenticatie Token\".\n 3. Een nieuwe applicatie registreren om een client-ID en client-geheim te krijgen.\n 4. Voeg https://cloud. ctivepieces.com/redirect naar de toegestane redirect URIs.\n 5. Gebruik de OAuth2 flow hieronder.",
|
||||
"Create Contact": "Contactpersoon aanmaken",
|
||||
"Update Contact": "Contactpersoon bijwerken",
|
||||
"Create Opportunity": "Verkoopkans creëren",
|
||||
"Create Project": "Project aanmaken",
|
||||
"Create Task": "Taak maken",
|
||||
"Update Opportunity": "Update Verkoopkans",
|
||||
"Add Note to Entity": "Notitie toevoegen aan entiteit",
|
||||
"Find Contact": "Contactpersoon zoeken",
|
||||
"Find Project": "Project zoeken",
|
||||
"Find Opportunity": "Zoek Opportunity",
|
||||
"Create a new Person or Organisation in Capsule CRM.": "Maak een nieuwe persoon of organisatie aan in Capsule CRM.",
|
||||
"Update fields on an existing Person or Organisation.": "Werk velden bij op een bestaande persoon of organisatie.",
|
||||
"Create a new Opportunity in Capsule CRM.": "Maak een nieuwe kans in Capsule CRM.",
|
||||
"Create a new Project in Capsule CRM.": "Maak een nieuw project aan in Capsule CRM.",
|
||||
"Create a new Task in Capsule CRM.": "Maak een nieuwe taak in Capsule CRM.",
|
||||
"Update an existing Opportunity in Capsule CRM.": "Update een bestaande Kans in Capsule CRM.",
|
||||
"Add a comment/note to an entity (e.g., contact, opportunity, project).": "Voeg een reactie/opmerking toe aan een entiteit (bijv. contact, opportunity, project).",
|
||||
"Find a Person by search criteria.": "Zoek een persoon op zoek criteria.",
|
||||
"Find a Project by search criteria.": "Zoek een project op zoek criteria.",
|
||||
"Find an Opportunity by search criteria.": "Vind een Mogelijkheid door zoekcriteria.",
|
||||
"Contact Type": "Type contactpersoon",
|
||||
"Details": "Beschrijving",
|
||||
"About": "Informatie",
|
||||
"Owner": "Eigenaar",
|
||||
"Team": "Team",
|
||||
"Tags": "Labels",
|
||||
"Custom Fields": "Aangepaste velden",
|
||||
"Email Addresses": "E-mail adressen",
|
||||
"Phone Numbers": "Telefoon nummers",
|
||||
"Addresses": "Adres",
|
||||
"Websites": "Websites",
|
||||
"Contact": "Contactpersoon",
|
||||
"Party": "Feest",
|
||||
"Name": "Naam",
|
||||
"Description": "Beschrijving",
|
||||
"Milestone": "Mijlpaal",
|
||||
"Currency": "valuta",
|
||||
"Amount": "Hoeveelheid",
|
||||
"Expected Close Date": "Verwachte afsluitdatum",
|
||||
"Probability": "Waarschijnlijkheid",
|
||||
"Duration Basis": "Duur Basis",
|
||||
"Duration": "Tijdsduur",
|
||||
"Opportunity": "Kans",
|
||||
"Stage": "Speelveld",
|
||||
"Status": "status",
|
||||
"Due Date": "Inleverdatum",
|
||||
"Due Time": "Achterstallige tijd",
|
||||
"Link To": "Link naar",
|
||||
"Linked Entity": "Verbonden entiteit",
|
||||
"Category": "categorie",
|
||||
"Note Content": "Notitie inhoud",
|
||||
"Entity Type": "Entiteit type",
|
||||
"Entity": "Entiteit",
|
||||
"Activity Type": "Type activiteit",
|
||||
"Search Term": "Zoek term",
|
||||
"Filter": "Filteren",
|
||||
"The type of contact to create.": "Het type contact dat moet worden gemaakt.",
|
||||
"The contact (Person or Organisation) to select.": "Het contact (Person of Organisatie) om te selecteren.",
|
||||
"The user to assign the task to.": "De gebruiker waaraan de taak moet worden toegewezen.",
|
||||
"The team to assign the contact to.": "Het team waaraan de contactpersoon wordt toegewezen.",
|
||||
"Update the biography or description for the contact.": "Werk de biografie of beschrijving van de contactpersoon bij.",
|
||||
"A short description of the opportunity.": "Een korte beschrijving van de kans.",
|
||||
"More details about the opportunity.": "Meer details over deze mogelijkheid.",
|
||||
"The currency for the opportunity value (e.g., USD, GBP).": "De valuta voor de kanswaarde (bijv. USD, GBP).",
|
||||
"The numerical value of the opportunity.": "De numerieke waarde van de kans.",
|
||||
"The expected closing date for the opportunity.": "De verwachte sluitingsdatum voor deze mogelijkheid.",
|
||||
"The probability of winning the opportunity.": "De kans is groot dat we deze kans zullen krijgen.",
|
||||
"The basis of the duration of the opportunity.": "De basis voor de duur van de mogelijkheid.",
|
||||
"The duration of the opportunity.": "De duur van de mogelijkheid.",
|
||||
"The user the opportunity is assigned to.": "De gebruiker waaraan de kans is toegewezen.",
|
||||
"The team the opportunity is assigned to.": "Het team waaraan de kans is toegewezen.",
|
||||
"The main contact for this project.": "Het hoofdcontact voor dit project.",
|
||||
"The name of this project.": "De naam van dit project.",
|
||||
"The description of this project.": "De beschrijving van dit project.",
|
||||
"An optional link to the opportunity that this project was created to support.": "Een facultatieve link naar de mogelijkheid die dit project werd gecreëerd om te ondersteunen.",
|
||||
"The stage that this project is on.": "De fase waarin dit project zich bevindt.",
|
||||
"The status of the project.": "De status van het project.",
|
||||
"The expected close date of this project.": "De verwachte sluitingsdatum van dit project.",
|
||||
"The user this project is assigned to.": "De gebruiker aan dit project is toegewezen.",
|
||||
"The team this project is assigned to.": "Het team waaraan dit project is toegewezen.",
|
||||
"An array of tags that are added to this project.": "Een reeks tags die worden toegevoegd aan dit project.",
|
||||
"An array of custom fields that are defined for this project.": "Een reeks aangepaste velden die zijn gedefinieerd voor dit project.",
|
||||
"A short description of the task.": "Een korte beschrijving van de taak.",
|
||||
"The date when this task is due.": "De datum waarop deze taak afgelopen is.",
|
||||
"More details about the task.": "Meer details over de taak.",
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.": "De tijd waarin deze taak afgerond moet zijn (bijv. 18:00:00). Opmerking: De tijd ligt in de tijdzone van de gebruiker.",
|
||||
"The entity this task is linked to. Only one can be selected.": "De entiteit waaraan deze taak is gekoppeld. Er kan maar één geselecteerd worden.",
|
||||
"The category of this task.": "De categorie van deze taak.",
|
||||
"The user this task is assigned to.": "De gebruiker waaraan deze taak is toegewezen.",
|
||||
"The body of the note.": "De body van de notitie.",
|
||||
"The type of entity to add the note to.": "Het type entiteit waaraan de notitie toe te voegen",
|
||||
"The activity type for this entry. Defaults to \"Note\".": "Het activiteitstype voor deze invoer. Standaard ingesteld op \"Opmerking\".",
|
||||
"The value to search for (e.g., a name or email).": "De waarde waarnaar gezocht moet worden (bijv. een naam of e-mail).",
|
||||
"The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.": "De gestructureerde filter query. Zie de [documentation](https://capsulecrm.com/developer/api-v2/filters/) voor voorbeelden.",
|
||||
"Person": "Persoon",
|
||||
"Organisation": "Organisation",
|
||||
"Fixed": "Opgelost",
|
||||
"Hour": "Uur",
|
||||
"Day": "dag",
|
||||
"Week": "week",
|
||||
"Month": "maand",
|
||||
"Quarter": "Kwartaal",
|
||||
"Year": "jaar",
|
||||
"Open": "Open",
|
||||
"Closed": "gesloten",
|
||||
"Party (Contact)": "Partij (contact)",
|
||||
"Project": "Project",
|
||||
"New Case": "Nieuwe Geval",
|
||||
"New Opportunity": "Nieuwe kans",
|
||||
"New Task": "Nieuwe taak",
|
||||
"New Project": "Nieuw project",
|
||||
"Fires when a new case (project) is created in Capsule CRM.": "Vuurt wanneer een nieuw geval (project) is gemaakt in Capsule CRM.",
|
||||
"Fires when a new opportunity is created.": "Vuurt af wanneer een nieuwe kans wordt gecreëerd.",
|
||||
"Fires when a new task is created.": "Vuurt af wanneer een nieuwe taak is aangemaakt.",
|
||||
"Fires when a project is created.": "Vuurt wanneer een project wordt aangemaakt."
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.": "\n Para autenticar com CRM em Capsula:\n 1. Vá para suas configurações de usuário em Capsula CRM.\n 2. Navegue até \"Minhas preferências\" > \"Tokens de Autenticação API\".\n 3. Registre um novo aplicativo para obter um Client ID e Client Secret.\n 4. Adicione https://cloud. ctivepieces.com/redirect para os URIs de redirecionamento autorizados.\n 5. Use o fluxo OAuth2 abaixo.",
|
||||
"Create Contact": "Criar contato",
|
||||
"Update Contact": "Atualizar contato",
|
||||
"Create Opportunity": "Criar Oportunidade",
|
||||
"Create Project": "Criar Projeto",
|
||||
"Create Task": "Criar tarefa",
|
||||
"Update Opportunity": "Atualizar Oportunidade",
|
||||
"Add Note to Entity": "Adicionar Nota à Entidade",
|
||||
"Find Contact": "Localizar contato",
|
||||
"Find Project": "Localizar projeto",
|
||||
"Find Opportunity": "Encontrar Oportunidade",
|
||||
"Create a new Person or Organisation in Capsule CRM.": "Criar uma nova Pessoa ou Organização em Capsule CRM.",
|
||||
"Update fields on an existing Person or Organisation.": "Atualizar campos para uma Pessoa ou Organização existente.",
|
||||
"Create a new Opportunity in Capsule CRM.": "Criar uma nova Oportunidade em Capsule CRM.",
|
||||
"Create a new Project in Capsule CRM.": "Criar um novo projeto no CRM de Cápsula.",
|
||||
"Create a new Task in Capsule CRM.": "Criar uma nova Tarefa em Capsule CRM.",
|
||||
"Update an existing Opportunity in Capsule CRM.": "Atualizar uma Oportunidade existente em Capsule CRM.",
|
||||
"Add a comment/note to an entity (e.g., contact, opportunity, project).": "Adicionar um comentário/nota a uma entidade (por exemplo, contato, oportunidade, projeto).",
|
||||
"Find a Person by search criteria.": "Encontre uma pessoa usando critérios de pesquisa.",
|
||||
"Find a Project by search criteria.": "Encontre um projeto com critérios de pesquisa.",
|
||||
"Find an Opportunity by search criteria.": "Encontrar uma oportunidade por critérios de busca.",
|
||||
"Contact Type": "Tipo de contato",
|
||||
"Details": "detalhes",
|
||||
"About": "SOBRE",
|
||||
"Owner": "Proprietário",
|
||||
"Team": "Equipe",
|
||||
"Tags": "Etiquetas",
|
||||
"Custom Fields": "Campos Personalizados",
|
||||
"Email Addresses": "Endereços de e-mail",
|
||||
"Phone Numbers": "Números de telefone",
|
||||
"Addresses": "Endereços",
|
||||
"Websites": "Sites",
|
||||
"Contact": "contato",
|
||||
"Party": "Festa",
|
||||
"Name": "Nome",
|
||||
"Description": "Descrição",
|
||||
"Milestone": "Marco",
|
||||
"Currency": "moeda",
|
||||
"Amount": "Quantidade",
|
||||
"Expected Close Date": "Data de fechamento esperada",
|
||||
"Probability": "Probabilidade",
|
||||
"Duration Basis": "Duração da Base",
|
||||
"Duration": "Duração",
|
||||
"Opportunity": "Oportunidade",
|
||||
"Stage": "Etapa",
|
||||
"Status": "Estado",
|
||||
"Due Date": "Data de vencimento",
|
||||
"Due Time": "Hora-Limite",
|
||||
"Link To": "Link para",
|
||||
"Linked Entity": "Entidade vinculada",
|
||||
"Category": "categoria",
|
||||
"Note Content": "Conteúdo da Nota",
|
||||
"Entity Type": "Tipo de entidade",
|
||||
"Entity": "Entidade",
|
||||
"Activity Type": "Tipo de Atividade",
|
||||
"Search Term": "Termo para pesquisa",
|
||||
"Filter": "filtro",
|
||||
"The type of contact to create.": "O tipo de contato para criar.",
|
||||
"The contact (Person or Organisation) to select.": "O contato (Pessoa ou Organização) para selecionar.",
|
||||
"The user to assign the task to.": "O usuário para atribuir a tarefa.",
|
||||
"The team to assign the contact to.": "A equipe para atribuir o contato.",
|
||||
"Update the biography or description for the contact.": "Atualize a biografia ou a descrição do contato.",
|
||||
"A short description of the opportunity.": "Uma breve descrição da oportunidade.",
|
||||
"More details about the opportunity.": "Mais detalhes sobre a oportunidade.",
|
||||
"The currency for the opportunity value (e.g., USD, GBP).": "A moeda para o valor de oportunidade (por exemplo, USD, GBP).",
|
||||
"The numerical value of the opportunity.": "O valor numérico da oportunidade.",
|
||||
"The expected closing date for the opportunity.": "A data esperada de encerramento da oportunidade.",
|
||||
"The probability of winning the opportunity.": "A probabilidade de ganhar a oportunidade.",
|
||||
"The basis of the duration of the opportunity.": "A base da duração da oportunidade.",
|
||||
"The duration of the opportunity.": "A duração da oportunidade.",
|
||||
"The user the opportunity is assigned to.": "O usuário à qual a oportunidade é atribuída.",
|
||||
"The team the opportunity is assigned to.": "A equipe à qual a oportunidade foi atribuída.",
|
||||
"The main contact for this project.": "O contato principal para este projeto.",
|
||||
"The name of this project.": "O nome deste projeto.",
|
||||
"The description of this project.": "A descrição deste projeto.",
|
||||
"An optional link to the opportunity that this project was created to support.": "Um link opcional para a oportunidade que este projeto foi criado para apoiar.",
|
||||
"The stage that this project is on.": "O estádio em que se encontra este projecto.",
|
||||
"The status of the project.": "O status do projeto.",
|
||||
"The expected close date of this project.": "A data esperada de fechamento deste projeto.",
|
||||
"The user this project is assigned to.": "O usuário a quem este projeto está atribuído.",
|
||||
"The team this project is assigned to.": "A equipe a qual este projeto está atribuído.",
|
||||
"An array of tags that are added to this project.": "Uma matriz de tags que são adicionadas a este projeto.",
|
||||
"An array of custom fields that are defined for this project.": "Um array de campos personalizados que são definidos para este projeto.",
|
||||
"A short description of the task.": "Uma breve descrição da tarefa.",
|
||||
"The date when this task is due.": "A data de término desta tarefa.",
|
||||
"More details about the task.": "Mais detalhes sobre a tarefa.",
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.": "O horário em que esta tarefa é encerrada (por exemplo, 18:00:00). Nota: A hora está no fuso horário do usuário.",
|
||||
"The entity this task is linked to. Only one can be selected.": "A entidade em que esta tarefa está vinculada. Apenas uma pode ser selecionada.",
|
||||
"The category of this task.": "A categoria desta tarefa.",
|
||||
"The user this task is assigned to.": "O usuário esta tarefa está atribuída.",
|
||||
"The body of the note.": "O corpo da nota.",
|
||||
"The type of entity to add the note to.": "O tipo de entidade a que adicionar a nota.",
|
||||
"The activity type for this entry. Defaults to \"Note\".": "O tipo de atividade para esta entrada. O padrão é \"Nota\".",
|
||||
"The value to search for (e.g., a name or email).": "O valor a pesquisar (por exemplo, um nome ou email)",
|
||||
"The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.": "A consulta de filtro estruturada. Veja o [documentation](https://capsulecrm.com/developer/api-v2/filters/) para exemplos.",
|
||||
"Person": "Pessoa",
|
||||
"Organisation": "Organisation",
|
||||
"Fixed": "Corrigido",
|
||||
"Hour": "hora",
|
||||
"Day": "dia",
|
||||
"Week": "semana",
|
||||
"Month": "Mês",
|
||||
"Quarter": "Trimestre",
|
||||
"Year": "ano",
|
||||
"Open": "Abertas",
|
||||
"Closed": "Fechado",
|
||||
"Party (Contact)": "Grupo (Contato)",
|
||||
"Project": "Projecto",
|
||||
"New Case": "Nova Ocorrência",
|
||||
"New Opportunity": "Nova Oportunidade",
|
||||
"New Task": "Nova tarefa",
|
||||
"New Project": "Novo Projeto",
|
||||
"Fires when a new case (project) is created in Capsule CRM.": "Atira quando um novo caso (projeto) é criado no Capsule CRM.",
|
||||
"Fires when a new opportunity is created.": "Atira quando uma nova oportunidade é criada.",
|
||||
"Fires when a new task is created.": "Atira quando uma nova tarefa é criada.",
|
||||
"Fires when a project is created.": "aciona quando um projeto é criado."
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.": "\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.",
|
||||
"Create Contact": "Create Contact",
|
||||
"Update Contact": "Update Contact",
|
||||
"Create Opportunity": "Create Opportunity",
|
||||
"Create Project": "Create Project",
|
||||
"Create Task": "Create Task",
|
||||
"Update Opportunity": "Update Opportunity",
|
||||
"Add Note to Entity": "Add Note to Entity",
|
||||
"Find Contact": "Find Contact",
|
||||
"Find Project": "Find Project",
|
||||
"Find Opportunity": "Find Opportunity",
|
||||
"Create a new Person or Organisation in Capsule CRM.": "Create a new Person or Organisation in Capsule CRM.",
|
||||
"Update fields on an existing Person or Organisation.": "Update fields on an existing Person or Organisation.",
|
||||
"Create a new Opportunity in Capsule CRM.": "Create a new Opportunity in Capsule CRM.",
|
||||
"Create a new Project in Capsule CRM.": "Create a new Project in Capsule CRM.",
|
||||
"Create a new Task in Capsule CRM.": "Create a new Task in Capsule CRM.",
|
||||
"Update an existing Opportunity in Capsule CRM.": "Update an existing Opportunity in Capsule CRM.",
|
||||
"Add a comment/note to an entity (e.g., contact, opportunity, project).": "Add a comment/note to an entity (e.g., contact, opportunity, project).",
|
||||
"Find a Person by search criteria.": "Find a Person by search criteria.",
|
||||
"Find a Project by search criteria.": "Find a Project by search criteria.",
|
||||
"Find an Opportunity by search criteria.": "Find an Opportunity by search criteria.",
|
||||
"Contact Type": "Contact Type",
|
||||
"Details": "Details",
|
||||
"About": "About",
|
||||
"Owner": "Owner",
|
||||
"Team": "Team",
|
||||
"Tags": "Tags",
|
||||
"Custom Fields": "Custom Fields",
|
||||
"Email Addresses": "Email Addresses",
|
||||
"Phone Numbers": "Phone Numbers",
|
||||
"Addresses": "Addresses",
|
||||
"Websites": "Websites",
|
||||
"Contact": "Contact",
|
||||
"Party": "Party",
|
||||
"Name": "Name",
|
||||
"Description": "Description",
|
||||
"Milestone": "Milestone",
|
||||
"Currency": "Currency",
|
||||
"Amount": "Amount",
|
||||
"Expected Close Date": "Expected Close Date",
|
||||
"Probability": "Probability",
|
||||
"Duration Basis": "Duration Basis",
|
||||
"Duration": "Duration",
|
||||
"Opportunity": "Opportunity",
|
||||
"Stage": "Stage",
|
||||
"Status": "Status",
|
||||
"Due Date": "Due Date",
|
||||
"Due Time": "Due Time",
|
||||
"Link To": "Link To",
|
||||
"Linked Entity": "Linked Entity",
|
||||
"Category": "Category",
|
||||
"Note Content": "Note Content",
|
||||
"Entity Type": "Entity Type",
|
||||
"Entity": "Entity",
|
||||
"Activity Type": "Activity Type",
|
||||
"Search Term": "Search Term",
|
||||
"Filter": "Filter",
|
||||
"The type of contact to create.": "The type of contact to create.",
|
||||
"The contact (Person or Organisation) to select.": "The contact (Person or Organisation) to select.",
|
||||
"The user to assign the task to.": "The user to assign the task to.",
|
||||
"The team to assign the contact to.": "The team to assign the contact to.",
|
||||
"Update the biography or description for the contact.": "Update the biography or description for the contact.",
|
||||
"A short description of the opportunity.": "A short description of the opportunity.",
|
||||
"More details about the opportunity.": "More details about the opportunity.",
|
||||
"The currency for the opportunity value (e.g., USD, GBP).": "The currency for the opportunity value (e.g., USD, GBP).",
|
||||
"The numerical value of the opportunity.": "The numerical value of the opportunity.",
|
||||
"The expected closing date for the opportunity.": "The expected closing date for the opportunity.",
|
||||
"The probability of winning the opportunity.": "The probability of winning the opportunity.",
|
||||
"The basis of the duration of the opportunity.": "The basis of the duration of the opportunity.",
|
||||
"The duration of the opportunity.": "The duration of the opportunity.",
|
||||
"The user the opportunity is assigned to.": "The user the opportunity is assigned to.",
|
||||
"The team the opportunity is assigned to.": "The team the opportunity is assigned to.",
|
||||
"The main contact for this project.": "The main contact for this project.",
|
||||
"The name of this project.": "The name of this project.",
|
||||
"The description of this project.": "The description of this project.",
|
||||
"An optional link to the opportunity that this project was created to support.": "An optional link to the opportunity that this project was created to support.",
|
||||
"The stage that this project is on.": "The stage that this project is on.",
|
||||
"The status of the project.": "The status of the project.",
|
||||
"The expected close date of this project.": "The expected close date of this project.",
|
||||
"The user this project is assigned to.": "The user this project is assigned to.",
|
||||
"The team this project is assigned to.": "The team this project is assigned to.",
|
||||
"An array of tags that are added to this project.": "An array of tags that are added to this project.",
|
||||
"An array of custom fields that are defined for this project.": "An array of custom fields that are defined for this project.",
|
||||
"A short description of the task.": "A short description of the task.",
|
||||
"The date when this task is due.": "The date when this task is due.",
|
||||
"More details about the task.": "More details about the task.",
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.": "The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.",
|
||||
"The entity this task is linked to. Only one can be selected.": "The entity this task is linked to. Only one can be selected.",
|
||||
"The category of this task.": "The category of this task.",
|
||||
"The user this task is assigned to.": "The user this task is assigned to.",
|
||||
"The body of the note.": "The body of the note.",
|
||||
"The type of entity to add the note to.": "The type of entity to add the note to.",
|
||||
"The activity type for this entry. Defaults to \"Note\".": "The activity type for this entry. Defaults to \"Note\".",
|
||||
"The value to search for (e.g., a name or email).": "The value to search for (e.g., a name or email).",
|
||||
"The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.": "The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.",
|
||||
"Person": "Person",
|
||||
"Organisation": "Organisation",
|
||||
"Fixed": "Fixed",
|
||||
"Hour": "Hour",
|
||||
"Day": "Day",
|
||||
"Week": "Week",
|
||||
"Month": "Month",
|
||||
"Quarter": "Quarter",
|
||||
"Year": "Year",
|
||||
"Open": "Open",
|
||||
"Closed": "Closed",
|
||||
"Party (Contact)": "Party (Contact)",
|
||||
"Project": "Project",
|
||||
"New Case": "New Case",
|
||||
"New Opportunity": "New Opportunity",
|
||||
"New Task": "New Task",
|
||||
"New Project": "New Project",
|
||||
"Fires when a new case (project) is created in Capsule CRM.": "Fires when a new case (project) is created in Capsule CRM.",
|
||||
"Fires when a new opportunity is created.": "Fires when a new opportunity is created.",
|
||||
"Fires when a new task is created.": "Fires when a new task is created.",
|
||||
"Fires when a project is created.": "Fires when a project is created."
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.": "\n To authenticate with Capsule CRM:\n 1. Go to your Capsule CRM user settings.\n 2. Navigate to \"My Preferences\" > \"API Authentication Tokens\".\n 3. Register a new application to get a Client ID and Client Secret.\n 4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.\n 5. Use the OAuth2 flow below.",
|
||||
"Create Contact": "Create Contact",
|
||||
"Update Contact": "Update Contact",
|
||||
"Create Opportunity": "Create Opportunity",
|
||||
"Create Project": "Create Project",
|
||||
"Create Task": "Create Task",
|
||||
"Update Opportunity": "Update Opportunity",
|
||||
"Add Note to Entity": "Add Note to Entity",
|
||||
"Find Contact": "Find Contact",
|
||||
"Find Project": "Find Project",
|
||||
"Find Opportunity": "Find Opportunity",
|
||||
"Create a new Person or Organisation in Capsule CRM.": "Create a new Person or Organisation in Capsule CRM.",
|
||||
"Update fields on an existing Person or Organisation.": "Update fields on an existing Person or Organisation.",
|
||||
"Create a new Opportunity in Capsule CRM.": "Create a new Opportunity in Capsule CRM.",
|
||||
"Create a new Project in Capsule CRM.": "Create a new Project in Capsule CRM.",
|
||||
"Create a new Task in Capsule CRM.": "Create a new Task in Capsule CRM.",
|
||||
"Update an existing Opportunity in Capsule CRM.": "Update an existing Opportunity in Capsule CRM.",
|
||||
"Add a comment/note to an entity (e.g., contact, opportunity, project).": "Add a comment/note to an entity (e.g., contact, opportunity, project).",
|
||||
"Find a Person by search criteria.": "Find a Person by search criteria.",
|
||||
"Find a Project by search criteria.": "Find a Project by search criteria.",
|
||||
"Find an Opportunity by search criteria.": "Find an Opportunity by search criteria.",
|
||||
"Contact Type": "Contact Type",
|
||||
"Details": "详细信息",
|
||||
"About": "About",
|
||||
"Owner": "所有者",
|
||||
"Team": "Team",
|
||||
"Tags": "标签",
|
||||
"Custom Fields": "Custom Fields",
|
||||
"Email Addresses": "Email Addresses",
|
||||
"Phone Numbers": "Phone Numbers",
|
||||
"Addresses": "Addresses",
|
||||
"Websites": "Websites",
|
||||
"Contact": "Contact",
|
||||
"Party": "Party",
|
||||
"Name": "名称",
|
||||
"Description": "描述",
|
||||
"Milestone": "Milestone",
|
||||
"Currency": "Currency",
|
||||
"Amount": "Amount",
|
||||
"Expected Close Date": "Expected Close Date",
|
||||
"Probability": "Probability",
|
||||
"Duration Basis": "Duration Basis",
|
||||
"Duration": "期限",
|
||||
"Opportunity": "Opportunity",
|
||||
"Stage": "Stage",
|
||||
"Status": "状态",
|
||||
"Due Date": "Due Date",
|
||||
"Due Time": "Due Time",
|
||||
"Link To": "Link To",
|
||||
"Linked Entity": "Linked Entity",
|
||||
"Category": "Category",
|
||||
"Note Content": "Note Content",
|
||||
"Entity Type": "Entity Type",
|
||||
"Entity": "Entity",
|
||||
"Activity Type": "Activity Type",
|
||||
"Search Term": "Search Term",
|
||||
"Filter": "Filter",
|
||||
"The type of contact to create.": "The type of contact to create.",
|
||||
"The contact (Person or Organisation) to select.": "The contact (Person or Organisation) to select.",
|
||||
"The user to assign the task to.": "The user to assign the task to.",
|
||||
"The team to assign the contact to.": "The team to assign the contact to.",
|
||||
"Update the biography or description for the contact.": "Update the biography or description for the contact.",
|
||||
"A short description of the opportunity.": "A short description of the opportunity.",
|
||||
"More details about the opportunity.": "More details about the opportunity.",
|
||||
"The currency for the opportunity value (e.g., USD, GBP).": "The currency for the opportunity value (e.g., USD, GBP).",
|
||||
"The numerical value of the opportunity.": "The numerical value of the opportunity.",
|
||||
"The expected closing date for the opportunity.": "The expected closing date for the opportunity.",
|
||||
"The probability of winning the opportunity.": "The probability of winning the opportunity.",
|
||||
"The basis of the duration of the opportunity.": "The basis of the duration of the opportunity.",
|
||||
"The duration of the opportunity.": "The duration of the opportunity.",
|
||||
"The user the opportunity is assigned to.": "The user the opportunity is assigned to.",
|
||||
"The team the opportunity is assigned to.": "The team the opportunity is assigned to.",
|
||||
"The main contact for this project.": "The main contact for this project.",
|
||||
"The name of this project.": "The name of this project.",
|
||||
"The description of this project.": "The description of this project.",
|
||||
"An optional link to the opportunity that this project was created to support.": "An optional link to the opportunity that this project was created to support.",
|
||||
"The stage that this project is on.": "The stage that this project is on.",
|
||||
"The status of the project.": "The status of the project.",
|
||||
"The expected close date of this project.": "The expected close date of this project.",
|
||||
"The user this project is assigned to.": "The user this project is assigned to.",
|
||||
"The team this project is assigned to.": "The team this project is assigned to.",
|
||||
"An array of tags that are added to this project.": "An array of tags that are added to this project.",
|
||||
"An array of custom fields that are defined for this project.": "An array of custom fields that are defined for this project.",
|
||||
"A short description of the task.": "A short description of the task.",
|
||||
"The date when this task is due.": "The date when this task is due.",
|
||||
"More details about the task.": "More details about the task.",
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.": "The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.",
|
||||
"The entity this task is linked to. Only one can be selected.": "The entity this task is linked to. Only one can be selected.",
|
||||
"The category of this task.": "The category of this task.",
|
||||
"The user this task is assigned to.": "The user this task is assigned to.",
|
||||
"The body of the note.": "The body of the note.",
|
||||
"The type of entity to add the note to.": "The type of entity to add the note to.",
|
||||
"The activity type for this entry. Defaults to \"Note\".": "The activity type for this entry. Defaults to \"Note\".",
|
||||
"The value to search for (e.g., a name or email).": "The value to search for (e.g., a name or email).",
|
||||
"The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.": "The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.",
|
||||
"Person": "Person",
|
||||
"Organisation": "Organisation",
|
||||
"Fixed": "Fixed",
|
||||
"Hour": "Hour",
|
||||
"Day": "Day",
|
||||
"Week": "Week",
|
||||
"Month": "Month",
|
||||
"Quarter": "Quarter",
|
||||
"Year": "Year",
|
||||
"Open": "Open",
|
||||
"Closed": "Closed",
|
||||
"Party (Contact)": "Party (Contact)",
|
||||
"Project": "项目",
|
||||
"New Case": "New Case",
|
||||
"New Opportunity": "New Opportunity",
|
||||
"New Task": "New Task",
|
||||
"New Project": "新建项目",
|
||||
"Fires when a new case (project) is created in Capsule CRM.": "Fires when a new case (project) is created in Capsule CRM.",
|
||||
"Fires when a new opportunity is created.": "Fires when a new opportunity is created.",
|
||||
"Fires when a new task is created.": "Fires when a new task is created.",
|
||||
"Fires when a project is created.": "Fires when a project is created."
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
import { createPiece } from "@activepieces/pieces-framework";
|
||||
import { capsuleCrmAuth } from "../src/lib/common/auth";
|
||||
import { createContactAction } from "../src/lib/actions/create-contact";
|
||||
import { updateContactAction } from "../src/lib/actions/update-contact";
|
||||
import { createOpportunityAction } from "../src/lib/actions/create-opportunity";
|
||||
import { createProjectAction } from "../src/lib/actions/create-project";
|
||||
import { createTaskAction } from "../src/lib/actions/create-task";
|
||||
import { updateOpportunityAction } from "../src/lib/actions/update-opportunity";
|
||||
import { addNoteToEntityAction } from "../src/lib/actions/add-note-to-entity";
|
||||
import { findContactAction } from "../src/lib/actions/find-contact";
|
||||
import { findProjectAction } from "../src/lib/actions/find-project";
|
||||
import { findOpportunityAction } from "../src/lib/actions/find-opportunity";
|
||||
import { newCaseTrigger } from "../src/lib/triggers/new-case";
|
||||
import { newOpportunityTrigger } from "../src/lib/triggers/new-opportunity";
|
||||
import { newTaskTrigger } from "../src/lib/triggers/new-task";
|
||||
import { newProjectTrigger } from "../src/lib/triggers/new-project";
|
||||
|
||||
export const capsuleCrm = createPiece({
|
||||
displayName: 'Capsule CRM',
|
||||
auth: capsuleCrmAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/capsule-crm.png',
|
||||
authors: ['Prabhukiran161', 'onyedikachi-david'],
|
||||
actions: [
|
||||
createContactAction,
|
||||
updateContactAction,
|
||||
createOpportunityAction,
|
||||
createProjectAction,
|
||||
createTaskAction,
|
||||
updateOpportunityAction,
|
||||
addNoteToEntityAction,
|
||||
findContactAction,
|
||||
findProjectAction,
|
||||
findOpportunityAction,
|
||||
],
|
||||
triggers: [
|
||||
newCaseTrigger,
|
||||
newOpportunityTrigger,
|
||||
newTaskTrigger,
|
||||
newProjectTrigger,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
DynamicPropsValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth, CapsuleCrmAuthType } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import { CreateEntryParams } from '../common/types';
|
||||
|
||||
export const addNoteToEntityAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'add_note_to_entity',
|
||||
displayName: 'Add Note to Entity',
|
||||
description:
|
||||
'Add a comment/note to an entity (e.g., contact, opportunity, project).',
|
||||
props: {
|
||||
content: Property.LongText({
|
||||
displayName: 'Note Content',
|
||||
description: 'The body of the note.',
|
||||
required: true,
|
||||
}),
|
||||
entityType: Property.StaticDropdown({
|
||||
displayName: 'Entity Type',
|
||||
description: 'The type of entity to add the note to.',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Party (Contact)', value: 'party' },
|
||||
{ label: 'Opportunity', value: 'opportunity' },
|
||||
{ label: 'Project', value: 'project' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
entityId: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Entity',
|
||||
required: true,
|
||||
refreshers: ['entityType'],
|
||||
props: async ({ auth, entityType }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
const entityTypeStr = entityType as unknown as string;
|
||||
if (!auth || !entityTypeStr) return fields;
|
||||
|
||||
if (entityTypeStr === 'party') {
|
||||
const contacts = await capsuleCrmClient.searchContacts(
|
||||
auth,
|
||||
''
|
||||
);
|
||||
fields['partyId'] = Property.StaticDropdown({
|
||||
displayName: 'Party',
|
||||
required: true,
|
||||
options:{
|
||||
options: contacts.map((contact) => ({
|
||||
label:
|
||||
contact.type === 'person'
|
||||
? `${contact.firstName} ${contact.lastName}`
|
||||
: contact.name || `Unnamed ${contact.type}`,
|
||||
value: contact.id,
|
||||
})),
|
||||
}})
|
||||
} else if (entityTypeStr === 'opportunity') {
|
||||
const opportunities =
|
||||
await capsuleCrmClient.searchOpportunities(
|
||||
auth
|
||||
);
|
||||
fields['opportunityId'] = Property.StaticDropdown({
|
||||
displayName: 'Opportunity',
|
||||
required: true,
|
||||
options: {
|
||||
options: opportunities.map((opportunity) => ({
|
||||
label: opportunity.name,
|
||||
value: opportunity.id,
|
||||
})),
|
||||
}})
|
||||
} else if (entityTypeStr === 'project') {
|
||||
const projects = await capsuleCrmClient.searchProjects(
|
||||
auth
|
||||
);
|
||||
fields['projectId'] = Property.StaticDropdown({
|
||||
displayName: 'Project',
|
||||
required: true,
|
||||
options:{
|
||||
options: projects.map((project) => ({
|
||||
label: project.name,
|
||||
value: project.id,
|
||||
})),
|
||||
}})
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
activityTypeId: Property.Dropdown({
|
||||
displayName: 'Activity Type',
|
||||
description: 'The activity type for this entry. Defaults to "Note".',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const activityTypes = await capsuleCrmClient.listActivityTypes(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: activityTypes.map((activityType) => ({
|
||||
label: activityType.name,
|
||||
value: activityType.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
|
||||
const entryData: CreateEntryParams = {
|
||||
type: 'note',
|
||||
content: propsValue.content,
|
||||
};
|
||||
|
||||
if (propsValue.activityTypeId) {
|
||||
entryData.activityType = { id: propsValue.activityTypeId };
|
||||
}
|
||||
|
||||
const entityId = propsValue.entityId as DynamicPropsValue;
|
||||
if (entityId) {
|
||||
if (entityId['partyId']) {
|
||||
entryData.party = { id: entityId['partyId'] as number };
|
||||
} else if (entityId['opportunityId']) {
|
||||
entryData.opportunity = { id: entityId['opportunityId'] as number };
|
||||
} else if (entityId['projectId']) {
|
||||
entryData.kase = { id: entityId['projectId'] as number };
|
||||
}
|
||||
}
|
||||
|
||||
return await capsuleCrmClient.createEntry(auth, entryData);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,378 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
DynamicPropsValue,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth, CapsuleCrmAuthType } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import { CreatePartyParams } from '../common/types';
|
||||
|
||||
export const createContactAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'create_contact',
|
||||
displayName: 'Create Contact',
|
||||
description: 'Create a new Person or Organisation in Capsule CRM.',
|
||||
props: {
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Contact Type',
|
||||
description: 'The type of contact to create.',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Person', value: 'person' },
|
||||
{ label: 'Organisation', value: 'organisation' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
contactFields: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Details',
|
||||
required: true,
|
||||
refreshers: ['type'],
|
||||
props: async ({ auth, type }) => {
|
||||
const contactType = type as unknown as string;
|
||||
const fields: DynamicPropsValue = {};
|
||||
|
||||
if (contactType === 'person') {
|
||||
// Fetch organisations data ONCE at the outer level
|
||||
let organisationOptions: { label: string; value: number }[] = [];
|
||||
|
||||
if (auth) {
|
||||
try {
|
||||
const organisations = await capsuleCrmClient.searchContacts(
|
||||
auth,
|
||||
''
|
||||
);
|
||||
|
||||
organisationOptions = organisations
|
||||
.filter((party) => party.type === 'organisation')
|
||||
.map((org) => ({
|
||||
label: org.name || 'Unnamed Organisation',
|
||||
value: org.id,
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error('Failed to load organisations:', error);
|
||||
}
|
||||
}
|
||||
|
||||
fields['firstName'] = Property.ShortText({
|
||||
displayName: 'First Name',
|
||||
required: true,
|
||||
});
|
||||
fields['lastName'] = Property.ShortText({
|
||||
displayName: 'Last Name',
|
||||
required: true,
|
||||
});
|
||||
fields['title'] = Property.ShortText({
|
||||
displayName: 'Title',
|
||||
required: false,
|
||||
});
|
||||
fields['jobTitle'] = Property.ShortText({
|
||||
displayName: 'Job Title',
|
||||
required: false,
|
||||
});
|
||||
fields['organisationId'] = Property.StaticDropdown({
|
||||
displayName: 'Organisation',
|
||||
required: false,
|
||||
options: {
|
||||
options: organisationOptions,
|
||||
},
|
||||
});
|
||||
} else if (contactType === 'organisation') {
|
||||
fields['organisationName'] = Property.ShortText({
|
||||
displayName: 'Organisation Name',
|
||||
required: true,
|
||||
});
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
about: Property.LongText({
|
||||
displayName: 'About',
|
||||
required: false,
|
||||
}),
|
||||
ownerId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Owner',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [] };
|
||||
const users = await capsuleCrmClient.listUsers(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: users.map((user) => ({
|
||||
label: user.name,
|
||||
value: user.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
teamId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Team',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [] };
|
||||
const teams = await capsuleCrmClient.listTeams(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: teams.map((team) => ({
|
||||
label: team.name,
|
||||
value: team.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
tags: Property.MultiSelectDropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Tags',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [] };
|
||||
const tags = await capsuleCrmClient.listTags(auth);
|
||||
return {
|
||||
options: tags.map((tag) => ({
|
||||
label: tag.name,
|
||||
value: tag.name,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
customFields: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Custom Fields',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
props: async ({ auth }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth) return fields;
|
||||
const customFields = await capsuleCrmClient.listCustomFields(
|
||||
auth
|
||||
);
|
||||
for (const field of customFields) {
|
||||
switch (field.type) {
|
||||
case 'list':
|
||||
fields[field.id] = Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
options: {
|
||||
options:
|
||||
field.options?.map((option) => ({
|
||||
label: option,
|
||||
value: option,
|
||||
})) || [],
|
||||
},
|
||||
});
|
||||
break;
|
||||
case 'boolean':
|
||||
fields[field.id] = Property.Checkbox({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case 'date':
|
||||
fields[field.id] = Property.DateTime({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
fields[field.id] = Property.ShortText({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
emailAddresses: Property.Array({
|
||||
displayName: 'Email Addresses',
|
||||
required: false,
|
||||
properties: {
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Home', value: 'Home' },
|
||||
{ label: 'Work', value: 'Work' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
address: Property.ShortText({
|
||||
displayName: 'Address',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
phoneNumbers: Property.Array({
|
||||
displayName: 'Phone Numbers',
|
||||
required: false,
|
||||
properties: {
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Home', value: 'Home' },
|
||||
{ label: 'Work', value: 'Work' },
|
||||
{ label: 'Mobile', value: 'Mobile' },
|
||||
{ label: 'Fax', value: 'Fax' },
|
||||
{ label: 'Direct', value: 'Direct' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
number: Property.ShortText({
|
||||
displayName: 'Number',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
addresses: Property.Array({
|
||||
displayName: 'Addresses',
|
||||
required: false,
|
||||
properties: {
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Home', value: 'Home' },
|
||||
{ label: 'Postal', value: 'Postal' },
|
||||
{ label: 'Office', value: 'Office' },
|
||||
{ label: 'Billing', value: 'Billing' },
|
||||
{ label: 'Shipping', value: 'Shipping' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
street: Property.ShortText({
|
||||
displayName: 'Street',
|
||||
required: false,
|
||||
}),
|
||||
city: Property.ShortText({
|
||||
displayName: 'City',
|
||||
required: false,
|
||||
}),
|
||||
state: Property.ShortText({
|
||||
displayName: 'State',
|
||||
required: false,
|
||||
}),
|
||||
country: Property.ShortText({
|
||||
displayName: 'Country',
|
||||
required: false,
|
||||
}),
|
||||
zip: Property.ShortText({
|
||||
displayName: 'Zip',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
websites: Property.Array({
|
||||
displayName: 'Websites',
|
||||
required: false,
|
||||
properties: {
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Home', value: 'Home' },
|
||||
{ label: 'Work', value: 'Work' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
service: Property.StaticDropdown({
|
||||
displayName: 'Service',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'URL', value: 'URL' },
|
||||
{ label: 'Skype', value: 'SKYPE' },
|
||||
{ label: 'Twitter', value: 'TWITTER' },
|
||||
{ label: 'LinkedIn', value: 'LINKED_IN' },
|
||||
{ label: 'Facebook', value: 'FACEBOOK' },
|
||||
{ label: 'Xing', value: 'XING' },
|
||||
{ label: 'Feed', value: 'FEED' },
|
||||
{ label: 'Google+', value: 'GOOGLE_PLUS' },
|
||||
{ label: 'Flickr', value: 'FLICKR' },
|
||||
{ label: 'GitHub', value: 'GITHUB' },
|
||||
{ label: 'YouTube', value: 'YOUTUBE' },
|
||||
{ label: 'Instagram', value: 'INSTAGRAM' },
|
||||
{ label: 'Pinterest', value: 'PINTEREST' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
address: Property.ShortText({
|
||||
displayName: 'Address',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
|
||||
const type = propsValue.type as 'person' | 'organisation';
|
||||
const contactFields = propsValue.contactFields as DynamicPropsValue;
|
||||
const contactData: Partial<CreatePartyParams> = {
|
||||
type: type,
|
||||
title: contactFields['title'] as string | undefined,
|
||||
jobTitle: contactFields['jobTitle'] as string | undefined,
|
||||
about: propsValue.about,
|
||||
organisationId: contactFields['organisationId'] as number | undefined,
|
||||
ownerId: propsValue.ownerId,
|
||||
teamId: propsValue.teamId,
|
||||
tags: propsValue.tags,
|
||||
emailAddresses: propsValue.emailAddresses as {
|
||||
type?: string;
|
||||
address: string;
|
||||
}[],
|
||||
phoneNumbers: propsValue.phoneNumbers as {
|
||||
type?: string;
|
||||
number: string;
|
||||
}[],
|
||||
addresses: propsValue.addresses as {
|
||||
type?: string;
|
||||
street?: string;
|
||||
city?: string;
|
||||
state?: string;
|
||||
country?: string;
|
||||
zip?: string;
|
||||
}[],
|
||||
websites: propsValue.websites as {
|
||||
type?: string;
|
||||
service: string;
|
||||
address: string;
|
||||
}[],
|
||||
};
|
||||
|
||||
if (type === 'person') {
|
||||
contactData.firstName = contactFields['firstName'] as string;
|
||||
contactData.lastName = contactFields['lastName'] as string;
|
||||
} else if (type === 'organisation') {
|
||||
contactData.name = contactFields['organisationName'] as string;
|
||||
}
|
||||
|
||||
const customFields = propsValue.customFields as DynamicPropsValue;
|
||||
if (customFields) {
|
||||
contactData.fields = Object.entries(customFields)
|
||||
.filter(([, value]) => value !== undefined && value !== null)
|
||||
.map(([id, value]) => ({
|
||||
definition: { id: Number(id) },
|
||||
value: value,
|
||||
}));
|
||||
}
|
||||
|
||||
return await capsuleCrmClient.createContact(
|
||||
auth,
|
||||
contactData as CreatePartyParams
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,263 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
DynamicPropsValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth, CapsuleCrmAuthType } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import {
|
||||
CreateOpportunityParams,
|
||||
OpportunityCustomField,
|
||||
OpportunityTag,
|
||||
} from '../common/types';
|
||||
|
||||
export const createOpportunityAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'create_opportunity',
|
||||
displayName: 'Create Opportunity',
|
||||
description: 'Create a new Opportunity in Capsule CRM.',
|
||||
props: {
|
||||
partyId: Property.Dropdown({
|
||||
displayName: 'Party',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const contacts = await capsuleCrmClient.searchContacts(
|
||||
auth,
|
||||
''
|
||||
);
|
||||
return {
|
||||
options: contacts.map((contact) => ({
|
||||
label:
|
||||
contact.type === 'person'
|
||||
? `${contact.firstName} ${contact.lastName}`
|
||||
: contact.name || `Unnamed ${contact.type}`,
|
||||
value: contact.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'Name',
|
||||
description: 'A short description of the opportunity.',
|
||||
required: true,
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Description',
|
||||
description: 'More details about the opportunity.',
|
||||
required: false,
|
||||
}),
|
||||
milestoneId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Milestone',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const milestones = await capsuleCrmClient.listMilestones(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: milestones.map((milestone) => ({
|
||||
label: milestone.name,
|
||||
value: milestone.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
currency: Property.ShortText({
|
||||
displayName: 'Currency',
|
||||
description: 'The currency for the opportunity value (e.g., USD, GBP).',
|
||||
required: false,
|
||||
}),
|
||||
amount: Property.Number({
|
||||
displayName: 'Amount',
|
||||
description: 'The numerical value of the opportunity.',
|
||||
required: false,
|
||||
}),
|
||||
expectedCloseOn: Property.DateTime({
|
||||
displayName: 'Expected Close Date',
|
||||
description: 'The expected closing date for the opportunity.',
|
||||
required: false,
|
||||
}),
|
||||
probability: Property.Number({
|
||||
displayName: 'Probability',
|
||||
description: 'The probability of winning the opportunity.',
|
||||
required: false,
|
||||
}),
|
||||
durationBasis: Property.StaticDropdown({
|
||||
displayName: 'Duration Basis',
|
||||
required: false,
|
||||
description: 'The basis of the duration of the opportunity.',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Fixed', value: 'FIXED' },
|
||||
{ label: 'Hour', value: 'HOUR' },
|
||||
{ label: 'Day', value: 'DAY' },
|
||||
{ label: 'Week', value: 'WEEK' },
|
||||
{ label: 'Month', value: 'MONTH' },
|
||||
{ label: 'Quarter', value: 'QUARTER' },
|
||||
{ label: 'Year', value: 'YEAR' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
duration: Property.Number({
|
||||
displayName: 'Duration',
|
||||
required: false,
|
||||
description: 'The duration of the opportunity.',
|
||||
}),
|
||||
ownerId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Owner',
|
||||
required: false,
|
||||
description: 'The user the opportunity is assigned to.',
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const users = await capsuleCrmClient.listUsers(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: users.map((user) => ({
|
||||
label: user.name,
|
||||
value: user.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
teamId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Team',
|
||||
required: false,
|
||||
description: 'The team the opportunity is assigned to.',
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const teams = await capsuleCrmClient.listTeams(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: teams.map((team) => ({
|
||||
label: team.name,
|
||||
value: team.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
tags: Property.MultiSelectDropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Tags',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const tags = await capsuleCrmClient.listTags(auth);
|
||||
return {
|
||||
options: tags.map((tag) => ({
|
||||
label: tag.name,
|
||||
value: tag.name,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
customFields: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Custom Fields',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
props: async ({ auth }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const customFields = await capsuleCrmClient.listCustomFields(
|
||||
auth
|
||||
);
|
||||
for (const field of customFields) {
|
||||
switch (field.type) {
|
||||
case 'list':
|
||||
fields[field.id] = Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
options: {
|
||||
options:
|
||||
field.options?.map((option) => ({
|
||||
label: option,
|
||||
value: option,
|
||||
})) || [],
|
||||
},
|
||||
});
|
||||
break;
|
||||
case 'boolean':
|
||||
fields[field.id] = Property.Checkbox({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case 'date':
|
||||
fields[field.id] = Property.DateTime({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
fields[field.id] = Property.ShortText({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
|
||||
const opportunityData: CreateOpportunityParams = {
|
||||
party: { id: propsValue.partyId },
|
||||
name: propsValue.name,
|
||||
milestone: { id: propsValue.milestoneId },
|
||||
description: propsValue.description,
|
||||
expectedCloseOn: propsValue.expectedCloseOn,
|
||||
probability: propsValue.probability,
|
||||
durationBasis: propsValue.durationBasis,
|
||||
duration: propsValue.duration,
|
||||
};
|
||||
|
||||
if (propsValue.ownerId) {
|
||||
opportunityData.owner = { id: propsValue.ownerId };
|
||||
}
|
||||
if (propsValue.teamId) {
|
||||
opportunityData.team = { id: propsValue.teamId };
|
||||
}
|
||||
|
||||
if (propsValue.currency && propsValue.amount) {
|
||||
opportunityData.value = {
|
||||
currency: propsValue.currency,
|
||||
amount: propsValue.amount,
|
||||
};
|
||||
}
|
||||
|
||||
if (propsValue.tags) {
|
||||
opportunityData.tags = propsValue.tags.map(
|
||||
(tag) => ({ name: tag } as OpportunityTag)
|
||||
);
|
||||
}
|
||||
|
||||
const customFields = propsValue.customFields as DynamicPropsValue;
|
||||
if (customFields) {
|
||||
opportunityData.fields = Object.entries(customFields)
|
||||
.filter(([, value]) => value !== undefined && value !== null)
|
||||
.map(
|
||||
([id, value]) =>
|
||||
({
|
||||
definition: { id: Number(id) },
|
||||
value: value,
|
||||
} as OpportunityCustomField)
|
||||
);
|
||||
}
|
||||
|
||||
return await capsuleCrmClient.createOpportunity(auth, opportunityData);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,288 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
DynamicPropsValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth, CapsuleCrmAuthType } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import {
|
||||
CreateProjectParams,
|
||||
OpportunityCustomField,
|
||||
OpportunityTag,
|
||||
} from '../common/types';
|
||||
|
||||
export const createProjectAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'create_project',
|
||||
displayName: 'Create Project',
|
||||
description: 'Create a new Project in Capsule CRM.',
|
||||
props: {
|
||||
partyId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Party',
|
||||
description: 'The main contact for this project.',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const contacts = await capsuleCrmClient.searchContacts(
|
||||
auth,
|
||||
''
|
||||
);
|
||||
return {
|
||||
options: contacts.map((contact) => ({
|
||||
label:
|
||||
contact.type === 'person'
|
||||
? `${contact.firstName} ${contact.lastName}`
|
||||
: contact.name || `Unnamed ${contact.type}`,
|
||||
value: contact.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'Name',
|
||||
description: 'The name of this project.',
|
||||
required: true,
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Description',
|
||||
description: 'The description of this project.',
|
||||
required: false,
|
||||
}),
|
||||
opportunityId: Property.Dropdown({
|
||||
displayName: 'Opportunity',
|
||||
description:
|
||||
'An optional link to the opportunity that this project was created to support.',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const opportunities = await capsuleCrmClient.searchOpportunities(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: opportunities.map((opportunity) => ({
|
||||
label: opportunity.name,
|
||||
value: opportunity.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
stageId: Property.Dropdown({
|
||||
displayName: 'Stage',
|
||||
description: 'The stage that this project is on.',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const stages = await capsuleCrmClient.listStages(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: stages.map((stage) => ({
|
||||
label: stage.name,
|
||||
value: stage.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
status: Property.StaticDropdown({
|
||||
displayName: 'Status',
|
||||
description: 'The status of the project.',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Open', value: 'OPEN' },
|
||||
{ label: 'Closed', value: 'CLOSED' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
expectedCloseOn: Property.DateTime({
|
||||
displayName: 'Expected Close Date',
|
||||
description: 'The expected close date of this project.',
|
||||
required: false,
|
||||
}),
|
||||
ownerId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Owner',
|
||||
description: 'The user this project is assigned to.',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const users = await capsuleCrmClient.listUsers(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: users.map((user) => ({
|
||||
label: user.name,
|
||||
value: user.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
teamId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Team',
|
||||
description: 'The team this project is assigned to.',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const teams = await capsuleCrmClient.listTeams(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: teams.map((team) => ({
|
||||
label: team.name,
|
||||
value: team.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
tags: Property.MultiSelectDropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Tags',
|
||||
description: 'An array of tags that are added to this project.',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const tags = await capsuleCrmClient.listTags(auth);
|
||||
return {
|
||||
options: tags.map((tag) => ({
|
||||
label: tag.name,
|
||||
value: tag.name,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
customFields: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Custom Fields',
|
||||
description: 'An array of custom fields that are defined for this project.',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
props: async ({ auth }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth) return fields;
|
||||
const customFields = await capsuleCrmClient.listCustomFields(
|
||||
auth
|
||||
);
|
||||
for (const field of customFields) {
|
||||
switch (field.type) {
|
||||
case 'list':
|
||||
fields[field.id] = Property.StaticDropdown({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
options: {
|
||||
options:
|
||||
field.options?.map((option) => ({
|
||||
label: option,
|
||||
value: option,
|
||||
})) || [],
|
||||
},
|
||||
});
|
||||
break;
|
||||
case 'boolean':
|
||||
fields[field.id] = Property.Checkbox({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case 'date':
|
||||
fields[field.id] = Property.DateTime({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
fields[field.id] = Property.ShortText({
|
||||
displayName: field.name,
|
||||
required: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
|
||||
const projectData: CreateProjectParams = {
|
||||
party: { id: propsValue.partyId },
|
||||
name: propsValue.name,
|
||||
description: propsValue.description,
|
||||
status: propsValue.status as 'OPEN' | 'CLOSED' | undefined,
|
||||
expectedCloseOn: propsValue.expectedCloseOn,
|
||||
};
|
||||
|
||||
if (propsValue.opportunityId) {
|
||||
projectData.opportunity = { id: propsValue.opportunityId };
|
||||
}
|
||||
if (propsValue.stageId) {
|
||||
projectData.stage = { id: propsValue.stageId };
|
||||
}
|
||||
if (propsValue.ownerId) {
|
||||
projectData.owner = { id: propsValue.ownerId };
|
||||
}
|
||||
if (propsValue.teamId) {
|
||||
projectData.team = { id: propsValue.teamId };
|
||||
}
|
||||
|
||||
if (propsValue.tags) {
|
||||
projectData.tags = propsValue.tags.map(
|
||||
(tag) => ({ name: tag } as OpportunityTag)
|
||||
);
|
||||
}
|
||||
|
||||
const customFields = propsValue.customFields as DynamicPropsValue;
|
||||
if (customFields) {
|
||||
projectData.fields = Object.entries(customFields)
|
||||
.filter(([, value]) => value !== undefined && value !== null)
|
||||
.map(
|
||||
([id, value]) =>
|
||||
({
|
||||
definition: { id: Number(id) },
|
||||
value: value,
|
||||
} as OpportunityCustomField)
|
||||
);
|
||||
}
|
||||
|
||||
return await capsuleCrmClient.createProject(auth, projectData);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,192 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
DynamicPropsValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth, CapsuleCrmAuthType } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import { CreateTaskParams } from '../common/types';
|
||||
|
||||
export const createTaskAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'create_task',
|
||||
displayName: 'Create Task',
|
||||
description: 'Create a new Task in Capsule CRM.',
|
||||
props: {
|
||||
description: Property.ShortText({
|
||||
displayName: 'Description',
|
||||
description: 'A short description of the task.',
|
||||
required: true,
|
||||
}),
|
||||
dueOn: Property.DateTime({
|
||||
displayName: 'Due Date',
|
||||
description: 'The date when this task is due.',
|
||||
required: true,
|
||||
}),
|
||||
detail: Property.LongText({
|
||||
displayName: 'Details',
|
||||
description: 'More details about the task.',
|
||||
required: false,
|
||||
}),
|
||||
dueTime: Property.ShortText({
|
||||
displayName: 'Due Time',
|
||||
description:
|
||||
"The time when this task is due (e.g., 18:00:00). Note: The time is in the user's timezone.",
|
||||
required: false,
|
||||
}),
|
||||
linkTo: Property.StaticDropdown({
|
||||
displayName: 'Link To',
|
||||
description:
|
||||
'The entity this task is linked to. Only one can be selected.',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Party (Contact)', value: 'party' },
|
||||
{ label: 'Opportunity', value: 'opportunity' },
|
||||
{ label: 'Project', value: 'project' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
linkedEntityId: Property.DynamicProperties({
|
||||
displayName: 'Linked Entity',
|
||||
required: false,
|
||||
refreshers: ['linkTo'],
|
||||
auth: capsuleCrmAuth,
|
||||
props: async ({ auth, linkTo }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
const linkToType = linkTo as unknown as string;
|
||||
if (!auth || !linkToType) return fields;
|
||||
|
||||
if (linkToType === 'party') {
|
||||
const contacts = await capsuleCrmClient.searchContacts(
|
||||
auth,
|
||||
''
|
||||
);
|
||||
const contactOptions = contacts.map((contact) => ({
|
||||
label:
|
||||
contact.type === 'person'
|
||||
? `${contact.firstName} ${contact.lastName}`
|
||||
: contact.name || `Unnamed ${contact.type}`,
|
||||
value: contact.id,
|
||||
}));
|
||||
fields['partyId'] = Property.StaticDropdown({
|
||||
displayName: 'Party',
|
||||
required: true,
|
||||
options: {
|
||||
options: contactOptions,
|
||||
},
|
||||
});
|
||||
} else if (linkToType === 'opportunity') {
|
||||
const opportunities = await capsuleCrmClient.searchOpportunities(
|
||||
auth
|
||||
);
|
||||
const opportunityOptions = opportunities.map((opportunity) => ({
|
||||
label: opportunity.name,
|
||||
value: opportunity.id,
|
||||
}));
|
||||
fields['opportunityId'] = Property.StaticDropdown({
|
||||
displayName: 'Opportunity',
|
||||
required: true,
|
||||
options: {
|
||||
options: opportunityOptions,
|
||||
},
|
||||
});
|
||||
} else if (linkToType === 'project') {
|
||||
const projects = await capsuleCrmClient.searchProjects(
|
||||
auth
|
||||
);
|
||||
const projectOptions = projects.map((project) => ({
|
||||
label: project.name,
|
||||
value: project.id,
|
||||
}));
|
||||
fields['projectId'] = Property.StaticDropdown({
|
||||
displayName: 'Project',
|
||||
required: true,
|
||||
options: {
|
||||
options: projectOptions,
|
||||
},
|
||||
});
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
categoryId: Property.Dropdown({
|
||||
displayName: 'Category',
|
||||
description: 'The category of this task.',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const categories = await capsuleCrmClient.listCategories(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: categories.map((category) => ({
|
||||
label: category.name,
|
||||
value: category.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
ownerId: Property.Dropdown({
|
||||
displayName: 'Owner',
|
||||
description: 'The user this task is assigned to.',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth)
|
||||
return {
|
||||
options: [],
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Capsule CRM account first',
|
||||
};
|
||||
const users = await capsuleCrmClient.listUsers(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: users.map((user) => ({
|
||||
label: user.name,
|
||||
value: user.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
|
||||
const taskData: CreateTaskParams = {
|
||||
description: propsValue.description,
|
||||
dueOn: propsValue.dueOn,
|
||||
detail: propsValue.detail,
|
||||
dueTime: propsValue.dueTime,
|
||||
};
|
||||
|
||||
if (propsValue.categoryId) {
|
||||
taskData.category = { id: propsValue.categoryId };
|
||||
}
|
||||
if (propsValue.ownerId) {
|
||||
taskData.owner = { id: propsValue.ownerId };
|
||||
}
|
||||
|
||||
const linkedEntity = propsValue.linkedEntityId as DynamicPropsValue;
|
||||
if (linkedEntity) {
|
||||
if (linkedEntity['partyId']) {
|
||||
taskData.party = { id: linkedEntity['partyId'] as number };
|
||||
} else if (linkedEntity['opportunityId']) {
|
||||
taskData.opportunity = { id: linkedEntity['opportunityId'] as number };
|
||||
} else if (linkedEntity['projectId']) {
|
||||
taskData.kase = { id: linkedEntity['projectId'] as number };
|
||||
}
|
||||
}
|
||||
|
||||
return await capsuleCrmClient.createTask(auth, taskData);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
|
||||
export const findContactAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'find_contact',
|
||||
displayName: 'Find Contact',
|
||||
description: 'Find a Person by search criteria.',
|
||||
props: {
|
||||
term: Property.ShortText({
|
||||
displayName: 'Search Term',
|
||||
description: 'The value to search for (e.g., a name or email).',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
const parties = await capsuleCrmClient.findContact(auth, propsValue.term);
|
||||
return parties.filter((party) => party.type === 'person');
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import { Filter } from '../common/types';
|
||||
|
||||
export const findOpportunityAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'find_opportunity',
|
||||
displayName: 'Find Opportunity',
|
||||
description: 'Find an Opportunity by search criteria.',
|
||||
props: {
|
||||
filter: Property.Json({
|
||||
displayName: 'Filter',
|
||||
description:
|
||||
'The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.',
|
||||
required: true,
|
||||
defaultValue: {
|
||||
conditions: [
|
||||
{
|
||||
field: 'name',
|
||||
operator: 'is',
|
||||
value: 'example',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
return await capsuleCrmClient.filterOpportunities(
|
||||
auth,
|
||||
propsValue.filter as unknown as Filter
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import { Filter } from '../common/types';
|
||||
|
||||
export const findProjectAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'find_project',
|
||||
displayName: 'Find Project',
|
||||
description: 'Find a Project by search criteria.',
|
||||
props: {
|
||||
filter: Property.Json({
|
||||
displayName: 'Filter',
|
||||
description:
|
||||
'The structured filter query. See the [documentation](https://capsulecrm.com/developer/api-v2/filters/) for examples.',
|
||||
required: true,
|
||||
defaultValue: {
|
||||
conditions: [
|
||||
{
|
||||
field: 'name',
|
||||
operator: 'is',
|
||||
value: 'example',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
return await capsuleCrmClient.filterProjects(
|
||||
auth,
|
||||
propsValue.filter as unknown as Filter
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,368 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
DynamicPropsValue,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth, CapsuleCrmAuthType } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import { capsuleCrmProps } from '../common/props';
|
||||
|
||||
export const updateContactAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'update_contact',
|
||||
displayName: 'Update Contact',
|
||||
description: 'Update fields on an existing Person or Organisation.',
|
||||
props: {
|
||||
contact_id: capsuleCrmProps.contact_id(),
|
||||
contactFields: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Details',
|
||||
required: true,
|
||||
refreshers: ['contact_id'],
|
||||
props: async ({ auth, contact_id }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth || !contact_id) return fields;
|
||||
|
||||
const contact = await capsuleCrmClient.getContact(
|
||||
auth,
|
||||
contact_id as unknown as number
|
||||
);
|
||||
|
||||
if (contact?.type === 'person') {
|
||||
fields['firstName'] = Property.ShortText({
|
||||
displayName: 'First Name',
|
||||
description: "Update the person's first name.",
|
||||
required: false,
|
||||
});
|
||||
fields['lastName'] = Property.ShortText({
|
||||
displayName: 'Last Name',
|
||||
description: "Update the person's last name.",
|
||||
required: false,
|
||||
});
|
||||
fields['title'] = Property.ShortText({
|
||||
displayName: 'Title',
|
||||
description: "Update the person's job title.",
|
||||
required: false,
|
||||
});
|
||||
} else if (contact?.type === 'organisation') {
|
||||
fields['organisationName'] = Property.ShortText({
|
||||
displayName: 'Organisation Name',
|
||||
description: "Update the organisation's name.",
|
||||
required: false,
|
||||
});
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
ownerId: capsuleCrmProps.owner_id(false),
|
||||
teamId: capsuleCrmProps.team_id(false),
|
||||
about: Property.LongText({
|
||||
displayName: 'About',
|
||||
description: 'Update the biography or description for the contact.',
|
||||
required: false,
|
||||
}),
|
||||
addresses: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Addresses',
|
||||
required: false,
|
||||
refreshers: ['contact_id'],
|
||||
props: async ({ auth, contact_id }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth || !contact_id) return fields;
|
||||
|
||||
const contact = await capsuleCrmClient.getContact(
|
||||
auth,
|
||||
contact_id as unknown as number
|
||||
);
|
||||
const addressOptions =
|
||||
contact?.addresses?.map((address) => ({
|
||||
label: `${address.street}, ${address.city}`,
|
||||
value: address.id,
|
||||
})) ?? [];
|
||||
|
||||
fields['addresses'] = Property.Array({
|
||||
displayName: 'Addresses',
|
||||
required: false,
|
||||
properties: {
|
||||
id: Property.StaticDropdown({
|
||||
displayName: 'Address',
|
||||
required: false,
|
||||
options: {
|
||||
options: addressOptions,
|
||||
},
|
||||
}),
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Home', value: 'Home' },
|
||||
{ label: 'Postal', value: 'Postal' },
|
||||
{ label: 'Office', value: 'Office' },
|
||||
{ label: 'Billing', value: 'Billing' },
|
||||
{ label: 'Shipping', value: 'Shipping' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
street: Property.ShortText({
|
||||
displayName: 'Street',
|
||||
required: false,
|
||||
}),
|
||||
city: Property.ShortText({
|
||||
displayName: 'City',
|
||||
required: false,
|
||||
}),
|
||||
state: Property.ShortText({
|
||||
displayName: 'State',
|
||||
required: false,
|
||||
}),
|
||||
country: Property.ShortText({
|
||||
displayName: 'Country',
|
||||
required: false,
|
||||
}),
|
||||
zip: Property.ShortText({
|
||||
displayName: 'Zip',
|
||||
required: false,
|
||||
}),
|
||||
delete: Property.Checkbox({
|
||||
displayName: 'Delete',
|
||||
description: 'Check this to delete the address.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
});
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
websites: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Websites',
|
||||
required: false,
|
||||
refreshers: ['contact_id'],
|
||||
props: async ({ auth, contact_id }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth || !contact_id) return fields;
|
||||
|
||||
const contact = await capsuleCrmClient.getContact(
|
||||
auth,
|
||||
contact_id as unknown as number
|
||||
);
|
||||
const websiteOptions =
|
||||
contact?.websites?.map((website) => ({
|
||||
label: website.address,
|
||||
value: website.id,
|
||||
})) ?? [];
|
||||
|
||||
fields['websites'] = Property.Array({
|
||||
displayName: 'Websites',
|
||||
required: false,
|
||||
properties: {
|
||||
id: Property.StaticDropdown({
|
||||
displayName: 'Website',
|
||||
required: false,
|
||||
options: {
|
||||
options: websiteOptions,
|
||||
},
|
||||
}),
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Home', value: 'Home' },
|
||||
{ label: 'Work', value: 'Work' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
service: Property.StaticDropdown({
|
||||
displayName: 'Service',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'URL', value: 'URL' },
|
||||
{ label: 'Skype', value: 'SKYPE' },
|
||||
{ label: 'Twitter', value: 'TWITTER' },
|
||||
{ label: 'LinkedIn', value: 'LINKED_IN' },
|
||||
{ label: 'Facebook', value: 'FACEBOOK' },
|
||||
{ label: 'Xing', value: 'XING' },
|
||||
{ label: 'Feed', value: 'FEED' },
|
||||
{ label: 'Google+', value: 'GOOGLE_PLUS' },
|
||||
{ label: 'Flickr', value: 'FLICKR' },
|
||||
{ label: 'GitHub', value: 'GITHUB' },
|
||||
{ label: 'YouTube', value: 'YOUTUBE' },
|
||||
{ label: 'Instagram', value: 'INSTAGRAM' },
|
||||
{ label: 'Pinterest', value: 'PINTEREST' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
address: Property.ShortText({
|
||||
displayName: 'Address',
|
||||
required: false,
|
||||
}),
|
||||
delete: Property.Checkbox({
|
||||
displayName: 'Delete',
|
||||
description: 'Check this to delete the website.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
});
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
emailAddresses: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Email Addresses',
|
||||
required: false,
|
||||
refreshers: ['contact_id'],
|
||||
props: async ({ auth, contact_id }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth || !contact_id) return fields;
|
||||
|
||||
const contact = await capsuleCrmClient.getContact(
|
||||
auth,
|
||||
contact_id as unknown as number
|
||||
);
|
||||
const emailOptions =
|
||||
contact?.emailAddresses?.map((email) => ({
|
||||
label: email.address,
|
||||
value: email.id,
|
||||
})) ?? [];
|
||||
|
||||
fields['emailAddresses'] = Property.Array({
|
||||
displayName: 'Email Addresses',
|
||||
required: false,
|
||||
properties: {
|
||||
id: Property.StaticDropdown({
|
||||
displayName: 'Email Address',
|
||||
required: false,
|
||||
options: {
|
||||
options: emailOptions,
|
||||
},
|
||||
}),
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Home', value: 'Home' },
|
||||
{ label: 'Work', value: 'Work' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
address: Property.ShortText({
|
||||
displayName: 'Address',
|
||||
required: false,
|
||||
}),
|
||||
delete: Property.Checkbox({
|
||||
displayName: 'Delete',
|
||||
description: 'Check this to delete the email.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
});
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
phoneNumbers: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Phone Numbers',
|
||||
required: false,
|
||||
refreshers: ['contact_id'],
|
||||
props: async ({ auth, contact_id }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth || !contact_id) return fields;
|
||||
|
||||
const contact = await capsuleCrmClient.getContact(
|
||||
auth,
|
||||
contact_id as unknown as number
|
||||
);
|
||||
const phoneOptions =
|
||||
contact?.phoneNumbers?.map((phone) => ({
|
||||
label: phone.number,
|
||||
value: phone.id,
|
||||
})) ?? [];
|
||||
|
||||
fields['phoneNumbers'] = Property.Array({
|
||||
displayName: 'Phone Numbers',
|
||||
required: false,
|
||||
properties: {
|
||||
id: Property.StaticDropdown({
|
||||
displayName: 'Phone Number',
|
||||
required: false,
|
||||
options: {
|
||||
options: phoneOptions,
|
||||
},
|
||||
}),
|
||||
type: Property.StaticDropdown({
|
||||
displayName: 'Type',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Home', value: 'Home' },
|
||||
{ label: 'Work', value: 'Work' },
|
||||
{ label: 'Mobile', value: 'Mobile' },
|
||||
{ label: 'Fax', value: 'Fax' },
|
||||
{ label: 'Direct', value: 'Direct' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
number: Property.ShortText({
|
||||
displayName: 'Number',
|
||||
required: false,
|
||||
}),
|
||||
delete: Property.Checkbox({
|
||||
displayName: 'Delete',
|
||||
description: 'Check this to delete the phone number.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
});
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
const contactId = propsValue.contact_id as number;
|
||||
const contactFields = propsValue.contactFields as DynamicPropsValue;
|
||||
|
||||
return await capsuleCrmClient.updateContact(auth, contactId, {
|
||||
firstName: contactFields['firstName'] as string | undefined,
|
||||
lastName: contactFields['lastName'] as string | undefined,
|
||||
name: contactFields['organisationName'] as string | undefined,
|
||||
title: contactFields['title'] as string | undefined,
|
||||
about: propsValue.about,
|
||||
ownerId: propsValue.ownerId,
|
||||
teamId: propsValue.teamId,
|
||||
addresses: (
|
||||
(propsValue.addresses as DynamicPropsValue)?.['addresses'] as any[]
|
||||
)?.map((address) => ({
|
||||
...address,
|
||||
_delete: address.delete,
|
||||
})),
|
||||
websites: (
|
||||
(propsValue.websites as DynamicPropsValue)?.['websites'] as any[]
|
||||
)?.map((website) => ({
|
||||
...website,
|
||||
_delete: website.delete,
|
||||
})),
|
||||
emailAddresses: (
|
||||
(propsValue.emailAddresses as DynamicPropsValue)?.[
|
||||
'emailAddresses'
|
||||
] as any[]
|
||||
)?.map((email) => ({
|
||||
...email,
|
||||
_delete: email.delete,
|
||||
})),
|
||||
phoneNumbers: (
|
||||
(propsValue.phoneNumbers as DynamicPropsValue)?.[
|
||||
'phoneNumbers'
|
||||
] as any[]
|
||||
)?.map((phone) => ({
|
||||
...phone,
|
||||
_delete: phone.delete,
|
||||
})),
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,286 @@
|
||||
import {
|
||||
createAction,
|
||||
Property,
|
||||
DynamicPropsValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth, CapsuleCrmAuthType } from '../common/auth';
|
||||
import { capsuleCrmClient } from '../common/client';
|
||||
import {
|
||||
UpdateOpportunityParams,
|
||||
OpportunityCustomField,
|
||||
OpportunityTag,
|
||||
} from '../common/types';
|
||||
|
||||
export const updateOpportunityAction = createAction({
|
||||
auth: capsuleCrmAuth,
|
||||
name: 'update_opportunity',
|
||||
displayName: 'Update Opportunity',
|
||||
description: 'Update an existing Opportunity in Capsule CRM.',
|
||||
props: {
|
||||
opportunityId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Opportunity',
|
||||
required: true,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const opportunities = await capsuleCrmClient.searchOpportunities(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: opportunities.map((opportunity) => ({
|
||||
label: opportunity.name,
|
||||
value: opportunity.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'Name',
|
||||
required: false,
|
||||
}),
|
||||
description: Property.LongText({
|
||||
displayName: 'Description',
|
||||
required: false,
|
||||
}),
|
||||
milestoneId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Milestone',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const milestones = await capsuleCrmClient.listMilestones(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: milestones.map((milestone) => ({
|
||||
label: milestone.name,
|
||||
value: milestone.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
currency: Property.ShortText({
|
||||
displayName: 'Currency',
|
||||
required: false,
|
||||
}),
|
||||
amount: Property.Number({
|
||||
displayName: 'Amount',
|
||||
required: false,
|
||||
}),
|
||||
expectedCloseOn: Property.DateTime({
|
||||
displayName: 'Expected Close Date',
|
||||
required: false,
|
||||
}),
|
||||
probability: Property.Number({
|
||||
displayName: 'Probability',
|
||||
required: false,
|
||||
}),
|
||||
durationBasis: Property.StaticDropdown({
|
||||
displayName: 'Duration Basis',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Fixed', value: 'FIXED' },
|
||||
{ label: 'Hour', value: 'HOUR' },
|
||||
{ label: 'Day', value: 'DAY' },
|
||||
{ label: 'Week', value: 'WEEK' },
|
||||
{ label: 'Month', value: 'MONTH' },
|
||||
{ label: 'Quarter', value: 'QUARTER' },
|
||||
{ label: 'Year', value: 'YEAR' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
duration: Property.Number({
|
||||
displayName: 'Duration',
|
||||
required: false,
|
||||
}),
|
||||
ownerId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Owner',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const users = await capsuleCrmClient.listUsers(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: users.map((user) => ({
|
||||
label: user.name,
|
||||
value: user.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
teamId: Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Team',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first" };
|
||||
const teams = await capsuleCrmClient.listTeams(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
options: teams.map((team) => ({
|
||||
label: team.name,
|
||||
value: team.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
tags: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Tags',
|
||||
required: false,
|
||||
refreshers: ['opportunityId'],
|
||||
props: async ({ auth, opportunityId }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth || !opportunityId) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first or select an opportunity" };
|
||||
|
||||
const opportunity = await capsuleCrmClient.getOpportunity(
|
||||
auth,
|
||||
opportunityId as unknown as number
|
||||
);
|
||||
const tagOptions =
|
||||
opportunity.tags?.map((tag) => ({
|
||||
label: tag.name,
|
||||
value: tag.id,
|
||||
})) ?? [];
|
||||
|
||||
fields['tags'] = Property.Array({
|
||||
displayName: 'Tags',
|
||||
required: false,
|
||||
properties: {
|
||||
id: Property.StaticDropdown({
|
||||
displayName: 'Tag',
|
||||
required: false,
|
||||
options: {
|
||||
options: tagOptions,
|
||||
},
|
||||
}),
|
||||
name: Property.ShortText({
|
||||
displayName: 'New Tag Name',
|
||||
description: 'Enter a name to create a new tag.',
|
||||
required: false,
|
||||
}),
|
||||
delete: Property.Checkbox({
|
||||
displayName: 'Delete',
|
||||
description: 'Check this to delete the tag.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
});
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
customFields: Property.DynamicProperties({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Custom Fields',
|
||||
required: false,
|
||||
refreshers: ['opportunityId'],
|
||||
props: async ({ auth, opportunityId }) => {
|
||||
const fields: DynamicPropsValue = {};
|
||||
if (!auth || !opportunityId) return { options: [], disabled: true, placeholder: "Please connect your Capsule CRM account first or select an opportunity" };
|
||||
|
||||
await capsuleCrmClient.getOpportunity(
|
||||
auth,
|
||||
opportunityId as unknown as number
|
||||
);
|
||||
const allCustomFields = await capsuleCrmClient.listCustomFields(
|
||||
auth
|
||||
);
|
||||
|
||||
const customFieldOptions =
|
||||
allCustomFields?.map((field) => ({
|
||||
label: field.name,
|
||||
value: field.id,
|
||||
})) ?? [];
|
||||
|
||||
fields['customFields'] = Property.Array({
|
||||
displayName: 'Custom Fields',
|
||||
required: false,
|
||||
properties: {
|
||||
definitionId: Property.StaticDropdown({
|
||||
displayName: 'Field',
|
||||
required: true,
|
||||
options: {
|
||||
options: customFieldOptions,
|
||||
},
|
||||
}),
|
||||
value: Property.ShortText({
|
||||
displayName: 'Value',
|
||||
required: true,
|
||||
}),
|
||||
delete: Property.Checkbox({
|
||||
displayName: 'Delete',
|
||||
description: 'Check this to delete the custom field value.',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
});
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { auth, propsValue } = context;
|
||||
const { opportunityId } = propsValue;
|
||||
|
||||
const opportunityData: UpdateOpportunityParams = {
|
||||
name: propsValue.name,
|
||||
description: propsValue.description,
|
||||
expectedCloseOn: propsValue.expectedCloseOn,
|
||||
probability: propsValue.probability,
|
||||
durationBasis: propsValue.durationBasis,
|
||||
duration: propsValue.duration,
|
||||
};
|
||||
|
||||
if (propsValue.ownerId) {
|
||||
opportunityData.owner = { id: propsValue.ownerId };
|
||||
}
|
||||
if (propsValue.teamId) {
|
||||
opportunityData.team = { id: propsValue.teamId };
|
||||
}
|
||||
if (propsValue.milestoneId) {
|
||||
opportunityData.milestone = { id: propsValue.milestoneId };
|
||||
}
|
||||
if (propsValue.currency && propsValue.amount) {
|
||||
opportunityData.value = {
|
||||
currency: propsValue.currency,
|
||||
amount: propsValue.amount,
|
||||
};
|
||||
}
|
||||
|
||||
const tags = (propsValue.tags as { tags: OpportunityTag[] })?.tags;
|
||||
if (tags) {
|
||||
opportunityData.tags = tags.map((tag) => ({
|
||||
id: tag.id,
|
||||
name: tag.name,
|
||||
_delete: tag._delete,
|
||||
}));
|
||||
}
|
||||
|
||||
const customFields = (
|
||||
propsValue.customFields as {
|
||||
customFields: { definitionId: number; value: unknown; delete: boolean }[];
|
||||
}
|
||||
)?.customFields;
|
||||
if (customFields) {
|
||||
opportunityData.fields = customFields.map((field) => ({
|
||||
definition: { id: field.definitionId },
|
||||
value: field.value,
|
||||
_delete: field.delete,
|
||||
}));
|
||||
}
|
||||
|
||||
return await capsuleCrmClient.updateOpportunity(
|
||||
auth,
|
||||
opportunityId,
|
||||
opportunityData
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import { OAuth2PropertyValue, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import {
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
AuthenticationType,
|
||||
} from '@activepieces/pieces-common';
|
||||
|
||||
export const capsuleCrmAuth = PieceAuth.OAuth2({
|
||||
description: `
|
||||
To authenticate with Capsule CRM:
|
||||
1. Go to your Capsule CRM user settings.
|
||||
2. Navigate to "My Preferences" > "API Authentication Tokens".
|
||||
3. Register a new application to get a Client ID and Client Secret.
|
||||
4. Add https://cloud.activepieces.com/redirect to the authorized redirect URIs.
|
||||
5. Use the OAuth2 flow below.`,
|
||||
authUrl: 'https://api.capsulecrm.com/oauth/authorise',
|
||||
tokenUrl: 'https://api.capsulecrm.com/oauth/token',
|
||||
required: true,
|
||||
scope: ['read', 'write'],
|
||||
validate: async ({ auth }) => {
|
||||
try {
|
||||
await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: 'https://api.capsulecrm.com/api/v2/site',
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
});
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid credentials',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export type CapsuleCrmAuthType = OAuth2PropertyValue;
|
||||
@@ -0,0 +1,778 @@
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
} from '@activepieces/pieces-common';
|
||||
import {
|
||||
CreateOpportunityParams,
|
||||
CreatePartyParams,
|
||||
CreateProjectParams,
|
||||
Milestone,
|
||||
Opportunity,
|
||||
Party,
|
||||
Project,
|
||||
UpdateOpportunityParams,
|
||||
UpdatePartyParams,
|
||||
Case,
|
||||
CreateTaskParams,
|
||||
Task,
|
||||
User,
|
||||
Team,
|
||||
Tag,
|
||||
CustomField,
|
||||
CreateNoteParams,
|
||||
Note,
|
||||
FindProjectParams,
|
||||
FindOpportunityParams,
|
||||
Webhook,
|
||||
Stage,
|
||||
Category,
|
||||
ActivityType,
|
||||
CreateEntryParams,
|
||||
Entry,
|
||||
Filter,
|
||||
CreateRestHookParams,
|
||||
RestHook,
|
||||
} from './types';
|
||||
import { CapsuleCrmAuthType } from './auth';
|
||||
|
||||
export const capsuleCrmClient = {
|
||||
async createContact(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: CreatePartyParams
|
||||
): Promise<Party> {
|
||||
const partyData: { [key: string]: unknown } = {
|
||||
type: params.type,
|
||||
};
|
||||
|
||||
if (params.type === 'person') {
|
||||
partyData['firstName'] = params.firstName;
|
||||
partyData['lastName'] = params.lastName;
|
||||
} else {
|
||||
partyData['name'] = params.name;
|
||||
}
|
||||
|
||||
if (params.title) partyData['title'] = params.title;
|
||||
if (params.jobTitle) partyData['jobTitle'] = params.jobTitle;
|
||||
if (params.about) partyData['about'] = params.about;
|
||||
|
||||
if (params.organisationId) {
|
||||
partyData['organisation'] = { id: params.organisationId };
|
||||
}
|
||||
|
||||
if (params.ownerId) {
|
||||
partyData['owner'] = { id: params.ownerId };
|
||||
}
|
||||
if (params.teamId) {
|
||||
partyData['team'] = { id: params.teamId };
|
||||
}
|
||||
if (params.tags) {
|
||||
partyData['tags'] = params.tags.map((tag) => ({ name: tag }));
|
||||
}
|
||||
if (params.fields) {
|
||||
partyData['fields'] = params.fields;
|
||||
}
|
||||
|
||||
if (params.emailAddresses) {
|
||||
partyData['emailAddresses'] = params.emailAddresses;
|
||||
}
|
||||
if (params.phoneNumbers) {
|
||||
partyData['phoneNumbers'] = params.phoneNumbers;
|
||||
}
|
||||
if (params.addresses) {
|
||||
partyData['addresses'] = params.addresses;
|
||||
}
|
||||
if (params.websites) {
|
||||
partyData['websites'] = params.websites;
|
||||
}
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: 'https://api.capsulecrm.com/api/v2/parties',
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
party: partyData,
|
||||
},
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<Party>(request);
|
||||
return response.body;
|
||||
},
|
||||
|
||||
async searchContacts(
|
||||
auth: CapsuleCrmAuthType,
|
||||
searchTerm: string
|
||||
): Promise<Party[]> {
|
||||
const isSearch = searchTerm && searchTerm.length > 0;
|
||||
const url = isSearch
|
||||
? `https://api.capsulecrm.com/api/v2/parties/search`
|
||||
: `https://api.capsulecrm.com/api/v2/parties`;
|
||||
|
||||
const queryParams: Record<string, string> = {};
|
||||
|
||||
if (isSearch) {
|
||||
queryParams['q'] = searchTerm;
|
||||
}
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: url,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
queryParams: queryParams,
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ parties: Party[] }>(
|
||||
request
|
||||
);
|
||||
return response.body.parties;
|
||||
},
|
||||
|
||||
async searchOrganisations(
|
||||
auth: CapsuleCrmAuthType,
|
||||
searchTerm?: string
|
||||
): Promise<Party[]> {
|
||||
try {
|
||||
const url = searchTerm
|
||||
? `https://api.capsulecrm.com/api/v2/parties/search`
|
||||
: `https://api.capsulecrm.com/api/v2/parties`;
|
||||
|
||||
const queryParams: Record<string, string> = {
|
||||
perPage: '100',
|
||||
};
|
||||
|
||||
if (searchTerm) {
|
||||
queryParams['q'] = searchTerm;
|
||||
}
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: url,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
queryParams: queryParams,
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<{ parties: Party[] }>(
|
||||
request
|
||||
);
|
||||
|
||||
if (!response.body || !response.body.parties) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Temporarily return all parties to debug
|
||||
console.log('Parties response:', response.body.parties);
|
||||
const organisations = response.body.parties.filter(
|
||||
(party) => party.type === 'organisation'
|
||||
);
|
||||
console.log('Filtered organisations:', organisations);
|
||||
return organisations;
|
||||
} catch (error) {
|
||||
console.error('searchOrganisations error:', error);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
async listTeams(auth: CapsuleCrmAuthType): Promise<Team[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/teams`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ teams: Team[] }>(request);
|
||||
return response.body.teams;
|
||||
},
|
||||
|
||||
async listTags(auth: CapsuleCrmAuthType): Promise<Tag[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/parties/tags`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ tags: Tag[] }>(request);
|
||||
return response.body.tags;
|
||||
},
|
||||
|
||||
async listCustomFields(auth: CapsuleCrmAuthType): Promise<CustomField[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/parties/fields/definitions`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{
|
||||
definitions: CustomField[];
|
||||
}>(request);
|
||||
return response.body.definitions;
|
||||
},
|
||||
|
||||
async updateContact(
|
||||
auth: CapsuleCrmAuthType,
|
||||
partyId: number,
|
||||
params: UpdatePartyParams
|
||||
): Promise<Party> {
|
||||
const partyData: { [key: string]: unknown } = {};
|
||||
if (params.firstName) partyData['firstName'] = params.firstName;
|
||||
if (params.lastName) partyData['lastName'] = params.lastName;
|
||||
if (params.name) partyData['name'] = params.name;
|
||||
if (params.title) partyData['title'] = params.title;
|
||||
if (params.about) partyData['about'] = params.about;
|
||||
if (params.ownerId) partyData['owner'] = { id: params.ownerId };
|
||||
if (params.teamId) partyData['team'] = { id: params.teamId };
|
||||
if (params.addresses) partyData['addresses'] = params.addresses;
|
||||
if (params.websites) partyData['websites'] = params.websites;
|
||||
if (params.emailAddresses)
|
||||
partyData['emailAddresses'] = params.emailAddresses;
|
||||
if (params.phoneNumbers) partyData['phoneNumbers'] = params.phoneNumbers;
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.PUT,
|
||||
url: `https://api.capsulecrm.com/api/v2/parties/${partyId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
party: partyData,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<Party>(request);
|
||||
return response.body;
|
||||
},
|
||||
|
||||
async listMilestones(auth: CapsuleCrmAuthType): Promise<Milestone[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/milestones`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ milestones: Milestone[] }>(
|
||||
request
|
||||
);
|
||||
return response.body.milestones;
|
||||
},
|
||||
|
||||
async searchOpportunities(
|
||||
auth: CapsuleCrmAuthType
|
||||
): Promise<Opportunity[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/opportunities`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{
|
||||
opportunities: Opportunity[];
|
||||
}>(request);
|
||||
return response.body.opportunities;
|
||||
},
|
||||
|
||||
async getOpportunity(
|
||||
auth: CapsuleCrmAuthType,
|
||||
opportunityId: number
|
||||
): Promise<Opportunity> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/opportunities/${opportunityId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
queryParams: {
|
||||
embed: 'tags,fields',
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ opportunity: Opportunity }>(
|
||||
request
|
||||
);
|
||||
return response.body.opportunity;
|
||||
},
|
||||
|
||||
async createOpportunity(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: CreateOpportunityParams
|
||||
): Promise<Opportunity> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.capsulecrm.com/api/v2/opportunities`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
opportunity: params,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ opportunity: Opportunity }>(
|
||||
request
|
||||
);
|
||||
return response.body.opportunity;
|
||||
},
|
||||
|
||||
async listOpportunities(auth: CapsuleCrmAuthType): Promise<Opportunity[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/opportunities`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{
|
||||
opportunities: Opportunity[];
|
||||
}>(request);
|
||||
return response.body.opportunities;
|
||||
},
|
||||
|
||||
async updateOpportunity(
|
||||
auth: CapsuleCrmAuthType,
|
||||
opportunityId: number,
|
||||
params: UpdateOpportunityParams
|
||||
): Promise<Opportunity> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.PUT,
|
||||
url: `https://api.capsulecrm.com/api/v2/opportunities/${opportunityId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
opportunity: params,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ opportunity: Opportunity }>(
|
||||
request
|
||||
);
|
||||
return response.body.opportunity;
|
||||
},
|
||||
|
||||
async listCategories(auth: CapsuleCrmAuthType): Promise<Category[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/categories`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ categories: Category[] }>(
|
||||
request
|
||||
);
|
||||
return response.body.categories;
|
||||
},
|
||||
|
||||
async searchProjects(auth: CapsuleCrmAuthType): Promise<Project[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/kases`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ kases: Project[] }>(request);
|
||||
return response.body.kases;
|
||||
},
|
||||
|
||||
async subscribeRestHook(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: CreateRestHookParams
|
||||
): Promise<RestHook> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.capsulecrm.com/api/v2/resthooks`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
restHook: params,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ restHook: RestHook }>(
|
||||
request
|
||||
);
|
||||
return response.body.restHook;
|
||||
},
|
||||
|
||||
async unsubscribeRestHook(
|
||||
auth: CapsuleCrmAuthType,
|
||||
hookId: number
|
||||
): Promise<void> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.DELETE,
|
||||
url: `https://api.capsulecrm.com/api/v2/resthooks/${hookId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
await httpClient.sendRequest(request);
|
||||
},
|
||||
|
||||
async listActivityTypes(auth: CapsuleCrmAuthType): Promise<ActivityType[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/activitytypes`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{
|
||||
activityTypes: ActivityType[];
|
||||
}>(request);
|
||||
return response.body.activityTypes;
|
||||
},
|
||||
|
||||
async findContact(
|
||||
auth: CapsuleCrmAuthType,
|
||||
term: string
|
||||
): Promise<Party[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/parties/search`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
queryParams: {
|
||||
q: term,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ parties: Party[] }>(
|
||||
request
|
||||
);
|
||||
return response.body.parties;
|
||||
},
|
||||
|
||||
async filterOpportunities(
|
||||
auth: CapsuleCrmAuthType,
|
||||
filter: Filter
|
||||
): Promise<Opportunity[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.capsulecrm.com/api/v2/opportunities/filters/results`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
filter: filter,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{
|
||||
opportunities: Opportunity[];
|
||||
}>(request);
|
||||
return response.body.opportunities;
|
||||
},
|
||||
|
||||
async filterProjects(
|
||||
auth: CapsuleCrmAuthType,
|
||||
filter: Filter
|
||||
): Promise<Project[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.capsulecrm.com/api/v2/kases/filters/results`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
filter: filter,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ kases: Project[] }>(
|
||||
request
|
||||
);
|
||||
return response.body.kases;
|
||||
},
|
||||
|
||||
async listStages(auth: CapsuleCrmAuthType): Promise<Stage[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/stages`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ stages: Stage[] }>(request);
|
||||
return response.body.stages;
|
||||
},
|
||||
|
||||
async createProject(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: CreateProjectParams
|
||||
): Promise<Project> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.capsulecrm.com/api/v2/kases`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
kase: params,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ kase: Project }>(request);
|
||||
return response.body.kase;
|
||||
},
|
||||
|
||||
async listProjects(auth: CapsuleCrmAuthType): Promise<Project[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/kases`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ kases: Project[] }>(
|
||||
request
|
||||
);
|
||||
return response.body.kases;
|
||||
},
|
||||
|
||||
async listCases(auth: CapsuleCrmAuthType): Promise<Case[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/kases`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ kases: Case[] }>(request);
|
||||
return response.body.kases;
|
||||
},
|
||||
|
||||
async listUsers(auth: CapsuleCrmAuthType): Promise<User[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/users`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ users: User[] }>(request);
|
||||
return response.body.users;
|
||||
},
|
||||
|
||||
async createEntry(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: CreateEntryParams
|
||||
): Promise<Entry> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.capsulecrm.com/api/v2/entries`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
entry: params,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ entry: Entry }>(request);
|
||||
return response.body.entry;
|
||||
},
|
||||
|
||||
async createTask(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: CreateTaskParams
|
||||
): Promise<Task> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.capsulecrm.com/api/v2/tasks`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
task: params,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ task: Task }>(request);
|
||||
return response.body.task;
|
||||
},
|
||||
|
||||
async createNote(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: CreateNoteParams
|
||||
): Promise<Note> {
|
||||
const entryData: { [key: string]: unknown } = {
|
||||
type: 'Note',
|
||||
content: params.content,
|
||||
};
|
||||
|
||||
if (params.partyId) entryData['party'] = { id: params.partyId };
|
||||
if (params.opportunityId)
|
||||
entryData['opportunity'] = { id: params.opportunityId };
|
||||
if (params.caseId) entryData['case'] = { id: params.caseId };
|
||||
if (params.projectId) entryData['project'] = { id: params.projectId };
|
||||
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: 'https://api.capsulecrm.com/api/v2/entries',
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
entry: entryData,
|
||||
},
|
||||
};
|
||||
|
||||
const response = await httpClient.sendRequest<Note>(request);
|
||||
return response.body;
|
||||
},
|
||||
|
||||
async getContact(
|
||||
auth: CapsuleCrmAuthType,
|
||||
contactId: number
|
||||
): Promise<Party | null> {
|
||||
try {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/parties/${contactId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
queryParams: {
|
||||
embed: 'addresses,phoneNumbers,websites,emailAddresses',
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ party: Party }>(request);
|
||||
return response.body.party;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
async findProject(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: FindProjectParams
|
||||
): Promise<Project[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/kases`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
queryParams: {
|
||||
q: params.searchTerm,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ kases: Project[] }>(
|
||||
request
|
||||
);
|
||||
return response.body.kases;
|
||||
},
|
||||
|
||||
async getProject(
|
||||
auth: CapsuleCrmAuthType,
|
||||
projectId: number
|
||||
): Promise<Project | null> {
|
||||
try {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/kases/${projectId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ kase: Project }>(request);
|
||||
return response.body.kase;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
async findOpportunity(
|
||||
auth: CapsuleCrmAuthType,
|
||||
params: FindOpportunityParams
|
||||
): Promise<Opportunity[]> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.GET,
|
||||
url: `https://api.capsulecrm.com/api/v2/opportunities/search`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
queryParams: {
|
||||
q: params.searchTerm,
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{
|
||||
opportunities: Opportunity[];
|
||||
}>(request);
|
||||
return response.body.opportunities;
|
||||
},
|
||||
|
||||
async subscribeWebhook(
|
||||
auth: CapsuleCrmAuthType,
|
||||
url: string,
|
||||
event: string
|
||||
): Promise<Webhook> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.POST,
|
||||
url: `https://api.capsulecrm.com/api/v2/webhooks`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
body: {
|
||||
webhook: {
|
||||
url: url,
|
||||
event: event,
|
||||
},
|
||||
},
|
||||
};
|
||||
const response = await httpClient.sendRequest<{ webhook: Webhook }>(
|
||||
request
|
||||
);
|
||||
return response.body.webhook;
|
||||
},
|
||||
|
||||
async unsubscribeWebhook(
|
||||
auth: CapsuleCrmAuthType,
|
||||
webhookId: number
|
||||
): Promise<void> {
|
||||
const request: HttpRequest = {
|
||||
method: HttpMethod.DELETE,
|
||||
url: `https://api.capsulecrm.com/api/v2/webhooks/${webhookId}`,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: auth.access_token,
|
||||
},
|
||||
};
|
||||
await httpClient.sendRequest(request);
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,215 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth, CapsuleCrmAuthType } from './auth';
|
||||
import { capsuleCrmClient } from './client';
|
||||
|
||||
export const capsuleCrmProps = {
|
||||
contact_id: (required = true) =>
|
||||
Property.Dropdown({
|
||||
displayName: 'Contact',
|
||||
description: 'The contact (Person or Organisation) to select.',
|
||||
required: required,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async (props) => {
|
||||
const { auth } = props;
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const searchTerm = (props['searchValue'] as string) ?? '';
|
||||
|
||||
const contacts = await capsuleCrmClient.searchContacts(
|
||||
auth,
|
||||
searchTerm
|
||||
);
|
||||
|
||||
const options = contacts.map((contact) => {
|
||||
const label =
|
||||
contact.type === 'person'
|
||||
? `${contact.firstName} ${contact.lastName}`
|
||||
: contact.name;
|
||||
return {
|
||||
label: label || 'Unnamed Contact',
|
||||
value: contact.id,
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: options,
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
milestone_id: (required = true) =>
|
||||
Property.Dropdown({
|
||||
displayName: 'Milestone',
|
||||
description: 'The milestone to assign the opportunity to.',
|
||||
required: required,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const milestones = await capsuleCrmClient.listMilestones(
|
||||
auth
|
||||
);
|
||||
const options = milestones.map((milestone) => {
|
||||
return {
|
||||
label: milestone.name,
|
||||
value: milestone.id,
|
||||
};
|
||||
});
|
||||
return {
|
||||
disabled: false,
|
||||
options: options,
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
opportunity_id: (required = true) =>
|
||||
Property.Dropdown({
|
||||
displayName: 'Opportunity',
|
||||
description: 'The opportunity to associate with this item.',
|
||||
required: required,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const opportunities = await capsuleCrmClient.listOpportunities(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: opportunities.map((opportunity) => ({
|
||||
label: opportunity.name,
|
||||
value: opportunity.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
project_id: (required = false) =>
|
||||
Property.Dropdown({
|
||||
displayName: 'Project',
|
||||
description: 'The project to associate this item with.',
|
||||
required: required,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const projects = await capsuleCrmClient.listProjects(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: projects.map((project) => ({
|
||||
label: project.name,
|
||||
value: project.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
case_id: (required = false) =>
|
||||
Property.Dropdown({
|
||||
displayName: 'Case',
|
||||
description: 'The case to associate this item with.',
|
||||
required: required,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const cases = await capsuleCrmClient.listCases(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: cases.map((kase) => ({ label: kase.name, value: kase.id })),
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
owner_id: (required = false) =>
|
||||
Property.Dropdown({
|
||||
auth: capsuleCrmAuth,
|
||||
displayName: 'Owner',
|
||||
description: 'The user to assign the task to.',
|
||||
required: required,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const users = await capsuleCrmClient.listUsers(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: users.map((user) => ({
|
||||
label: user.username,
|
||||
value: user.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
team_id: (required = false) =>
|
||||
Property.Dropdown({
|
||||
displayName: 'Team',
|
||||
description: 'The team to assign the contact to.',
|
||||
required: required,
|
||||
refreshers: [],
|
||||
auth: capsuleCrmAuth,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const teams = await capsuleCrmClient.listTeams(
|
||||
auth
|
||||
);
|
||||
return {
|
||||
disabled: false,
|
||||
options: teams.map((team) => ({
|
||||
label: team.name,
|
||||
value: team.id,
|
||||
})),
|
||||
};
|
||||
},
|
||||
}),
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { capsuleCrmAuth } from './auth';
|
||||
import { capsuleCrmClient } from './client';
|
||||
|
||||
type TriggerParams = {
|
||||
name: string;
|
||||
displayName: string;
|
||||
description: string;
|
||||
event: string;
|
||||
sampleData: unknown;
|
||||
};
|
||||
|
||||
export const capsuleCrmCreateTrigger = ({
|
||||
name,
|
||||
displayName,
|
||||
description,
|
||||
event,
|
||||
sampleData,
|
||||
}: TriggerParams) => {
|
||||
return createTrigger({
|
||||
auth: capsuleCrmAuth,
|
||||
name: name,
|
||||
displayName: displayName,
|
||||
description: description,
|
||||
props: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
sampleData: sampleData,
|
||||
async onEnable(context) {
|
||||
const hook = await capsuleCrmClient.subscribeRestHook(context.auth, {
|
||||
targetUrl: context.webhookUrl,
|
||||
event: event,
|
||||
description: `Activepieces - ${displayName}`,
|
||||
});
|
||||
await context.store.put(`capsule_crm_trigger_${name}`, {
|
||||
hookId: hook.id,
|
||||
});
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
const storedData = await context.store.get<{ hookId: number }>(
|
||||
`capsule_crm_trigger_${name}`
|
||||
);
|
||||
if (storedData) {
|
||||
await capsuleCrmClient.unsubscribeRestHook(context.auth, storedData.hookId);
|
||||
}
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
const body = context.payload.body as { payload: unknown[] };
|
||||
return body.payload;
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,337 @@
|
||||
export interface Party {
|
||||
id: number;
|
||||
type: 'person' | 'organisation';
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
name?: string;
|
||||
addresses?: {
|
||||
id: number;
|
||||
street: string;
|
||||
city: string;
|
||||
}[];
|
||||
websites?: {
|
||||
id: number;
|
||||
address: string;
|
||||
}[];
|
||||
emailAddresses?: {
|
||||
id: number;
|
||||
address: string;
|
||||
}[];
|
||||
phoneNumbers?: {
|
||||
id: number;
|
||||
number: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface CreatePartyParams {
|
||||
type: 'person' | 'organisation';
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
name?: string;
|
||||
emailAddresses?: {
|
||||
type?: string;
|
||||
address: string;
|
||||
}[];
|
||||
phoneNumbers?: {
|
||||
type?: string;
|
||||
number: string;
|
||||
}[];
|
||||
title?: string;
|
||||
jobTitle?: string;
|
||||
about?: string;
|
||||
organisationId?: number;
|
||||
ownerId?: number;
|
||||
teamId?: number;
|
||||
tags?: string[];
|
||||
fields?: { definition: { id: number }; value: unknown }[];
|
||||
addresses?: {
|
||||
type?: string;
|
||||
street?: string;
|
||||
city?: string;
|
||||
state?: string;
|
||||
country?: string;
|
||||
zip?: string;
|
||||
}[];
|
||||
websites?: {
|
||||
type?: string;
|
||||
service: string;
|
||||
address: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface UpdatePartyParams {
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
name?: string;
|
||||
title?: string;
|
||||
about?: string;
|
||||
ownerId?: number;
|
||||
teamId?: number;
|
||||
addresses?: {
|
||||
id?: number;
|
||||
type?: string;
|
||||
street?: string;
|
||||
city?: string;
|
||||
state?: string;
|
||||
country?: string;
|
||||
zip?: string;
|
||||
_delete?: boolean;
|
||||
}[];
|
||||
websites?: {
|
||||
id?: number;
|
||||
type?: string;
|
||||
service?: string;
|
||||
address?: string;
|
||||
_delete?: boolean;
|
||||
}[];
|
||||
emailAddresses?: {
|
||||
id?: number;
|
||||
type?: string;
|
||||
address?: string;
|
||||
_delete?: boolean;
|
||||
}[];
|
||||
phoneNumbers?: {
|
||||
id?: number;
|
||||
type?: string;
|
||||
number?: string;
|
||||
_delete?: boolean;
|
||||
}[];
|
||||
}
|
||||
|
||||
export interface Milestone {
|
||||
id: number;
|
||||
name: string;
|
||||
description?: string;
|
||||
probability: number;
|
||||
complete: boolean;
|
||||
daysUntilStale: number;
|
||||
}
|
||||
|
||||
export interface OpportunityValue {
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
export interface OpportunityCustomField {
|
||||
id?: number;
|
||||
definition: {
|
||||
id: number;
|
||||
};
|
||||
value: unknown;
|
||||
_delete?: boolean;
|
||||
}
|
||||
|
||||
export interface OpportunityTag {
|
||||
id?: number;
|
||||
name: string;
|
||||
_delete?: boolean;
|
||||
}
|
||||
|
||||
export interface Opportunity extends CreateOpportunityParams {
|
||||
id: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
tags?: OpportunityTag[];
|
||||
fields?: OpportunityCustomField[];
|
||||
}
|
||||
|
||||
export interface Stage {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface CreateProjectParams {
|
||||
party: { id: number };
|
||||
name: string;
|
||||
description?: string;
|
||||
owner?: { id: number };
|
||||
team?: { id: number };
|
||||
status?: 'OPEN' | 'CLOSED';
|
||||
opportunity?: { id: number };
|
||||
stage?: { id: number };
|
||||
expectedCloseOn?: string;
|
||||
tags?: OpportunityTag[];
|
||||
fields?: OpportunityCustomField[];
|
||||
}
|
||||
|
||||
export interface Project extends CreateProjectParams {
|
||||
id: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
closedOn?: string;
|
||||
}
|
||||
|
||||
export interface CreateOpportunityParams {
|
||||
name: string;
|
||||
party: {
|
||||
id: number;
|
||||
};
|
||||
milestone: {
|
||||
id: number;
|
||||
};
|
||||
description?: string;
|
||||
owner?: { id: number };
|
||||
team?: { id: number };
|
||||
value?: OpportunityValue;
|
||||
expectedCloseOn?: string;
|
||||
probability?: number;
|
||||
durationBasis?: string;
|
||||
duration?: number;
|
||||
tags?: OpportunityTag[];
|
||||
fields?: OpportunityCustomField[];
|
||||
}
|
||||
|
||||
export interface UpdateOpportunityParams {
|
||||
name?: string;
|
||||
description?: string;
|
||||
owner?: { id: number };
|
||||
team?: { id: number };
|
||||
milestone?: { id: number };
|
||||
value?: OpportunityValue;
|
||||
expectedCloseOn?: string;
|
||||
probability?: number;
|
||||
durationBasis?: string;
|
||||
duration?: number;
|
||||
tags?: OpportunityTag[];
|
||||
fields?: OpportunityCustomField[];
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Case {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: number;
|
||||
username: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Team {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Tag {
|
||||
id: number;
|
||||
name: string;
|
||||
dataTag: boolean;
|
||||
}
|
||||
|
||||
export interface CustomField {
|
||||
id: number;
|
||||
name: string;
|
||||
type: string;
|
||||
options?: string[];
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
id: number;
|
||||
type: 'Task';
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface CreateTaskParams {
|
||||
description: string;
|
||||
dueOn: string;
|
||||
detail?: string;
|
||||
category?: { id: number };
|
||||
owner?: { id: number };
|
||||
party?: { id: number };
|
||||
opportunity?: { id: number };
|
||||
kase?: { id: number };
|
||||
dueTime?: string;
|
||||
}
|
||||
|
||||
export interface Task extends CreateTaskParams {
|
||||
id: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
status: 'OPEN' | 'COMPLETED' | 'PENDING';
|
||||
}
|
||||
|
||||
export interface ActivityType {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface CreateEntryParams {
|
||||
type: 'note';
|
||||
content: string;
|
||||
activityType?: { id: number };
|
||||
party?: { id: number };
|
||||
opportunity?: { id: number };
|
||||
kase?: { id: number };
|
||||
}
|
||||
|
||||
export interface Entry extends CreateEntryParams {
|
||||
id: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface Note {
|
||||
id: number;
|
||||
type: 'Note';
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface CreateNoteParams {
|
||||
content: string;
|
||||
partyId?: number;
|
||||
opportunityId?: number;
|
||||
caseId?: number;
|
||||
projectId?: number;
|
||||
}
|
||||
|
||||
export interface FindContactParams {
|
||||
email?: string;
|
||||
searchTerm?: string;
|
||||
}
|
||||
|
||||
export interface FindProjectParams {
|
||||
searchTerm: string;
|
||||
}
|
||||
|
||||
export interface FindOpportunityParams {
|
||||
searchTerm: string;
|
||||
}
|
||||
|
||||
export interface Webhook {
|
||||
id: number;
|
||||
url: string;
|
||||
event: string;
|
||||
}
|
||||
|
||||
export interface Category {
|
||||
id: number;
|
||||
name: string;
|
||||
colour: string;
|
||||
}
|
||||
|
||||
export interface FilterCondition {
|
||||
field: string;
|
||||
operator: string;
|
||||
value: string | number | boolean;
|
||||
}
|
||||
|
||||
export interface Filter {
|
||||
conditions: FilterCondition[];
|
||||
}
|
||||
|
||||
export interface RestHook {
|
||||
id: number;
|
||||
event: string;
|
||||
targetUrl: string;
|
||||
}
|
||||
|
||||
export interface CreateRestHookParams {
|
||||
event: string;
|
||||
targetUrl: string;
|
||||
description: string;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { capsuleCrmCreateTrigger } from '../common/trigger';
|
||||
|
||||
export const newCaseTrigger = capsuleCrmCreateTrigger({
|
||||
name: 'new_case',
|
||||
displayName: 'New Case',
|
||||
description: 'Fires when a new case (project) is created in Capsule CRM.',
|
||||
event: 'kase/created',
|
||||
sampleData: {
|
||||
event: 'kase/created',
|
||||
payload: [
|
||||
{
|
||||
id: 12,
|
||||
party: {
|
||||
id: 892,
|
||||
type: 'organisation',
|
||||
name: 'Zestia',
|
||||
pictureURL:
|
||||
'https://capsulecrm.com/theme/default/images/org_avatar_70.png',
|
||||
},
|
||||
owner: {
|
||||
id: 61,
|
||||
username: 'ted',
|
||||
name: 'Ted Danson',
|
||||
},
|
||||
status: 'OPEN',
|
||||
stage: {
|
||||
name: 'Project Brief',
|
||||
id: 149,
|
||||
},
|
||||
createdAt: '2015-12-07T16:54:27Z',
|
||||
updatedAt: '2015-12-07T16:54:27Z',
|
||||
expectedCloseOn: '2015-12-09',
|
||||
description: 'Scope and design web site shopping cart',
|
||||
name: 'Consulting',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import { capsuleCrmCreateTrigger } from '../common/trigger';
|
||||
|
||||
export const newOpportunityTrigger = capsuleCrmCreateTrigger({
|
||||
name: 'new_opportunity',
|
||||
displayName: 'New Opportunity',
|
||||
description: 'Fires when a new opportunity is created.',
|
||||
event: 'opportunity/created',
|
||||
sampleData: {
|
||||
event: 'opportunity/created',
|
||||
payload: [
|
||||
{
|
||||
id: 83948362,
|
||||
updatedAt: '2015-10-29T12:55:12Z',
|
||||
description: 'Scope and design web site shopping cart',
|
||||
owner: {
|
||||
id: 6,
|
||||
username: 'scottspacey',
|
||||
name: 'Scott Spacey',
|
||||
},
|
||||
party: {
|
||||
id: 581,
|
||||
pictureURL:
|
||||
'https://capsulecrm.com/theme/default/images/person_avatar_70.png',
|
||||
type: 'organisation',
|
||||
name: 'Capsule',
|
||||
},
|
||||
lostReason: null,
|
||||
milestone: {
|
||||
id: 14,
|
||||
name: 'Bid',
|
||||
},
|
||||
value: {
|
||||
amount: 500,
|
||||
currency: 'GBP',
|
||||
},
|
||||
expectedCloseOn: '2015-10-31',
|
||||
probability: 50,
|
||||
durationBasis: 'FIXED',
|
||||
duration: null,
|
||||
closedOn: null,
|
||||
createdAt: '2015-10-29T12:55:12Z',
|
||||
name: 'Consulting',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { capsuleCrmCreateTrigger } from '../common/trigger';
|
||||
|
||||
export const newProjectTrigger = capsuleCrmCreateTrigger({
|
||||
name: 'new_project',
|
||||
displayName: 'New Project',
|
||||
description: 'Fires when a project is created.',
|
||||
event: 'kase/created',
|
||||
sampleData: {
|
||||
event: 'kase/created',
|
||||
payload: [
|
||||
{
|
||||
id: 12,
|
||||
party: {
|
||||
id: 892,
|
||||
type: 'organisation',
|
||||
name: 'Zestia',
|
||||
pictureURL:
|
||||
'https://capsulecrm.com/theme/default/images/org_avatar_70.png',
|
||||
},
|
||||
owner: {
|
||||
id: 61,
|
||||
username: 'ted',
|
||||
name: 'Ted Danson',
|
||||
},
|
||||
status: 'OPEN',
|
||||
stage: {
|
||||
name: 'Project Brief',
|
||||
id: 149,
|
||||
},
|
||||
createdAt: '2015-12-07T16:54:27Z',
|
||||
updatedAt: '2015-12-07T16:54:27Z',
|
||||
expectedCloseOn: '2015-12-09',
|
||||
description: 'Scope and design web site shopping cart',
|
||||
name: 'Consulting',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { capsuleCrmCreateTrigger } from '../common/trigger';
|
||||
|
||||
export const newTaskTrigger = capsuleCrmCreateTrigger({
|
||||
name: 'new_task',
|
||||
displayName: 'New Task',
|
||||
description: 'Fires when a new task is created.',
|
||||
event: 'task/created',
|
||||
sampleData: {
|
||||
event: 'task/created',
|
||||
payload: [
|
||||
{
|
||||
id: 530,
|
||||
description: 'Email product details',
|
||||
dueTime: '18:00:00',
|
||||
status: 'OPEN',
|
||||
party: {
|
||||
id: 11587,
|
||||
type: 'person',
|
||||
firstName: 'Scott',
|
||||
lastName: 'Spacey',
|
||||
pictureURL:
|
||||
'https://capsulecrm.com/theme/default/images/person_avatar_70.png',
|
||||
},
|
||||
owner: {
|
||||
id: 1,
|
||||
username: 'john',
|
||||
name: 'John Spacey',
|
||||
},
|
||||
createdAt: '2015-12-21T13:51:38Z',
|
||||
updatedAt: '2015-12-21T13:51:38Z',
|
||||
dueOn: '2014-05-20',
|
||||
hasTrack: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"importHelpers": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noPropertyAccessFromIndexSignature": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user