@connectorx/n8n-nodes-cortex 0.1.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.
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CortexApi = void 0;
4
+ class CortexApi {
5
+ constructor() {
6
+ this.name = 'cortexApi';
7
+ this.displayName = 'Cortex API';
8
+ this.properties = [
9
+ {
10
+ displayName: 'API Base URL',
11
+ name: 'apiBaseUrl',
12
+ type: 'string',
13
+ default: 'https://api.your-cortex-instance.com',
14
+ description: 'The base URL of the Cortex API (e.g. https://api.example.com)',
15
+ required: true,
16
+ },
17
+ {
18
+ displayName: 'Access Token',
19
+ name: 'accessToken',
20
+ type: 'string',
21
+ typeOptions: {
22
+ password: true,
23
+ },
24
+ default: '',
25
+ required: true,
26
+ },
27
+ ];
28
+ this.test = {
29
+ request: {
30
+ baseURL: '={{$credentials.apiBaseUrl}}',
31
+ url: '/auth/validate',
32
+ method: 'GET',
33
+ headers: {
34
+ Authorization: '={{ "Bearer " + $credentials.accessToken }}',
35
+ },
36
+ },
37
+ };
38
+ }
39
+ }
40
+ exports.CortexApi = CortexApi;
@@ -0,0 +1,417 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Cortex = void 0;
4
+ class Cortex {
5
+ constructor() {
6
+ this.description = {
7
+ displayName: 'Cortex v1.1',
8
+ name: 'cortex',
9
+ icon: 'file:cortex.png',
10
+ group: ['input'],
11
+ version: 1,
12
+ subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
13
+ description: 'Interact with Cortex API',
14
+ defaults: {
15
+ name: 'Cortex',
16
+ },
17
+ inputs: ['main'],
18
+ outputs: ['main'],
19
+ credentials: [
20
+ {
21
+ name: 'cortexApi',
22
+ required: true,
23
+ },
24
+ ],
25
+ properties: [
26
+ {
27
+ displayName: 'Resource',
28
+ name: 'resource',
29
+ type: 'options',
30
+ noDataExpression: true,
31
+ options: [
32
+ {
33
+ name: 'Message',
34
+ value: 'message',
35
+ },
36
+ {
37
+ name: 'Conversation',
38
+ value: 'conversation',
39
+ },
40
+ ],
41
+ default: 'message',
42
+ },
43
+ {
44
+ displayName: 'Operation',
45
+ name: 'operation',
46
+ type: 'options',
47
+ noDataExpression: true,
48
+ displayOptions: {
49
+ show: {
50
+ resource: [
51
+ 'message',
52
+ ],
53
+ },
54
+ },
55
+ options: [
56
+ {
57
+ name: 'Send',
58
+ value: 'send',
59
+ description: 'Send a message (Text, Media, Note, Reaction)',
60
+ },
61
+ {
62
+ name: 'Send Typing',
63
+ value: 'sendTyping',
64
+ description: 'Send a typing indicator',
65
+ },
66
+ ],
67
+ default: 'send',
68
+ },
69
+ {
70
+ displayName: 'Operation',
71
+ name: 'operation',
72
+ type: 'options',
73
+ noDataExpression: true,
74
+ displayOptions: {
75
+ show: {
76
+ resource: [
77
+ 'conversation',
78
+ ],
79
+ },
80
+ },
81
+ options: [
82
+ {
83
+ name: 'Update',
84
+ value: 'update',
85
+ description: 'Update conversation (Column, Owner, Status)',
86
+ },
87
+ ],
88
+ default: 'update',
89
+ },
90
+ {
91
+ displayName: 'Conversation ID',
92
+ name: 'conversation_id',
93
+ type: 'string',
94
+ default: '',
95
+ required: true,
96
+ description: 'The Conversation ID',
97
+ },
98
+ {
99
+ displayName: 'Message Type',
100
+ name: 'msg_type',
101
+ type: 'options',
102
+ displayOptions: {
103
+ show: {
104
+ resource: ['message'],
105
+ operation: ['send'],
106
+ },
107
+ },
108
+ options: [
109
+ { name: 'Text', value: 'text' },
110
+ { name: 'Image', value: 'image' },
111
+ { name: 'Video', value: 'video' },
112
+ { name: 'Audio', value: 'audio' },
113
+ { name: 'Document', value: 'document' },
114
+ { name: 'Voice', value: 'voice' },
115
+ { name: 'Internal Note', value: 'note' },
116
+ { name: 'Reaction', value: 'reaction' },
117
+ ],
118
+ default: 'text',
119
+ },
120
+ {
121
+ displayName: 'Content (URL or Text)',
122
+ name: 'content',
123
+ type: 'string',
124
+ displayOptions: {
125
+ show: {
126
+ resource: ['message'],
127
+ operation: ['send'],
128
+ },
129
+ hide: {
130
+ msg_type: ['reaction'],
131
+ },
132
+ },
133
+ default: '',
134
+ description: 'Text content or Media URL. For reactions, use the "Emoji" field if separate, or put emoji here.',
135
+ },
136
+ {
137
+ displayName: 'React to Message ID',
138
+ name: 'react_to_message_id',
139
+ type: 'string',
140
+ displayOptions: {
141
+ show: {
142
+ resource: ['message'],
143
+ operation: ['send'],
144
+ msg_type: ['reaction'],
145
+ },
146
+ },
147
+ default: '',
148
+ required: true,
149
+ description: 'ID of the message to react to',
150
+ },
151
+ {
152
+ displayName: 'Emoji',
153
+ name: 'content',
154
+ type: 'string',
155
+ displayOptions: {
156
+ show: {
157
+ resource: ['message'],
158
+ operation: ['send'],
159
+ msg_type: ['reaction'],
160
+ },
161
+ },
162
+ default: '',
163
+ description: 'Emoji to react with',
164
+ },
165
+ {
166
+ displayName: 'Sender Type',
167
+ name: 'sender_type',
168
+ type: 'options',
169
+ displayOptions: {
170
+ show: {
171
+ resource: ['message'],
172
+ operation: ['send'],
173
+ },
174
+ },
175
+ options: [
176
+ { name: 'Human Agent', value: 'human_agent' },
177
+ { name: 'AI Agent', value: 'ai_agent' },
178
+ ],
179
+ default: 'human_agent',
180
+ },
181
+ {
182
+ displayName: 'Sender ID',
183
+ name: 'sender_id',
184
+ type: 'string',
185
+ displayOptions: {
186
+ show: {
187
+ resource: ['message'],
188
+ operation: ['send'],
189
+ },
190
+ },
191
+ default: '',
192
+ description: 'ID of the sender (e.g. system, user_email). Optional.',
193
+ },
194
+ {
195
+ displayName: 'Reply To Message ID',
196
+ name: 'reply_to_message_id',
197
+ type: 'string',
198
+ displayOptions: {
199
+ show: {
200
+ resource: ['message'],
201
+ operation: ['send'],
202
+ },
203
+ hide: {
204
+ msg_type: ['reaction'],
205
+ }
206
+ },
207
+ default: '',
208
+ description: 'ID of the message to reply to',
209
+ },
210
+ {
211
+ displayName: 'Status',
212
+ name: 'typing_status',
213
+ type: 'options',
214
+ displayOptions: {
215
+ show: {
216
+ resource: ['message'],
217
+ operation: ['sendTyping'],
218
+ },
219
+ },
220
+ options: [
221
+ { name: 'Typing', value: 'typing' },
222
+ { name: 'Stop', value: 'stop' },
223
+ ],
224
+ default: 'typing',
225
+ },
226
+ {
227
+ displayName: 'Column ID',
228
+ name: 'column_id',
229
+ type: 'options',
230
+ typeOptions: {
231
+ loadOptionsMethod: 'getColumns',
232
+ },
233
+ displayOptions: {
234
+ show: {
235
+ resource: ['conversation'],
236
+ operation: ['update'],
237
+ },
238
+ },
239
+ default: '',
240
+ description: 'New Kanban Column ID. Leave empty to keep current.',
241
+ },
242
+ {
243
+ displayName: 'Owner ID',
244
+ name: 'owner_id',
245
+ type: 'options',
246
+ typeOptions: {
247
+ loadOptionsMethod: 'getUsers',
248
+ },
249
+ displayOptions: {
250
+ show: {
251
+ resource: ['conversation'],
252
+ operation: ['update'],
253
+ },
254
+ },
255
+ default: '',
256
+ description: 'New Owner ID. Leave empty to keep current.',
257
+ },
258
+ {
259
+ displayName: 'Status',
260
+ name: 'status',
261
+ type: 'options',
262
+ displayOptions: {
263
+ show: {
264
+ resource: ['conversation'],
265
+ operation: ['update'],
266
+ },
267
+ },
268
+ options: [
269
+ { name: 'No Change', value: '' },
270
+ { name: 'Open', value: 'open' },
271
+ { name: 'Closed', value: 'closed' },
272
+ { name: 'Snoozed', value: 'snoozed' },
273
+ ],
274
+ default: '',
275
+ description: 'Update conversation status',
276
+ },
277
+ ],
278
+ };
279
+ this.methods = {
280
+ loadOptions: {
281
+ async getColumns() {
282
+ const credentials = await this.getCredentials('cortexApi');
283
+ const baseUrl = credentials.apiBaseUrl.replace(/\/$/, '');
284
+ const options = {
285
+ headers: {
286
+ 'Content-Type': 'application/json',
287
+ 'Authorization': `Bearer ${credentials.accessToken}`,
288
+ },
289
+ method: 'GET',
290
+ uri: `${baseUrl}/kanban/columns`,
291
+ json: true,
292
+ };
293
+ try {
294
+ const response = await this.helpers.request(options);
295
+ return response;
296
+ }
297
+ catch (error) {
298
+ return [];
299
+ }
300
+ },
301
+ async getUsers() {
302
+ const credentials = await this.getCredentials('cortexApi');
303
+ const baseUrl = credentials.apiBaseUrl.replace(/\/$/, '');
304
+ const options = {
305
+ headers: {
306
+ 'Content-Type': 'application/json',
307
+ 'Authorization': `Bearer ${credentials.accessToken}`,
308
+ },
309
+ method: 'GET',
310
+ uri: `${baseUrl}/kanban/users`,
311
+ json: true,
312
+ };
313
+ try {
314
+ const response = await this.helpers.request(options);
315
+ return response;
316
+ }
317
+ catch (error) {
318
+ return [];
319
+ }
320
+ },
321
+ },
322
+ };
323
+ }
324
+ async execute() {
325
+ const items = this.getInputData();
326
+ const returnData = [];
327
+ const resource = this.getNodeParameter('resource', 0);
328
+ const operation = this.getNodeParameter('operation', 0);
329
+ const credentials = await this.getCredentials('cortexApi');
330
+ const baseUrl = credentials.apiBaseUrl.replace(/\/$/, '');
331
+ for (let i = 0; i < items.length; i++) {
332
+ try {
333
+ const conversationId = this.getNodeParameter('conversation_id', i);
334
+ let responseData;
335
+ const options = {
336
+ headers: {
337
+ 'Content-Type': 'application/json',
338
+ 'Authorization': `Bearer ${credentials.accessToken}`,
339
+ },
340
+ method: 'POST',
341
+ uri: '',
342
+ body: {},
343
+ json: true,
344
+ };
345
+ if (resource === 'message') {
346
+ if (operation === 'send') {
347
+ options.method = 'POST';
348
+ options.uri = `${baseUrl}/messages/send`;
349
+ const msgType = this.getNodeParameter('msg_type', i);
350
+ const content = this.getNodeParameter('content', i);
351
+ const senderType = this.getNodeParameter('sender_type', i);
352
+ const senderId = this.getNodeParameter('sender_id', i);
353
+ const replyTo = this.getNodeParameter('reply_to_message_id', i);
354
+ const reactTo = this.getNodeParameter('react_to_message_id', i);
355
+ const body = {
356
+ conversation_id: conversationId,
357
+ type: msgType,
358
+ sender_type: senderType,
359
+ };
360
+ if (content)
361
+ body.content = content;
362
+ if (senderId)
363
+ body.sender_id = senderId;
364
+ if (replyTo && msgType !== 'reaction')
365
+ body.reply_to_message_id = replyTo;
366
+ if (msgType === 'reaction' && reactTo)
367
+ body.react_to_message_id = reactTo;
368
+ options.body = body;
369
+ }
370
+ else if (operation === 'sendTyping') {
371
+ options.method = 'POST';
372
+ options.uri = `${baseUrl}/messages/typing`;
373
+ const status = this.getNodeParameter('typing_status', i);
374
+ options.body = {
375
+ conversation_id: conversationId,
376
+ status: status,
377
+ };
378
+ }
379
+ }
380
+ else if (resource === 'conversation') {
381
+ if (operation === 'update') {
382
+ options.method = 'PATCH';
383
+ options.uri = `${baseUrl}/kanban/conversations/${conversationId}`;
384
+ const columnId = this.getNodeParameter('column_id', i);
385
+ const ownerId = this.getNodeParameter('owner_id', i);
386
+ const status = this.getNodeParameter('status', i);
387
+ const body = {};
388
+ if (columnId)
389
+ body.column_id = columnId;
390
+ if (ownerId)
391
+ body.owner_id = ownerId;
392
+ if (status)
393
+ body.status = status;
394
+ if (Object.keys(body).length > 0) {
395
+ options.body = body;
396
+ }
397
+ else {
398
+ returnData.push({ json: { status: 'no_changes' } });
399
+ continue;
400
+ }
401
+ }
402
+ }
403
+ responseData = await this.helpers.request(options);
404
+ returnData.push(responseData);
405
+ }
406
+ catch (error) {
407
+ if (this.continueOnFail()) {
408
+ returnData.push({ json: { error: error.message } });
409
+ continue;
410
+ }
411
+ throw error;
412
+ }
413
+ }
414
+ return [this.helpers.returnJsonArray(returnData)];
415
+ }
416
+ }
417
+ exports.Cortex = Cortex;
Binary file
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@connectorx/n8n-nodes-cortex",
3
+ "version": "0.1.2",
4
+ "description": "n8n nodes for Cortex API",
5
+ "keywords": [
6
+ "n8n-community-node-package"
7
+ ],
8
+ "license": "MIT",
9
+ "author": {
10
+ "name": "Adriano",
11
+ "email": "adriano@example.com"
12
+ },
13
+ "main": "index.js",
14
+ "scripts": {
15
+ "build": "tsc && npm run copy-files",
16
+ "copy-files": "copyfiles -u 1 \"nodes/**/*.svg\" \"nodes/**/*.png\" dist/nodes && copyfiles -u 1 \"credentials/**/*.svg\" \"credentials/**/*.png\" dist/credentials",
17
+ "dev": "tsc --watch",
18
+ "lint": "eslint nodes credentials --ext .ts",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "n8n": {
25
+ "nodes": [
26
+ "dist/nodes/Cortex/Cortex.node.js"
27
+ ],
28
+ "credentials": [
29
+ "dist/credentials/CortexApi.credentials.js"
30
+ ]
31
+ },
32
+ "devDependencies": {
33
+ "@types/express": "^4.17.6",
34
+ "@types/node": "^14.14.41",
35
+ "@types/request-promise-native": "~1.0.15",
36
+ "@typescript-eslint/parser": "~4.22.0",
37
+ "copyfiles": "^2.4.1",
38
+ "eslint": "~7.25.0",
39
+ "n8n-core": "~0.119.0",
40
+ "n8n-workflow": "~0.119.0",
41
+ "prettier": "^2.2.1",
42
+ "typescript": "~4.2.4"
43
+ },
44
+ "peerDependencies": {
45
+ "n8n-workflow": "*"
46
+ }
47
+ }