n8n-nodes-clientify 0.1.4 → 0.2.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
CHANGED
|
@@ -11,6 +11,7 @@ Official n8n node for integrating with Clientify CRM via Model Context Protocol
|
|
|
11
11
|
- [Prerequisites](#prerequisites)
|
|
12
12
|
- [Configuration](#configuration)
|
|
13
13
|
- [Available Operations](#available-operations)
|
|
14
|
+
- [Trigger Events](#trigger-events)
|
|
14
15
|
- [Usage Examples](#usage-examples)
|
|
15
16
|
- [Troubleshooting](#troubleshooting)
|
|
16
17
|
- [Support](#support)
|
|
@@ -121,6 +122,84 @@ This node dynamically supports **26 operations** from the Clientify MCP API:
|
|
|
121
122
|
- **Get Current User** - Get information about the authenticated user
|
|
122
123
|
- **Get Current Time** - Get current date/time with timezone awareness
|
|
123
124
|
|
|
125
|
+
## Trigger Events
|
|
126
|
+
|
|
127
|
+
**NEW in v0.2.0!** The Clientify Trigger node enables automatic workflow execution when events occur in Clientify CRM.
|
|
128
|
+
|
|
129
|
+
### Available Triggers
|
|
130
|
+
|
|
131
|
+
#### 👥 Contact Triggers
|
|
132
|
+
- **Contact Created** - Fires when a new contact is added to Clientify
|
|
133
|
+
- **Contact Updated** - Fires when contact details are modified
|
|
134
|
+
- **Contact Deleted** - Fires when a contact is removed
|
|
135
|
+
|
|
136
|
+
#### 📊 Company Triggers
|
|
137
|
+
- **Company Created** - Fires when a new company is added to Clientify
|
|
138
|
+
- **Company Updated** - Fires when company details are modified
|
|
139
|
+
- **Company Deleted** - Fires when a company is removed
|
|
140
|
+
|
|
141
|
+
#### 💼 Deal Triggers
|
|
142
|
+
- **Deal Created** - Fires when a new deal is created
|
|
143
|
+
- **Deal Updated** - Fires when deal details are modified
|
|
144
|
+
- **Deal Won** - Fires when a deal is marked as won
|
|
145
|
+
- **Deal Lost** - Fires when a deal is marked as lost
|
|
146
|
+
- **Deal Stage Changed** - Fires when a deal moves to a different pipeline stage
|
|
147
|
+
- **Deal Deleted** - Fires when a deal is removed
|
|
148
|
+
|
|
149
|
+
#### ✅ Task Triggers
|
|
150
|
+
- **Task Created** - Fires when a new task is created
|
|
151
|
+
- **Task Completed** - Fires when a task is marked as completed
|
|
152
|
+
- **Task Due Soon** - Fires when a task is approaching its due date
|
|
153
|
+
- **Task Overdue** - Fires when a task passes its due date
|
|
154
|
+
|
|
155
|
+
### Setting Up Webhooks
|
|
156
|
+
|
|
157
|
+
1. **Add Clientify Trigger node** to your workflow in n8n
|
|
158
|
+
2. **Select the event** you want to listen for (e.g., "Contact Created")
|
|
159
|
+
3. **Save and activate** the workflow to generate webhook URL
|
|
160
|
+
4. **Copy the webhook URL** from the trigger node
|
|
161
|
+
5. **Configure webhook in Clientify:**
|
|
162
|
+
- Go to Clientify Settings → Webhooks
|
|
163
|
+
- Add new webhook
|
|
164
|
+
- Paste the n8n webhook URL
|
|
165
|
+
- Select the corresponding event type
|
|
166
|
+
- Save the webhook configuration
|
|
167
|
+
|
|
168
|
+
### Webhook Data Structure
|
|
169
|
+
|
|
170
|
+
When a webhook triggers your workflow, the data is automatically flattened for easy access:
|
|
171
|
+
|
|
172
|
+
**Contact Created Example:**
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"event": "contact.created",
|
|
176
|
+
"timestamp": "2025-10-02T15:30:00Z",
|
|
177
|
+
"contact_id": 12345,
|
|
178
|
+
"first_name": "John",
|
|
179
|
+
"last_name": "Doe",
|
|
180
|
+
"email": "john.doe@example.com",
|
|
181
|
+
"phone": "+1234567890",
|
|
182
|
+
"company_id": 456,
|
|
183
|
+
"company_name": "Acme Corp"
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Deal Won Example:**
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"event": "deal.won",
|
|
191
|
+
"timestamp": "2025-10-02T17:00:00Z",
|
|
192
|
+
"deal_id": 98765,
|
|
193
|
+
"title": "Enterprise License Sale",
|
|
194
|
+
"value": 50000,
|
|
195
|
+
"currency": "USD",
|
|
196
|
+
"contact_id": 12345,
|
|
197
|
+
"contact_name": "John Doe",
|
|
198
|
+
"company_id": 789,
|
|
199
|
+
"company_name": "New Corp"
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
124
203
|
## Usage Examples
|
|
125
204
|
|
|
126
205
|
### Example 1: List All Contacts
|
|
@@ -226,6 +305,55 @@ Retrieve deals that are in the "Negotiation" stage.
|
|
|
226
305
|
|
|
227
306
|
---
|
|
228
307
|
|
|
308
|
+
### Example 6: Auto-Send Welcome Email (Using Trigger)
|
|
309
|
+
|
|
310
|
+
**NEW in v0.2.0!** Automatically send a welcome email when a new contact is created.
|
|
311
|
+
|
|
312
|
+
**Workflow:**
|
|
313
|
+
1. **Clientify Trigger**
|
|
314
|
+
- Event: `Contact Created`
|
|
315
|
+
|
|
316
|
+
2. **Send Email**
|
|
317
|
+
- To: `{{$json.email}}`
|
|
318
|
+
- Subject: `Welcome {{$json.first_name}}!`
|
|
319
|
+
- Body: Welcome message
|
|
320
|
+
|
|
321
|
+
3. **Create Task**
|
|
322
|
+
- Title: `Follow up with {{$json.first_name}} {{$json.last_name}}`
|
|
323
|
+
- Contact ID: `{{$json.contact_id}}`
|
|
324
|
+
- Due: 3 days from now
|
|
325
|
+
|
|
326
|
+
**Result:** When someone creates a contact "Jane Smith" in Clientify:
|
|
327
|
+
- Jane automatically receives welcome email
|
|
328
|
+
- Follow-up task is created for sales team
|
|
329
|
+
- All happens instantly without manual intervention
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
### Example 7: Deal Won Notification (Using Trigger)
|
|
334
|
+
|
|
335
|
+
**NEW in v0.2.0!** Notify your team when a deal is won.
|
|
336
|
+
|
|
337
|
+
**Workflow:**
|
|
338
|
+
1. **Clientify Trigger**
|
|
339
|
+
- Event: `Deal Won`
|
|
340
|
+
|
|
341
|
+
2. **Slack** (or Email)
|
|
342
|
+
- Message: `🎉 Deal Won! {{$json.title}} - ${{$json.value}} - {{$json.contact_name}}`
|
|
343
|
+
- Channel: `#sales-wins`
|
|
344
|
+
|
|
345
|
+
3. **Clientify** (Action Node)
|
|
346
|
+
- Operation: `Create Task`
|
|
347
|
+
- Title: `Onboard {{$json.contact_name}}`
|
|
348
|
+
- Deal ID: `{{$json.deal_id}}`
|
|
349
|
+
|
|
350
|
+
**Result:** When a deal is marked as won:
|
|
351
|
+
- Team gets instant Slack notification
|
|
352
|
+
- Onboarding task is automatically created
|
|
353
|
+
- No manual steps required
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
229
357
|
## Troubleshooting
|
|
230
358
|
|
|
231
359
|
### Node Doesn't Appear After Installation
|
|
@@ -359,6 +487,12 @@ This is an official Clientify node. Contributions are welcome!
|
|
|
359
487
|
|
|
360
488
|
## Version History
|
|
361
489
|
|
|
490
|
+
- **v0.2.0** (2025-10-02): Trigger support added
|
|
491
|
+
- **NEW:** Clientify Trigger node for webhook events
|
|
492
|
+
- 16 trigger events (contact, company, deal, task)
|
|
493
|
+
- Automatic workflow execution on Clientify events
|
|
494
|
+
- Flattened webhook payload for easy data access
|
|
495
|
+
|
|
362
496
|
- **v0.1.0** (2025-10-01): Initial release
|
|
363
497
|
- 26 MCP operations supported
|
|
364
498
|
- Dynamic field generation from MCP API
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { IWebhookFunctions, INodeType, INodeTypeDescription, IWebhookResponseData } from 'n8n-workflow';
|
|
2
|
+
export declare class ClientifyMcpTrigger implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClientifyMcpTrigger = void 0;
|
|
4
|
+
class ClientifyMcpTrigger {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.description = {
|
|
7
|
+
displayName: 'Clientify Trigger',
|
|
8
|
+
name: 'clientifyMcpTrigger',
|
|
9
|
+
icon: 'file:clientify.svg',
|
|
10
|
+
group: ['trigger'],
|
|
11
|
+
version: 1,
|
|
12
|
+
subtitle: '={{$parameter["event"]}}',
|
|
13
|
+
description: 'Starts workflow when Clientify CRM events occur',
|
|
14
|
+
defaults: {
|
|
15
|
+
name: 'Clientify Trigger',
|
|
16
|
+
},
|
|
17
|
+
inputs: [],
|
|
18
|
+
outputs: ["main" /* NodeConnectionType.Main */],
|
|
19
|
+
credentials: [
|
|
20
|
+
{
|
|
21
|
+
name: 'clientifyMcpApi',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
webhooks: [
|
|
26
|
+
{
|
|
27
|
+
name: 'default',
|
|
28
|
+
httpMethod: 'POST',
|
|
29
|
+
responseMode: 'onReceived',
|
|
30
|
+
path: 'webhook',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
properties: [
|
|
34
|
+
{
|
|
35
|
+
displayName: 'Event',
|
|
36
|
+
name: 'event',
|
|
37
|
+
type: 'options',
|
|
38
|
+
required: true,
|
|
39
|
+
default: 'contact.created',
|
|
40
|
+
description: 'The Clientify event that will trigger this workflow',
|
|
41
|
+
options: [
|
|
42
|
+
// Company Events
|
|
43
|
+
{
|
|
44
|
+
name: 'Company Created',
|
|
45
|
+
value: 'company.created',
|
|
46
|
+
description: 'Triggers when a new company is created in Clientify',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'Company Deleted',
|
|
50
|
+
value: 'company.deleted',
|
|
51
|
+
description: 'Triggers when a company is deleted from Clientify',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'Company Updated',
|
|
55
|
+
value: 'company.updated',
|
|
56
|
+
description: 'Triggers when a company is updated in Clientify',
|
|
57
|
+
},
|
|
58
|
+
// Contact Events
|
|
59
|
+
{
|
|
60
|
+
name: 'Contact Created',
|
|
61
|
+
value: 'contact.created',
|
|
62
|
+
description: 'Triggers when a new contact is created in Clientify',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'Contact Deleted',
|
|
66
|
+
value: 'contact.deleted',
|
|
67
|
+
description: 'Triggers when a contact is deleted from Clientify',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'Contact Updated',
|
|
71
|
+
value: 'contact.updated',
|
|
72
|
+
description: 'Triggers when a contact is updated in Clientify',
|
|
73
|
+
},
|
|
74
|
+
// Deal Events
|
|
75
|
+
{
|
|
76
|
+
name: 'Deal Created',
|
|
77
|
+
value: 'deal.created',
|
|
78
|
+
description: 'Triggers when a new deal is created in Clientify',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'Deal Deleted',
|
|
82
|
+
value: 'deal.deleted',
|
|
83
|
+
description: 'Triggers when a deal is deleted from Clientify',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'Deal Lost',
|
|
87
|
+
value: 'deal.lost',
|
|
88
|
+
description: 'Triggers when a deal is marked as lost',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'Deal Stage Changed',
|
|
92
|
+
value: 'deal.stage_changed',
|
|
93
|
+
description: 'Triggers when a deal moves to a different stage',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'Deal Updated',
|
|
97
|
+
value: 'deal.updated',
|
|
98
|
+
description: 'Triggers when a deal is updated in Clientify',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'Deal Won',
|
|
102
|
+
value: 'deal.won',
|
|
103
|
+
description: 'Triggers when a deal is marked as won',
|
|
104
|
+
},
|
|
105
|
+
// Task Events
|
|
106
|
+
{
|
|
107
|
+
name: 'Task Completed',
|
|
108
|
+
value: 'task.completed',
|
|
109
|
+
description: 'Triggers when a task is marked as completed',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'Task Created',
|
|
113
|
+
value: 'task.created',
|
|
114
|
+
description: 'Triggers when a new task is created in Clientify',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'Task Due Soon',
|
|
118
|
+
value: 'task.due_soon',
|
|
119
|
+
description: 'Triggers when a task is approaching its due date',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'Task Overdue',
|
|
123
|
+
value: 'task.overdue',
|
|
124
|
+
description: 'Triggers when a task is overdue',
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async webhook() {
|
|
132
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
133
|
+
const req = this.getRequestObject();
|
|
134
|
+
const event = this.getNodeParameter('event');
|
|
135
|
+
// Get webhook payload from request body
|
|
136
|
+
const payload = req.body;
|
|
137
|
+
// Validate that we received a payload
|
|
138
|
+
if (!payload || typeof payload !== 'object') {
|
|
139
|
+
return {
|
|
140
|
+
workflowData: [],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Validate that the event matches what user configured
|
|
144
|
+
// If events don't match, don't trigger the workflow
|
|
145
|
+
if (payload.event !== event) {
|
|
146
|
+
return {
|
|
147
|
+
workflowData: [],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Extract and flatten data based on event type for easier access in workflows
|
|
151
|
+
let workflowData = {
|
|
152
|
+
event: payload.event,
|
|
153
|
+
timestamp: payload.timestamp,
|
|
154
|
+
};
|
|
155
|
+
// Add account and user info if present
|
|
156
|
+
if (payload.account_id) {
|
|
157
|
+
workflowData.account_id = payload.account_id;
|
|
158
|
+
}
|
|
159
|
+
if (payload.user_id) {
|
|
160
|
+
workflowData.user_id = payload.user_id;
|
|
161
|
+
}
|
|
162
|
+
// Flatten the nested data structure based on event type
|
|
163
|
+
if (payload.event.startsWith('contact.')) {
|
|
164
|
+
// Contact events
|
|
165
|
+
if ((_a = payload.data) === null || _a === void 0 ? void 0 : _a.contact) {
|
|
166
|
+
workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { contact_id: payload.data.contact.id }), payload.data.contact);
|
|
167
|
+
}
|
|
168
|
+
// Include changes for update events
|
|
169
|
+
if ((_b = payload.data) === null || _b === void 0 ? void 0 : _b.changes) {
|
|
170
|
+
workflowData.changes = payload.data.changes;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else if (payload.event.startsWith('company.')) {
|
|
174
|
+
// Company events
|
|
175
|
+
if ((_c = payload.data) === null || _c === void 0 ? void 0 : _c.company) {
|
|
176
|
+
workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { company_id: payload.data.company.id }), payload.data.company);
|
|
177
|
+
}
|
|
178
|
+
// Include changes for update events
|
|
179
|
+
if ((_d = payload.data) === null || _d === void 0 ? void 0 : _d.changes) {
|
|
180
|
+
workflowData.changes = payload.data.changes;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else if (payload.event.startsWith('deal.')) {
|
|
184
|
+
// Deal events
|
|
185
|
+
if ((_e = payload.data) === null || _e === void 0 ? void 0 : _e.deal) {
|
|
186
|
+
workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { deal_id: payload.data.deal.id }), payload.data.deal);
|
|
187
|
+
}
|
|
188
|
+
// Include changes for update events
|
|
189
|
+
if ((_f = payload.data) === null || _f === void 0 ? void 0 : _f.changes) {
|
|
190
|
+
workflowData.changes = payload.data.changes;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else if (payload.event.startsWith('task.')) {
|
|
194
|
+
// Task events
|
|
195
|
+
if ((_g = payload.data) === null || _g === void 0 ? void 0 : _g.task) {
|
|
196
|
+
workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { task_id: payload.data.task.id }), payload.data.task);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Keep the original raw payload for advanced users who need it
|
|
200
|
+
workflowData._raw = payload;
|
|
201
|
+
// Return the data that will be passed to the workflow
|
|
202
|
+
return {
|
|
203
|
+
workflowData: [
|
|
204
|
+
[
|
|
205
|
+
{
|
|
206
|
+
json: workflowData,
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
exports.ClientifyMcpTrigger = ClientifyMcpTrigger;
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-clientify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "N8N node for Clientify CRM integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-node",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"dist/credentials/ClientifyMcpApi.credentials.js"
|
|
39
39
|
],
|
|
40
40
|
"nodes": [
|
|
41
|
-
"dist/nodes/ClientifyMcp/ClientifyMcpDynamic.node.js"
|
|
41
|
+
"dist/nodes/ClientifyMcp/ClientifyMcpDynamic.node.js",
|
|
42
|
+
"dist/nodes/ClientifyMcp/ClientifyMcpTrigger.node.js"
|
|
42
43
|
]
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-clientify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "N8N node for Clientify CRM integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-node",
|
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
"dist/credentials/ClientifyMcpApi.credentials.js"
|
|
39
39
|
],
|
|
40
40
|
"nodes": [
|
|
41
|
-
"dist/nodes/ClientifyMcp/ClientifyMcpDynamic.node.js"
|
|
41
|
+
"dist/nodes/ClientifyMcp/ClientifyMcpDynamic.node.js",
|
|
42
|
+
"dist/nodes/ClientifyMcp/ClientifyMcpTrigger.node.js"
|
|
42
43
|
]
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|