n8n-nodes-clientify 0.2.17 → 0.2.18

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.
@@ -1,922 +1,112 @@
1
- # Clientify Triggers - Complete Reference
1
+ # Clientify Triggers Reference
2
2
 
3
3
  **Package:** n8n-nodes-clientify
4
- **Total Triggers:** 16
4
+ **Total Triggers:** 5
5
5
 
6
- ---
6
+ The Clientify Trigger node listens for the event names sent by Clientify webhooks. Clientify sends broad `*.saved` events for create/update-style changes, so workflows that need more specific behavior should branch on payload fields with an n8n IF node after the trigger.
7
7
 
8
- ## How Triggers Work
8
+ ## Available Events
9
9
 
10
- 1. **Create workflow** in n8n with Clientify Trigger node
11
- 2. **Select event** (e.g., "Contact Created")
12
- 3. **Activate workflow** Get webhook URL
13
- 4. **Configure in Clientify** Point event to webhook URL
14
- 5. **Event happens** Workflow runs automatically
10
+ | n8n Label | Payload Event | Notes |
11
+ |---|---|---|
12
+ | Contact Saved | `contact.saved` | Contact created or updated |
13
+ | Company Saved | `company.saved` | Company created or updated |
14
+ | Company Deleted | `company.deleted` | Company deleted |
15
+ | Deal Saved | `deal.saved` | Deal created, updated, won, lost, or moved |
16
+ | Task Saved | `task.saved` | Task created or updated |
15
17
 
16
- **Webhook URL Format:**
17
- ```
18
- https://your-n8n-instance.com/webhook/{unique-workflow-id}/webhook
19
- ```
20
-
21
- Each workflow gets a unique URL when activated.
22
-
23
- ---
24
-
25
- ## 👥 Contact Triggers
18
+ ## Payload Matching
26
19
 
27
- ### 1. Contact Created
20
+ The trigger matches the selected event against either payload shape:
28
21
 
29
- **Event:** `contact.created`
30
- **When:** New contact added to Clientify
31
-
32
- **Input Payload:**
33
22
  ```json
34
23
  {
35
- "event": "contact.created",
36
- "timestamp": "2025-10-02T15:30:00Z",
37
- "account_id": "acc_12345",
38
- "user_id": "user_67890",
39
- "data": {
40
- "contact": {
41
- "id": 12345,
42
- "first_name": "John",
43
- "last_name": "Doe",
44
- "email": "john.doe@example.com",
45
- "phone": "+1234567890",
46
- "company_id": 456,
47
- "company_name": "Acme Corp",
48
- "created_at": "2025-10-02T15:30:00Z"
49
- }
24
+ "event": "contact.saved",
25
+ "contact": {
26
+ "id": 12345,
27
+ "first_name": "Ada",
28
+ "last_name": "Lovelace",
29
+ "email": "ada@example.com"
50
30
  }
51
31
  }
52
32
  ```
53
33
 
54
- **Output (Available in Workflow):**
55
34
  ```json
56
35
  {
57
- "event": "contact.created",
58
- "timestamp": "2025-10-02T15:30:00Z",
59
- "account_id": "acc_12345",
60
- "user_id": "user_67890",
61
- "contact_id": 12345,
62
- "first_name": "John",
63
- "last_name": "Doe",
64
- "email": "john.doe@example.com",
65
- "phone": "+1234567890",
66
- "company_id": 456,
67
- "company_name": "Acme Corp",
68
- "created_at": "2025-10-02T15:30:00Z",
69
- "_raw": { /* original payload */ }
70
- }
71
- ```
72
-
73
- **Access Data:** `{{$json.first_name}}`, `{{$json.email}}`, etc.
74
-
75
- ---
76
-
77
- ### 2. Contact Updated
78
-
79
- **Event:** `contact.updated`
80
- **When:** Contact details modified
81
-
82
- **Input Payload:**
83
- ```json
84
- {
85
- "event": "contact.updated",
86
- "timestamp": "2025-10-02T16:00:00Z",
87
- "account_id": "acc_12345",
88
- "user_id": "user_67890",
89
- "data": {
90
- "contact": {
91
- "id": 12345,
92
- "first_name": "John",
93
- "last_name": "Doe",
94
- "email": "john.new@example.com",
95
- "phone": "+1234567890",
96
- "company_id": 789,
97
- "company_name": "New Corp",
98
- "updated_at": "2025-10-02T16:00:00Z"
99
- },
100
- "changes": {
101
- "email": {
102
- "old": "john.doe@example.com",
103
- "new": "john.new@example.com"
104
- },
105
- "company_id": {
106
- "old": 456,
107
- "new": 789
108
- }
109
- }
110
- }
111
- }
112
- ```
113
-
114
- **Output:**
115
- ```json
116
- {
117
- "event": "contact.updated",
118
- "timestamp": "2025-10-02T16:00:00Z",
119
- "contact_id": 12345,
120
- "first_name": "John",
121
- "last_name": "Doe",
122
- "email": "john.new@example.com",
123
- "phone": "+1234567890",
124
- "company_id": 789,
125
- "company_name": "New Corp",
126
- "updated_at": "2025-10-02T16:00:00Z",
127
- "changes": {
128
- "email": { "old": "john.doe@example.com", "new": "john.new@example.com" },
129
- "company_id": { "old": 456, "new": 789 }
36
+ "hook": {
37
+ "id": 9823,
38
+ "event": "contact.saved"
130
39
  },
131
- "_raw": { /* original payload */ }
40
+ "contact": {
41
+ "id": 12345,
42
+ "first_name": "Ada",
43
+ "last_name": "Lovelace",
44
+ "email": "ada@example.com"
45
+ }
132
46
  }
133
47
  ```
134
48
 
135
- **Access Changes:** `{{$json.changes.email.old}}`, `{{$json.changes.email.new}}`
136
-
137
- ---
49
+ The trigger also supports the nested data shape:
138
50
 
139
- ### 3. Contact Deleted
140
-
141
- **Event:** `contact.deleted`
142
- **When:** Contact removed from Clientify
143
-
144
- **Input Payload:**
145
51
  ```json
146
52
  {
147
- "event": "contact.deleted",
148
- "timestamp": "2025-10-02T17:00:00Z",
149
- "account_id": "acc_12345",
150
- "user_id": "user_67890",
53
+ "event": "contact.saved",
151
54
  "data": {
152
55
  "contact": {
153
56
  "id": 12345,
154
- "first_name": "John",
155
- "last_name": "Doe",
156
- "email": "john.doe@example.com"
57
+ "first_name": "Ada",
58
+ "last_name": "Lovelace",
59
+ "email": "ada@example.com"
157
60
  }
158
61
  }
159
62
  }
160
63
  ```
161
64
 
162
- **Output:**
163
- ```json
164
- {
165
- "event": "contact.deleted",
166
- "timestamp": "2025-10-02T17:00:00Z",
167
- "contact_id": 12345,
168
- "first_name": "John",
169
- "last_name": "Doe",
170
- "email": "john.doe@example.com",
171
- "_raw": { /* original payload */ }
172
- }
173
- ```
174
-
175
- ---
176
-
177
- ## 📊 Company Triggers
178
-
179
- ### 4. Company Created
180
-
181
- **Event:** `company.created`
182
- **When:** New company added to Clientify
183
-
184
- **Input Payload:**
185
- ```json
186
- {
187
- "event": "company.created",
188
- "timestamp": "2025-10-02T18:00:00Z",
189
- "account_id": "acc_12345",
190
- "user_id": "user_67890",
191
- "data": {
192
- "company": {
193
- "id": 999,
194
- "name": "Tech Startup Inc",
195
- "domain": "techstartup.com",
196
- "industry": "Technology",
197
- "size": "50-100",
198
- "country": "USA",
199
- "created_at": "2025-10-02T18:00:00Z"
200
- }
201
- }
202
- }
203
- ```
204
-
205
- **Output:**
206
- ```json
207
- {
208
- "event": "company.created",
209
- "timestamp": "2025-10-02T18:00:00Z",
210
- "company_id": 999,
211
- "name": "Tech Startup Inc",
212
- "domain": "techstartup.com",
213
- "industry": "Technology",
214
- "size": "50-100",
215
- "country": "USA",
216
- "created_at": "2025-10-02T18:00:00Z",
217
- "_raw": { /* original payload */ }
218
- }
219
- ```
220
-
221
- **Access Data:** `{{$json.name}}`, `{{$json.domain}}`, `{{$json.industry}}`
222
-
223
- ---
224
-
225
- ### 5. Company Updated
65
+ ## Output Shape
226
66
 
227
- **Event:** `company.updated`
228
- **When:** Company details modified
229
-
230
- **Input Payload:**
231
- ```json
232
- {
233
- "event": "company.updated",
234
- "timestamp": "2025-10-02T19:00:00Z",
235
- "account_id": "acc_12345",
236
- "user_id": "user_67890",
237
- "data": {
238
- "company": {
239
- "id": 999,
240
- "name": "Tech Startup Inc",
241
- "domain": "newdomain.com",
242
- "industry": "SaaS",
243
- "updated_at": "2025-10-02T19:00:00Z"
244
- },
245
- "changes": {
246
- "domain": { "old": "techstartup.com", "new": "newdomain.com" },
247
- "industry": { "old": "Technology", "new": "SaaS" }
248
- }
249
- }
250
- }
251
- ```
67
+ The trigger flattens the matching entity onto the output item and keeps the original payload in `_raw`.
252
68
 
253
- **Output:**
254
69
  ```json
255
70
  {
256
- "event": "company.updated",
257
- "timestamp": "2025-10-02T19:00:00Z",
258
- "company_id": 999,
259
- "name": "Tech Startup Inc",
260
- "domain": "newdomain.com",
261
- "industry": "SaaS",
262
- "updated_at": "2025-10-02T19:00:00Z",
263
- "changes": {
264
- "domain": { "old": "techstartup.com", "new": "newdomain.com" },
265
- "industry": { "old": "Technology", "new": "SaaS" }
266
- },
267
- "_raw": { /* original payload */ }
268
- }
269
- ```
270
-
271
- ---
272
-
273
- ### 6. Company Deleted
274
-
275
- **Event:** `company.deleted`
276
- **When:** Company removed from Clientify
277
-
278
- **Input Payload:**
279
- ```json
280
- {
281
- "event": "company.deleted",
282
- "timestamp": "2025-10-02T20:00:00Z",
283
- "account_id": "acc_12345",
284
- "user_id": "user_67890",
285
- "data": {
286
- "company": {
287
- "id": 999,
288
- "name": "Tech Startup Inc"
289
- }
290
- }
291
- }
292
- ```
293
-
294
- **Output:**
295
- ```json
296
- {
297
- "event": "company.deleted",
298
- "timestamp": "2025-10-02T20:00:00Z",
299
- "company_id": 999,
300
- "name": "Tech Startup Inc",
301
- "_raw": { /* original payload */ }
302
- }
303
- ```
304
-
305
- ---
306
-
307
- ## 💼 Deal Triggers
308
-
309
- ### 7. Deal Created
310
-
311
- **Event:** `deal.created`
312
- **When:** New deal/opportunity created
313
-
314
- **Input Payload:**
315
- ```json
316
- {
317
- "event": "deal.created",
318
- "timestamp": "2025-10-02T21:00:00Z",
319
- "account_id": "acc_12345",
320
- "user_id": "user_67890",
321
- "data": {
322
- "deal": {
323
- "id": 98765,
324
- "title": "Enterprise License Sale",
325
- "value": 50000,
326
- "currency": "USD",
327
- "contact_id": 12345,
328
- "contact_name": "John Doe",
329
- "company_id": 999,
330
- "company_name": "Tech Startup Inc",
331
- "pipeline_id": 1,
332
- "pipeline_name": "Sales Pipeline",
333
- "stage_id": 3,
334
- "stage_name": "Proposal",
335
- "created_at": "2025-10-02T21:00:00Z"
336
- }
337
- }
338
- }
339
- ```
340
-
341
- **Output:**
342
- ```json
343
- {
344
- "event": "deal.created",
345
- "timestamp": "2025-10-02T21:00:00Z",
346
- "deal_id": 98765,
347
- "title": "Enterprise License Sale",
348
- "value": 50000,
349
- "currency": "USD",
350
- "contact_id": 12345,
351
- "contact_name": "John Doe",
352
- "company_id": 999,
353
- "company_name": "Tech Startup Inc",
354
- "pipeline_id": 1,
355
- "pipeline_name": "Sales Pipeline",
356
- "stage_id": 3,
357
- "stage_name": "Proposal",
358
- "created_at": "2025-10-02T21:00:00Z",
359
- "_raw": { /* original payload */ }
360
- }
361
- ```
362
-
363
- **Access Data:** `{{$json.title}}`, `{{$json.value}}`, `{{$json.stage_name}}`
364
-
365
- ---
366
-
367
- ### 8. Deal Updated
368
-
369
- **Event:** `deal.updated`
370
- **When:** Deal details modified
371
-
372
- **Input Payload:**
373
- ```json
374
- {
375
- "event": "deal.updated",
376
- "timestamp": "2025-10-02T22:00:00Z",
377
- "account_id": "acc_12345",
378
- "user_id": "user_67890",
379
- "data": {
380
- "deal": {
381
- "id": 98765,
382
- "title": "Enterprise License Sale",
383
- "value": 60000,
384
- "currency": "USD",
385
- "stage_name": "Negotiation",
386
- "updated_at": "2025-10-02T22:00:00Z"
387
- },
388
- "changes": {
389
- "value": { "old": 50000, "new": 60000 },
390
- "stage_name": { "old": "Proposal", "new": "Negotiation" }
391
- }
392
- }
393
- }
394
- ```
395
-
396
- **Output:**
397
- ```json
398
- {
399
- "event": "deal.updated",
400
- "timestamp": "2025-10-02T22:00:00Z",
401
- "deal_id": 98765,
402
- "title": "Enterprise License Sale",
403
- "value": 60000,
404
- "currency": "USD",
405
- "stage_name": "Negotiation",
406
- "updated_at": "2025-10-02T22:00:00Z",
407
- "changes": {
408
- "value": { "old": 50000, "new": 60000 },
409
- "stage_name": { "old": "Proposal", "new": "Negotiation" }
410
- },
411
- "_raw": { /* original payload */ }
412
- }
413
- ```
414
-
415
- ---
416
-
417
- ### 9. Deal Won
418
-
419
- **Event:** `deal.won`
420
- **When:** Deal marked as won/closed successfully
421
-
422
- **Input Payload:**
423
- ```json
424
- {
425
- "event": "deal.won",
426
- "timestamp": "2025-10-02T23:00:00Z",
427
- "account_id": "acc_12345",
428
- "user_id": "user_67890",
429
- "data": {
430
- "deal": {
431
- "id": 98765,
432
- "title": "Enterprise License Sale",
433
- "value": 60000,
434
- "currency": "USD",
435
- "contact_id": 12345,
436
- "contact_name": "John Doe",
437
- "company_id": 999,
438
- "company_name": "Tech Startup Inc",
439
- "stage_name": "Won",
440
- "won_at": "2025-10-02T23:00:00Z"
441
- }
442
- }
443
- }
444
- ```
445
-
446
- **Output:**
447
- ```json
448
- {
449
- "event": "deal.won",
450
- "timestamp": "2025-10-02T23:00:00Z",
451
- "deal_id": 98765,
452
- "title": "Enterprise License Sale",
453
- "value": 60000,
454
- "currency": "USD",
71
+ "event": "contact.saved",
455
72
  "contact_id": 12345,
456
- "contact_name": "John Doe",
457
- "company_id": 999,
458
- "company_name": "Tech Startup Inc",
459
- "stage_name": "Won",
460
- "won_at": "2025-10-02T23:00:00Z",
461
- "_raw": { /* original payload */ }
462
- }
463
- ```
464
-
465
- **Use Case:** Send celebration email, create onboarding task, post to Slack
466
-
467
- ---
468
-
469
- ### 10. Deal Lost
470
-
471
- **Event:** `deal.lost`
472
- **When:** Deal marked as lost/closed unsuccessfully
473
-
474
- **Input Payload:**
475
- ```json
476
- {
477
- "event": "deal.lost",
478
- "timestamp": "2025-10-03T00:00:00Z",
479
- "account_id": "acc_12345",
480
- "user_id": "user_67890",
481
- "data": {
482
- "deal": {
483
- "id": 98766,
484
- "title": "SMB Deal",
485
- "value": 5000,
486
- "currency": "USD",
487
- "contact_id": 12346,
488
- "contact_name": "Jane Smith",
489
- "stage_name": "Lost",
490
- "lost_at": "2025-10-03T00:00:00Z",
491
- "lost_reason": "Budget constraints"
492
- }
493
- }
494
- }
495
- ```
496
-
497
- **Output:**
498
- ```json
499
- {
500
- "event": "deal.lost",
501
- "timestamp": "2025-10-03T00:00:00Z",
502
- "deal_id": 98766,
503
- "title": "SMB Deal",
504
- "value": 5000,
505
- "currency": "USD",
506
- "contact_id": 12346,
507
- "contact_name": "Jane Smith",
508
- "stage_name": "Lost",
509
- "lost_at": "2025-10-03T00:00:00Z",
510
- "lost_reason": "Budget constraints",
511
- "_raw": { /* original payload */ }
512
- }
513
- ```
514
-
515
- **Use Case:** Add to nurture campaign, schedule follow-up in 6 months
516
-
517
- ---
518
-
519
- ### 11. Deal Stage Changed
520
-
521
- **Event:** `deal.stage_changed`
522
- **When:** Deal moves to different pipeline stage
523
-
524
- **Input Payload:**
525
- ```json
526
- {
527
- "event": "deal.stage_changed",
528
- "timestamp": "2025-10-03T01:00:00Z",
529
- "account_id": "acc_12345",
530
- "user_id": "user_67890",
531
- "data": {
532
- "deal": {
533
- "id": 98765,
534
- "title": "Enterprise License Sale",
535
- "value": 60000,
536
- "stage_id": 4,
537
- "stage_name": "Contract",
538
- "previous_stage_id": 3,
539
- "previous_stage_name": "Negotiation"
540
- },
541
- "changes": {
542
- "stage_name": { "old": "Negotiation", "new": "Contract" }
543
- }
544
- }
545
- }
546
- ```
547
-
548
- **Output:**
549
- ```json
550
- {
551
- "event": "deal.stage_changed",
552
- "timestamp": "2025-10-03T01:00:00Z",
553
- "deal_id": 98765,
554
- "title": "Enterprise License Sale",
555
- "value": 60000,
556
- "stage_id": 4,
557
- "stage_name": "Contract",
558
- "previous_stage_id": 3,
559
- "previous_stage_name": "Negotiation",
560
- "changes": {
561
- "stage_name": { "old": "Negotiation", "new": "Contract" }
562
- },
563
- "_raw": { /* original payload */ }
564
- }
565
- ```
566
-
567
- **Use Case:** Different actions per stage (Proposal → send pricing, Contract → generate document)
568
-
569
- ---
570
-
571
- ### 12. Deal Deleted
572
-
573
- **Event:** `deal.deleted`
574
- **When:** Deal removed from Clientify
575
-
576
- **Input Payload:**
577
- ```json
578
- {
579
- "event": "deal.deleted",
580
- "timestamp": "2025-10-03T02:00:00Z",
581
- "account_id": "acc_12345",
582
- "user_id": "user_67890",
583
- "data": {
584
- "deal": {
585
- "id": 98767,
586
- "title": "Canceled Deal"
587
- }
588
- }
589
- }
590
- ```
591
-
592
- **Output:**
593
- ```json
594
- {
595
- "event": "deal.deleted",
596
- "timestamp": "2025-10-03T02:00:00Z",
597
- "deal_id": 98767,
598
- "title": "Canceled Deal",
599
- "_raw": { /* original payload */ }
600
- }
601
- ```
602
-
603
- ---
604
-
605
- ## ✅ Task Triggers
606
-
607
- ### 13. Task Created
608
-
609
- **Event:** `task.created`
610
- **When:** New task/activity created
611
-
612
- **Input Payload:**
613
- ```json
614
- {
615
- "event": "task.created",
616
- "timestamp": "2025-10-03T03:00:00Z",
617
- "account_id": "acc_12345",
618
- "user_id": "user_67890",
619
- "data": {
620
- "task": {
621
- "id": 5555,
622
- "title": "Follow up with John Doe",
623
- "description": "Discuss pricing options",
624
- "type": "call",
625
- "contact_id": 12345,
626
- "contact_name": "John Doe",
627
- "deal_id": 98765,
628
- "deal_title": "Enterprise License Sale",
629
- "assigned_to": "user_67890",
630
- "assigned_to_name": "Sales Rep",
631
- "due_date": "2025-10-05",
632
- "created_at": "2025-10-03T03:00:00Z"
633
- }
634
- }
635
- }
636
- ```
637
-
638
- **Output:**
639
- ```json
640
- {
641
- "event": "task.created",
642
- "timestamp": "2025-10-03T03:00:00Z",
643
- "task_id": 5555,
644
- "title": "Follow up with John Doe",
645
- "description": "Discuss pricing options",
646
- "type": "call",
647
- "contact_id": 12345,
648
- "contact_name": "John Doe",
649
- "deal_id": 98765,
650
- "deal_title": "Enterprise License Sale",
651
- "assigned_to": "user_67890",
652
- "assigned_to_name": "Sales Rep",
653
- "due_date": "2025-10-05",
654
- "created_at": "2025-10-03T03:00:00Z",
655
- "_raw": { /* original payload */ }
656
- }
657
- ```
658
-
659
- **Use Case:** Add task to Google Calendar, send notification to assigned user
660
-
661
- ---
662
-
663
- ### 14. Task Completed
664
-
665
- **Event:** `task.completed`
666
- **When:** Task marked as completed
667
-
668
- **Input Payload:**
669
- ```json
670
- {
671
- "event": "task.completed",
672
- "timestamp": "2025-10-03T04:00:00Z",
673
- "account_id": "acc_12345",
674
- "user_id": "user_67890",
675
- "data": {
676
- "task": {
677
- "id": 5555,
678
- "title": "Follow up with John Doe",
679
- "type": "call",
680
- "contact_id": 12345,
681
- "contact_name": "John Doe",
682
- "deal_id": 98765,
683
- "assigned_to": "user_67890",
684
- "assigned_to_name": "Sales Rep",
685
- "completed_at": "2025-10-03T04:00:00Z"
686
- }
687
- }
688
- }
689
- ```
690
-
691
- **Output:**
692
- ```json
693
- {
694
- "event": "task.completed",
695
- "timestamp": "2025-10-03T04:00:00Z",
696
- "task_id": 5555,
697
- "title": "Follow up with John Doe",
698
- "type": "call",
699
- "contact_id": 12345,
700
- "contact_name": "John Doe",
701
- "deal_id": 98765,
702
- "assigned_to": "user_67890",
703
- "assigned_to_name": "Sales Rep",
704
- "completed_at": "2025-10-03T04:00:00Z",
705
- "_raw": { /* original payload */ }
706
- }
707
- ```
708
-
709
- **Use Case:** Log activity in reporting system, update deal progress
710
-
711
- ---
712
-
713
- ### 15. Task Due Soon
714
-
715
- **Event:** `task.due_soon`
716
- **When:** Task approaching due date (configured in Clientify)
717
-
718
- **Input Payload:**
719
- ```json
720
- {
721
- "event": "task.due_soon",
722
- "timestamp": "2025-10-03T05:00:00Z",
723
- "account_id": "acc_12345",
724
- "user_id": "user_67890",
725
- "data": {
726
- "task": {
727
- "id": 5556,
728
- "title": "Send proposal to Jane Smith",
729
- "type": "email",
730
- "contact_id": 12346,
731
- "contact_name": "Jane Smith",
732
- "assigned_to": "user_67890",
733
- "assigned_to_name": "Sales Rep",
734
- "due_date": "2025-10-04",
735
- "hours_until_due": 23
736
- }
737
- }
738
- }
739
- ```
740
-
741
- **Output:**
742
- ```json
743
- {
744
- "event": "task.due_soon",
745
- "timestamp": "2025-10-03T05:00:00Z",
746
- "task_id": 5556,
747
- "title": "Send proposal to Jane Smith",
748
- "type": "email",
749
- "contact_id": 12346,
750
- "contact_name": "Jane Smith",
751
- "assigned_to": "user_67890",
752
- "assigned_to_name": "Sales Rep",
753
- "due_date": "2025-10-04",
754
- "hours_until_due": 23,
755
- "_raw": { /* original payload */ }
756
- }
757
- ```
758
-
759
- **Use Case:** Send reminder to assigned user
760
-
761
- ---
762
-
763
- ### 16. Task Overdue
764
-
765
- **Event:** `task.overdue`
766
- **When:** Task passed due date without completion
767
-
768
- **Input Payload:**
769
- ```json
770
- {
771
- "event": "task.overdue",
772
- "timestamp": "2025-10-03T06:00:00Z",
773
- "account_id": "acc_12345",
774
- "user_id": "user_67890",
775
- "data": {
776
- "task": {
777
- "id": 5557,
778
- "title": "Call prospect",
779
- "type": "call",
780
- "contact_id": 12347,
781
- "contact_name": "Bob Johnson",
782
- "assigned_to": "user_67891",
783
- "assigned_to_name": "Sales Rep 2",
784
- "due_date": "2025-10-02",
785
- "days_overdue": 1
73
+ "id": 12345,
74
+ "first_name": "Ada",
75
+ "last_name": "Lovelace",
76
+ "email": "ada@example.com",
77
+ "_raw": {
78
+ "event": "contact.saved",
79
+ "contact": {
80
+ "id": 12345,
81
+ "first_name": "Ada",
82
+ "last_name": "Lovelace",
83
+ "email": "ada@example.com"
786
84
  }
787
85
  }
788
86
  }
789
87
  ```
790
88
 
791
- **Output:**
792
- ```json
793
- {
794
- "event": "task.overdue",
795
- "timestamp": "2025-10-03T06:00:00Z",
796
- "task_id": 5557,
797
- "title": "Call prospect",
798
- "type": "call",
799
- "contact_id": 12347,
800
- "contact_name": "Bob Johnson",
801
- "assigned_to": "user_67891",
802
- "assigned_to_name": "Sales Rep 2",
803
- "due_date": "2025-10-02",
804
- "days_overdue": 1,
805
- "_raw": { /* original payload */ }
806
- }
807
- ```
808
-
809
- **Use Case:** Send urgent notification to manager, escalate task
810
-
811
- ---
812
-
813
- ## Quick Reference Table
814
-
815
- | # | Event | Type | Use Case |
816
- |---|-------|------|----------|
817
- | 1 | `contact.created` | Contact | Welcome email, create follow-up task |
818
- | 2 | `contact.updated` | Contact | Sync to external CRM, log changes |
819
- | 3 | `contact.deleted` | Contact | Archive data, remove from mailing lists |
820
- | 4 | `company.created` | Company | Research company, assign account manager |
821
- | 5 | `company.updated` | Company | Update external systems |
822
- | 6 | `company.deleted` | Company | Clean up related data |
823
- | 7 | `deal.created` | Deal | Notify sales team, create tasks |
824
- | 8 | `deal.updated` | Deal | Track changes, update forecasts |
825
- | 9 | `deal.won` | Deal | Send celebration, create invoice, onboard customer |
826
- | 10 | `deal.lost` | Deal | Add to nurture campaign, analyze loss reason |
827
- | 11 | `deal.stage_changed` | Deal | Stage-specific actions (pricing, contracts) |
828
- | 12 | `deal.deleted` | Deal | Log deletion, archive data |
829
- | 13 | `task.created` | Task | Add to calendar, notify assignee |
830
- | 14 | `task.completed` | Task | Log activity, update metrics |
831
- | 15 | `task.due_soon` | Task | Send reminder |
832
- | 16 | `task.overdue` | Task | Escalate to manager |
833
-
834
- ---
835
-
836
- ## Common Workflow Patterns
837
-
838
- ### Pattern 1: Instant Notification
839
- ```
840
- [Clientify Trigger: Deal Won] → [Slack: Post to #sales-wins]
841
- ```
842
-
843
- ### Pattern 2: Multi-Step Automation
844
- ```
845
- [Clientify Trigger: Contact Created] → [Send Email] → [Create Task] → [Add to Mailchimp]
846
- ```
847
-
848
- ### Pattern 3: Conditional Logic
849
- ```
850
- [Clientify Trigger: Deal Stage Changed] → [IF: stage = "Contract"] → [Generate PDF Contract]
851
- ```
852
-
853
- ### Pattern 4: Data Sync
854
- ```
855
- [Clientify Trigger: Contact Updated] → [IF: email changed] → [HTTP: Update HubSpot]
856
- ```
857
-
858
- ---
859
-
860
- ## Setup Instructions
861
-
862
- ### 1. In n8n
863
-
864
- 1. Add "Clientify Trigger" node
865
- 2. Select event from dropdown
866
- 3. Choose Clientify MCP credentials
867
- 4. Save workflow
868
- 5. **Activate workflow** (toggle ON)
869
- 6. Click trigger node → Expand "Webhook URLs"
870
- 7. Switch to "Production URL" tab
871
- 8. **Copy the URL** (unique per workflow)
89
+ Entity-specific ID aliases:
872
90
 
873
- ### 2. In Clientify
91
+ | Event Family | Alias |
92
+ |---|---|
93
+ | `contact.*` | `contact_id` |
94
+ | `company.*` | `company_id` |
95
+ | `deal.*` | `deal_id` |
96
+ | `task.*` | `task_id` |
874
97
 
875
- 1. Go to Settings → Webhooks
876
- 2. Click "Add Webhook"
877
- 3. **Event:** Select matching event (e.g., "contact.created")
878
- 4. **URL:** Paste n8n webhook URL
879
- 5. **Status:** Active
880
- 6. Save
98
+ ## Example Workflow Patterns
881
99
 
882
- ### 3. Test
883
-
884
- Create a contact/deal/task in Clientify Check n8n executions Verify workflow ran!
885
-
886
- ---
887
-
888
- ## Important Notes
889
-
890
- ### Event Name Matching
891
- - n8n event: "Contact Created" = `contact.created`
892
- - Clientify must send: `"event": "contact.created"`
893
- - **Case-sensitive!**
894
-
895
- ### Data Access in Workflows
896
- ```javascript
897
- {{$json.first_name}} // "John"
898
- {{$json.email}} // "john@example.com"
899
- {{$json.value}} // 50000 (for deals)
900
- {{$json.changes.email.old}} // Previous email (for updates)
901
- {{$json._raw}} // Full original payload
100
+ ```text
101
+ Clientify Trigger: Contact Saved -> IF: email exists -> Add tag / send email
102
+ Clientify Trigger: Company Saved -> IF: company sector changed -> Update downstream system
103
+ Clientify Trigger: Deal Saved -> IF: status is won -> Notify sales channel
104
+ Clientify Trigger: Task Saved -> IF: due date is today -> Create reminder
902
105
  ```
903
106
 
904
- ### Webhook URL Requirements
905
- - Unique per workflow
906
- - Only works when workflow is ACTIVE
907
- - Recreating workflow = new URL
908
- - Must be publicly accessible (for production)
909
-
910
- ---
911
-
912
- ## Support
913
-
914
- - **Issues:** https://github.com/contacteitor/clientify_n8n/issues
915
- - **Email:** develop@clientify.com
916
- - **Docs:** https://mcp.clientify.com/docs
917
-
918
- ---
107
+ ## Troubleshooting
919
108
 
920
- **Last Updated:** 2025-10-02
921
- **Package Version:** 0.2.0
922
- **Status:** Production Ready
109
+ - If the workflow does not run, confirm the incoming payload event is one of the five events above.
110
+ - If Clientify sends `hook.event`, the node will use that value automatically.
111
+ - If Clientify sends both top-level `event` and `hook.event`, the top-level `event` takes precedence.
112
+ - If you need created vs updated or won vs lost behavior, inspect fields inside `_raw` or the flattened entity output and branch in the workflow.
@@ -1,6 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ClientifyTrigger = void 0;
4
+ function getPayloadEvent(payload) {
5
+ var _a;
6
+ return payload.event || ((_a = payload.hook) === null || _a === void 0 ? void 0 : _a.event);
7
+ }
8
+ function getPayloadEntity(payload, entity) {
9
+ var _a;
10
+ const fromData = (_a = payload.data) === null || _a === void 0 ? void 0 : _a[entity];
11
+ if (fromData && typeof fromData === 'object') {
12
+ return fromData;
13
+ }
14
+ const fromRoot = payload[entity];
15
+ if (fromRoot && typeof fromRoot === 'object') {
16
+ return fromRoot;
17
+ }
18
+ return undefined;
19
+ }
4
20
  class ClientifyTrigger {
5
21
  constructor() {
6
22
  this.description = {
@@ -31,92 +47,34 @@ class ClientifyTrigger {
31
47
  name: 'event',
32
48
  type: 'options',
33
49
  required: true,
34
- default: 'contact.created',
50
+ default: 'contact.saved',
35
51
  description: 'The Clientify event that will trigger this workflow',
36
52
  options: [
37
- // Company Events
38
- {
39
- name: 'Company Created',
40
- value: 'company.created',
41
- description: 'Triggers when a new company is created in Clientify',
42
- },
53
+ // Clientify sends saved events for create and update operations.
43
54
  {
44
55
  name: 'Company Deleted',
45
56
  value: 'company.deleted',
46
57
  description: 'Triggers when a company is deleted from Clientify',
47
58
  },
48
59
  {
49
- name: 'Company Updated',
50
- value: 'company.updated',
51
- description: 'Triggers when a company is updated in Clientify',
52
- },
53
- // Contact Events
54
- {
55
- name: 'Contact Created',
56
- value: 'contact.created',
57
- description: 'Triggers when a new contact is created in Clientify',
58
- },
59
- {
60
- name: 'Contact Deleted',
61
- value: 'contact.deleted',
62
- description: 'Triggers when a contact is deleted from Clientify',
63
- },
64
- {
65
- name: 'Contact Updated',
66
- value: 'contact.updated',
67
- description: 'Triggers when a contact is updated in Clientify',
68
- },
69
- // Deal Events
70
- {
71
- name: 'Deal Created',
72
- value: 'deal.created',
73
- description: 'Triggers when a new deal is created in Clientify',
60
+ name: 'Company Saved',
61
+ value: 'company.saved',
62
+ description: 'Triggers when a company is created or updated in Clientify',
74
63
  },
75
64
  {
76
- name: 'Deal Deleted',
77
- value: 'deal.deleted',
78
- description: 'Triggers when a deal is deleted from Clientify',
65
+ name: 'Contact Saved',
66
+ value: 'contact.saved',
67
+ description: 'Triggers when a contact is created or updated in Clientify',
79
68
  },
80
69
  {
81
- name: 'Deal Lost',
82
- value: 'deal.lost',
83
- description: 'Triggers when a deal is marked as lost',
70
+ name: 'Deal Saved',
71
+ value: 'deal.saved',
72
+ description: 'Triggers when a deal is created, updated, won, lost, or moved in Clientify',
84
73
  },
85
74
  {
86
- name: 'Deal Stage Changed',
87
- value: 'deal.stage_changed',
88
- description: 'Triggers when a deal moves to a different stage',
89
- },
90
- {
91
- name: 'Deal Updated',
92
- value: 'deal.updated',
93
- description: 'Triggers when a deal is updated in Clientify',
94
- },
95
- {
96
- name: 'Deal Won',
97
- value: 'deal.won',
98
- description: 'Triggers when a deal is marked as won',
99
- },
100
- // Task Events
101
- {
102
- name: 'Task Completed',
103
- value: 'task.completed',
104
- description: 'Triggers when a task is marked as completed',
105
- },
106
- {
107
- name: 'Task Created',
108
- value: 'task.created',
109
- description: 'Triggers when a new task is created in Clientify',
110
- },
111
- {
112
- name: 'Task Due Soon',
113
- value: 'task.due_soon',
114
- description: 'Triggers when a task is approaching its due date',
115
- },
116
- {
117
- name: 'Task Overdue',
118
- value: 'task.overdue',
119
- description: 'Triggers when a task is overdue',
75
+ name: 'Task Saved',
76
+ value: 'task.saved',
77
+ description: 'Triggers when a task is created or updated in Clientify',
120
78
  },
121
79
  ],
122
80
  },
@@ -124,7 +82,7 @@ class ClientifyTrigger {
124
82
  };
125
83
  }
126
84
  async webhook() {
127
- var _a, _b, _c, _d, _e, _f, _g;
85
+ var _a, _b, _c;
128
86
  const req = this.getRequestObject();
129
87
  const event = this.getNodeParameter('event');
130
88
  // Get webhook payload from request body
@@ -135,16 +93,17 @@ class ClientifyTrigger {
135
93
  workflowData: [],
136
94
  };
137
95
  }
96
+ const payloadEvent = getPayloadEvent(payload);
138
97
  // Validate that the event matches what user configured
139
98
  // If events don't match, don't trigger the workflow
140
- if (payload.event !== event) {
99
+ if (payloadEvent !== event) {
141
100
  return {
142
101
  workflowData: [],
143
102
  };
144
103
  }
145
104
  // Extract and flatten data based on event type for easier access in workflows
146
105
  let workflowData = {
147
- event: payload.event,
106
+ event: payloadEvent,
148
107
  timestamp: payload.timestamp,
149
108
  };
150
109
  // Add account and user info if present
@@ -155,40 +114,44 @@ class ClientifyTrigger {
155
114
  workflowData.user_id = payload.user_id;
156
115
  }
157
116
  // Flatten the nested data structure based on event type
158
- if (payload.event.startsWith('contact.')) {
117
+ if (payloadEvent.startsWith('contact.')) {
159
118
  // Contact events
160
- if ((_a = payload.data) === null || _a === void 0 ? void 0 : _a.contact) {
161
- workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { contact_id: payload.data.contact.id }), payload.data.contact);
119
+ const contact = getPayloadEntity(payload, 'contact');
120
+ if (contact) {
121
+ workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { contact_id: contact.id }), contact);
162
122
  }
163
123
  // Include changes for update events
164
- if ((_b = payload.data) === null || _b === void 0 ? void 0 : _b.changes) {
124
+ if ((_a = payload.data) === null || _a === void 0 ? void 0 : _a.changes) {
165
125
  workflowData.changes = payload.data.changes;
166
126
  }
167
127
  }
168
- else if (payload.event.startsWith('company.')) {
128
+ else if (payloadEvent.startsWith('company.')) {
169
129
  // Company events
170
- if ((_c = payload.data) === null || _c === void 0 ? void 0 : _c.company) {
171
- workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { company_id: payload.data.company.id }), payload.data.company);
130
+ const company = getPayloadEntity(payload, 'company');
131
+ if (company) {
132
+ workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { company_id: company.id }), company);
172
133
  }
173
134
  // Include changes for update events
174
- if ((_d = payload.data) === null || _d === void 0 ? void 0 : _d.changes) {
135
+ if ((_b = payload.data) === null || _b === void 0 ? void 0 : _b.changes) {
175
136
  workflowData.changes = payload.data.changes;
176
137
  }
177
138
  }
178
- else if (payload.event.startsWith('deal.')) {
139
+ else if (payloadEvent.startsWith('deal.')) {
179
140
  // Deal events
180
- if ((_e = payload.data) === null || _e === void 0 ? void 0 : _e.deal) {
181
- workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { deal_id: payload.data.deal.id }), payload.data.deal);
141
+ const deal = getPayloadEntity(payload, 'deal');
142
+ if (deal) {
143
+ workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { deal_id: deal.id }), deal);
182
144
  }
183
145
  // Include changes for update events
184
- if ((_f = payload.data) === null || _f === void 0 ? void 0 : _f.changes) {
146
+ if ((_c = payload.data) === null || _c === void 0 ? void 0 : _c.changes) {
185
147
  workflowData.changes = payload.data.changes;
186
148
  }
187
149
  }
188
- else if (payload.event.startsWith('task.')) {
150
+ else if (payloadEvent.startsWith('task.')) {
189
151
  // Task events
190
- if ((_g = payload.data) === null || _g === void 0 ? void 0 : _g.task) {
191
- workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { task_id: payload.data.task.id }), payload.data.task);
152
+ const task = getPayloadEntity(payload, 'task');
153
+ if (task) {
154
+ workflowData = Object.assign(Object.assign(Object.assign({}, workflowData), { task_id: task.id }), task);
192
155
  }
193
156
  }
194
157
  // Keep the original raw payload for advanced users who need it
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-clientify",
3
- "version": "0.2.17",
3
+ "version": "0.2.18",
4
4
  "description": "N8N node for Clientify CRM integration",
5
5
  "keywords": [
6
6
  "n8n-node",