n8n-nodes-twenty-pro 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -0
- package/gulpfile.js +38 -0
- package/package.json +55 -0
- package/src/credentials/TwentyProApi.credentials.ts +27 -0
- package/src/index.ts +2 -0
- package/src/nodes/actions/ApiKey/TwentyProApiKey.node.ts +84 -0
- package/src/nodes/actions/ApiKey/operations/create.ts +14 -0
- package/src/nodes/actions/ApiKey/operations/delete.ts +12 -0
- package/src/nodes/actions/ApiKey/operations/get.ts +12 -0
- package/src/nodes/actions/ApiKey/operations/getMany.ts +14 -0
- package/src/nodes/actions/ApiKey/operations/update.ts +15 -0
- package/src/nodes/actions/Attachment/TwentyProAttachment.node.ts +85 -0
- package/src/nodes/actions/Attachment/operations/create.ts +14 -0
- package/src/nodes/actions/Attachment/operations/delete.ts +12 -0
- package/src/nodes/actions/Attachment/operations/get.ts +12 -0
- package/src/nodes/actions/Attachment/operations/getMany.ts +14 -0
- package/src/nodes/actions/Attachment/operations/update.ts +15 -0
- package/src/nodes/actions/CalendarEvent/TwentyProCalendarEvent.node.ts +85 -0
- package/src/nodes/actions/CalendarEvent/operations/create.ts +14 -0
- package/src/nodes/actions/CalendarEvent/operations/delete.ts +12 -0
- package/src/nodes/actions/CalendarEvent/operations/get.ts +12 -0
- package/src/nodes/actions/CalendarEvent/operations/getMany.ts +14 -0
- package/src/nodes/actions/CalendarEvent/operations/update.ts +15 -0
- package/src/nodes/actions/Company/TwentyProCompany.node.ts +111 -0
- package/src/nodes/actions/Company/operations/create.ts +14 -0
- package/src/nodes/actions/Company/operations/delete.ts +12 -0
- package/src/nodes/actions/Company/operations/get.ts +12 -0
- package/src/nodes/actions/Company/operations/getMany.ts +14 -0
- package/src/nodes/actions/Company/operations/update.ts +15 -0
- package/src/nodes/actions/CustomObject/TwentyProCustomObject.node.ts +84 -0
- package/src/nodes/actions/CustomObject/operations/create.ts +14 -0
- package/src/nodes/actions/CustomObject/operations/delete.ts +12 -0
- package/src/nodes/actions/CustomObject/operations/get.ts +12 -0
- package/src/nodes/actions/CustomObject/operations/getMany.ts +14 -0
- package/src/nodes/actions/CustomObject/operations/update.ts +15 -0
- package/src/nodes/actions/Message/TwentyProMessage.node.ts +84 -0
- package/src/nodes/actions/Message/operations/create.ts +14 -0
- package/src/nodes/actions/Message/operations/delete.ts +12 -0
- package/src/nodes/actions/Message/operations/get.ts +12 -0
- package/src/nodes/actions/Message/operations/getMany.ts +14 -0
- package/src/nodes/actions/Message/operations/update.ts +15 -0
- package/src/nodes/actions/Note/TwentyProNote.node.ts +97 -0
- package/src/nodes/actions/Note/operations/create.ts +14 -0
- package/src/nodes/actions/Note/operations/delete.ts +12 -0
- package/src/nodes/actions/Note/operations/get.ts +12 -0
- package/src/nodes/actions/Note/operations/getMany.ts +14 -0
- package/src/nodes/actions/Note/operations/update.ts +15 -0
- package/src/nodes/actions/Opportunity/TwentyProOpportunity.node.ts +89 -0
- package/src/nodes/actions/Opportunity/operations/create.ts +14 -0
- package/src/nodes/actions/Opportunity/operations/delete.ts +12 -0
- package/src/nodes/actions/Opportunity/operations/get.ts +12 -0
- package/src/nodes/actions/Opportunity/operations/getMany.ts +14 -0
- package/src/nodes/actions/Opportunity/operations/update.ts +15 -0
- package/src/nodes/actions/Person/TwentyProPerson.node.ts +93 -0
- package/src/nodes/actions/Person/operations/create.ts +14 -0
- package/src/nodes/actions/Person/operations/delete.ts +12 -0
- package/src/nodes/actions/Person/operations/get.ts +12 -0
- package/src/nodes/actions/Person/operations/getMany.ts +14 -0
- package/src/nodes/actions/Person/operations/update.ts +15 -0
- package/src/nodes/actions/Task/TwentyProTask.node.ts +89 -0
- package/src/nodes/actions/Task/operations/create.ts +14 -0
- package/src/nodes/actions/Task/operations/delete.ts +12 -0
- package/src/nodes/actions/Task/operations/get.ts +12 -0
- package/src/nodes/actions/Task/operations/getMany.ts +14 -0
- package/src/nodes/actions/Task/operations/update.ts +15 -0
- package/src/nodes/actions/View/TwentyProView.node.ts +84 -0
- package/src/nodes/actions/View/operations/create.ts +14 -0
- package/src/nodes/actions/View/operations/delete.ts +12 -0
- package/src/nodes/actions/View/operations/get.ts +12 -0
- package/src/nodes/actions/View/operations/getMany.ts +14 -0
- package/src/nodes/actions/View/operations/update.ts +15 -0
- package/src/nodes/actions/Webhook/TwentyProWebhook.node.ts +84 -0
- package/src/nodes/actions/Webhook/operations/create.ts +14 -0
- package/src/nodes/actions/Webhook/operations/delete.ts +12 -0
- package/src/nodes/actions/Webhook/operations/get.ts +12 -0
- package/src/nodes/actions/Webhook/operations/getMany.ts +14 -0
- package/src/nodes/actions/Webhook/operations/update.ts +15 -0
- package/src/nodes/actions/Workflow/TwentyProWorkflow.node.ts +85 -0
- package/src/nodes/actions/Workflow/operations/create.ts +14 -0
- package/src/nodes/actions/Workflow/operations/delete.ts +12 -0
- package/src/nodes/actions/Workflow/operations/get.ts +12 -0
- package/src/nodes/actions/Workflow/operations/getMany.ts +14 -0
- package/src/nodes/actions/Workflow/operations/update.ts +15 -0
- package/src/nodes/shared/FieldTransformers.ts +245 -0
- package/src/nodes/shared/RecordLocator.ts +68 -0
- package/src/nodes/shared/SchemaDiscovery.ts +95 -0
- package/src/nodes/shared/TwentyProApi.client.ts +156 -0
- package/src/nodes/shared/twentyPro.svg +6 -0
- package/src/nodes/shared/types.ts +59 -0
- package/src/nodes/triggers/ApiKey/TwentyProApiKeyTrigger.node.ts +50 -0
- package/src/nodes/triggers/Attachment/TwentyProAttachmentTrigger.node.ts +50 -0
- package/src/nodes/triggers/CalendarEvent/TwentyProCalendarEventTrigger.node.ts +50 -0
- package/src/nodes/triggers/Company/TwentyProCompanyTrigger.node.ts +50 -0
- package/src/nodes/triggers/CustomObject/TwentyProCustomObjectTrigger.node.ts +50 -0
- package/src/nodes/triggers/Message/TwentyProMessageTrigger.node.ts +50 -0
- package/src/nodes/triggers/Note/TwentyProNoteTrigger.node.ts +50 -0
- package/src/nodes/triggers/Opportunity/TwentyProOpportunityTrigger.node.ts +50 -0
- package/src/nodes/triggers/Person/TwentyProPersonTrigger.node.ts +50 -0
- package/src/nodes/triggers/Task/TwentyProTaskTrigger.node.ts +50 -0
- package/src/nodes/triggers/View/TwentyProViewTrigger.node.ts +50 -0
- package/src/nodes/triggers/Webhook/TwentyProWebhookTrigger.node.ts +50 -0
- package/src/nodes/triggers/Workflow/TwentyProWorkflowTrigger.node.ts +50 -0
- package/tsconfig.json +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# n8n-nodes-twenty-pro
|
|
2
|
+
|
|
3
|
+
Comprehensive n8n community node for [Twenty CRM](https://twenty.com) — open-source CRM.
|
|
4
|
+
|
|
5
|
+
**13 action nodes + 13 trigger nodes** for complete Twenty CRM integration.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **13 resource-specific nodes** — Person, Company, Opportunity, Note, Task, CalendarEvent, Message, Attachment, Workflow, View, Webhook, ApiKey, CustomObject
|
|
10
|
+
- **13 webhook trigger nodes** — one per resource (record created/updated/deleted)
|
|
11
|
+
- **Dynamic schema discovery** — custom objects/fields auto-detected
|
|
12
|
+
- **Complex field types** — FullName, Links, Currency, Address, Emails, Phones
|
|
13
|
+
- **Full CRUD** — Create, Get, Update, Delete, Get Many on every resource
|
|
14
|
+
- **Auto-retry** — exponential backoff on rate limits and network errors
|
|
15
|
+
- **Record locator** — search by name, paste URL, or enter ID
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
In n8n, go to **Settings > Community Nodes > Install** and enter:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
n8n-nodes-twenty-pro
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Configuration
|
|
26
|
+
|
|
27
|
+
1. In Twenty CRM: **Settings > Developers > API Keys** > Create API Key
|
|
28
|
+
2. In n8n: Add **Twenty Pro API** credential
|
|
29
|
+
3. Enter: **API Key** (from step 1), **Domain** (your Twenty URL, e.g. `https://app.twenty.com`)
|
|
30
|
+
|
|
31
|
+
**Important:** Do NOT include `/graphql` or `/rest` in the domain.
|
|
32
|
+
|
|
33
|
+
## Nodes
|
|
34
|
+
|
|
35
|
+
### Action Nodes
|
|
36
|
+
|
|
37
|
+
| Node | Operations | Fields |
|
|
38
|
+
|------|-----------|--------|
|
|
39
|
+
| Twenty Person | Create, Get, Update, Delete, Get Many | First Name, Last Name, Email, Phone, Job Title, City, LinkedIn, X |
|
|
40
|
+
| Twenty Company | Create, Get, Update, Delete, Get Many | Name, Domain, LinkedIn, X, Address (6 fields), Revenue, Employees |
|
|
41
|
+
| Twenty Opportunity | Create, Get, Update, Delete, Get Many | Name, Amount, Stage, Close Date |
|
|
42
|
+
| Twenty Note | Create, Get, Update, Delete, Get Many | Title, Content |
|
|
43
|
+
| Twenty Task | Create, Get, Update, Delete, Get Many | Title, Due Date, Priority, Assignee ID |
|
|
44
|
+
| Twenty Calendar Event | Create, Get, Update, Delete, Get Many | Title, Starts At, Ends At |
|
|
45
|
+
| Twenty Message | Create, Get, Update, Delete, Get Many | Subject, Body |
|
|
46
|
+
| Twenty Attachment | Create, Get, Update, Delete, Get Many | Name, MIME Type, Attachment URL |
|
|
47
|
+
| Twenty Workflow | Create, Get, Update, Delete, Get Many | Name, Status, Trigger Type |
|
|
48
|
+
| Twenty View | Create, Get, Update, Delete, Get Many | Name, Object Type |
|
|
49
|
+
| Twenty Webhook | Create, Get, Update, Delete, Get Many | Target URL, Event Types |
|
|
50
|
+
| Twenty API Key | Create, Get, Update, Delete, Get Many | Name, Expires At |
|
|
51
|
+
| Twenty Custom Object | Create, Get, Update, Delete, Get Many | Dynamic (based on schema) |
|
|
52
|
+
|
|
53
|
+
### Trigger Nodes
|
|
54
|
+
|
|
55
|
+
Every resource has a corresponding trigger node: Twenty [Resource] Trigger.
|
|
56
|
+
|
|
57
|
+
Events per trigger: Record Created / Record Updated / Record Deleted
|
|
58
|
+
|
|
59
|
+
## API
|
|
60
|
+
|
|
61
|
+
Uses **REST** for all data operations. **GraphQL** only for schema introspection (custom field discovery).
|
|
62
|
+
|
|
63
|
+
- Requires Twenty CRM v1.4.0+
|
|
64
|
+
- Requires n8n v1.0.0+
|
|
65
|
+
- Node.js 18.10+
|
|
66
|
+
|
|
67
|
+
## Development
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone <repo>
|
|
71
|
+
cd n8n-nodes-twenty-pro
|
|
72
|
+
npm install
|
|
73
|
+
npm run build
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
package/gulpfile.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const { src, dest, series } = require('gulp');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
// Copy SVG icon to every directory that contains a .node.js file
|
|
6
|
+
function copySvg(done) {
|
|
7
|
+
const svgSrc = 'src/nodes/shared/twentyPro.svg';
|
|
8
|
+
if (!fs.existsSync(svgSrc)) {
|
|
9
|
+
console.warn('twentyPro.svg not found, skipping copy');
|
|
10
|
+
return done();
|
|
11
|
+
}
|
|
12
|
+
const distNodes = 'dist/nodes';
|
|
13
|
+
const entries = fs.readdirSync(distNodes, { withFileTypes: true });
|
|
14
|
+
const dirs = [];
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
if (!entry.isDirectory()) continue;
|
|
17
|
+
const sub = entry.name; // actions or triggers
|
|
18
|
+
const subPath = path.join(distNodes, sub);
|
|
19
|
+
for (const resource of fs.readdirSync(subPath)) {
|
|
20
|
+
const resourcePath = path.join(subPath, resource);
|
|
21
|
+
if (fs.statSync(resourcePath).isDirectory()) {
|
|
22
|
+
dirs.push(resourcePath);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
for (const dir of dirs) {
|
|
27
|
+
fs.copyFileSync(svgSrc, path.join(dir, 'twentyPro.svg'));
|
|
28
|
+
}
|
|
29
|
+
console.log(`Copied twentyPro.svg to ${dirs.length} node directories`);
|
|
30
|
+
done();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function build() {
|
|
34
|
+
return src('dist/**/*.js')
|
|
35
|
+
.pipe(dest('dist/'));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
exports.build = series(build, copySvg);
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-twenty-pro",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Comprehensive n8n community node for Twenty CRM with 32 resource nodes + 32 trigger nodes",
|
|
5
|
+
"keywords": ["n8n", "n8n-community-node", "twenty", "twenty-crm", "crm"],
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": { "name": "Suheb", "email": "suheb@example.com" },
|
|
8
|
+
"engines": { "node": ">=18.10.0" },
|
|
9
|
+
"n8n": {
|
|
10
|
+
"n8nNodesApiVersion": 1,
|
|
11
|
+
"credentials": ["dist/credentials/TwentyProApi.credentials.js"],
|
|
12
|
+
"nodes": [
|
|
13
|
+
"dist/nodes/actions/Person/TwentyProPerson.node.js",
|
|
14
|
+
"dist/nodes/actions/Company/TwentyProCompany.node.js",
|
|
15
|
+
"dist/nodes/actions/Opportunity/TwentyProOpportunity.node.js",
|
|
16
|
+
"dist/nodes/actions/Note/TwentyProNote.node.js",
|
|
17
|
+
"dist/nodes/actions/Task/TwentyProTask.node.js",
|
|
18
|
+
"dist/nodes/actions/CalendarEvent/TwentyProCalendarEvent.node.js",
|
|
19
|
+
"dist/nodes/actions/Message/TwentyProMessage.node.js",
|
|
20
|
+
"dist/nodes/actions/Attachment/TwentyProAttachment.node.js",
|
|
21
|
+
"dist/nodes/actions/Workflow/TwentyProWorkflow.node.js",
|
|
22
|
+
"dist/nodes/actions/View/TwentyProView.node.js",
|
|
23
|
+
"dist/nodes/actions/Webhook/TwentyProWebhook.node.js",
|
|
24
|
+
"dist/nodes/actions/ApiKey/TwentyProApiKey.node.js",
|
|
25
|
+
"dist/nodes/actions/CustomObject/TwentyProCustomObject.node.js",
|
|
26
|
+
"dist/nodes/triggers/Person/TwentyProPersonTrigger.node.js",
|
|
27
|
+
"dist/nodes/triggers/Company/TwentyProCompanyTrigger.node.js",
|
|
28
|
+
"dist/nodes/triggers/Opportunity/TwentyProOpportunityTrigger.node.js",
|
|
29
|
+
"dist/nodes/triggers/Note/TwentyProNoteTrigger.node.js",
|
|
30
|
+
"dist/nodes/triggers/Task/TwentyProTaskTrigger.node.js",
|
|
31
|
+
"dist/nodes/triggers/CalendarEvent/TwentyProCalendarEventTrigger.node.js",
|
|
32
|
+
"dist/nodes/triggers/Message/TwentyProMessageTrigger.node.js",
|
|
33
|
+
"dist/nodes/triggers/Attachment/TwentyProAttachmentTrigger.node.js",
|
|
34
|
+
"dist/nodes/triggers/Workflow/TwentyProWorkflowTrigger.node.js",
|
|
35
|
+
"dist/nodes/triggers/View/TwentyProViewTrigger.node.js",
|
|
36
|
+
"dist/nodes/triggers/Webhook/TwentyProWebhookTrigger.node.js",
|
|
37
|
+
"dist/nodes/triggers/ApiKey/TwentyProApiKeyTrigger.node.js",
|
|
38
|
+
"dist/nodes/triggers/CustomObject/TwentyProCustomObjectTrigger.node.js"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc && gulp build",
|
|
43
|
+
"dev": "tsc -w",
|
|
44
|
+
"lint": "tslint -p tsconfig.json -c tslint.json",
|
|
45
|
+
"lint:fix": "tslint --fix -p tsconfig.json -c tslint.json"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": { "n8n-workflow": "*" },
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^18.10.0",
|
|
50
|
+
"gulp": "^4.0.2",
|
|
51
|
+
"n8n-node-dev": "^2.9.1",
|
|
52
|
+
"tslint": "^6.1.3",
|
|
53
|
+
"typescript": "^5.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
|
|
3
|
+
export class TwentyProApi implements ICredentialType {
|
|
4
|
+
name = 'twentyProApi';
|
|
5
|
+
displayName = 'Twenty Pro API';
|
|
6
|
+
documentationUrl = 'https://twenty.com/developers';
|
|
7
|
+
properties: INodeProperties[] = [
|
|
8
|
+
{
|
|
9
|
+
displayName: 'API Key',
|
|
10
|
+
name: 'apiKey',
|
|
11
|
+
type: 'string',
|
|
12
|
+
typeOptions: { password: true },
|
|
13
|
+
required: true,
|
|
14
|
+
default: '',
|
|
15
|
+
description: 'API key from Twenty CRM (Settings → Developers → API Keys)',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
displayName: 'Domain',
|
|
19
|
+
name: 'domain',
|
|
20
|
+
type: 'string',
|
|
21
|
+
required: true,
|
|
22
|
+
default: '',
|
|
23
|
+
placeholder: 'https://app.twenty.com',
|
|
24
|
+
description: 'Your Twenty CRM instance URL. Do NOT include /graphql or /rest.',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { IDataObject, INodeType, INodeTypeDescription, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import * as create from './operations/create';
|
|
3
|
+
import * as get from './operations/get';
|
|
4
|
+
import * as update from './operations/update';
|
|
5
|
+
import * as del from './operations/delete';
|
|
6
|
+
import * as getMany from './operations/getMany';
|
|
7
|
+
|
|
8
|
+
export class TwentyProApiKey implements INodeType {
|
|
9
|
+
description: INodeTypeDescription = {
|
|
10
|
+
displayName: 'Twenty API Key',
|
|
11
|
+
name: 'twentyProApiKey',
|
|
12
|
+
icon: 'file:twentyPro.svg',
|
|
13
|
+
group: ['transform'],
|
|
14
|
+
version: 1,
|
|
15
|
+
subtitle: '={{$parameter["operation"]}}',
|
|
16
|
+
description: 'Manage API keys in Twenty CRM',
|
|
17
|
+
defaults: { name: 'Twenty API Key' },
|
|
18
|
+
inputs: ['main'],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
credentials: [{ name: 'twentyProApi', required: true }],
|
|
21
|
+
properties: [
|
|
22
|
+
{
|
|
23
|
+
displayName: 'Operation',
|
|
24
|
+
name: 'operation',
|
|
25
|
+
type: 'options',
|
|
26
|
+
noDataExpression: true,
|
|
27
|
+
required: true,
|
|
28
|
+
default: 'create',
|
|
29
|
+
options: [
|
|
30
|
+
{ name: 'Create', value: 'create', description: 'Create a new API key' },
|
|
31
|
+
{ name: 'Get', value: 'get', description: 'Get an API key by ID' },
|
|
32
|
+
{ name: 'Update', value: 'update', description: 'Update an API key' },
|
|
33
|
+
{ name: 'Delete', value: 'delete', description: 'Delete an API key' },
|
|
34
|
+
{ name: 'Get Many', value: 'getMany', description: 'List API keys' },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
displayName: 'Record ID',
|
|
39
|
+
name: 'recordId',
|
|
40
|
+
type: 'string',
|
|
41
|
+
default: '',
|
|
42
|
+
required: true,
|
|
43
|
+
displayOptions: { show: { operation: ['get', 'update', 'delete'] } },
|
|
44
|
+
placeholder: 'abc-123-def-456',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
displayName: 'Fields',
|
|
48
|
+
name: 'fields',
|
|
49
|
+
placeholder: 'Add Field',
|
|
50
|
+
type: 'fixedCollection',
|
|
51
|
+
default: {},
|
|
52
|
+
typeOptions: { multipleValues: true },
|
|
53
|
+
displayOptions: { show: { operation: ['create', 'update'] } },
|
|
54
|
+
options: [
|
|
55
|
+
{
|
|
56
|
+
name: 'fieldValues',
|
|
57
|
+
displayName: 'Field',
|
|
58
|
+
values: [
|
|
59
|
+
{ displayName: 'Name', name: 'name', type: 'string', default: '' },
|
|
60
|
+
{ displayName: 'Expires At', name: 'expiresAt', type: 'string', default: '' },
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
{ displayName: 'Return All', name: 'returnAll', type: 'boolean', default: false, displayOptions: { show: { operation: ['getMany'] } } },
|
|
66
|
+
{ displayName: 'Limit', name: 'limit', type: 'number', default: 50, displayOptions: { show: { operation: ['getMany'], returnAll: [false] } }, typeOptions: { minValue: 1, maxValue: 100 } },
|
|
67
|
+
],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
71
|
+
const items = this.getInputData();
|
|
72
|
+
const operation = this.getNode().parameters.operation as string;
|
|
73
|
+
let result: INodeExecutionData[];
|
|
74
|
+
switch (operation) {
|
|
75
|
+
case 'create': result = await create.execute.call(this, items); break;
|
|
76
|
+
case 'get': result = await get.execute.call(this, items); break;
|
|
77
|
+
case 'update': result = await update.execute.call(this, items); break;
|
|
78
|
+
case 'delete': result = await del.execute.call(this, items); break;
|
|
79
|
+
case 'getMany': result = await getMany.execute.call(this, items); break;
|
|
80
|
+
default: throw new Error(`Unknown operation: ${operation}`);
|
|
81
|
+
}
|
|
82
|
+
return [result];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
import { transformApiKeyFields } from '../../../shared/FieldTransformers';
|
|
4
|
+
|
|
5
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
6
|
+
const returnData: INodeExecutionData[] = [];
|
|
7
|
+
for (let i = 0; i < items.length; i++) {
|
|
8
|
+
const fields = this.getNode().parameters.fields as Record<string, unknown> || {};
|
|
9
|
+
const transformed = transformApiKeyFields(fields);
|
|
10
|
+
const response = await apiRequest.call(this, 'POST', '/apiKeys', transformed);
|
|
11
|
+
returnData.push({ json: response as IDataObject });
|
|
12
|
+
}
|
|
13
|
+
return returnData;
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
|
|
4
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
5
|
+
const returnData: INodeExecutionData[] = [];
|
|
6
|
+
for (let i = 0; i < items.length; i++) {
|
|
7
|
+
const id = this.getNode().parameters.recordId as string;
|
|
8
|
+
await apiRequest.call(this, 'DELETE', `/apiKeys/${id}`);
|
|
9
|
+
returnData.push({ json: { success: true, id } as IDataObject });
|
|
10
|
+
}
|
|
11
|
+
return returnData;
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
|
|
4
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
5
|
+
const returnData: INodeExecutionData[] = [];
|
|
6
|
+
for (let i = 0; i < items.length; i++) {
|
|
7
|
+
const id = this.getNode().parameters.recordId as string;
|
|
8
|
+
const response = await apiRequest.call(this, 'GET', `/apiKeys/${id}`);
|
|
9
|
+
returnData.push({ json: response as IDataObject });
|
|
10
|
+
}
|
|
11
|
+
return returnData;
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
|
|
4
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
5
|
+
const returnAll = this.getNode().parameters.returnAll as boolean;
|
|
6
|
+
const limit = this.getNode().parameters.limit as number;
|
|
7
|
+
const qs: Record<string, string> = {};
|
|
8
|
+
if (!returnAll) { qs.limit = String(limit); }
|
|
9
|
+
const response = await apiRequest.call(this, 'GET', '/apiKeys', undefined, qs) as IDataObject;
|
|
10
|
+
const data = response.data as IDataObject | undefined;
|
|
11
|
+
const dataKeys = data ? Object.keys(data) : [];
|
|
12
|
+
const items_arr = dataKeys.length > 0 ? ((data![dataKeys[0]] as IDataObject[]) ?? []) : [];
|
|
13
|
+
return items_arr.map((item) => ({ json: item }));
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
import { transformApiKeyFields } from '../../../shared/FieldTransformers';
|
|
4
|
+
|
|
5
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
6
|
+
const returnData: INodeExecutionData[] = [];
|
|
7
|
+
for (let i = 0; i < items.length; i++) {
|
|
8
|
+
const id = this.getNode().parameters.recordId as string;
|
|
9
|
+
const fields = this.getNode().parameters.fields as Record<string, unknown> || {};
|
|
10
|
+
const transformed = transformApiKeyFields(fields);
|
|
11
|
+
const response = await apiRequest.call(this, 'PATCH', `/apiKeys/${id}`, transformed);
|
|
12
|
+
returnData.push({ json: response as IDataObject });
|
|
13
|
+
}
|
|
14
|
+
return returnData;
|
|
15
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { IDataObject, INodeType, INodeTypeDescription, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import * as create from './operations/create';
|
|
3
|
+
import * as get from './operations/get';
|
|
4
|
+
import * as update from './operations/update';
|
|
5
|
+
import * as del from './operations/delete';
|
|
6
|
+
import * as getMany from './operations/getMany';
|
|
7
|
+
|
|
8
|
+
export class TwentyProAttachment implements INodeType {
|
|
9
|
+
description: INodeTypeDescription = {
|
|
10
|
+
displayName: 'Twenty Attachment',
|
|
11
|
+
name: 'twentyProAttachment',
|
|
12
|
+
icon: 'file:twentyPro.svg',
|
|
13
|
+
group: ['transform'],
|
|
14
|
+
version: 1,
|
|
15
|
+
subtitle: '={{$parameter["operation"]}}',
|
|
16
|
+
description: 'Manage attachments in Twenty CRM',
|
|
17
|
+
defaults: { name: 'Twenty Attachment' },
|
|
18
|
+
inputs: ['main'],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
credentials: [{ name: 'twentyProApi', required: true }],
|
|
21
|
+
properties: [
|
|
22
|
+
{
|
|
23
|
+
displayName: 'Operation',
|
|
24
|
+
name: 'operation',
|
|
25
|
+
type: 'options',
|
|
26
|
+
noDataExpression: true,
|
|
27
|
+
required: true,
|
|
28
|
+
default: 'create',
|
|
29
|
+
options: [
|
|
30
|
+
{ name: 'Create', value: 'create', description: 'Create a new attachment' },
|
|
31
|
+
{ name: 'Get', value: 'get', description: 'Get an attachment by ID' },
|
|
32
|
+
{ name: 'Update', value: 'update', description: 'Update an attachment' },
|
|
33
|
+
{ name: 'Delete', value: 'delete', description: 'Delete an attachment' },
|
|
34
|
+
{ name: 'Get Many', value: 'getMany', description: 'List attachments' },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
displayName: 'Record ID',
|
|
39
|
+
name: 'recordId',
|
|
40
|
+
type: 'string',
|
|
41
|
+
default: '',
|
|
42
|
+
required: true,
|
|
43
|
+
displayOptions: { show: { operation: ['get', 'update', 'delete'] } },
|
|
44
|
+
placeholder: 'abc-123-def-456',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
displayName: 'Fields',
|
|
48
|
+
name: 'fields',
|
|
49
|
+
placeholder: 'Add Field',
|
|
50
|
+
type: 'fixedCollection',
|
|
51
|
+
default: {},
|
|
52
|
+
typeOptions: { multipleValues: true },
|
|
53
|
+
displayOptions: { show: { operation: ['create', 'update'] } },
|
|
54
|
+
options: [
|
|
55
|
+
{
|
|
56
|
+
name: 'fieldValues',
|
|
57
|
+
displayName: 'Field',
|
|
58
|
+
values: [
|
|
59
|
+
{ displayName: 'Name', name: 'name', type: 'string', default: '' },
|
|
60
|
+
{ displayName: 'Mime Type', name: 'mimeType', type: 'string', default: '' },
|
|
61
|
+
{ displayName: 'Attachment Url', name: 'attachmentUrl', type: 'string', default: '' },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{ displayName: 'Return All', name: 'returnAll', type: 'boolean', default: false, displayOptions: { show: { operation: ['getMany'] } } },
|
|
67
|
+
{ displayName: 'Limit', name: 'limit', type: 'number', default: 50, displayOptions: { show: { operation: ['getMany'], returnAll: [false] } }, typeOptions: { minValue: 1, maxValue: 100 } },
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
72
|
+
const items = this.getInputData();
|
|
73
|
+
const operation = this.getNode().parameters.operation as string;
|
|
74
|
+
let result: INodeExecutionData[];
|
|
75
|
+
switch (operation) {
|
|
76
|
+
case 'create': result = await create.execute.call(this, items); break;
|
|
77
|
+
case 'get': result = await get.execute.call(this, items); break;
|
|
78
|
+
case 'update': result = await update.execute.call(this, items); break;
|
|
79
|
+
case 'delete': result = await del.execute.call(this, items); break;
|
|
80
|
+
case 'getMany': result = await getMany.execute.call(this, items); break;
|
|
81
|
+
default: throw new Error(`Unknown operation: ${operation}`);
|
|
82
|
+
}
|
|
83
|
+
return [result];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
import { transformAttachmentFields } from '../../../shared/FieldTransformers';
|
|
4
|
+
|
|
5
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
6
|
+
const returnData: INodeExecutionData[] = [];
|
|
7
|
+
for (let i = 0; i < items.length; i++) {
|
|
8
|
+
const fields = this.getNode().parameters.fields as Record<string, unknown> || {};
|
|
9
|
+
const transformed = transformAttachmentFields(fields);
|
|
10
|
+
const response = await apiRequest.call(this, 'POST', '/attachments', transformed);
|
|
11
|
+
returnData.push({ json: response as IDataObject });
|
|
12
|
+
}
|
|
13
|
+
return returnData;
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
|
|
4
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
5
|
+
const returnData: INodeExecutionData[] = [];
|
|
6
|
+
for (let i = 0; i < items.length; i++) {
|
|
7
|
+
const id = this.getNode().parameters.recordId as string;
|
|
8
|
+
await apiRequest.call(this, 'DELETE', `/attachments/${id}`);
|
|
9
|
+
returnData.push({ json: { success: true, id } as IDataObject });
|
|
10
|
+
}
|
|
11
|
+
return returnData;
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
|
|
4
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
5
|
+
const returnData: INodeExecutionData[] = [];
|
|
6
|
+
for (let i = 0; i < items.length; i++) {
|
|
7
|
+
const id = this.getNode().parameters.recordId as string;
|
|
8
|
+
const response = await apiRequest.call(this, 'GET', `/attachments/${id}`);
|
|
9
|
+
returnData.push({ json: response as IDataObject });
|
|
10
|
+
}
|
|
11
|
+
return returnData;
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
|
|
4
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
5
|
+
const returnAll = this.getNode().parameters.returnAll as boolean;
|
|
6
|
+
const limit = this.getNode().parameters.limit as number;
|
|
7
|
+
const qs: Record<string, string> = {};
|
|
8
|
+
if (!returnAll) { qs.limit = String(limit); }
|
|
9
|
+
const response = await apiRequest.call(this, 'GET', '/attachments', undefined, qs) as IDataObject;
|
|
10
|
+
const data = response.data as IDataObject | undefined;
|
|
11
|
+
const dataKeys = data ? Object.keys(data) : [];
|
|
12
|
+
const items_arr = dataKeys.length > 0 ? ((data![dataKeys[0]] as IDataObject[]) ?? []) : [];
|
|
13
|
+
return items_arr.map((item) => ({ json: item }));
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
import { transformAttachmentFields } from '../../../shared/FieldTransformers';
|
|
4
|
+
|
|
5
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
6
|
+
const returnData: INodeExecutionData[] = [];
|
|
7
|
+
for (let i = 0; i < items.length; i++) {
|
|
8
|
+
const id = this.getNode().parameters.recordId as string;
|
|
9
|
+
const fields = this.getNode().parameters.fields as Record<string, unknown> || {};
|
|
10
|
+
const transformed = transformAttachmentFields(fields);
|
|
11
|
+
const response = await apiRequest.call(this, 'PATCH', `/attachments/${id}`, transformed);
|
|
12
|
+
returnData.push({ json: response as IDataObject });
|
|
13
|
+
}
|
|
14
|
+
return returnData;
|
|
15
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { IDataObject, INodeType, INodeTypeDescription, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import * as create from './operations/create';
|
|
3
|
+
import * as get from './operations/get';
|
|
4
|
+
import * as update from './operations/update';
|
|
5
|
+
import * as del from './operations/delete';
|
|
6
|
+
import * as getMany from './operations/getMany';
|
|
7
|
+
|
|
8
|
+
export class TwentyProCalendarEvent implements INodeType {
|
|
9
|
+
description: INodeTypeDescription = {
|
|
10
|
+
displayName: 'Twenty Calendar Event',
|
|
11
|
+
name: 'twentyProCalendarEvent',
|
|
12
|
+
icon: 'file:twentyPro.svg',
|
|
13
|
+
group: ['transform'],
|
|
14
|
+
version: 1,
|
|
15
|
+
subtitle: '={{$parameter["operation"]}}',
|
|
16
|
+
description: 'Manage calendar events in Twenty CRM',
|
|
17
|
+
defaults: { name: 'Twenty Calendar Event' },
|
|
18
|
+
inputs: ['main'],
|
|
19
|
+
outputs: ['main'],
|
|
20
|
+
credentials: [{ name: 'twentyProApi', required: true }],
|
|
21
|
+
properties: [
|
|
22
|
+
{
|
|
23
|
+
displayName: 'Operation',
|
|
24
|
+
name: 'operation',
|
|
25
|
+
type: 'options',
|
|
26
|
+
noDataExpression: true,
|
|
27
|
+
required: true,
|
|
28
|
+
default: 'create',
|
|
29
|
+
options: [
|
|
30
|
+
{ name: 'Create', value: 'create', description: 'Create a new calendar event' },
|
|
31
|
+
{ name: 'Get', value: 'get', description: 'Get a calendar event by ID' },
|
|
32
|
+
{ name: 'Update', value: 'update', description: 'Update a calendar event' },
|
|
33
|
+
{ name: 'Delete', value: 'delete', description: 'Delete a calendar event' },
|
|
34
|
+
{ name: 'Get Many', value: 'getMany', description: 'List calendar events' },
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
displayName: 'Record ID',
|
|
39
|
+
name: 'recordId',
|
|
40
|
+
type: 'string',
|
|
41
|
+
default: '',
|
|
42
|
+
required: true,
|
|
43
|
+
displayOptions: { show: { operation: ['get', 'update', 'delete'] } },
|
|
44
|
+
placeholder: 'abc-123-def-456',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
displayName: 'Fields',
|
|
48
|
+
name: 'fields',
|
|
49
|
+
placeholder: 'Add Field',
|
|
50
|
+
type: 'fixedCollection',
|
|
51
|
+
default: {},
|
|
52
|
+
typeOptions: { multipleValues: true },
|
|
53
|
+
displayOptions: { show: { operation: ['create', 'update'] } },
|
|
54
|
+
options: [
|
|
55
|
+
{
|
|
56
|
+
name: 'fieldValues',
|
|
57
|
+
displayName: 'Field',
|
|
58
|
+
values: [
|
|
59
|
+
{ displayName: 'Title', name: 'title', type: 'string', default: '' },
|
|
60
|
+
{ displayName: 'Starts At', name: 'startsAt', type: 'string', default: '' },
|
|
61
|
+
{ displayName: 'Ends At', name: 'endsAt', type: 'string', default: '' },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{ displayName: 'Return All', name: 'returnAll', type: 'boolean', default: false, displayOptions: { show: { operation: ['getMany'] } } },
|
|
67
|
+
{ displayName: 'Limit', name: 'limit', type: 'number', default: 50, displayOptions: { show: { operation: ['getMany'], returnAll: [false] } }, typeOptions: { minValue: 1, maxValue: 100 } },
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
72
|
+
const items = this.getInputData();
|
|
73
|
+
const operation = this.getNode().parameters.operation as string;
|
|
74
|
+
let result: INodeExecutionData[];
|
|
75
|
+
switch (operation) {
|
|
76
|
+
case 'create': result = await create.execute.call(this, items); break;
|
|
77
|
+
case 'get': result = await get.execute.call(this, items); break;
|
|
78
|
+
case 'update': result = await update.execute.call(this, items); break;
|
|
79
|
+
case 'delete': result = await del.execute.call(this, items); break;
|
|
80
|
+
case 'getMany': result = await getMany.execute.call(this, items); break;
|
|
81
|
+
default: throw new Error(`Unknown operation: ${operation}`);
|
|
82
|
+
}
|
|
83
|
+
return [result];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
import { transformCalendarEventFields } from '../../../shared/FieldTransformers';
|
|
4
|
+
|
|
5
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
6
|
+
const returnData: INodeExecutionData[] = [];
|
|
7
|
+
for (let i = 0; i < items.length; i++) {
|
|
8
|
+
const fields = this.getNode().parameters.fields as Record<string, unknown> || {};
|
|
9
|
+
const transformed = transformCalendarEventFields(fields);
|
|
10
|
+
const response = await apiRequest.call(this, 'POST', '/calendarEvents', transformed);
|
|
11
|
+
returnData.push({ json: response as IDataObject });
|
|
12
|
+
}
|
|
13
|
+
return returnData;
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
|
|
4
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
5
|
+
const returnData: INodeExecutionData[] = [];
|
|
6
|
+
for (let i = 0; i < items.length; i++) {
|
|
7
|
+
const id = this.getNode().parameters.recordId as string;
|
|
8
|
+
await apiRequest.call(this, 'DELETE', `/calendarEvents/${id}`);
|
|
9
|
+
returnData.push({ json: { success: true, id } as IDataObject });
|
|
10
|
+
}
|
|
11
|
+
return returnData;
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IDataObject, IExecuteFunctions, INodeExecutionData } from 'n8n-workflow';
|
|
2
|
+
import { apiRequest } from '../../../shared/TwentyProApi.client';
|
|
3
|
+
|
|
4
|
+
export async function execute(this: IExecuteFunctions, items: INodeExecutionData[]): Promise<INodeExecutionData[]> {
|
|
5
|
+
const returnData: INodeExecutionData[] = [];
|
|
6
|
+
for (let i = 0; i < items.length; i++) {
|
|
7
|
+
const id = this.getNode().parameters.recordId as string;
|
|
8
|
+
const response = await apiRequest.call(this, 'GET', `/calendarEvents/${id}`);
|
|
9
|
+
returnData.push({ json: response as IDataObject });
|
|
10
|
+
}
|
|
11
|
+
return returnData;
|
|
12
|
+
}
|