@ixiam/n8n-nodes-civicrm 0.4.4 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.cjs CHANGED
@@ -1,10 +1,12 @@
1
1
  module.exports = {
2
- root: true,
3
2
  parser: '@typescript-eslint/parser',
4
- plugins: ['@typescript-eslint','n8n-nodes-base'],
3
+ plugins: ['@typescript-eslint'],
5
4
  extends: [
5
+ 'eslint:recommended',
6
6
  'plugin:@typescript-eslint/recommended',
7
- 'plugin:n8n-nodes-base/community'
8
7
  ],
9
- ignorePatterns: ['dist/**'],
8
+ rules: {
9
+ '@typescript-eslint/no-unused-vars': 'off',
10
+ '@typescript-eslint/no-explicit-any': 'off',
11
+ },
10
12
  };
package/README.md CHANGED
@@ -1,13 +1,150 @@
1
1
  # n8n-nodes-civicrm
2
- Community node for **CiviCRM API v4** and **Form Processor**.
3
2
 
4
- Install: Settings → Community Nodes → Install → `n8n-nodes-civicrm`
3
+ ![n8n Community Node](https://img.shields.io/badge/n8n-Community%20Node-blue.svg)
4
+ ![CiviCRM API v4](https://img.shields.io/badge/CiviCRM-API%20v4-orange.svg)
5
+ ![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)
5
6
 
6
- Credentials:
7
- - Base URL: `https://crm.example.org` (no trailing slash)
8
- - API Token: header `X-Civi-Auth: Bearer <token>`
9
- - Use the **Save** button to verify connectivity.
7
+ Community Node for **CiviCRM API v4** (Civi-Go compatible)
8
+ Developed and maintained by **Ixiam Global Solutions**.
10
9
 
11
- Entities: Contact, Event, Case, Contribution, Membership `get|getMany|create|update|delete`
10
+ This package provides integration between **n8n** and **CiviCRM API v4**, supporting create, update, delete operations, advanced filtering, dynamic location types, and structured sub-entities (email, phone, address).
11
+ Custom fields are **not** supported.
12
12
 
13
- Node developed by Ixiam Global Solution: `https://www.ixiam.com'
13
+ ---
14
+
15
+ ## Installation
16
+
17
+ 1. In your n8n instance, open:
18
+ **Settings → Community Nodes → Install**
19
+ 2. Enter the package name:
20
+
21
+ ```
22
+ @ixiam/n8n-nodes-civicrm
23
+ ```
24
+
25
+ 3. Confirm installation and enable Community Nodes.
26
+ 4. If running n8n via Docker, restart/rebuild for the node to load.
27
+
28
+ ---
29
+
30
+ ## Credentials
31
+
32
+ Authentication uses **Bearer Token**.
33
+
34
+ | Field | Description |
35
+ |-------|-------------|
36
+ | **Base URL** | Root URL of your CiviCRM instance (no trailing slash). Example: `https://crm.example.org` |
37
+ | **API Token** | Sent as header `X-Civi-Auth: Bearer <token>` |
38
+
39
+ ---
40
+
41
+ ## Supported Entities
42
+
43
+ This node implements API v4 operations for:
44
+
45
+ - Contact
46
+ - Membership
47
+ - Group
48
+ - Relationship
49
+ - Activity
50
+ - Custom API Call (raw API4 request)
51
+
52
+ Each entity supports:
53
+ - get
54
+ - getMany
55
+ - create
56
+ - update
57
+ - delete
58
+
59
+ ---
60
+
61
+ ## Features
62
+
63
+ ### Email, phone and address with location types
64
+ Two mapping modes:
65
+
66
+ Simple:
67
+ ```
68
+ email = test@example.org
69
+ address.city = Barcelona
70
+ ```
71
+
72
+ With location prefixes:
73
+ ```
74
+ work.email = user@company.org
75
+ billing.address.postal_code = 08014
76
+ home.phone.phone_type_id = 2
77
+ ```
78
+
79
+ ### GET MANY with JSON filters
80
+ Example:
81
+ ```json
82
+ [
83
+ ["first_name", "LIKE", "Ju%"],
84
+ ["birth_date", ">", "1990-01-01"],
85
+ ["gender_id", "IN", [1, 2]]
86
+ ]
87
+ ```
88
+
89
+ ### Birth date normalization
90
+ Accepted input formats:
91
+ - YYYY-MM-DD
92
+ - DD/MM/YYYY
93
+ - DD-MM-YYYY
94
+ - YYYY/MM/DD
95
+ - YYYY.MM.DD
96
+
97
+ Normalized to `YYYY-MM-DD`.
98
+
99
+ ### Custom API Call
100
+ Example:
101
+ ```json
102
+ {
103
+ "entity": "Contact",
104
+ "action": "get",
105
+ "params": { "limit": 10 }
106
+ }
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Compatibility
112
+
113
+ - **n8n version:** 1.0.0 or higher
114
+ - **Node.js:** 18 or higher
115
+ - **CiviCRM:** API v4 compatible (including Civi-Go)
116
+
117
+ ---
118
+
119
+ ## Development
120
+
121
+ Clone the repository and run:
122
+
123
+ ```
124
+ npm install
125
+ npm run dev
126
+ ```
127
+
128
+ Build:
129
+
130
+ ```
131
+ npm run build
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Contributions
137
+
138
+ Pull requests and issues are welcome in the GitHub repository.
139
+
140
+ ---
141
+
142
+ ## About Ixiam Global Solutions
143
+ Website: https://www.ixiam.com
144
+ Email: info@ixiam.com
145
+
146
+ ---
147
+
148
+ ## License
149
+
150
+ MIT License
@@ -1,61 +1,58 @@
1
1
  import type {
2
- ICredentialType,
3
- INodeProperties,
4
- IHttpRequestMethods,
2
+ ICredentialType,
3
+ INodeProperties,
4
+ IHttpRequestMethods,
5
5
  } from 'n8n-workflow';
6
6
 
7
7
  export class CiviCrmApi implements ICredentialType {
8
- name = 'civiCrmApi';
9
- displayName = 'CiviCRM API';
10
- documentationUrl = 'https://docs.civicrm.org/dev/en/latest/api/v4/';
8
+ name = 'civiCrmApi';
9
+ displayName = 'CiviCRM API';
10
+ documentationUrl = 'https://docs.civicrm.org/dev/en/latest/api/';
11
11
 
12
- authenticate = {
13
- type: 'generic' as const,
14
- properties: {
15
- headers: {
16
- 'X-Civi-Auth': '={{"Bearer " + $credentials.apiToken}}',
17
- 'Content-Type': 'application/json',
18
- },
19
- },
20
- };
12
+ authenticate = {
13
+ type: 'generic' as const,
14
+ properties: {
15
+ headers: {
16
+ 'X-Civi-Auth': '={{"Bearer " + $credentials.apiToken}}',
17
+ 'Content-Type': 'application/x-www-form-urlencoded',
18
+ },
19
+ },
20
+ };
21
21
 
22
- // Button "Test" in credential UI
23
- test = {
24
- request: {
25
- // IMPORTANT: method must be typed as IHttpRequestMethods
26
- method: 'POST' as IHttpRequestMethods,
27
- url: '={{$credentials.baseUrl.replace(/\\/$/, "")}}/civicrm/ajax/api4/Contact/get',
28
- headers: {
29
- 'X-Civi-Auth': '={{"Bearer " + $credentials.apiToken}}',
30
- 'Content-Type': 'application/json',
31
- },
32
- body: {
33
- entity: 'Contact',
34
- action: 'get',
35
- params: { limit: 1 },
36
- },
37
- json: true,
38
- },
39
- };
22
+ // Credential test button
23
+ test = {
24
+ request: {
25
+ method: 'POST' as IHttpRequestMethods,
26
+ url: '={{$credentials.baseUrl.replace(/\\/$/, "")}}/civicrm/ajax/api4/Contact/get',
27
+ headers: {
28
+ 'X-Civi-Auth': '={{"Bearer " + $credentials.apiToken}}',
29
+ 'Content-Type': 'application/x-www-form-urlencoded',
30
+ },
31
+ body: {
32
+ params: '={"limit":1}', // API4 compatible
33
+ },
34
+ json: true,
35
+ },
36
+ };
40
37
 
41
- properties: INodeProperties[] = [
42
- {
43
- displayName: 'Base URL',
44
- name: 'baseUrl',
45
- type: 'string',
46
- default: '',
47
- required: true,
48
- placeholder: 'https://crm.example.org',
49
- description: 'Sin la barra final',
50
- },
51
- {
52
- displayName: 'API Token',
53
- name: 'apiToken',
54
- type: 'string',
55
- typeOptions: { password: true },
56
- default: '',
57
- required: true,
58
- description: 'Se envía como X-Civi-Auth: Bearer <token>',
59
- },
60
- ];
38
+ properties: INodeProperties[] = [
39
+ {
40
+ displayName: 'Base URL',
41
+ name: 'baseUrl',
42
+ type: 'string',
43
+ default: '',
44
+ required: true,
45
+ placeholder: 'https://crm.example.org',
46
+ description: 'Base URL without a trailing slash.',
47
+ },
48
+ {
49
+ displayName: 'API Token',
50
+ name: 'apiToken',
51
+ type: 'string',
52
+ typeOptions: { password: true },
53
+ default: '',
54
+ required: true,
55
+ description: 'Sent as "X-Civi-Auth: Bearer &lt;token&gt;"',
56
+ },
57
+ ];
61
58
  }
@@ -21,11 +21,7 @@ export declare class CiviCrmApi implements ICredentialType {
21
21
  'Content-Type': string;
22
22
  };
23
23
  body: {
24
- entity: string;
25
- action: string;
26
- params: {
27
- limit: number;
28
- };
24
+ params: string;
29
25
  };
30
26
  json: boolean;
31
27
  };
@@ -5,30 +5,27 @@ class CiviCrmApi {
5
5
  constructor() {
6
6
  this.name = 'civiCrmApi';
7
7
  this.displayName = 'CiviCRM API';
8
- this.documentationUrl = 'https://docs.civicrm.org/dev/en/latest/api/v4/';
8
+ this.documentationUrl = 'https://docs.civicrm.org/dev/en/latest/api/';
9
9
  this.authenticate = {
10
10
  type: 'generic',
11
11
  properties: {
12
12
  headers: {
13
13
  'X-Civi-Auth': '={{"Bearer " + $credentials.apiToken}}',
14
- 'Content-Type': 'application/json',
14
+ 'Content-Type': 'application/x-www-form-urlencoded',
15
15
  },
16
16
  },
17
17
  };
18
- // Button "Test" in credential UI
18
+ // Credential test button
19
19
  this.test = {
20
20
  request: {
21
- // IMPORTANT: method must be typed as IHttpRequestMethods
22
21
  method: 'POST',
23
22
  url: '={{$credentials.baseUrl.replace(/\\/$/, "")}}/civicrm/ajax/api4/Contact/get',
24
23
  headers: {
25
24
  'X-Civi-Auth': '={{"Bearer " + $credentials.apiToken}}',
26
- 'Content-Type': 'application/json',
25
+ 'Content-Type': 'application/x-www-form-urlencoded',
27
26
  },
28
27
  body: {
29
- entity: 'Contact',
30
- action: 'get',
31
- params: { limit: 1 },
28
+ params: '={"limit":1}', // API4 compatible
32
29
  },
33
30
  json: true,
34
31
  },
@@ -41,7 +38,7 @@ class CiviCrmApi {
41
38
  default: '',
42
39
  required: true,
43
40
  placeholder: 'https://crm.example.org',
44
- description: 'Sin la barra final',
41
+ description: 'Base URL without a trailing slash.',
45
42
  },
46
43
  {
47
44
  displayName: 'API Token',
@@ -50,7 +47,7 @@ class CiviCrmApi {
50
47
  typeOptions: { password: true },
51
48
  default: '',
52
49
  required: true,
53
- description: 'Se envía como X-Civi-Auth: Bearer <token>',
50
+ description: 'Sent as "X-Civi-Auth: Bearer &lt;token&gt;"',
54
51
  },
55
52
  ];
56
53
  }
@@ -1,12 +1,12 @@
1
- import type { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
- /**
3
- * Nodo principal CiviCRM para n8n
4
- */
1
+ import type { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
5
2
  export declare class CiviCrm implements INodeType {
6
3
  description: INodeTypeDescription;
7
4
  methods: {
8
5
  loadOptions: {
9
- getOptionValues(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
6
+ loadOptionValues(this: ILoadOptionsFunctions): Promise<{
7
+ name: string;
8
+ value: number;
9
+ }[]>;
10
10
  };
11
11
  };
12
12
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;