@connectorx/n8n-nodes-cortex 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/dist/credentials/CortexApi.credentials.js +3 -3
- package/dist/nodes/Cortex/Cortex.node.js +212 -138
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# n8n-nodes-cortex
|
|
2
|
+
|
|
3
|
+
This is an n8n Community Node for interacting with the **Cortex API**. It allows you to send messages, manage conversations, and interact with Kanban resources within your Cortex environment.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Authentication**: Supports standard Cortex User Tokens and API Tokens.
|
|
8
|
+
- **Dynamic Tenant Selection**: Automatically fetches accessible tenants.
|
|
9
|
+
- **User Tokens**: Lists all tenants the user has access to.
|
|
10
|
+
- **API Tokens**: Automatically detects the single tenant associated with the token.
|
|
11
|
+
- **Resources**:
|
|
12
|
+
- **Message**: Send text, media, notes, and reactions.
|
|
13
|
+
- **Conversation**: Update conversation status, owner, and column.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
You can install this node directly in n8n via **Settings > Community Nodes**.
|
|
18
|
+
|
|
19
|
+
**Package Name**: `@connectorx/n8n-nodes-cortex`
|
|
20
|
+
|
|
21
|
+
## Credentials
|
|
22
|
+
|
|
23
|
+
1. **Base URL**: The URL to your Cortex API functions (e.g., `https://your-project.supabase.co/functions/v1/api`).
|
|
24
|
+
2. **Access Token**: Your Cortex JWT or API Token (`cortex_...`).
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### Tenant Selection
|
|
29
|
+
The node requires you to select a **Tenant** to interact with.
|
|
30
|
+
- If you use a **User Token**, the dropdown will populate with all your tenants.
|
|
31
|
+
- If you use an **API Token** (`cortex_...`), the dropdown will automatically show the specific tenant bound to that token.
|
|
32
|
+
|
|
33
|
+
### Operations
|
|
34
|
+
- **Send Message**: Supports various types (Text, Image, Video, Audio, Document, Voice, Note, Reaction).
|
|
35
|
+
- **Update Conversation**: Move cards between columns, change owners, or update status (Open/Closed/Snoozed).
|
|
@@ -11,11 +11,11 @@ class CortexApi {
|
|
|
11
11
|
name: 'apiBaseUrl',
|
|
12
12
|
type: 'string',
|
|
13
13
|
default: 'https://api.your-cortex-instance.com',
|
|
14
|
-
description: 'The base URL of the Cortex API (e.g. https://your-project.supabase.co/functions/v1/api)
|
|
14
|
+
description: 'The base URL of the Cortex Integration API (e.g. https://your-project.supabase.co/functions/v1/api/integrations)',
|
|
15
15
|
required: true,
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
|
-
displayName: '
|
|
18
|
+
displayName: 'API Token',
|
|
19
19
|
name: 'accessToken',
|
|
20
20
|
type: 'string',
|
|
21
21
|
typeOptions: {
|
|
@@ -29,7 +29,7 @@ class CortexApi {
|
|
|
29
29
|
this.test = {
|
|
30
30
|
request: {
|
|
31
31
|
baseURL: '={{$credentials.apiBaseUrl.replace(/\\/$/, "")}}',
|
|
32
|
-
url: '/
|
|
32
|
+
url: '/validate',
|
|
33
33
|
method: 'GET',
|
|
34
34
|
headers: {
|
|
35
35
|
Authorization: '={{ "Bearer " + $credentials.accessToken }}',
|
|
@@ -4,7 +4,7 @@ exports.Cortex = void 0;
|
|
|
4
4
|
class Cortex {
|
|
5
5
|
constructor() {
|
|
6
6
|
this.description = {
|
|
7
|
-
displayName: 'Cortex
|
|
7
|
+
displayName: 'Cortex',
|
|
8
8
|
name: 'cortex',
|
|
9
9
|
icon: 'file:cortex.png',
|
|
10
10
|
group: ['input'],
|
|
@@ -37,20 +37,13 @@ class Cortex {
|
|
|
37
37
|
name: 'Conversation',
|
|
38
38
|
value: 'conversation',
|
|
39
39
|
},
|
|
40
|
+
{
|
|
41
|
+
name: 'Contact',
|
|
42
|
+
value: 'contact',
|
|
43
|
+
},
|
|
40
44
|
],
|
|
41
45
|
default: 'message',
|
|
42
46
|
},
|
|
43
|
-
{
|
|
44
|
-
displayName: 'Tenant Name',
|
|
45
|
-
name: 'tenantId',
|
|
46
|
-
type: 'options',
|
|
47
|
-
typeOptions: {
|
|
48
|
-
loadOptionsMethod: 'getTenants',
|
|
49
|
-
},
|
|
50
|
-
default: '',
|
|
51
|
-
required: true,
|
|
52
|
-
description: 'The Tenant to interact with',
|
|
53
|
-
},
|
|
54
47
|
{
|
|
55
48
|
displayName: 'Operation',
|
|
56
49
|
name: 'operation',
|
|
@@ -58,21 +51,19 @@ class Cortex {
|
|
|
58
51
|
noDataExpression: true,
|
|
59
52
|
displayOptions: {
|
|
60
53
|
show: {
|
|
61
|
-
resource: [
|
|
62
|
-
'message',
|
|
63
|
-
],
|
|
54
|
+
resource: ['message'],
|
|
64
55
|
},
|
|
65
56
|
},
|
|
66
57
|
options: [
|
|
67
58
|
{
|
|
68
59
|
name: 'Send',
|
|
69
60
|
value: 'send',
|
|
70
|
-
description: 'Send a message (Text, Media,
|
|
61
|
+
description: 'Send a message (Text, Media, Template, etc.)',
|
|
71
62
|
},
|
|
72
63
|
{
|
|
73
64
|
name: 'Send Typing',
|
|
74
65
|
value: 'sendTyping',
|
|
75
|
-
description: 'Send a typing indicator',
|
|
66
|
+
description: 'Send a typing/recording indicator',
|
|
76
67
|
},
|
|
77
68
|
],
|
|
78
69
|
default: 'send',
|
|
@@ -84,98 +75,90 @@ class Cortex {
|
|
|
84
75
|
noDataExpression: true,
|
|
85
76
|
displayOptions: {
|
|
86
77
|
show: {
|
|
87
|
-
resource: [
|
|
88
|
-
'conversation',
|
|
89
|
-
],
|
|
78
|
+
resource: ['conversation'],
|
|
90
79
|
},
|
|
91
80
|
},
|
|
92
81
|
options: [
|
|
93
82
|
{
|
|
94
83
|
name: 'Update',
|
|
95
84
|
value: 'update',
|
|
96
|
-
description: '
|
|
85
|
+
description: 'Move column or assign owner',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'Get History',
|
|
89
|
+
value: 'getHistory',
|
|
90
|
+
description: 'Get conversation message history',
|
|
97
91
|
},
|
|
98
92
|
],
|
|
99
93
|
default: 'update',
|
|
100
94
|
},
|
|
101
95
|
{
|
|
102
|
-
displayName: '
|
|
103
|
-
name: '
|
|
104
|
-
type: 'string',
|
|
105
|
-
default: '',
|
|
106
|
-
required: true,
|
|
107
|
-
description: 'The Conversation ID',
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
displayName: 'Message Type',
|
|
111
|
-
name: 'msg_type',
|
|
96
|
+
displayName: 'Operation',
|
|
97
|
+
name: 'operation',
|
|
112
98
|
type: 'options',
|
|
99
|
+
noDataExpression: true,
|
|
113
100
|
displayOptions: {
|
|
114
101
|
show: {
|
|
115
|
-
resource: ['
|
|
116
|
-
operation: ['send'],
|
|
102
|
+
resource: ['contact'],
|
|
117
103
|
},
|
|
118
104
|
},
|
|
119
105
|
options: [
|
|
120
|
-
{
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
106
|
+
{
|
|
107
|
+
name: 'Get',
|
|
108
|
+
value: 'get',
|
|
109
|
+
description: 'Get contact details',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'Update',
|
|
113
|
+
value: 'update',
|
|
114
|
+
description: 'Update contact fields (name, email, tags, custom_data)',
|
|
115
|
+
},
|
|
128
116
|
],
|
|
129
|
-
default: '
|
|
117
|
+
default: 'get',
|
|
130
118
|
},
|
|
131
119
|
{
|
|
132
|
-
displayName: '
|
|
133
|
-
name: '
|
|
120
|
+
displayName: 'Conversation ID',
|
|
121
|
+
name: 'conversationId',
|
|
134
122
|
type: 'string',
|
|
123
|
+
required: true,
|
|
135
124
|
displayOptions: {
|
|
136
125
|
show: {
|
|
137
|
-
resource: ['message'],
|
|
138
|
-
operation: ['send'],
|
|
139
|
-
},
|
|
140
|
-
hide: {
|
|
141
|
-
msg_type: ['reaction'],
|
|
126
|
+
resource: ['message', 'conversation'],
|
|
142
127
|
},
|
|
143
128
|
},
|
|
144
129
|
default: '',
|
|
145
|
-
description: '
|
|
130
|
+
description: 'The UUID of the conversation',
|
|
146
131
|
},
|
|
147
132
|
{
|
|
148
|
-
displayName: '
|
|
149
|
-
name: '
|
|
133
|
+
displayName: 'Contact ID',
|
|
134
|
+
name: 'contactId',
|
|
150
135
|
type: 'string',
|
|
136
|
+
required: true,
|
|
151
137
|
displayOptions: {
|
|
152
138
|
show: {
|
|
153
|
-
resource: ['
|
|
154
|
-
operation: ['send'],
|
|
155
|
-
msg_type: ['reaction'],
|
|
139
|
+
resource: ['contact'],
|
|
156
140
|
},
|
|
157
141
|
},
|
|
158
142
|
default: '',
|
|
159
|
-
|
|
160
|
-
description: 'ID of the message to react to',
|
|
143
|
+
description: 'The UUID of the contact',
|
|
161
144
|
},
|
|
162
145
|
{
|
|
163
|
-
displayName: '
|
|
146
|
+
displayName: 'Content (Text, URL, or Template JSON)',
|
|
164
147
|
name: 'content',
|
|
165
148
|
type: 'string',
|
|
149
|
+
required: true,
|
|
166
150
|
displayOptions: {
|
|
167
151
|
show: {
|
|
168
152
|
resource: ['message'],
|
|
169
153
|
operation: ['send'],
|
|
170
|
-
msg_type: ['reaction'],
|
|
171
154
|
},
|
|
172
155
|
},
|
|
173
156
|
default: '',
|
|
174
|
-
description: '
|
|
157
|
+
description: 'Message text, media URL, or JSON string for templates',
|
|
175
158
|
},
|
|
176
159
|
{
|
|
177
|
-
displayName: '
|
|
178
|
-
name: '
|
|
160
|
+
displayName: 'Message Type',
|
|
161
|
+
name: 'msg_type',
|
|
179
162
|
type: 'options',
|
|
180
163
|
displayOptions: {
|
|
181
164
|
show: {
|
|
@@ -184,10 +167,17 @@ class Cortex {
|
|
|
184
167
|
},
|
|
185
168
|
},
|
|
186
169
|
options: [
|
|
187
|
-
{ name: '
|
|
188
|
-
{ name: '
|
|
170
|
+
{ name: 'Text', value: 'text' },
|
|
171
|
+
{ name: 'Image', value: 'image' },
|
|
172
|
+
{ name: 'Video', value: 'video' },
|
|
173
|
+
{ name: 'Audio', value: 'audio' },
|
|
174
|
+
{ name: 'Document', value: 'document' },
|
|
175
|
+
{ name: 'Voice', value: 'voice' },
|
|
176
|
+
{ name: 'Internal Note', value: 'internal_note' },
|
|
177
|
+
{ name: 'Template', value: 'template' },
|
|
178
|
+
{ name: 'Reaction', value: 'reaction' },
|
|
189
179
|
],
|
|
190
|
-
default: '
|
|
180
|
+
default: 'text',
|
|
191
181
|
},
|
|
192
182
|
{
|
|
193
183
|
displayName: 'Sender ID',
|
|
@@ -200,7 +190,21 @@ class Cortex {
|
|
|
200
190
|
},
|
|
201
191
|
},
|
|
202
192
|
default: '',
|
|
203
|
-
description: '
|
|
193
|
+
description: 'Optional sender identifier (defaults to "agent")',
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
displayName: 'React to Message ID',
|
|
197
|
+
name: 'react_to_message_id',
|
|
198
|
+
type: 'string',
|
|
199
|
+
displayOptions: {
|
|
200
|
+
show: {
|
|
201
|
+
resource: ['message'],
|
|
202
|
+
operation: ['send'],
|
|
203
|
+
msg_type: ['reaction'],
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
default: '',
|
|
207
|
+
description: 'UUID of the message to react to',
|
|
204
208
|
},
|
|
205
209
|
{
|
|
206
210
|
displayName: 'Reply To Message ID',
|
|
@@ -213,10 +217,10 @@ class Cortex {
|
|
|
213
217
|
},
|
|
214
218
|
hide: {
|
|
215
219
|
msg_type: ['reaction'],
|
|
216
|
-
}
|
|
220
|
+
},
|
|
217
221
|
},
|
|
218
222
|
default: '',
|
|
219
|
-
description: '
|
|
223
|
+
description: 'UUID of the message to reply to',
|
|
220
224
|
},
|
|
221
225
|
{
|
|
222
226
|
displayName: 'Status',
|
|
@@ -230,7 +234,8 @@ class Cortex {
|
|
|
230
234
|
},
|
|
231
235
|
options: [
|
|
232
236
|
{ name: 'Typing', value: 'typing' },
|
|
233
|
-
{ name: '
|
|
237
|
+
{ name: 'Recording', value: 'recording' },
|
|
238
|
+
{ name: 'Stopped', value: 'stopped' },
|
|
234
239
|
],
|
|
235
240
|
default: 'typing',
|
|
236
241
|
},
|
|
@@ -240,7 +245,6 @@ class Cortex {
|
|
|
240
245
|
type: 'options',
|
|
241
246
|
typeOptions: {
|
|
242
247
|
loadOptionsMethod: 'getColumns',
|
|
243
|
-
loadOptionsDependsOn: ['tenantId'],
|
|
244
248
|
},
|
|
245
249
|
displayOptions: {
|
|
246
250
|
show: {
|
|
@@ -257,7 +261,6 @@ class Cortex {
|
|
|
257
261
|
type: 'options',
|
|
258
262
|
typeOptions: {
|
|
259
263
|
loadOptionsMethod: 'getUsers',
|
|
260
|
-
loadOptionsDependsOn: ['tenantId'],
|
|
261
264
|
},
|
|
262
265
|
displayOptions: {
|
|
263
266
|
show: {
|
|
@@ -269,71 +272,109 @@ class Cortex {
|
|
|
269
272
|
description: 'New Owner ID. Leave empty to keep current.',
|
|
270
273
|
},
|
|
271
274
|
{
|
|
272
|
-
displayName: '
|
|
273
|
-
name: '
|
|
274
|
-
type: '
|
|
275
|
+
displayName: 'Limit',
|
|
276
|
+
name: 'limit',
|
|
277
|
+
type: 'number',
|
|
275
278
|
displayOptions: {
|
|
276
279
|
show: {
|
|
277
280
|
resource: ['conversation'],
|
|
281
|
+
operation: ['getHistory'],
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
typeOptions: {
|
|
285
|
+
minValue: 1,
|
|
286
|
+
maxValue: 100,
|
|
287
|
+
},
|
|
288
|
+
default: 20,
|
|
289
|
+
description: 'How many messages to retrieve',
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
displayName: 'Before (ISO Timestamp)',
|
|
293
|
+
name: 'before',
|
|
294
|
+
type: 'dateTime',
|
|
295
|
+
displayOptions: {
|
|
296
|
+
show: {
|
|
297
|
+
resource: ['conversation'],
|
|
298
|
+
operation: ['getHistory'],
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
default: '',
|
|
302
|
+
description: 'Timestamp for pagination',
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
displayName: 'Name',
|
|
306
|
+
name: 'contactName',
|
|
307
|
+
type: 'string',
|
|
308
|
+
displayOptions: {
|
|
309
|
+
show: {
|
|
310
|
+
resource: ['contact'],
|
|
278
311
|
operation: ['update'],
|
|
279
312
|
},
|
|
280
313
|
},
|
|
281
|
-
options: [
|
|
282
|
-
{ name: 'No Change', value: '' },
|
|
283
|
-
{ name: 'Open', value: 'open' },
|
|
284
|
-
{ name: 'Closed', value: 'closed' },
|
|
285
|
-
{ name: 'Snoozed', value: 'snoozed' },
|
|
286
|
-
],
|
|
287
314
|
default: '',
|
|
288
|
-
description: '
|
|
315
|
+
description: 'Updated contact name',
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
displayName: 'Email',
|
|
319
|
+
name: 'contactEmail',
|
|
320
|
+
type: 'string',
|
|
321
|
+
displayOptions: {
|
|
322
|
+
show: {
|
|
323
|
+
resource: ['contact'],
|
|
324
|
+
operation: ['update'],
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
default: '',
|
|
328
|
+
description: 'Updated contact email',
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
displayName: 'Tags (Comma Separated)',
|
|
332
|
+
name: 'contactTags',
|
|
333
|
+
type: 'string',
|
|
334
|
+
displayOptions: {
|
|
335
|
+
show: {
|
|
336
|
+
resource: ['contact'],
|
|
337
|
+
operation: ['update'],
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
default: '',
|
|
341
|
+
description: 'List of tags separated by commas',
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
displayName: 'Custom Data (JSON)',
|
|
345
|
+
name: 'contactCustomData',
|
|
346
|
+
type: 'string',
|
|
347
|
+
displayOptions: {
|
|
348
|
+
show: {
|
|
349
|
+
resource: ['contact'],
|
|
350
|
+
operation: ['update'],
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
default: '',
|
|
354
|
+
description: 'Custom properties in JSON format',
|
|
289
355
|
},
|
|
290
356
|
],
|
|
291
357
|
};
|
|
292
358
|
this.methods = {
|
|
293
359
|
loadOptions: {
|
|
294
|
-
async getTenants() {
|
|
295
|
-
const credentials = await this.getCredentials('cortexApi');
|
|
296
|
-
const baseUrl = credentials.apiBaseUrl.replace(/\/$/, '');
|
|
297
|
-
const options = {
|
|
298
|
-
headers: {
|
|
299
|
-
'Content-Type': 'application/json',
|
|
300
|
-
'Authorization': `Bearer ${credentials.accessToken}`,
|
|
301
|
-
},
|
|
302
|
-
method: 'GET',
|
|
303
|
-
uri: `${baseUrl}/user-tenants`,
|
|
304
|
-
json: true,
|
|
305
|
-
};
|
|
306
|
-
try {
|
|
307
|
-
const response = await this.helpers.request(options);
|
|
308
|
-
return response.map((t) => ({
|
|
309
|
-
name: t.name || t.tenant_id,
|
|
310
|
-
value: t.tenant_id
|
|
311
|
-
}));
|
|
312
|
-
}
|
|
313
|
-
catch (error) {
|
|
314
|
-
console.error('getTenants error:', error);
|
|
315
|
-
return [];
|
|
316
|
-
}
|
|
317
|
-
},
|
|
318
360
|
async getColumns() {
|
|
319
361
|
const credentials = await this.getCredentials('cortexApi');
|
|
320
362
|
const baseUrl = credentials.apiBaseUrl.replace(/\/$/, '');
|
|
321
|
-
const tenantId = this.getNodeParameter('tenantId');
|
|
322
|
-
if (!tenantId) {
|
|
323
|
-
return [];
|
|
324
|
-
}
|
|
325
363
|
const options = {
|
|
326
364
|
headers: {
|
|
327
365
|
'Content-Type': 'application/json',
|
|
328
366
|
'Authorization': `Bearer ${credentials.accessToken}`,
|
|
329
367
|
},
|
|
330
368
|
method: 'GET',
|
|
331
|
-
uri: `${baseUrl}/
|
|
369
|
+
uri: `${baseUrl}/columns`,
|
|
332
370
|
json: true,
|
|
333
371
|
};
|
|
334
372
|
try {
|
|
335
373
|
const response = await this.helpers.request(options);
|
|
336
|
-
return response
|
|
374
|
+
return response.map((c) => ({
|
|
375
|
+
name: c.name || c.id,
|
|
376
|
+
value: c.id
|
|
377
|
+
}));
|
|
337
378
|
}
|
|
338
379
|
catch (error) {
|
|
339
380
|
return [];
|
|
@@ -342,24 +383,20 @@ class Cortex {
|
|
|
342
383
|
async getUsers() {
|
|
343
384
|
const credentials = await this.getCredentials('cortexApi');
|
|
344
385
|
const baseUrl = credentials.apiBaseUrl.replace(/\/$/, '');
|
|
345
|
-
const tenantId = this.getNodeParameter('tenantId');
|
|
346
|
-
if (!tenantId) {
|
|
347
|
-
return [];
|
|
348
|
-
}
|
|
349
386
|
const options = {
|
|
350
387
|
headers: {
|
|
351
388
|
'Content-Type': 'application/json',
|
|
352
389
|
'Authorization': `Bearer ${credentials.accessToken}`,
|
|
353
390
|
},
|
|
354
391
|
method: 'GET',
|
|
355
|
-
uri: `${baseUrl}/
|
|
392
|
+
uri: `${baseUrl}/users`,
|
|
356
393
|
json: true,
|
|
357
394
|
};
|
|
358
395
|
try {
|
|
359
396
|
const response = await this.helpers.request(options);
|
|
360
397
|
return response.map((u) => ({
|
|
361
|
-
name: u.name || u.
|
|
362
|
-
value: u.
|
|
398
|
+
name: u.name || u.email || u.id,
|
|
399
|
+
value: u.id
|
|
363
400
|
}));
|
|
364
401
|
}
|
|
365
402
|
catch (error) {
|
|
@@ -378,9 +415,6 @@ class Cortex {
|
|
|
378
415
|
const baseUrl = credentials.apiBaseUrl.replace(/\/$/, '');
|
|
379
416
|
for (let i = 0; i < items.length; i++) {
|
|
380
417
|
try {
|
|
381
|
-
const tenantId = this.getNodeParameter('tenantId', i);
|
|
382
|
-
const conversationId = this.getNodeParameter('conversation_id', i);
|
|
383
|
-
let responseData;
|
|
384
418
|
const options = {
|
|
385
419
|
headers: {
|
|
386
420
|
'Content-Type': 'application/json',
|
|
@@ -388,60 +422,100 @@ class Cortex {
|
|
|
388
422
|
},
|
|
389
423
|
method: 'POST',
|
|
390
424
|
uri: '',
|
|
391
|
-
body: {},
|
|
392
425
|
json: true,
|
|
393
426
|
};
|
|
394
427
|
if (resource === 'message') {
|
|
428
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
395
429
|
if (operation === 'send') {
|
|
396
|
-
options.method = 'POST';
|
|
397
430
|
options.uri = `${baseUrl}/messages/send`;
|
|
398
|
-
const msgType = this.getNodeParameter('msg_type', i);
|
|
399
431
|
const content = this.getNodeParameter('content', i);
|
|
400
|
-
const
|
|
432
|
+
const msgType = this.getNodeParameter('msg_type', i);
|
|
401
433
|
const senderId = this.getNodeParameter('sender_id', i);
|
|
402
434
|
const replyTo = this.getNodeParameter('reply_to_message_id', i);
|
|
403
435
|
const reactTo = this.getNodeParameter('react_to_message_id', i);
|
|
404
436
|
const body = {
|
|
405
437
|
conversation_id: conversationId,
|
|
406
|
-
|
|
438
|
+
content: content,
|
|
407
439
|
type: msgType,
|
|
408
|
-
sender_type: senderType,
|
|
409
440
|
};
|
|
410
|
-
if (content)
|
|
411
|
-
body.content = content;
|
|
412
441
|
if (senderId)
|
|
413
442
|
body.sender_id = senderId;
|
|
414
|
-
if (replyTo
|
|
443
|
+
if (replyTo)
|
|
415
444
|
body.reply_to_message_id = replyTo;
|
|
416
445
|
if (msgType === 'reaction' && reactTo)
|
|
417
446
|
body.react_to_message_id = reactTo;
|
|
418
447
|
options.body = body;
|
|
419
448
|
}
|
|
420
449
|
else if (operation === 'sendTyping') {
|
|
421
|
-
options.method = 'POST';
|
|
422
450
|
options.uri = `${baseUrl}/messages/typing`;
|
|
423
451
|
const status = this.getNodeParameter('typing_status', i);
|
|
424
452
|
options.body = {
|
|
425
453
|
conversation_id: conversationId,
|
|
426
|
-
tenant_id: tenantId,
|
|
427
454
|
status: status,
|
|
428
455
|
};
|
|
429
456
|
}
|
|
430
457
|
}
|
|
431
458
|
else if (resource === 'conversation') {
|
|
459
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
432
460
|
if (operation === 'update') {
|
|
433
461
|
options.method = 'PATCH';
|
|
434
|
-
options.uri = `${baseUrl}/
|
|
462
|
+
options.uri = `${baseUrl}/conversations/${conversationId}`;
|
|
435
463
|
const columnId = this.getNodeParameter('column_id', i);
|
|
436
464
|
const ownerId = this.getNodeParameter('owner_id', i);
|
|
437
|
-
const status = this.getNodeParameter('status', i);
|
|
438
465
|
const body = {};
|
|
439
466
|
if (columnId)
|
|
440
467
|
body.column_id = columnId;
|
|
441
468
|
if (ownerId)
|
|
442
469
|
body.owner_id = ownerId;
|
|
443
|
-
if (
|
|
444
|
-
body
|
|
470
|
+
if (Object.keys(body).length > 0) {
|
|
471
|
+
options.body = body;
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
returnData.push({ json: { status: 'no_changes' } });
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
else if (operation === 'getHistory') {
|
|
479
|
+
options.method = 'GET';
|
|
480
|
+
const limit = this.getNodeParameter('limit', i);
|
|
481
|
+
const before = this.getNodeParameter('before', i);
|
|
482
|
+
options.uri = `${baseUrl}/conversations/${conversationId}/messages`;
|
|
483
|
+
options.qs = {
|
|
484
|
+
limit: limit,
|
|
485
|
+
};
|
|
486
|
+
if (before)
|
|
487
|
+
options.qs.before = before;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
else if (resource === 'contact') {
|
|
491
|
+
const contactId = this.getNodeParameter('contactId', i);
|
|
492
|
+
if (operation === 'get') {
|
|
493
|
+
options.method = 'GET';
|
|
494
|
+
options.uri = `${baseUrl}/contacts/${contactId}`;
|
|
495
|
+
}
|
|
496
|
+
else if (operation === 'update') {
|
|
497
|
+
options.method = 'PATCH';
|
|
498
|
+
options.uri = `${baseUrl}/contacts/${contactId}`;
|
|
499
|
+
const name = this.getNodeParameter('contactName', i);
|
|
500
|
+
const email = this.getNodeParameter('contactEmail', i);
|
|
501
|
+
const tagsStr = this.getNodeParameter('contactTags', i);
|
|
502
|
+
const customDataStr = this.getNodeParameter('contactCustomData', i);
|
|
503
|
+
const body = {};
|
|
504
|
+
if (name)
|
|
505
|
+
body.name = name;
|
|
506
|
+
if (email)
|
|
507
|
+
body.email = email;
|
|
508
|
+
if (tagsStr) {
|
|
509
|
+
body.tags = tagsStr.split(',').map(t => t.trim()).filter(t => t);
|
|
510
|
+
}
|
|
511
|
+
if (customDataStr) {
|
|
512
|
+
try {
|
|
513
|
+
body.custom_data = JSON.parse(customDataStr);
|
|
514
|
+
}
|
|
515
|
+
catch (e) {
|
|
516
|
+
throw new Error('Custom Data must be a valid JSON string');
|
|
517
|
+
}
|
|
518
|
+
}
|
|
445
519
|
if (Object.keys(body).length > 0) {
|
|
446
520
|
options.body = body;
|
|
447
521
|
}
|
|
@@ -451,8 +525,8 @@ class Cortex {
|
|
|
451
525
|
}
|
|
452
526
|
}
|
|
453
527
|
}
|
|
454
|
-
responseData = await this.helpers.request(options);
|
|
455
|
-
returnData.push(responseData);
|
|
528
|
+
const responseData = await this.helpers.request(options);
|
|
529
|
+
returnData.push(Array.isArray(responseData) ? { json: responseData } : responseData);
|
|
456
530
|
}
|
|
457
531
|
catch (error) {
|
|
458
532
|
if (this.continueOnFail()) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@connectorx/n8n-nodes-cortex",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "n8n nodes for Cortex API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package"
|
|
@@ -44,4 +44,4 @@
|
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"n8n-workflow": "*"
|
|
46
46
|
}
|
|
47
|
-
}
|
|
47
|
+
}
|