@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 +6 -4
- package/README.md +145 -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 +23 -8
- package/test/helpers/mockServer.ts +27 -0
- package/test/nodes/CiviCrm.test.ts +67 -0
- package/test/tsconfig.json +10 -0
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'
|
|
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
|
-
|
|
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
|
-
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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[][]>;
|