@belmontdigitalmarketing/n8n-nodes-flowlu 0.2.1 → 0.2.2
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/dist/nodes/Flowlu/Flowlu.node.js +591 -166
- package/dist/nodes/Flowlu/Flowlu.node.json +17 -17
- package/package.json +2 -2
|
@@ -9,9 +9,7 @@ async function getFlowluCredentials(context) {
|
|
|
9
9
|
const credentials = await context.getCredentials('flowluApi');
|
|
10
10
|
const subdomain = credentials.subdomain;
|
|
11
11
|
const apiKey = credentials.apiKey;
|
|
12
|
-
const baseUrl = subdomain.endsWith('.flowlu.com')
|
|
13
|
-
? `https://${subdomain}`
|
|
14
|
-
: `https://${subdomain}.flowlu.com`;
|
|
12
|
+
const baseUrl = subdomain.endsWith('.flowlu.com') ? `https://${subdomain}` : `https://${subdomain}.flowlu.com`;
|
|
15
13
|
return { baseUrl, apiKey };
|
|
16
14
|
}
|
|
17
15
|
async function flowluApiRequest(method, baseUrl, endpoint, apiKey, body, queryParams) {
|
|
@@ -31,6 +29,55 @@ async function flowluApiRequest(method, baseUrl, endpoint, apiKey, body, queryPa
|
|
|
31
29
|
const response = await this.helpers.request(requestOptions);
|
|
32
30
|
return typeof response === 'string' ? JSON.parse(response) : response;
|
|
33
31
|
}
|
|
32
|
+
// Detect Flowlu's rate-limit signal in either a thrown error or a returned body.
|
|
33
|
+
function isFlowluRateLimit(value) {
|
|
34
|
+
const text = value instanceof Error ? value.message : typeof value === 'string' ? value : JSON.stringify(value ?? '');
|
|
35
|
+
return /limit exceeded|too many requests|\b429\b/i.test(text);
|
|
36
|
+
}
|
|
37
|
+
// GET wrapper that retries through Flowlu's rate limit with linear backoff. If it
|
|
38
|
+
// never succeeds it throws, so callers surface the real cause instead of silently
|
|
39
|
+
// returning no data (which previously masqueraded as "No fields found").
|
|
40
|
+
async function flowluApiGetWithRetry(baseUrl, endpoint, apiKey, queryParams, maxRetries = 3) {
|
|
41
|
+
let lastError = new Error('Flowlu request failed');
|
|
42
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
43
|
+
try {
|
|
44
|
+
const response = await flowluApiRequest.call(this, 'GET', baseUrl, endpoint, apiKey, undefined, queryParams);
|
|
45
|
+
if (!isFlowluRateLimit(response?.error ?? response)) {
|
|
46
|
+
return response;
|
|
47
|
+
}
|
|
48
|
+
lastError = new Error(String(response?.error ?? 'Flowlu request limit exceeded'));
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (!isFlowluRateLimit(error))
|
|
52
|
+
throw error;
|
|
53
|
+
lastError = error;
|
|
54
|
+
}
|
|
55
|
+
// linear backoff before the next attempt (no wait after the final one)
|
|
56
|
+
if (attempt < maxRetries) {
|
|
57
|
+
await new Promise((resolve) => {
|
|
58
|
+
setTimeout(resolve, 1500 * (attempt + 1));
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
throw lastError instanceof Error ? lastError : new Error('Flowlu request failed');
|
|
63
|
+
}
|
|
64
|
+
// Fetch every page of a Flowlu list endpoint. The API caps responses at 50 items
|
|
65
|
+
// per page, so a single call silently truncates larger result sets.
|
|
66
|
+
async function flowluListAll(baseUrl, endpoint, apiKey) {
|
|
67
|
+
const items = [];
|
|
68
|
+
const maxPages = 100; // safety bound
|
|
69
|
+
for (let page = 1; page <= maxPages; page++) {
|
|
70
|
+
const response = await flowluApiGetWithRetry.call(this, baseUrl, endpoint, apiKey, { page: String(page) });
|
|
71
|
+
const pageItems = response?.response?.items;
|
|
72
|
+
if (!Array.isArray(pageItems) || pageItems.length === 0)
|
|
73
|
+
break;
|
|
74
|
+
items.push(...pageItems);
|
|
75
|
+
const total = Number(response.response.total ?? items.length);
|
|
76
|
+
if (items.length >= total)
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
return items;
|
|
80
|
+
}
|
|
34
81
|
function appendWorkflowFooter(target, contentKey = 'description') {
|
|
35
82
|
const { id } = this.getWorkflow();
|
|
36
83
|
const footer = `<hr><em>Generated via n8n:</em> <a href="${this.getInstanceBaseUrl()}workflow/${id}">View Workflow</a>`;
|
|
@@ -52,49 +99,27 @@ function applyResourceMapperFields(context, body, paramName, itemIndex) {
|
|
|
52
99
|
// No custom fields set - ignore
|
|
53
100
|
}
|
|
54
101
|
}
|
|
55
|
-
// Helper to load custom fields
|
|
102
|
+
// Helper to load an entity's custom fields as name/value options.
|
|
56
103
|
async function loadCustomFieldsForEntity(context, moduleFilter, modelFilter) {
|
|
104
|
+
const { baseUrl, apiKey } = await getFlowluCredentials(context);
|
|
105
|
+
let fieldsets;
|
|
106
|
+
let allFields;
|
|
57
107
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const fieldsetsResponse = await flowluApiRequest.call(context, 'GET', baseUrl, '/api/v1/module/customfields/fieldsets/list', apiKey);
|
|
61
|
-
const fieldsetIds = [];
|
|
62
|
-
if (fieldsetsResponse?.response?.items) {
|
|
63
|
-
for (const fs of fieldsetsResponse.response.items) {
|
|
64
|
-
if (fs.module === moduleFilter && fs.model === modelFilter) {
|
|
65
|
-
fieldsetIds.push(fs.id.toString());
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// Get all custom fields
|
|
70
|
-
const fieldsResponse = await flowluApiRequest.call(context, 'GET', baseUrl, '/api/v1/module/customfields/fields/list', apiKey);
|
|
71
|
-
if (fieldsResponse?.response?.items) {
|
|
72
|
-
let fields = fieldsResponse.response.items;
|
|
73
|
-
// Filter by fieldset if we found matching fieldsets
|
|
74
|
-
if (fieldsetIds.length > 0) {
|
|
75
|
-
fields = fields.filter((f) => fieldsetIds.includes(f.fieldset_id?.toString()));
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
// Fallback: filter by module/model directly on the field
|
|
79
|
-
fields = fields.filter((f) => f.module === moduleFilter && f.model === modelFilter);
|
|
80
|
-
}
|
|
81
|
-
return fields
|
|
82
|
-
.filter((f) => f.active !== 0)
|
|
83
|
-
.map((f) => {
|
|
84
|
-
const cfKey = (f.api_use_alias && f.alias)
|
|
85
|
-
? `cf_${f.alias}`
|
|
86
|
-
: `cf_${f.id}`;
|
|
87
|
-
return {
|
|
88
|
-
name: f.name || cfKey,
|
|
89
|
-
value: cfKey,
|
|
90
|
-
};
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
return [];
|
|
108
|
+
fieldsets = await flowluListAll.call(context, baseUrl, '/api/v1/module/customfields/fieldsets/list', apiKey);
|
|
109
|
+
allFields = await flowluListAll.call(context, baseUrl, '/api/v1/module/customfields/fields/list', apiKey);
|
|
94
110
|
}
|
|
95
111
|
catch (error) {
|
|
96
|
-
|
|
112
|
+
throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Could not load Flowlu custom fields: ${error.message}. If this is a rate limit, wait a moment and try again.`);
|
|
97
113
|
}
|
|
114
|
+
// Fields don't reliably carry module/model, so match via their fieldset.
|
|
115
|
+
const matchingFieldsetIds = new Set(fieldsets.filter((fs) => fs.module === moduleFilter && fs.model === modelFilter).map((fs) => String(fs.id)));
|
|
116
|
+
return allFields
|
|
117
|
+
.filter((f) => f.active !== 0)
|
|
118
|
+
.filter((f) => matchingFieldsetIds.has(String(f.fieldset_id)) || (f.module === moduleFilter && f.model === modelFilter))
|
|
119
|
+
.map((f) => {
|
|
120
|
+
const cfKey = f.api_use_alias && f.alias ? `cf_${f.alias}` : `cf_${f.id}`;
|
|
121
|
+
return { name: f.name || cfKey, value: cfKey };
|
|
122
|
+
});
|
|
98
123
|
}
|
|
99
124
|
// ============================================================
|
|
100
125
|
// Reusable custom field option definitions
|
|
@@ -103,27 +128,16 @@ async function loadCustomFieldsForEntity(context, moduleFilter, modelFilter) {
|
|
|
103
128
|
async function loadEntityCustomFieldColumns(moduleFilter, modelFilter) {
|
|
104
129
|
try {
|
|
105
130
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
const fieldsResponse = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/customfields/fields/list', apiKey);
|
|
116
|
-
if (!fieldsResponse?.response?.items)
|
|
117
|
-
return { fields: [] };
|
|
118
|
-
let filtered = fieldsResponse.response.items.filter((f) => f.active !== 0);
|
|
119
|
-
if (fieldsetIds.length > 0) {
|
|
120
|
-
filtered = filtered.filter((f) => fieldsetIds.includes(f.fieldset_id?.toString()));
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
filtered = filtered.filter((f) => f.module === moduleFilter && f.model === modelFilter);
|
|
124
|
-
}
|
|
131
|
+
const fieldsets = await flowluListAll.call(this, baseUrl, '/api/v1/module/customfields/fieldsets/list', apiKey);
|
|
132
|
+
const allFields = await flowluListAll.call(this, baseUrl, '/api/v1/module/customfields/fields/list', apiKey);
|
|
133
|
+
// Fields don't reliably carry module/model, so match via their fieldset.
|
|
134
|
+
const matchingFieldsetIds = new Set(fieldsets
|
|
135
|
+
.filter((fs) => fs.module === moduleFilter && fs.model === modelFilter)
|
|
136
|
+
.map((fs) => String(fs.id)));
|
|
137
|
+
const filtered = allFields.filter((f) => f.active !== 0 &&
|
|
138
|
+
(matchingFieldsetIds.has(String(f.fieldset_id)) || (f.module === moduleFilter && f.model === modelFilter)));
|
|
125
139
|
const fields = filtered.map((f) => {
|
|
126
|
-
const cfKey =
|
|
140
|
+
const cfKey = f.api_use_alias && f.alias ? `cf_${f.alias}` : `cf_${f.id}`;
|
|
127
141
|
let fieldType = 'string';
|
|
128
142
|
if (f.type === 'int')
|
|
129
143
|
fieldType = 'number';
|
|
@@ -145,7 +159,9 @@ async function loadEntityCustomFieldColumns(moduleFilter, modelFilter) {
|
|
|
145
159
|
.filter((o) => o.value)
|
|
146
160
|
.map((o) => ({ name: o.value, value: o.id?.toString() || o.value }));
|
|
147
161
|
}
|
|
148
|
-
catch {
|
|
162
|
+
catch {
|
|
163
|
+
/* ignore */
|
|
164
|
+
}
|
|
149
165
|
}
|
|
150
166
|
const field = {
|
|
151
167
|
id: cfKey,
|
|
@@ -163,7 +179,9 @@ async function loadEntityCustomFieldColumns(moduleFilter, modelFilter) {
|
|
|
163
179
|
return { fields };
|
|
164
180
|
}
|
|
165
181
|
catch (error) {
|
|
166
|
-
|
|
182
|
+
if (error instanceof n8n_workflow_1.NodeOperationError)
|
|
183
|
+
throw error;
|
|
184
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Could not load Flowlu custom fields: ${error.message}. If this is a rate limit, wait a moment and click Retry.`);
|
|
167
185
|
}
|
|
168
186
|
}
|
|
169
187
|
function makeCustomFieldsOption(loadMethod) {
|
|
@@ -251,7 +269,12 @@ class Flowlu {
|
|
|
251
269
|
displayOptions: { show: { resource: ['tag'] } },
|
|
252
270
|
options: [
|
|
253
271
|
{ name: 'Add', value: 'add', description: 'Add a tag to an entity', action: 'Add a tag' },
|
|
254
|
-
{
|
|
272
|
+
{
|
|
273
|
+
name: 'Get Many',
|
|
274
|
+
value: 'getAll',
|
|
275
|
+
description: 'Get many tags on an entity',
|
|
276
|
+
action: 'Get tags on entity',
|
|
277
|
+
},
|
|
255
278
|
{ name: 'List All', value: 'listAll', description: 'List all tags in your account', action: 'List all tags' },
|
|
256
279
|
{ name: 'Remove', value: 'remove', description: 'Remove a tag from an entity', action: 'Remove a tag' },
|
|
257
280
|
],
|
|
@@ -268,7 +291,12 @@ class Flowlu {
|
|
|
268
291
|
displayOptions: { show: { resource: ['comment'] } },
|
|
269
292
|
options: [
|
|
270
293
|
{ name: 'Create', value: 'create', description: 'Create a comment on an entity', action: 'Create a comment' },
|
|
271
|
-
{
|
|
294
|
+
{
|
|
295
|
+
name: 'Get Many',
|
|
296
|
+
value: 'getAll',
|
|
297
|
+
description: 'Get many comments on an entity',
|
|
298
|
+
action: 'Get comments on entity',
|
|
299
|
+
},
|
|
272
300
|
],
|
|
273
301
|
default: 'create',
|
|
274
302
|
},
|
|
@@ -303,7 +331,12 @@ class Flowlu {
|
|
|
303
331
|
{ name: 'Create', value: 'create', description: 'Create a new opportunity', action: 'Create an opportunity' },
|
|
304
332
|
{ name: 'Delete', value: 'delete', description: 'Delete an opportunity', action: 'Delete an opportunity' },
|
|
305
333
|
{ name: 'Get', value: 'get', description: 'Get an opportunity by ID', action: 'Get an opportunity' },
|
|
306
|
-
{
|
|
334
|
+
{
|
|
335
|
+
name: 'Get Many',
|
|
336
|
+
value: 'getAll',
|
|
337
|
+
description: 'Get many opportunities',
|
|
338
|
+
action: 'Get many opportunities',
|
|
339
|
+
},
|
|
307
340
|
{ name: 'Update', value: 'update', description: 'Update an opportunity', action: 'Update an opportunity' },
|
|
308
341
|
],
|
|
309
342
|
default: 'create',
|
|
@@ -432,7 +465,14 @@ class Flowlu {
|
|
|
432
465
|
{ displayName: 'Instagram', name: 'social_network_link_6', type: 'string', default: '' },
|
|
433
466
|
{ displayName: 'LinkedIn', name: 'social_network_link_5', type: 'string', default: '' },
|
|
434
467
|
{ displayName: 'Middle Name', name: 'middle_name', type: 'string', default: '' },
|
|
435
|
-
{
|
|
468
|
+
{
|
|
469
|
+
displayName: 'Owner Name or ID',
|
|
470
|
+
name: 'owner_id',
|
|
471
|
+
type: 'options',
|
|
472
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
473
|
+
default: '',
|
|
474
|
+
description: 'Assigned user for this contact. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
475
|
+
},
|
|
436
476
|
{ displayName: 'Personal Email', name: 'email_personal', type: 'string', default: '' },
|
|
437
477
|
{ displayName: 'Phone 2', name: 'phone2', type: 'string', default: '' },
|
|
438
478
|
{ displayName: 'Phone 3', name: 'phone3', type: 'string', default: '' },
|
|
@@ -491,7 +531,14 @@ class Flowlu {
|
|
|
491
531
|
{ displayName: 'Last Name', name: 'last_name', type: 'string', default: '' },
|
|
492
532
|
{ displayName: 'LinkedIn', name: 'social_network_link_5', type: 'string', default: '' },
|
|
493
533
|
{ displayName: 'Middle Name', name: 'middle_name', type: 'string', default: '' },
|
|
494
|
-
{
|
|
534
|
+
{
|
|
535
|
+
displayName: 'Owner Name or ID',
|
|
536
|
+
name: 'owner_id',
|
|
537
|
+
type: 'options',
|
|
538
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
539
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
540
|
+
default: '',
|
|
541
|
+
},
|
|
495
542
|
{ displayName: 'Personal Email', name: 'email_personal', type: 'string', default: '' },
|
|
496
543
|
{ displayName: 'Phone', name: 'phone', type: 'string', default: '' },
|
|
497
544
|
{ displayName: 'Phone 2', name: 'phone2', type: 'string', default: '' },
|
|
@@ -541,10 +588,23 @@ class Flowlu {
|
|
|
541
588
|
displayOptions: { show: { resource: ['contact'], operation: ['getAll'] } },
|
|
542
589
|
options: [
|
|
543
590
|
{ displayName: 'Name', name: 'name', type: 'string', default: '', description: 'Filter by contact name' },
|
|
544
|
-
{
|
|
545
|
-
|
|
591
|
+
{
|
|
592
|
+
displayName: 'Email',
|
|
593
|
+
name: 'email',
|
|
594
|
+
type: 'string',
|
|
595
|
+
placeholder: 'name@email.com',
|
|
596
|
+
default: '',
|
|
597
|
+
description: 'Filter by email address',
|
|
598
|
+
},
|
|
546
599
|
{ displayName: 'Phone', name: 'phone', type: 'string', default: '', description: 'Filter by phone number' },
|
|
547
|
-
{
|
|
600
|
+
{
|
|
601
|
+
displayName: 'Owner Name or ID',
|
|
602
|
+
name: 'owner_id',
|
|
603
|
+
type: 'options',
|
|
604
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
605
|
+
default: '',
|
|
606
|
+
description: 'Filter by assigned owner. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
607
|
+
},
|
|
548
608
|
],
|
|
549
609
|
},
|
|
550
610
|
// ========================================
|
|
@@ -606,11 +666,23 @@ class Flowlu {
|
|
|
606
666
|
default: {},
|
|
607
667
|
displayOptions: { show: { resource: ['opportunity'], operation: ['create'] } },
|
|
608
668
|
options: [
|
|
609
|
-
{
|
|
669
|
+
{
|
|
670
|
+
displayName: 'Budget',
|
|
671
|
+
name: 'budget',
|
|
672
|
+
type: 'number',
|
|
673
|
+
default: 0,
|
|
674
|
+
description: 'Opportunity value/amount',
|
|
675
|
+
},
|
|
610
676
|
{ displayName: 'Contact Company', name: 'contact_company', type: 'string', default: '' },
|
|
611
677
|
{ displayName: 'Contact Email', name: 'contact_email', type: 'string', default: '' },
|
|
612
678
|
{ displayName: 'Contact Mobile', name: 'contact_mobile', type: 'string', default: '' },
|
|
613
|
-
{
|
|
679
|
+
{
|
|
680
|
+
displayName: 'Contact Name',
|
|
681
|
+
name: 'contact_name',
|
|
682
|
+
type: 'string',
|
|
683
|
+
default: '',
|
|
684
|
+
description: 'Quick-add contact name (if not linking to existing contact)',
|
|
685
|
+
},
|
|
614
686
|
{ displayName: 'Contact Phone', name: 'contact_phone', type: 'string', default: '' },
|
|
615
687
|
{ displayName: 'Contact Position', name: 'contact_position', type: 'string', default: '' },
|
|
616
688
|
{ displayName: 'Contact Website', name: 'contact_web', type: 'string', default: '' },
|
|
@@ -622,10 +694,31 @@ class Flowlu {
|
|
|
622
694
|
default: false,
|
|
623
695
|
description: 'Whether to append a "Generated via n8n: View Workflow" footer to the opportunity description, linking back to this workflow',
|
|
624
696
|
},
|
|
625
|
-
{
|
|
626
|
-
|
|
697
|
+
{
|
|
698
|
+
displayName: 'Link to Account Name or ID',
|
|
699
|
+
name: 'link_account_id',
|
|
700
|
+
type: 'options',
|
|
701
|
+
typeOptions: { loadOptionsMethod: 'getAccounts' },
|
|
702
|
+
default: '',
|
|
703
|
+
description: 'Link this opportunity to an existing CRM account (organization). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
displayName: 'Link to Contact Name or ID',
|
|
707
|
+
name: 'link_contact_id',
|
|
708
|
+
type: 'options',
|
|
709
|
+
typeOptions: { loadOptionsMethod: 'getContacts' },
|
|
710
|
+
default: '',
|
|
711
|
+
description: 'Link this opportunity to an existing CRM contact. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
712
|
+
},
|
|
627
713
|
{ displayName: 'Planned Close Date', name: 'deadline', type: 'dateTime', default: '' },
|
|
628
|
-
{
|
|
714
|
+
{
|
|
715
|
+
displayName: 'Source Name or ID',
|
|
716
|
+
name: 'source_id',
|
|
717
|
+
type: 'options',
|
|
718
|
+
typeOptions: { loadOptionsMethod: 'getOpportunitySources' },
|
|
719
|
+
default: '',
|
|
720
|
+
description: 'Where this opportunity came from. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
721
|
+
},
|
|
629
722
|
{ displayName: 'Start Date', name: 'start_date', type: 'dateTime', default: '' },
|
|
630
723
|
],
|
|
631
724
|
},
|
|
@@ -655,9 +748,22 @@ class Flowlu {
|
|
|
655
748
|
default: {},
|
|
656
749
|
displayOptions: { show: { resource: ['opportunity'], operation: ['update'] } },
|
|
657
750
|
options: [
|
|
658
|
-
{
|
|
751
|
+
{
|
|
752
|
+
displayName: 'Assignee Name or ID',
|
|
753
|
+
name: 'assignee_id',
|
|
754
|
+
type: 'options',
|
|
755
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
756
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
757
|
+
default: '',
|
|
758
|
+
},
|
|
659
759
|
{ displayName: 'Budget', name: 'budget', type: 'number', default: 0 },
|
|
660
|
-
{
|
|
760
|
+
{
|
|
761
|
+
displayName: 'Closing Comment',
|
|
762
|
+
name: 'closing_comment',
|
|
763
|
+
type: 'string',
|
|
764
|
+
default: '',
|
|
765
|
+
description: 'Reason for win/loss',
|
|
766
|
+
},
|
|
661
767
|
{ displayName: 'Contact Email', name: 'contact_email', type: 'string', default: '' },
|
|
662
768
|
{ displayName: 'Contact Name', name: 'contact_name', type: 'string', default: '' },
|
|
663
769
|
{ displayName: 'Contact Phone', name: 'contact_phone', type: 'string', default: '' },
|
|
@@ -669,11 +775,39 @@ class Flowlu {
|
|
|
669
775
|
default: false,
|
|
670
776
|
description: 'Whether to append a "Generated via n8n: View Workflow" footer to the opportunity description, linking back to this workflow. Requires Description to be set.',
|
|
671
777
|
},
|
|
672
|
-
{
|
|
673
|
-
|
|
778
|
+
{
|
|
779
|
+
displayName: 'Link to Account Name or ID',
|
|
780
|
+
name: 'link_account_id',
|
|
781
|
+
type: 'options',
|
|
782
|
+
typeOptions: { loadOptionsMethod: 'getAccounts' },
|
|
783
|
+
default: '',
|
|
784
|
+
description: 'Link this opportunity to a CRM account. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
displayName: 'Link to Contact Name or ID',
|
|
788
|
+
name: 'link_contact_id',
|
|
789
|
+
type: 'options',
|
|
790
|
+
typeOptions: { loadOptionsMethod: 'getContacts' },
|
|
791
|
+
default: '',
|
|
792
|
+
description: 'Link this opportunity to a CRM contact. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
793
|
+
},
|
|
674
794
|
{ displayName: 'Name', name: 'name', type: 'string', default: '' },
|
|
675
|
-
{
|
|
676
|
-
|
|
795
|
+
{
|
|
796
|
+
displayName: 'Pipeline Name or ID',
|
|
797
|
+
name: 'pipeline_id',
|
|
798
|
+
type: 'options',
|
|
799
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
800
|
+
typeOptions: { loadOptionsMethod: 'getPipelines' },
|
|
801
|
+
default: '',
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
displayName: 'Pipeline Stage Name or ID',
|
|
805
|
+
name: 'pipeline_stage_id',
|
|
806
|
+
type: 'options',
|
|
807
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
808
|
+
typeOptions: { loadOptionsMethod: 'getPipelineStages' },
|
|
809
|
+
default: '',
|
|
810
|
+
},
|
|
677
811
|
{ displayName: 'Planned Close Date', name: 'deadline', type: 'dateTime', default: '' },
|
|
678
812
|
{ displayName: 'Start Date', name: 'start_date', type: 'dateTime', default: '' },
|
|
679
813
|
{
|
|
@@ -748,8 +882,22 @@ class Flowlu {
|
|
|
748
882
|
displayOptions: { show: { resource: ['opportunity'], operation: ['getAll'] } },
|
|
749
883
|
options: [
|
|
750
884
|
{ displayName: 'Name', name: 'name', type: 'string', default: '', description: 'Filter by opportunity name' },
|
|
751
|
-
{
|
|
752
|
-
|
|
885
|
+
{
|
|
886
|
+
displayName: 'Assignee Name or ID',
|
|
887
|
+
name: 'assignee_id',
|
|
888
|
+
type: 'options',
|
|
889
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
890
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
891
|
+
default: '',
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
displayName: 'Account / Contact Name or ID',
|
|
895
|
+
name: 'company_id',
|
|
896
|
+
type: 'options',
|
|
897
|
+
typeOptions: { loadOptionsMethod: 'getAllCrmAccounts' },
|
|
898
|
+
default: '',
|
|
899
|
+
description: 'Filter by linked company or contact (note: Flowlu may not support this filter). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
900
|
+
},
|
|
753
901
|
{
|
|
754
902
|
displayName: 'Status',
|
|
755
903
|
name: 'active',
|
|
@@ -823,8 +971,22 @@ class Flowlu {
|
|
|
823
971
|
default: 0,
|
|
824
972
|
},
|
|
825
973
|
{ displayName: 'Contract Sum (Revenue)', name: 'estimated_revenue', type: 'number', default: 0 },
|
|
826
|
-
{
|
|
827
|
-
|
|
974
|
+
{
|
|
975
|
+
displayName: 'Customer (Company ID) Name or ID',
|
|
976
|
+
name: 'customer_id',
|
|
977
|
+
type: 'options',
|
|
978
|
+
typeOptions: { loadOptionsMethod: 'getContacts' },
|
|
979
|
+
default: '',
|
|
980
|
+
description: 'CRM company linked to this project. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
displayName: 'Customer Contact Name or ID',
|
|
984
|
+
name: 'customer_crm_contact_id',
|
|
985
|
+
type: 'options',
|
|
986
|
+
typeOptions: { loadOptionsMethod: 'getContacts' },
|
|
987
|
+
default: '',
|
|
988
|
+
description: 'CRM contact linked to this project. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
989
|
+
},
|
|
828
990
|
{ displayName: 'End Date', name: 'enddate', type: 'dateTime', default: '' },
|
|
829
991
|
{ displayName: 'Expense Sum', name: 'estimated_expenses', type: 'number', default: 0 },
|
|
830
992
|
{
|
|
@@ -834,8 +996,21 @@ class Flowlu {
|
|
|
834
996
|
default: false,
|
|
835
997
|
description: 'Whether to append a "Generated via n8n: View Workflow" footer to the project description, linking back to this workflow',
|
|
836
998
|
},
|
|
837
|
-
{
|
|
838
|
-
|
|
999
|
+
{
|
|
1000
|
+
displayName: 'Opportunity',
|
|
1001
|
+
name: 'crm_lead_id',
|
|
1002
|
+
type: 'number',
|
|
1003
|
+
default: 0,
|
|
1004
|
+
description: 'ID of a linked CRM opportunity',
|
|
1005
|
+
},
|
|
1006
|
+
{
|
|
1007
|
+
displayName: 'Portfolio Name or ID',
|
|
1008
|
+
name: 'briefcase_id',
|
|
1009
|
+
type: 'options',
|
|
1010
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1011
|
+
typeOptions: { loadOptionsMethod: 'getPortfolios' },
|
|
1012
|
+
default: '',
|
|
1013
|
+
},
|
|
839
1014
|
{
|
|
840
1015
|
displayName: 'Priority',
|
|
841
1016
|
name: 'priority',
|
|
@@ -847,9 +1022,23 @@ class Flowlu {
|
|
|
847
1022
|
],
|
|
848
1023
|
default: 2,
|
|
849
1024
|
},
|
|
850
|
-
{
|
|
1025
|
+
{
|
|
1026
|
+
displayName: 'Project Stage Name or ID',
|
|
1027
|
+
name: 'stage_id',
|
|
1028
|
+
type: 'options',
|
|
1029
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1030
|
+
typeOptions: { loadOptionsMethod: 'getProjectStages' },
|
|
1031
|
+
default: '',
|
|
1032
|
+
},
|
|
851
1033
|
{ displayName: 'Start Date', name: 'startdate', type: 'dateTime', default: '' },
|
|
852
|
-
{
|
|
1034
|
+
{
|
|
1035
|
+
displayName: 'Task Workflow Name or ID',
|
|
1036
|
+
name: 'tasks_workflow_id',
|
|
1037
|
+
type: 'options',
|
|
1038
|
+
typeOptions: { loadOptionsMethod: 'getTaskWorkflows' },
|
|
1039
|
+
default: '',
|
|
1040
|
+
description: 'Default task workflow for tasks in this project. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
1041
|
+
},
|
|
853
1042
|
],
|
|
854
1043
|
},
|
|
855
1044
|
{
|
|
@@ -895,7 +1084,14 @@ class Flowlu {
|
|
|
895
1084
|
default: false,
|
|
896
1085
|
description: 'Whether to append a "Generated via n8n: View Workflow" footer to the project description, linking back to this workflow. Requires Description to be set.',
|
|
897
1086
|
},
|
|
898
|
-
{
|
|
1087
|
+
{
|
|
1088
|
+
displayName: 'Manager Name or ID',
|
|
1089
|
+
name: 'manager_id',
|
|
1090
|
+
type: 'options',
|
|
1091
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1092
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
1093
|
+
default: '',
|
|
1094
|
+
},
|
|
899
1095
|
{
|
|
900
1096
|
displayName: 'Priority',
|
|
901
1097
|
name: 'priority',
|
|
@@ -908,7 +1104,14 @@ class Flowlu {
|
|
|
908
1104
|
default: 2,
|
|
909
1105
|
},
|
|
910
1106
|
{ displayName: 'Project Name', name: 'name', type: 'string', default: '' },
|
|
911
|
-
{
|
|
1107
|
+
{
|
|
1108
|
+
displayName: 'Project Stage Name or ID',
|
|
1109
|
+
name: 'stage_id',
|
|
1110
|
+
type: 'options',
|
|
1111
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1112
|
+
typeOptions: { loadOptionsMethod: 'getProjectStages' },
|
|
1113
|
+
default: '',
|
|
1114
|
+
},
|
|
912
1115
|
{ displayName: 'Start Date', name: 'startdate', type: 'dateTime', default: '' },
|
|
913
1116
|
],
|
|
914
1117
|
},
|
|
@@ -950,8 +1153,22 @@ class Flowlu {
|
|
|
950
1153
|
displayOptions: { show: { resource: ['project'], operation: ['getAll'] } },
|
|
951
1154
|
options: [
|
|
952
1155
|
{ displayName: 'Name', name: 'name', type: 'string', default: '', description: 'Filter by project name' },
|
|
953
|
-
{
|
|
954
|
-
|
|
1156
|
+
{
|
|
1157
|
+
displayName: 'Manager Name or ID',
|
|
1158
|
+
name: 'manager_id',
|
|
1159
|
+
type: 'options',
|
|
1160
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1161
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
1162
|
+
default: '',
|
|
1163
|
+
},
|
|
1164
|
+
{
|
|
1165
|
+
displayName: 'Customer Name or ID',
|
|
1166
|
+
name: 'customer_id',
|
|
1167
|
+
type: 'options',
|
|
1168
|
+
typeOptions: { loadOptionsMethod: 'getAccounts' },
|
|
1169
|
+
default: '',
|
|
1170
|
+
description: 'Filter by linked company. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
1171
|
+
},
|
|
955
1172
|
{
|
|
956
1173
|
displayName: 'Include Archived',
|
|
957
1174
|
name: 'is_archive',
|
|
@@ -1046,7 +1263,13 @@ class Flowlu {
|
|
|
1046
1263
|
default: {},
|
|
1047
1264
|
displayOptions: { show: { resource: ['recordList'], operation: ['getAll'] } },
|
|
1048
1265
|
options: [
|
|
1049
|
-
{
|
|
1266
|
+
{
|
|
1267
|
+
displayName: 'Search',
|
|
1268
|
+
name: 'search',
|
|
1269
|
+
type: 'string',
|
|
1270
|
+
default: '',
|
|
1271
|
+
description: 'Search records by name/content',
|
|
1272
|
+
},
|
|
1050
1273
|
],
|
|
1051
1274
|
},
|
|
1052
1275
|
// ========================================
|
|
@@ -1098,7 +1321,14 @@ class Flowlu {
|
|
|
1098
1321
|
displayOptions: { show: { resource: ['task'], operation: ['create'] } },
|
|
1099
1322
|
options: [
|
|
1100
1323
|
{ displayName: 'Allow End Date Change', name: 'deadline_allowchange', type: 'boolean', default: true },
|
|
1101
|
-
{
|
|
1324
|
+
{
|
|
1325
|
+
displayName: 'Contact Name or ID',
|
|
1326
|
+
name: 'contact_id',
|
|
1327
|
+
type: 'options',
|
|
1328
|
+
typeOptions: { loadOptionsMethod: 'getContacts' },
|
|
1329
|
+
default: '',
|
|
1330
|
+
description: 'The contact this task is related to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
1331
|
+
},
|
|
1102
1332
|
{ displayName: 'End Date', name: 'deadline', type: 'dateTime', default: '' },
|
|
1103
1333
|
{
|
|
1104
1334
|
displayName: 'Include Link to Workflow',
|
|
@@ -1107,8 +1337,21 @@ class Flowlu {
|
|
|
1107
1337
|
default: false,
|
|
1108
1338
|
description: 'Whether to append a "Generated via n8n: View Workflow" footer to the task description, linking back to this workflow',
|
|
1109
1339
|
},
|
|
1110
|
-
{
|
|
1111
|
-
|
|
1340
|
+
{
|
|
1341
|
+
displayName: 'Owner Name or ID',
|
|
1342
|
+
name: 'owner_id',
|
|
1343
|
+
type: 'options',
|
|
1344
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
1345
|
+
description: 'The user who owns/created this task. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
1346
|
+
default: '',
|
|
1347
|
+
},
|
|
1348
|
+
{
|
|
1349
|
+
displayName: 'Parent Task ID',
|
|
1350
|
+
name: 'parent_id',
|
|
1351
|
+
type: 'number',
|
|
1352
|
+
default: 0,
|
|
1353
|
+
description: 'ID of the parent task (for subtasks)',
|
|
1354
|
+
},
|
|
1112
1355
|
{ displayName: 'Planned Cost', name: 'cost', type: 'number', default: 0, typeOptions: { minValue: 0 } },
|
|
1113
1356
|
{ displayName: 'Planned Income', name: 'price', type: 'number', default: 0, typeOptions: { minValue: 0 } },
|
|
1114
1357
|
{
|
|
@@ -1122,7 +1365,14 @@ class Flowlu {
|
|
|
1122
1365
|
],
|
|
1123
1366
|
default: 2,
|
|
1124
1367
|
},
|
|
1125
|
-
{
|
|
1368
|
+
{
|
|
1369
|
+
displayName: 'Project Name or ID',
|
|
1370
|
+
name: 'model_id',
|
|
1371
|
+
type: 'options',
|
|
1372
|
+
typeOptions: { loadOptionsMethod: 'getProjects' },
|
|
1373
|
+
description: 'The project this task belongs to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
1374
|
+
default: '',
|
|
1375
|
+
},
|
|
1126
1376
|
{ displayName: 'Reviewed by Owner', name: 'task_checkbyowner', type: 'boolean', default: false },
|
|
1127
1377
|
{ displayName: 'Start Date', name: 'plan_start_date', type: 'dateTime', default: '' },
|
|
1128
1378
|
{
|
|
@@ -1137,9 +1387,29 @@ class Flowlu {
|
|
|
1137
1387
|
],
|
|
1138
1388
|
default: 1,
|
|
1139
1389
|
},
|
|
1140
|
-
{
|
|
1141
|
-
|
|
1142
|
-
|
|
1390
|
+
{
|
|
1391
|
+
displayName: 'Time Estimate (Minutes)',
|
|
1392
|
+
name: 'time_estimate',
|
|
1393
|
+
type: 'number',
|
|
1394
|
+
default: 0,
|
|
1395
|
+
typeOptions: { minValue: 0 },
|
|
1396
|
+
},
|
|
1397
|
+
{
|
|
1398
|
+
displayName: 'Workflow Name or ID',
|
|
1399
|
+
name: 'workflow_id',
|
|
1400
|
+
type: 'options',
|
|
1401
|
+
typeOptions: { loadOptionsMethod: 'getTaskWorkflows' },
|
|
1402
|
+
default: '',
|
|
1403
|
+
description: 'The task workflow to use (defaults to the first workflow if not set). Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
1404
|
+
},
|
|
1405
|
+
{
|
|
1406
|
+
displayName: 'Workflow Stage Name or ID',
|
|
1407
|
+
name: 'workflow_stage_id',
|
|
1408
|
+
type: 'options',
|
|
1409
|
+
typeOptions: { loadOptionsMethod: 'getTaskWorkflowStages' },
|
|
1410
|
+
default: '',
|
|
1411
|
+
description: 'The starting stage within the workflow. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
1412
|
+
},
|
|
1143
1413
|
],
|
|
1144
1414
|
},
|
|
1145
1415
|
{
|
|
@@ -1168,7 +1438,14 @@ class Flowlu {
|
|
|
1168
1438
|
default: {},
|
|
1169
1439
|
displayOptions: { show: { resource: ['task'], operation: ['update'] } },
|
|
1170
1440
|
options: [
|
|
1171
|
-
{
|
|
1441
|
+
{
|
|
1442
|
+
displayName: 'Assignee Name or ID',
|
|
1443
|
+
name: 'responsible_id',
|
|
1444
|
+
type: 'options',
|
|
1445
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1446
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
1447
|
+
default: '',
|
|
1448
|
+
},
|
|
1172
1449
|
{ displayName: 'Description', name: 'description', type: 'string', typeOptions: { rows: 4 }, default: '' },
|
|
1173
1450
|
{ displayName: 'End Date', name: 'deadline', type: 'dateTime', default: '' },
|
|
1174
1451
|
{
|
|
@@ -1178,7 +1455,14 @@ class Flowlu {
|
|
|
1178
1455
|
default: false,
|
|
1179
1456
|
description: 'Whether to append a "Generated via n8n: View Workflow" footer to the task description, linking back to this workflow. Requires Description to be set.',
|
|
1180
1457
|
},
|
|
1181
|
-
{
|
|
1458
|
+
{
|
|
1459
|
+
displayName: 'Owner Name or ID',
|
|
1460
|
+
name: 'owner_id',
|
|
1461
|
+
type: 'options',
|
|
1462
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1463
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
1464
|
+
default: '',
|
|
1465
|
+
},
|
|
1182
1466
|
{ displayName: 'Parent Task ID', name: 'parent_id', type: 'number', default: 0 },
|
|
1183
1467
|
{ displayName: 'Planned Cost', name: 'cost', type: 'number', default: 0, typeOptions: { minValue: 0 } },
|
|
1184
1468
|
{ displayName: 'Planned Income', name: 'price', type: 'number', default: 0, typeOptions: { minValue: 0 } },
|
|
@@ -1193,7 +1477,14 @@ class Flowlu {
|
|
|
1193
1477
|
],
|
|
1194
1478
|
default: 2,
|
|
1195
1479
|
},
|
|
1196
|
-
{
|
|
1480
|
+
{
|
|
1481
|
+
displayName: 'Project Name or ID',
|
|
1482
|
+
name: 'model_id',
|
|
1483
|
+
type: 'options',
|
|
1484
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1485
|
+
typeOptions: { loadOptionsMethod: 'getProjects' },
|
|
1486
|
+
default: '',
|
|
1487
|
+
},
|
|
1197
1488
|
{ displayName: 'Start Date', name: 'plan_start_date', type: 'dateTime', default: '' },
|
|
1198
1489
|
{
|
|
1199
1490
|
displayName: 'Status',
|
|
@@ -1208,9 +1499,29 @@ class Flowlu {
|
|
|
1208
1499
|
default: 1,
|
|
1209
1500
|
},
|
|
1210
1501
|
{ displayName: 'Task Name', name: 'name', type: 'string', default: '' },
|
|
1211
|
-
{
|
|
1212
|
-
|
|
1213
|
-
|
|
1502
|
+
{
|
|
1503
|
+
displayName: 'Time Estimate (Minutes)',
|
|
1504
|
+
name: 'time_estimate',
|
|
1505
|
+
type: 'number',
|
|
1506
|
+
default: 0,
|
|
1507
|
+
typeOptions: { minValue: 0 },
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
displayName: 'Workflow Name or ID',
|
|
1511
|
+
name: 'workflow_id',
|
|
1512
|
+
type: 'options',
|
|
1513
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1514
|
+
typeOptions: { loadOptionsMethod: 'getTaskWorkflows' },
|
|
1515
|
+
default: '',
|
|
1516
|
+
},
|
|
1517
|
+
{
|
|
1518
|
+
displayName: 'Workflow Stage Name or ID',
|
|
1519
|
+
name: 'workflow_stage_id',
|
|
1520
|
+
type: 'options',
|
|
1521
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1522
|
+
typeOptions: { loadOptionsMethod: 'getTaskWorkflowStages' },
|
|
1523
|
+
default: '',
|
|
1524
|
+
},
|
|
1214
1525
|
],
|
|
1215
1526
|
},
|
|
1216
1527
|
{
|
|
@@ -1250,7 +1561,14 @@ class Flowlu {
|
|
|
1250
1561
|
default: {},
|
|
1251
1562
|
displayOptions: { show: { resource: ['task'], operation: ['getAll'] } },
|
|
1252
1563
|
options: [
|
|
1253
|
-
{
|
|
1564
|
+
{
|
|
1565
|
+
displayName: 'Assignee Name or ID',
|
|
1566
|
+
name: 'responsible_id',
|
|
1567
|
+
type: 'options',
|
|
1568
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1569
|
+
typeOptions: { loadOptionsMethod: 'getUsers' },
|
|
1570
|
+
default: '',
|
|
1571
|
+
},
|
|
1254
1572
|
{ displayName: 'Name', name: 'name', type: 'string', default: '', description: 'Filter by task name' },
|
|
1255
1573
|
{
|
|
1256
1574
|
displayName: 'Priority',
|
|
@@ -1263,7 +1581,14 @@ class Flowlu {
|
|
|
1263
1581
|
],
|
|
1264
1582
|
default: 2,
|
|
1265
1583
|
},
|
|
1266
|
-
{
|
|
1584
|
+
{
|
|
1585
|
+
displayName: 'Project Name or ID',
|
|
1586
|
+
name: 'model_id',
|
|
1587
|
+
type: 'options',
|
|
1588
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1589
|
+
typeOptions: { loadOptionsMethod: 'getProjects' },
|
|
1590
|
+
default: '',
|
|
1591
|
+
},
|
|
1267
1592
|
{
|
|
1268
1593
|
displayName: 'Status',
|
|
1269
1594
|
name: 'status',
|
|
@@ -1388,7 +1713,10 @@ class Flowlu {
|
|
|
1388
1713
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1389
1714
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/core/user/list', apiKey, undefined, { 'filter[role_login]': '1' });
|
|
1390
1715
|
if (response?.response?.items) {
|
|
1391
|
-
return response.response.items.map((user) => ({
|
|
1716
|
+
return response.response.items.map((user) => ({
|
|
1717
|
+
name: user.name || user.email || `User ${user.id}`,
|
|
1718
|
+
value: user.id.toString(),
|
|
1719
|
+
}));
|
|
1392
1720
|
}
|
|
1393
1721
|
return [];
|
|
1394
1722
|
}
|
|
@@ -1401,7 +1729,10 @@ class Flowlu {
|
|
|
1401
1729
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1402
1730
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/crm/account/list', apiKey, undefined, { 'filter[type]': '1' });
|
|
1403
1731
|
if (response?.response?.items) {
|
|
1404
|
-
return response.response.items.map((a) => ({
|
|
1732
|
+
return response.response.items.map((a) => ({
|
|
1733
|
+
name: a.name || `Account ${a.id}`,
|
|
1734
|
+
value: a.id.toString(),
|
|
1735
|
+
}));
|
|
1405
1736
|
}
|
|
1406
1737
|
return [];
|
|
1407
1738
|
}
|
|
@@ -1414,7 +1745,10 @@ class Flowlu {
|
|
|
1414
1745
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1415
1746
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/crm/account/list', apiKey, undefined, { 'filter[type]': '2' });
|
|
1416
1747
|
if (response?.response?.items) {
|
|
1417
|
-
return response.response.items.map((c) => ({
|
|
1748
|
+
return response.response.items.map((c) => ({
|
|
1749
|
+
name: c.name || `Contact ${c.id}`,
|
|
1750
|
+
value: c.id.toString(),
|
|
1751
|
+
}));
|
|
1418
1752
|
}
|
|
1419
1753
|
return [];
|
|
1420
1754
|
}
|
|
@@ -1427,7 +1761,10 @@ class Flowlu {
|
|
|
1427
1761
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1428
1762
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/st/projects/list', apiKey, undefined, { 'filter[is_archive]': '0' });
|
|
1429
1763
|
if (response?.response?.items) {
|
|
1430
|
-
return response.response.items.map((p) => ({
|
|
1764
|
+
return response.response.items.map((p) => ({
|
|
1765
|
+
name: p.name || `Project ${p.id}`,
|
|
1766
|
+
value: p.id.toString(),
|
|
1767
|
+
}));
|
|
1431
1768
|
}
|
|
1432
1769
|
return [];
|
|
1433
1770
|
}
|
|
@@ -1440,7 +1777,10 @@ class Flowlu {
|
|
|
1440
1777
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1441
1778
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/task/workflows/list', apiKey);
|
|
1442
1779
|
if (response?.response?.items) {
|
|
1443
|
-
return response.response.items.map((wf) => ({
|
|
1780
|
+
return response.response.items.map((wf) => ({
|
|
1781
|
+
name: wf.name || `Workflow ${wf.id}`,
|
|
1782
|
+
value: wf.id.toString(),
|
|
1783
|
+
}));
|
|
1444
1784
|
}
|
|
1445
1785
|
return [];
|
|
1446
1786
|
}
|
|
@@ -1453,7 +1793,11 @@ class Flowlu {
|
|
|
1453
1793
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1454
1794
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/task/stages/list', apiKey);
|
|
1455
1795
|
if (response?.response?.items) {
|
|
1456
|
-
return response.response.items.map((s) => ({
|
|
1796
|
+
return response.response.items.map((s) => ({
|
|
1797
|
+
name: s.name || `Stage ${s.id}`,
|
|
1798
|
+
value: s.id.toString(),
|
|
1799
|
+
description: `Workflow ID: ${s.workflow_id}`,
|
|
1800
|
+
}));
|
|
1457
1801
|
}
|
|
1458
1802
|
return [];
|
|
1459
1803
|
}
|
|
@@ -1466,7 +1810,10 @@ class Flowlu {
|
|
|
1466
1810
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1467
1811
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/crm/pipeline/list', apiKey);
|
|
1468
1812
|
if (response?.response?.items) {
|
|
1469
|
-
return response.response.items.map((p) => ({
|
|
1813
|
+
return response.response.items.map((p) => ({
|
|
1814
|
+
name: p.name || `Pipeline ${p.id}`,
|
|
1815
|
+
value: p.id.toString(),
|
|
1816
|
+
}));
|
|
1470
1817
|
}
|
|
1471
1818
|
return [];
|
|
1472
1819
|
}
|
|
@@ -1479,7 +1826,11 @@ class Flowlu {
|
|
|
1479
1826
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1480
1827
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/crm/pipeline_stage/list', apiKey);
|
|
1481
1828
|
if (response?.response?.items) {
|
|
1482
|
-
return response.response.items.map((s) => ({
|
|
1829
|
+
return response.response.items.map((s) => ({
|
|
1830
|
+
name: s.name || `Stage ${s.id}`,
|
|
1831
|
+
value: s.id.toString(),
|
|
1832
|
+
description: `Pipeline ID: ${s.pipeline_id}`,
|
|
1833
|
+
}));
|
|
1483
1834
|
}
|
|
1484
1835
|
return [];
|
|
1485
1836
|
}
|
|
@@ -1494,7 +1845,9 @@ class Flowlu {
|
|
|
1494
1845
|
try {
|
|
1495
1846
|
pipelineId = this.getNodeParameter('opportunityFilterPipeline');
|
|
1496
1847
|
}
|
|
1497
|
-
catch {
|
|
1848
|
+
catch {
|
|
1849
|
+
/* not set yet */
|
|
1850
|
+
}
|
|
1498
1851
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/crm/pipeline_stage/list', apiKey);
|
|
1499
1852
|
if (response?.response?.items) {
|
|
1500
1853
|
let stages = response.response.items;
|
|
@@ -1530,7 +1883,10 @@ class Flowlu {
|
|
|
1530
1883
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1531
1884
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/crm/source/list', apiKey);
|
|
1532
1885
|
if (response?.response?.items) {
|
|
1533
|
-
return response.response.items.map((s) => ({
|
|
1886
|
+
return response.response.items.map((s) => ({
|
|
1887
|
+
name: s.name || `Source ${s.id}`,
|
|
1888
|
+
value: s.id.toString(),
|
|
1889
|
+
}));
|
|
1534
1890
|
}
|
|
1535
1891
|
return [];
|
|
1536
1892
|
}
|
|
@@ -1543,7 +1899,10 @@ class Flowlu {
|
|
|
1543
1899
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1544
1900
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/st/portfolio/list', apiKey);
|
|
1545
1901
|
if (response?.response?.items) {
|
|
1546
|
-
return response.response.items.map((p) => ({
|
|
1902
|
+
return response.response.items.map((p) => ({
|
|
1903
|
+
name: p.name || `Portfolio ${p.id}`,
|
|
1904
|
+
value: p.id.toString(),
|
|
1905
|
+
}));
|
|
1547
1906
|
}
|
|
1548
1907
|
return [];
|
|
1549
1908
|
}
|
|
@@ -1556,7 +1915,10 @@ class Flowlu {
|
|
|
1556
1915
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1557
1916
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/st/stages/list', apiKey);
|
|
1558
1917
|
if (response?.response?.items) {
|
|
1559
|
-
return response.response.items.map((s) => ({
|
|
1918
|
+
return response.response.items.map((s) => ({
|
|
1919
|
+
name: s.name || `Stage ${s.id}`,
|
|
1920
|
+
value: s.id.toString(),
|
|
1921
|
+
}));
|
|
1560
1922
|
}
|
|
1561
1923
|
return [];
|
|
1562
1924
|
}
|
|
@@ -1569,7 +1931,10 @@ class Flowlu {
|
|
|
1569
1931
|
const { baseUrl, apiKey } = await getFlowluCredentials(this);
|
|
1570
1932
|
const response = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/customlists/lists/list', apiKey);
|
|
1571
1933
|
if (response?.response?.items) {
|
|
1572
|
-
return response.response.items.map((l) => ({
|
|
1934
|
+
return response.response.items.map((l) => ({
|
|
1935
|
+
name: l.name || `List ${l.id}`,
|
|
1936
|
+
value: l.id.toString(),
|
|
1937
|
+
}));
|
|
1573
1938
|
}
|
|
1574
1939
|
return [];
|
|
1575
1940
|
}
|
|
@@ -1611,7 +1976,7 @@ class Flowlu {
|
|
|
1611
1976
|
.filter((f) => fieldsetIds.includes(f.fieldset_id?.toString()))
|
|
1612
1977
|
.filter((f) => f.active !== 0)
|
|
1613
1978
|
.map((f) => {
|
|
1614
|
-
const cfKey =
|
|
1979
|
+
const cfKey = f.api_use_alias && f.alias ? `cf_${f.alias}` : `cf_${f.id}`;
|
|
1615
1980
|
let label = f.name || cfKey;
|
|
1616
1981
|
let desc = '';
|
|
1617
1982
|
// Detect link fields (model.any) and show what they link to
|
|
@@ -1631,7 +1996,9 @@ class Flowlu {
|
|
|
1631
1996
|
}
|
|
1632
1997
|
else if (f.module === 'customlists' && f.model === 'items' && f.group_id) {
|
|
1633
1998
|
// Link to another custom list - find its name
|
|
1634
|
-
const targetList = allFieldsets.find((fs) => fs.module === 'customlists' &&
|
|
1999
|
+
const targetList = allFieldsets.find((fs) => fs.module === 'customlists' &&
|
|
2000
|
+
fs.model === 'items' &&
|
|
2001
|
+
fs.group_id?.toString() === f.group_id.toString());
|
|
1635
2002
|
const listName = targetList?.name || `List #${f.group_id}`;
|
|
1636
2003
|
label = `${f.name} → ${listName}`;
|
|
1637
2004
|
desc = `Enter the Record ID from "${listName}"`;
|
|
@@ -1763,7 +2130,7 @@ class Flowlu {
|
|
|
1763
2130
|
// Find the label field for this list
|
|
1764
2131
|
const labelFieldId = f.group_label_field_id;
|
|
1765
2132
|
linkOptionsCache[clKey] = (resp?.response?.items || []).map((item) => {
|
|
1766
|
-
const label = labelFieldId ?
|
|
2133
|
+
const label = labelFieldId ? item[`cf_${labelFieldId}`] || `#${item.id}` : `#${item.id}`;
|
|
1767
2134
|
return { name: label, value: item.id };
|
|
1768
2135
|
});
|
|
1769
2136
|
}
|
|
@@ -1775,7 +2142,7 @@ class Flowlu {
|
|
|
1775
2142
|
}
|
|
1776
2143
|
}
|
|
1777
2144
|
const fields = filteredFields.map((f) => {
|
|
1778
|
-
const cfKey =
|
|
2145
|
+
const cfKey = f.api_use_alias && f.alias ? `cf_${f.alias}` : `cf_${f.id}`;
|
|
1779
2146
|
let displayName = f.name || cfKey;
|
|
1780
2147
|
let fieldType = 'string';
|
|
1781
2148
|
let fieldOptions;
|
|
@@ -1797,7 +2164,9 @@ class Flowlu {
|
|
|
1797
2164
|
.filter((o) => o.value)
|
|
1798
2165
|
.map((o) => ({ name: o.value, value: o.id?.toString() || o.value }));
|
|
1799
2166
|
}
|
|
1800
|
-
catch {
|
|
2167
|
+
catch {
|
|
2168
|
+
/* ignore parse errors */
|
|
2169
|
+
}
|
|
1801
2170
|
}
|
|
1802
2171
|
// Link fields - use dropdown with fetched options
|
|
1803
2172
|
if (f.type === 'model.any' && f.module && f.model) {
|
|
@@ -1806,12 +2175,12 @@ class Flowlu {
|
|
|
1806
2175
|
displayName = `${f.name} → ${linkLabels[key]}`;
|
|
1807
2176
|
}
|
|
1808
2177
|
else if (f.module === 'customlists' && f.model === 'items' && f.group_id) {
|
|
1809
|
-
const targetList = allFieldsets.find((fs) => fs.module === 'customlists' &&
|
|
2178
|
+
const targetList = allFieldsets.find((fs) => fs.module === 'customlists' &&
|
|
2179
|
+
fs.model === 'items' &&
|
|
2180
|
+
fs.group_id?.toString() === f.group_id.toString());
|
|
1810
2181
|
displayName = `${f.name} → ${targetList?.name || `List #${f.group_id}`}`;
|
|
1811
2182
|
}
|
|
1812
|
-
const cacheKey =
|
|
1813
|
-
? `customlists/${f.group_id}`
|
|
1814
|
-
: key;
|
|
2183
|
+
const cacheKey = f.module === 'customlists' && f.model === 'items' && f.group_id ? `customlists/${f.group_id}` : key;
|
|
1815
2184
|
if (linkOptionsCache[cacheKey]?.length) {
|
|
1816
2185
|
fieldType = 'options';
|
|
1817
2186
|
fieldOptions = linkOptionsCache[cacheKey];
|
|
@@ -1869,15 +2238,32 @@ class Flowlu {
|
|
|
1869
2238
|
body.phone = phone;
|
|
1870
2239
|
const additional = this.getNodeParameter('contactAdditionalFields', i);
|
|
1871
2240
|
const contactSimpleFields = [
|
|
1872
|
-
'middle_name',
|
|
1873
|
-
'
|
|
1874
|
-
'
|
|
1875
|
-
'
|
|
1876
|
-
'
|
|
1877
|
-
'
|
|
1878
|
-
'
|
|
1879
|
-
'
|
|
1880
|
-
'
|
|
2241
|
+
'middle_name',
|
|
2242
|
+
'description',
|
|
2243
|
+
'owner_id',
|
|
2244
|
+
'web',
|
|
2245
|
+
'phone2',
|
|
2246
|
+
'phone3',
|
|
2247
|
+
'email_personal',
|
|
2248
|
+
'social_network_link_1',
|
|
2249
|
+
'social_network_link_2',
|
|
2250
|
+
'social_network_link_3',
|
|
2251
|
+
'social_network_link_4',
|
|
2252
|
+
'social_network_link_5',
|
|
2253
|
+
'social_network_link_6',
|
|
2254
|
+
'address',
|
|
2255
|
+
'shipping_address_line_1',
|
|
2256
|
+
'shipping_city',
|
|
2257
|
+
'shipping_state',
|
|
2258
|
+
'shipping_zip',
|
|
2259
|
+
'shipping_country',
|
|
2260
|
+
'billing_address_line_1',
|
|
2261
|
+
'billing_city',
|
|
2262
|
+
'billing_state',
|
|
2263
|
+
'billing_zip',
|
|
2264
|
+
'billing_country',
|
|
2265
|
+
'VAT',
|
|
2266
|
+
'timezone',
|
|
1881
2267
|
];
|
|
1882
2268
|
for (const field of contactSimpleFields) {
|
|
1883
2269
|
if (additional[field] !== undefined && additional[field] !== '') {
|
|
@@ -1910,7 +2296,7 @@ class Flowlu {
|
|
|
1910
2296
|
if (filters.owner_id)
|
|
1911
2297
|
qs['filter[owner_id]'] = filters.owner_id;
|
|
1912
2298
|
responseData = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/crm/account/list', apiKey, undefined, qs);
|
|
1913
|
-
for (const item of
|
|
2299
|
+
for (const item of responseData?.response?.items || []) {
|
|
1914
2300
|
returnData.push({ json: item });
|
|
1915
2301
|
}
|
|
1916
2302
|
continue;
|
|
@@ -1920,13 +2306,25 @@ class Flowlu {
|
|
|
1920
2306
|
const updateFields = this.getNodeParameter('contactUpdateFields', i);
|
|
1921
2307
|
const body = { id };
|
|
1922
2308
|
const contactUpdateSimpleFields = [
|
|
1923
|
-
'first_name',
|
|
1924
|
-
'
|
|
2309
|
+
'first_name',
|
|
2310
|
+
'last_name',
|
|
2311
|
+
'middle_name',
|
|
2312
|
+
'email',
|
|
2313
|
+
'phone',
|
|
2314
|
+
'phone2',
|
|
2315
|
+
'phone3',
|
|
2316
|
+
'description',
|
|
2317
|
+
'owner_id',
|
|
2318
|
+
'web',
|
|
1925
2319
|
'email_personal',
|
|
1926
|
-
'social_network_link_1',
|
|
1927
|
-
'
|
|
1928
|
-
'
|
|
1929
|
-
'
|
|
2320
|
+
'social_network_link_1',
|
|
2321
|
+
'social_network_link_2',
|
|
2322
|
+
'social_network_link_3',
|
|
2323
|
+
'social_network_link_4',
|
|
2324
|
+
'social_network_link_5',
|
|
2325
|
+
'social_network_link_6',
|
|
2326
|
+
'address',
|
|
2327
|
+
'VAT',
|
|
1930
2328
|
];
|
|
1931
2329
|
for (const field of contactUpdateSimpleFields) {
|
|
1932
2330
|
if (updateFields[field] !== undefined && updateFields[field] !== '') {
|
|
@@ -1962,9 +2360,16 @@ class Flowlu {
|
|
|
1962
2360
|
body.assignee_id = assignee;
|
|
1963
2361
|
const additional = this.getNodeParameter('opportunityAdditionalFields', i);
|
|
1964
2362
|
const oppSimpleFields = [
|
|
1965
|
-
'budget',
|
|
1966
|
-
'
|
|
1967
|
-
'
|
|
2363
|
+
'budget',
|
|
2364
|
+
'description',
|
|
2365
|
+
'contact_name',
|
|
2366
|
+
'contact_email',
|
|
2367
|
+
'contact_phone',
|
|
2368
|
+
'contact_mobile',
|
|
2369
|
+
'contact_company',
|
|
2370
|
+
'contact_position',
|
|
2371
|
+
'contact_web',
|
|
2372
|
+
'source_id',
|
|
1968
2373
|
];
|
|
1969
2374
|
for (const field of oppSimpleFields) {
|
|
1970
2375
|
if (additional[field] !== undefined && additional[field] !== '') {
|
|
@@ -2022,7 +2427,7 @@ class Flowlu {
|
|
|
2022
2427
|
if (filters.active !== undefined)
|
|
2023
2428
|
qs['filter[active]'] = filters.active.toString();
|
|
2024
2429
|
responseData = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/crm/lead/list', apiKey, undefined, qs);
|
|
2025
|
-
for (const item of
|
|
2430
|
+
for (const item of responseData?.response?.items || []) {
|
|
2026
2431
|
returnData.push({ json: item });
|
|
2027
2432
|
}
|
|
2028
2433
|
continue;
|
|
@@ -2032,9 +2437,17 @@ class Flowlu {
|
|
|
2032
2437
|
const updateFields = this.getNodeParameter('opportunityUpdateFields', i);
|
|
2033
2438
|
const body = { id };
|
|
2034
2439
|
const oppUpdateFields = [
|
|
2035
|
-
'name',
|
|
2036
|
-
'
|
|
2037
|
-
'
|
|
2440
|
+
'name',
|
|
2441
|
+
'pipeline_id',
|
|
2442
|
+
'pipeline_stage_id',
|
|
2443
|
+
'assignee_id',
|
|
2444
|
+
'budget',
|
|
2445
|
+
'description',
|
|
2446
|
+
'active',
|
|
2447
|
+
'closing_comment',
|
|
2448
|
+
'contact_name',
|
|
2449
|
+
'contact_email',
|
|
2450
|
+
'contact_phone',
|
|
2038
2451
|
];
|
|
2039
2452
|
for (const field of oppUpdateFields) {
|
|
2040
2453
|
if (updateFields[field] !== undefined && updateFields[field] !== '') {
|
|
@@ -2077,9 +2490,16 @@ class Flowlu {
|
|
|
2077
2490
|
body.description = desc;
|
|
2078
2491
|
const additional = this.getNodeParameter('projectAdditionalFields', i);
|
|
2079
2492
|
const projSimpleFields = [
|
|
2080
|
-
'priority',
|
|
2081
|
-
'
|
|
2082
|
-
'
|
|
2493
|
+
'priority',
|
|
2494
|
+
'estimated_revenue',
|
|
2495
|
+
'estimated_expenses',
|
|
2496
|
+
'customer_id',
|
|
2497
|
+
'customer_crm_contact_id',
|
|
2498
|
+
'briefcase_id',
|
|
2499
|
+
'stage_id',
|
|
2500
|
+
'tasks_workflow_id',
|
|
2501
|
+
'billing_type',
|
|
2502
|
+
'crm_lead_id',
|
|
2083
2503
|
];
|
|
2084
2504
|
for (const field of projSimpleFields) {
|
|
2085
2505
|
if (additional[field] !== undefined && additional[field] !== '' && additional[field] !== 0) {
|
|
@@ -2115,7 +2535,7 @@ class Flowlu {
|
|
|
2115
2535
|
if (!filters.is_archive)
|
|
2116
2536
|
qs['filter[is_archive]'] = '0';
|
|
2117
2537
|
responseData = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/st/projects/list', apiKey, undefined, qs);
|
|
2118
|
-
for (const item of
|
|
2538
|
+
for (const item of responseData?.response?.items || []) {
|
|
2119
2539
|
returnData.push({ json: item });
|
|
2120
2540
|
}
|
|
2121
2541
|
continue;
|
|
@@ -2125,8 +2545,13 @@ class Flowlu {
|
|
|
2125
2545
|
const updateFields = this.getNodeParameter('projectUpdateFields', i);
|
|
2126
2546
|
const body = { id };
|
|
2127
2547
|
const projUpdateFields = [
|
|
2128
|
-
'name',
|
|
2129
|
-
'
|
|
2548
|
+
'name',
|
|
2549
|
+
'description',
|
|
2550
|
+
'manager_id',
|
|
2551
|
+
'priority',
|
|
2552
|
+
'estimated_revenue',
|
|
2553
|
+
'estimated_expenses',
|
|
2554
|
+
'stage_id',
|
|
2130
2555
|
];
|
|
2131
2556
|
for (const field of projUpdateFields) {
|
|
2132
2557
|
if (updateFields[field] !== undefined && updateFields[field] !== '') {
|
|
@@ -2179,7 +2604,7 @@ class Flowlu {
|
|
|
2179
2604
|
if (filters.search)
|
|
2180
2605
|
qs['search'] = filters.search;
|
|
2181
2606
|
responseData = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/customlists/items/list', apiKey, undefined, qs);
|
|
2182
|
-
for (const item of
|
|
2607
|
+
for (const item of responseData?.response?.items || []) {
|
|
2183
2608
|
returnData.push({ json: item });
|
|
2184
2609
|
}
|
|
2185
2610
|
continue;
|
|
@@ -2278,7 +2703,7 @@ class Flowlu {
|
|
|
2278
2703
|
if (filters.status !== undefined)
|
|
2279
2704
|
qs['filter[status]'] = filters.status.toString();
|
|
2280
2705
|
responseData = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/task/tasks/list', apiKey, undefined, qs);
|
|
2281
|
-
for (const item of
|
|
2706
|
+
for (const item of responseData?.response?.items || []) {
|
|
2282
2707
|
returnData.push({ json: item });
|
|
2283
2708
|
}
|
|
2284
2709
|
continue;
|
|
@@ -2349,14 +2774,14 @@ class Flowlu {
|
|
|
2349
2774
|
const entityType = this.getNodeParameter('tagEntityType', i);
|
|
2350
2775
|
const entityId = this.getNodeParameter('tagEntityId', i);
|
|
2351
2776
|
responseData = await flowluApiRequest.call(this, 'GET', baseUrl, `/api/v1/module/${entityType}/${entityId}/global_tags/list`, apiKey);
|
|
2352
|
-
for (const item of
|
|
2777
|
+
for (const item of responseData?.response?.items || []) {
|
|
2353
2778
|
returnData.push({ json: item });
|
|
2354
2779
|
}
|
|
2355
2780
|
continue;
|
|
2356
2781
|
}
|
|
2357
2782
|
else if (operation === 'listAll') {
|
|
2358
2783
|
responseData = await flowluApiRequest.call(this, 'GET', baseUrl, '/api/v1/module/core/tag/list', apiKey);
|
|
2359
|
-
for (const item of
|
|
2784
|
+
for (const item of responseData?.response?.items || []) {
|
|
2360
2785
|
returnData.push({ json: item });
|
|
2361
2786
|
}
|
|
2362
2787
|
continue;
|
|
@@ -2387,7 +2812,7 @@ class Flowlu {
|
|
|
2387
2812
|
const entityId = this.getNodeParameter('commentEntityId', i);
|
|
2388
2813
|
const limit = this.getNodeParameter('limit', i);
|
|
2389
2814
|
responseData = await flowluApiRequest.call(this, 'GET', baseUrl, `/api/v1/module/${entityType}/${entityId}/comments/list`, apiKey, undefined, { limit: limit.toString() });
|
|
2390
|
-
for (const item of
|
|
2815
|
+
for (const item of responseData?.response?.items || []) {
|
|
2391
2816
|
returnData.push({ json: item });
|
|
2392
2817
|
}
|
|
2393
2818
|
continue;
|