@ixiam/n8n-nodes-civicrm 0.4.4 → 1.0.0
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/README.md +105 -8
- package/credentials/CiviCrmApi.credentials.ts +50 -53
- package/dist/credentials/CiviCrmApi.credentials.d.ts +1 -5
- package/dist/credentials/CiviCrmApi.credentials.js +7 -10
- package/dist/nodes/CiviCrm/CiviCrm.node.d.ts +5 -5
- package/dist/nodes/CiviCrm/CiviCrm.node.js +302 -336
- package/dist/nodes/CiviCrm/descriptions/resources.js +11 -5
- package/jest.config.cjs +9 -0
- package/nodes/CiviCrm/CiviCrm.node.ts +385 -449
- package/nodes/CiviCrm/descriptions/resources.ts +11 -5
- package/package.json +21 -7
- package/test/helpers/mockServer.ts +27 -0
- package/test/nodes/CiviCrm.test.ts +67 -0
- package/test/tsconfig.json +10 -0
package/README.md
CHANGED
|
@@ -1,13 +1,110 @@
|
|
|
1
1
|
# n8n-nodes-civicrm
|
|
2
|
-
Community
|
|
2
|
+
Community Node for **CiviCRM API v4** (Civi-Go compatible)
|
|
3
|
+
Developed and maintained by **Ixiam Global Solutions**.
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
This node enables full integration between **n8n** and **CiviCRM API v4**, supporting create/update/delete operations, smart field mapping, dynamic location types, and advanced filtering on GET operations.
|
|
5
6
|
|
|
6
|
-
|
|
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
|
+
## 🚀 Installation
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
1. In your n8n instance, go to:
|
|
10
|
+
**Settings → Community Nodes → Install**
|
|
11
|
+
2. Enter the package name:
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```
|
|
14
|
+
n8n-nodes-civicrm
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
3. Approve installation and enable Community Nodes.
|
|
18
|
+
|
|
19
|
+
## 🔐 Credentials
|
|
20
|
+
|
|
21
|
+
The node uses **Bearer Token Authentication**.
|
|
22
|
+
|
|
23
|
+
| Field | Description |
|
|
24
|
+
|-------|-------------|
|
|
25
|
+
| **Base URL** | The root URL of your CiviCRM instance (without trailing slash). Example: `https://crm.example.org` |
|
|
26
|
+
| **API Token** | Sent as header `X-Civi-Auth: Bearer <token>` |
|
|
27
|
+
|
|
28
|
+
After entering credentials, click **Save** to validate the connection.
|
|
29
|
+
|
|
30
|
+
## 📦 Supported Entities
|
|
31
|
+
|
|
32
|
+
The node includes full API v4 support for the following entities:
|
|
33
|
+
|
|
34
|
+
| Entity | Operations |
|
|
35
|
+
|--------|------------|
|
|
36
|
+
| **Contact** | get, getMany, create, update, delete |
|
|
37
|
+
| **Membership** | get, getMany, create, update, delete |
|
|
38
|
+
| **Group** | get, getMany, create, update, delete |
|
|
39
|
+
| **Relationship** | get, getMany, create, update, delete |
|
|
40
|
+
| **Activity** | get, getMany, create, update, delete |
|
|
41
|
+
| **Custom API Call** | full custom API4 request |
|
|
42
|
+
|
|
43
|
+
## 🧩 Key Features
|
|
44
|
+
|
|
45
|
+
### **1. Dynamic Field Mapping**
|
|
46
|
+
Supports any standard or custom field:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
first_name = John
|
|
50
|
+
last_name = Doe
|
|
51
|
+
custom_45 = Blue
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### **2. Smart Email, Phone & Address Mapping**
|
|
55
|
+
Two ways to set location-aware fields:
|
|
56
|
+
|
|
57
|
+
**(A) Simple fields**
|
|
58
|
+
```
|
|
59
|
+
email = test@example.org
|
|
60
|
+
phone.mobile = 600123456
|
|
61
|
+
address.city = Barcelona
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**(B) Dynamic prefixes matched to CiviCRM Location Types**
|
|
65
|
+
```
|
|
66
|
+
work.email = user@company.org
|
|
67
|
+
billing.address.postal_code = 80331
|
|
68
|
+
home.phone.phone_type_id = 2
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### **3. Default Location Type selectors**
|
|
72
|
+
If no prefix is used, default types are applied.
|
|
73
|
+
|
|
74
|
+
### **4. Birth Date Normalization**
|
|
75
|
+
Accepted input formats:
|
|
76
|
+
|
|
77
|
+
- YYYY-MM-DD
|
|
78
|
+
- DD/MM/YYYY
|
|
79
|
+
- DD-MM-YYYY
|
|
80
|
+
- YYYY/MM/DD
|
|
81
|
+
- YYYY.MM.DD
|
|
82
|
+
|
|
83
|
+
Auto-normalized to `YYYY-MM-DD`.
|
|
84
|
+
|
|
85
|
+
### **5. GET MANY with JSON Filters**
|
|
86
|
+
```
|
|
87
|
+
[
|
|
88
|
+
["first_name", "LIKE", "Ju%"],
|
|
89
|
+
["birth_date", ">", "1990-01-01"],
|
|
90
|
+
["gender_id", "IN", [1, 2]]
|
|
91
|
+
]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### **6. Custom API Call Mode**
|
|
95
|
+
```
|
|
96
|
+
{
|
|
97
|
+
"entity": "Contact",
|
|
98
|
+
"action": "get",
|
|
99
|
+
"params": { "limit": 10 }
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## 🧑💻 About Ixiam Global Solutions
|
|
104
|
+
|
|
105
|
+
Website: **https://www.ixiam.com**
|
|
106
|
+
Contact: **info@ixiam.com**
|
|
107
|
+
|
|
108
|
+
## 📄 License
|
|
109
|
+
|
|
110
|
+
MIT License
|
|
@@ -1,61 +1,58 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
ICredentialType,
|
|
3
|
+
INodeProperties,
|
|
4
|
+
IHttpRequestMethods,
|
|
5
5
|
} from 'n8n-workflow';
|
|
6
6
|
|
|
7
7
|
export class CiviCrmApi implements ICredentialType {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
name = 'civiCrmApi';
|
|
9
|
+
displayName = 'CiviCRM API';
|
|
10
|
+
documentationUrl = 'https://docs.civicrm.org/dev/en/latest/api/';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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 <token>"',
|
|
56
|
+
},
|
|
57
|
+
];
|
|
61
58
|
}
|
|
@@ -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/
|
|
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/
|
|
14
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
};
|
|
18
|
-
//
|
|
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/
|
|
25
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
27
26
|
},
|
|
28
27
|
body: {
|
|
29
|
-
|
|
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: '
|
|
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: '
|
|
50
|
+
description: 'Sent as "X-Civi-Auth: Bearer <token>"',
|
|
54
51
|
},
|
|
55
52
|
];
|
|
56
53
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData,
|
|
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
|
-
|
|
6
|
+
loadOptionValues(this: ILoadOptionsFunctions): Promise<{
|
|
7
|
+
name: string;
|
|
8
|
+
value: number;
|
|
9
|
+
}[]>;
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
12
|
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|