@lbono/n8n-nodes-npaw 2.0.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 ADDED
@@ -0,0 +1,62 @@
1
+ # n8n-nodes-npaw
2
+
3
+ Nodo personalizado de n8n para interactuar con la API de NPAW/Youbora.
4
+
5
+ ## Instalación
6
+
7
+ ### Instalación en n8n
8
+
9
+ #### Instalación desde la comunidad (recomendado)
10
+ 1. Ve a Settings > Community Nodes en tu instancia de n8n
11
+ 2. Busca `@lbono/n8n-nodes-npaw`
12
+ 3. Haz clic en Install
13
+
14
+ #### Instalación manual
15
+ ```bash
16
+ npm install @lbono/n8n-nodes-npaw
17
+ ```
18
+
19
+ ### Desarrollo local
20
+
21
+ ```bash
22
+ npm install
23
+ npm run build
24
+ ```
25
+
26
+ ## Uso
27
+
28
+ Este nodo permite interactuar con la API de NPAW/Youbora para obtener:
29
+
30
+ - **Data**: Métricas agregadas (views, hours, uniques, etc.)
31
+ - **Events**: Datos de eventos en tiempo real
32
+ - **Raw Data**: Datos raw de sesiones
33
+ - **Alerts**: Alertas generadas
34
+ - **Version**: Versión de la API
35
+
36
+ ## Configuración
37
+
38
+ Necesitas configurar las credenciales con:
39
+ - API Key de NPAW
40
+ - Account Code
41
+ - Base URL (por defecto: https://api.npaw.com)
42
+
43
+ ## Recursos disponibles
44
+
45
+ ### Data
46
+ Obtiene métricas agregadas con opciones de:
47
+ - Rango de fechas (fromDate)
48
+ - Métricas específicas
49
+ - Granularidad (hour, day, week, month)
50
+ - Filtros, agrupación y ordenamiento
51
+
52
+ ### Events
53
+ Obtiene eventos con límite configurable.
54
+
55
+ ### Raw Data
56
+ Obtiene datos raw de sesiones.
57
+
58
+ ### Alerts
59
+ Obtiene alertas generadas en el sistema.
60
+
61
+ ### Version
62
+ Obtiene la versión de la API.
@@ -0,0 +1,35 @@
1
+ import {
2
+ ICredentialType,
3
+ INodeProperties,
4
+ } from 'n8n-workflow';
5
+
6
+ export class NpawApi implements ICredentialType {
7
+ name = 'npawApi';
8
+ displayName = 'NPAW API';
9
+ documentationUrl = 'npaw';
10
+ properties: INodeProperties[] = [
11
+ {
12
+ displayName: 'API Key',
13
+ name: 'apiKey',
14
+ type: 'string',
15
+ typeOptions: {
16
+ password: true,
17
+ },
18
+ default: '',
19
+ required: true,
20
+ },
21
+ {
22
+ displayName: 'Account Code',
23
+ name: 'accountCode',
24
+ type: 'string',
25
+ default: '',
26
+ required: true,
27
+ },
28
+ {
29
+ displayName: 'Base URL',
30
+ name: 'baseUrl',
31
+ type: 'string',
32
+ default: 'https://api.npaw.com',
33
+ },
34
+ ];
35
+ }
@@ -0,0 +1,7 @@
1
+ import { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class NpawApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NpawApi = void 0;
4
+ class NpawApi {
5
+ constructor() {
6
+ this.name = 'npawApi';
7
+ this.displayName = 'NPAW API';
8
+ this.documentationUrl = 'npaw';
9
+ this.properties = [
10
+ {
11
+ displayName: 'API Key',
12
+ name: 'apiKey',
13
+ type: 'string',
14
+ typeOptions: {
15
+ password: true,
16
+ },
17
+ default: '',
18
+ required: true,
19
+ },
20
+ {
21
+ displayName: 'Account Code',
22
+ name: 'accountCode',
23
+ type: 'string',
24
+ default: '',
25
+ required: true,
26
+ },
27
+ {
28
+ displayName: 'Base URL',
29
+ name: 'baseUrl',
30
+ type: 'string',
31
+ default: 'https://api.npaw.com',
32
+ },
33
+ ];
34
+ }
35
+ }
36
+ exports.NpawApi = NpawApi;
37
+ //# sourceMappingURL=NpawApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NpawApi.credentials.js","sourceRoot":"","sources":["../../credentials/NpawApi.credentials.ts"],"names":[],"mappings":";;;AAKA,MAAa,OAAO;IAApB;QACC,SAAI,GAAG,SAAS,CAAC;QACjB,gBAAW,GAAG,UAAU,CAAC;QACzB,qBAAgB,GAAG,MAAM,CAAC;QAC1B,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACZ,QAAQ,EAAE,IAAI;iBACd;gBACD,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;aACd;YACD;gBACC,WAAW,EAAE,cAAc;gBAC3B,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;aACd;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,sBAAsB;aAC/B;SACD,CAAC;IACH,CAAC;CAAA;AA7BD,0BA6BC"}
@@ -0,0 +1,2 @@
1
+ import { IExecuteFunctions, IDataObject, IHttpRequestMethods } from 'n8n-workflow';
2
+ export declare function npawApiRequest(this: IExecuteFunctions, method: IHttpRequestMethods, endpoint: string, params?: IDataObject): Promise<any>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.npawApiRequest = npawApiRequest;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ async function npawApiRequest(method, endpoint, params = {}) {
6
+ const credentials = await this.getCredentials('npawApi');
7
+ const url = new URL(`${credentials.baseUrl}${endpoint}`);
8
+ Object.keys(params).forEach(key => {
9
+ if (params[key] !== undefined && params[key] !== null) {
10
+ url.searchParams.append(key, String(params[key]));
11
+ }
12
+ });
13
+ const options = {
14
+ method,
15
+ url: url.toString(),
16
+ headers: {
17
+ 'npaw-api-key': credentials.apiKey,
18
+ },
19
+ json: true,
20
+ };
21
+ try {
22
+ return await this.helpers.httpRequest(options);
23
+ }
24
+ catch (error) {
25
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
26
+ }
27
+ }
28
+ //# sourceMappingURL=GenericFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenericFunctions.js","sourceRoot":"","sources":["../../../nodes/Npaw/GenericFunctions.ts"],"names":[],"mappings":";;AAQA,wCA6BC;AArCD,+CAMsB;AAEf,KAAK,UAAU,cAAc,CAEnC,MAA2B,EAC3B,QAAgB,EAChB,SAAsB,EAAE;IAExB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAEzD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,WAAW,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QACjC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YACvD,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAwB;QACpC,MAAM;QACN,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;QACnB,OAAO,EAAE;YACR,cAAc,EAAE,WAAW,CAAC,MAAgB;SAC5C;QACD,IAAI,EAAE,IAAI;KACV,CAAC;IAEF,IAAI,CAAC;QACJ,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACrB,MAAM,IAAI,2BAAY,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;AACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class Npaw implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Npaw = void 0;
4
+ const GenericFunctions_1 = require("./GenericFunctions");
5
+ class Npaw {
6
+ constructor() {
7
+ this.description = {
8
+ displayName: 'NPAW',
9
+ name: 'npaw',
10
+ icon: 'file:npaw.svg',
11
+ group: ['transform'],
12
+ version: 1,
13
+ subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
14
+ description: 'Consume NPAW/Youbora API',
15
+ defaults: {
16
+ name: 'NPAW',
17
+ },
18
+ inputs: ['main'],
19
+ outputs: ['main'],
20
+ credentials: [
21
+ {
22
+ name: 'npawApi',
23
+ required: true,
24
+ },
25
+ ],
26
+ properties: [
27
+ {
28
+ displayName: 'Resource',
29
+ name: 'resource',
30
+ type: 'options',
31
+ noDataExpression: true,
32
+ options: [
33
+ {
34
+ name: 'Data',
35
+ value: 'data',
36
+ },
37
+ {
38
+ name: 'Events',
39
+ value: 'events',
40
+ },
41
+ {
42
+ name: 'Raw Data',
43
+ value: 'rawData',
44
+ },
45
+ {
46
+ name: 'Alerts',
47
+ value: 'alerts',
48
+ },
49
+ {
50
+ name: 'Version',
51
+ value: 'version',
52
+ },
53
+ ],
54
+ default: 'data',
55
+ },
56
+ {
57
+ displayName: 'Operation',
58
+ name: 'operation',
59
+ type: 'options',
60
+ noDataExpression: true,
61
+ displayOptions: {
62
+ show: {
63
+ resource: ['data', 'events', 'rawData', 'alerts'],
64
+ },
65
+ },
66
+ options: [
67
+ {
68
+ name: 'Get',
69
+ value: 'get',
70
+ },
71
+ ],
72
+ default: 'get',
73
+ },
74
+ {
75
+ displayName: 'From Date',
76
+ name: 'fromDate',
77
+ type: 'string',
78
+ displayOptions: {
79
+ show: {
80
+ resource: ['data', 'events', 'rawData', 'alerts'],
81
+ },
82
+ },
83
+ default: 'last24hours',
84
+ description: 'Date range (e.g., last24hours, last7days)',
85
+ },
86
+ {
87
+ displayName: 'Metrics',
88
+ name: 'metrics',
89
+ type: 'string',
90
+ displayOptions: {
91
+ show: {
92
+ resource: ['data'],
93
+ },
94
+ },
95
+ default: 'views,hours,uniques',
96
+ description: 'Comma-separated metrics',
97
+ },
98
+ {
99
+ displayName: 'Granularity',
100
+ name: 'granularity',
101
+ type: 'options',
102
+ displayOptions: {
103
+ show: {
104
+ resource: ['data'],
105
+ },
106
+ },
107
+ options: [
108
+ { name: 'Hour', value: 'hour' },
109
+ { name: 'Day', value: 'day' },
110
+ { name: 'Week', value: 'week' },
111
+ { name: 'Month', value: 'month' },
112
+ ],
113
+ default: 'hour',
114
+ },
115
+ {
116
+ displayName: 'Limit',
117
+ name: 'limit',
118
+ type: 'number',
119
+ displayOptions: {
120
+ show: {
121
+ resource: ['events', 'rawData'],
122
+ },
123
+ },
124
+ default: 10,
125
+ description: 'Max number of results',
126
+ },
127
+ {
128
+ displayName: 'Additional Fields',
129
+ name: 'additionalFields',
130
+ type: 'collection',
131
+ placeholder: 'Add Field',
132
+ default: {},
133
+ displayOptions: {
134
+ show: {
135
+ resource: ['data'],
136
+ },
137
+ },
138
+ options: [
139
+ {
140
+ displayName: 'Group By',
141
+ name: 'groupBy',
142
+ type: 'string',
143
+ default: '',
144
+ },
145
+ {
146
+ displayName: 'Order By',
147
+ name: 'orderBy',
148
+ type: 'string',
149
+ default: '',
150
+ },
151
+ {
152
+ displayName: 'Order Direction',
153
+ name: 'orderDirection',
154
+ type: 'options',
155
+ options: [
156
+ { name: 'Ascending', value: 'asc' },
157
+ { name: 'Descending', value: 'desc' },
158
+ ],
159
+ default: 'desc',
160
+ },
161
+ {
162
+ displayName: 'Filter (JSON)',
163
+ name: 'filter',
164
+ type: 'string',
165
+ default: '',
166
+ description: 'JSON filter string',
167
+ },
168
+ ],
169
+ },
170
+ ],
171
+ };
172
+ }
173
+ async execute() {
174
+ const items = this.getInputData();
175
+ const returnData = [];
176
+ const credentials = await this.getCredentials('npawApi');
177
+ for (let i = 0; i < items.length; i++) {
178
+ const resource = this.getNodeParameter('resource', i);
179
+ const params = {};
180
+ if (resource === 'version') {
181
+ const response = await GenericFunctions_1.npawApiRequest.call(this, 'GET', '/version', {});
182
+ returnData.push(response);
183
+ continue;
184
+ }
185
+ const operation = this.getNodeParameter('operation', i);
186
+ if (operation === 'get') {
187
+ const fromDate = this.getNodeParameter('fromDate', i);
188
+ params.fromDate = fromDate;
189
+ let endpoint = '';
190
+ if (resource === 'data') {
191
+ endpoint = `/${credentials.accountCode}/data`;
192
+ params.metrics = this.getNodeParameter('metrics', i);
193
+ params.granularity = this.getNodeParameter('granularity', i);
194
+ params.version = '2';
195
+ const additionalFields = this.getNodeParameter('additionalFields', i);
196
+ if (additionalFields.groupBy)
197
+ params.groupBy = additionalFields.groupBy;
198
+ if (additionalFields.orderBy)
199
+ params.orderBy = additionalFields.orderBy;
200
+ if (additionalFields.orderDirection)
201
+ params.orderDirection = additionalFields.orderDirection;
202
+ if (additionalFields.filter)
203
+ params.filter = additionalFields.filter;
204
+ }
205
+ else if (resource === 'events') {
206
+ endpoint = `/${credentials.accountCode}/rawdata/events`;
207
+ params.limit = this.getNodeParameter('limit', i);
208
+ }
209
+ else if (resource === 'rawData') {
210
+ endpoint = `/${credentials.accountCode}/rawdata`;
211
+ params.limit = this.getNodeParameter('limit', i);
212
+ }
213
+ else if (resource === 'alerts') {
214
+ endpoint = `/${credentials.accountCode}/rawdata/genericalerts`;
215
+ }
216
+ const response = await GenericFunctions_1.npawApiRequest.call(this, 'GET', endpoint, params);
217
+ returnData.push(response);
218
+ }
219
+ }
220
+ return [this.helpers.returnJsonArray(returnData)];
221
+ }
222
+ }
223
+ exports.Npaw = Npaw;
224
+ //# sourceMappingURL=Npaw.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Npaw.node.js","sourceRoot":"","sources":["../../../nodes/Npaw/Npaw.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
2
+ <rect width="100" height="100" fill="#00A0DC"/>
3
+ <text x="50" y="60" font-family="Arial" font-size="40" font-weight="bold" fill="white" text-anchor="middle">N</text>
4
+ </svg>
package/index.js ADDED
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,38 @@
1
+ import {
2
+ IExecuteFunctions,
3
+ IDataObject,
4
+ NodeApiError,
5
+ IHttpRequestOptions,
6
+ IHttpRequestMethods,
7
+ } from 'n8n-workflow';
8
+
9
+ export async function npawApiRequest(
10
+ this: IExecuteFunctions,
11
+ method: IHttpRequestMethods,
12
+ endpoint: string,
13
+ params: IDataObject = {},
14
+ ): Promise<any> {
15
+ const credentials = await this.getCredentials('npawApi');
16
+
17
+ const url = new URL(`${credentials.baseUrl}${endpoint}`);
18
+ Object.keys(params).forEach(key => {
19
+ if (params[key] !== undefined && params[key] !== null) {
20
+ url.searchParams.append(key, String(params[key]));
21
+ }
22
+ });
23
+
24
+ const options: IHttpRequestOptions = {
25
+ method,
26
+ url: url.toString(),
27
+ headers: {
28
+ 'npaw-api-key': credentials.apiKey as string,
29
+ },
30
+ json: true,
31
+ };
32
+
33
+ try {
34
+ return await this.helpers.httpRequest(options);
35
+ } catch (error: any) {
36
+ throw new NodeApiError(this.getNode(), error);
37
+ }
38
+ }
@@ -0,0 +1,229 @@
1
+ import {
2
+ IExecuteFunctions,
3
+ INodeExecutionData,
4
+ INodeType,
5
+ INodeTypeDescription,
6
+ IDataObject,
7
+ } from 'n8n-workflow';
8
+
9
+ import { npawApiRequest } from './GenericFunctions';
10
+
11
+ export class Npaw implements INodeType {
12
+ description: INodeTypeDescription = {
13
+ displayName: 'NPAW',
14
+ name: 'npaw',
15
+ icon: 'file:npaw.svg',
16
+ group: ['transform'],
17
+ version: 1,
18
+ subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
19
+ description: 'Consume NPAW/Youbora API',
20
+ defaults: {
21
+ name: 'NPAW',
22
+ },
23
+ inputs: ['main'],
24
+ outputs: ['main'],
25
+ credentials: [
26
+ {
27
+ name: 'npawApi',
28
+ required: true,
29
+ },
30
+ ],
31
+ properties: [
32
+ {
33
+ displayName: 'Resource',
34
+ name: 'resource',
35
+ type: 'options',
36
+ noDataExpression: true,
37
+ options: [
38
+ {
39
+ name: 'Data',
40
+ value: 'data',
41
+ },
42
+ {
43
+ name: 'Events',
44
+ value: 'events',
45
+ },
46
+ {
47
+ name: 'Raw Data',
48
+ value: 'rawData',
49
+ },
50
+ {
51
+ name: 'Alerts',
52
+ value: 'alerts',
53
+ },
54
+ {
55
+ name: 'Version',
56
+ value: 'version',
57
+ },
58
+ ],
59
+ default: 'data',
60
+ },
61
+ {
62
+ displayName: 'Operation',
63
+ name: 'operation',
64
+ type: 'options',
65
+ noDataExpression: true,
66
+ displayOptions: {
67
+ show: {
68
+ resource: ['data', 'events', 'rawData', 'alerts'],
69
+ },
70
+ },
71
+ options: [
72
+ {
73
+ name: 'Get',
74
+ value: 'get',
75
+ },
76
+ ],
77
+ default: 'get',
78
+ },
79
+ {
80
+ displayName: 'From Date',
81
+ name: 'fromDate',
82
+ type: 'string',
83
+ displayOptions: {
84
+ show: {
85
+ resource: ['data', 'events', 'rawData', 'alerts'],
86
+ },
87
+ },
88
+ default: 'last24hours',
89
+ description: 'Date range (e.g., last24hours, last7days)',
90
+ },
91
+ {
92
+ displayName: 'Metrics',
93
+ name: 'metrics',
94
+ type: 'string',
95
+ displayOptions: {
96
+ show: {
97
+ resource: ['data'],
98
+ },
99
+ },
100
+ default: 'views,hours,uniques',
101
+ description: 'Comma-separated metrics',
102
+ },
103
+ {
104
+ displayName: 'Granularity',
105
+ name: 'granularity',
106
+ type: 'options',
107
+ displayOptions: {
108
+ show: {
109
+ resource: ['data'],
110
+ },
111
+ },
112
+ options: [
113
+ { name: 'Hour', value: 'hour' },
114
+ { name: 'Day', value: 'day' },
115
+ { name: 'Week', value: 'week' },
116
+ { name: 'Month', value: 'month' },
117
+ ],
118
+ default: 'hour',
119
+ },
120
+ {
121
+ displayName: 'Limit',
122
+ name: 'limit',
123
+ type: 'number',
124
+ displayOptions: {
125
+ show: {
126
+ resource: ['events', 'rawData'],
127
+ },
128
+ },
129
+ default: 10,
130
+ description: 'Max number of results',
131
+ },
132
+ {
133
+ displayName: 'Additional Fields',
134
+ name: 'additionalFields',
135
+ type: 'collection',
136
+ placeholder: 'Add Field',
137
+ default: {},
138
+ displayOptions: {
139
+ show: {
140
+ resource: ['data'],
141
+ },
142
+ },
143
+ options: [
144
+ {
145
+ displayName: 'Group By',
146
+ name: 'groupBy',
147
+ type: 'string',
148
+ default: '',
149
+ },
150
+ {
151
+ displayName: 'Order By',
152
+ name: 'orderBy',
153
+ type: 'string',
154
+ default: '',
155
+ },
156
+ {
157
+ displayName: 'Order Direction',
158
+ name: 'orderDirection',
159
+ type: 'options',
160
+ options: [
161
+ { name: 'Ascending', value: 'asc' },
162
+ { name: 'Descending', value: 'desc' },
163
+ ],
164
+ default: 'desc',
165
+ },
166
+ {
167
+ displayName: 'Filter (JSON)',
168
+ name: 'filter',
169
+ type: 'string',
170
+ default: '',
171
+ description: 'JSON filter string',
172
+ },
173
+ ],
174
+ },
175
+ ],
176
+ };
177
+
178
+ async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
179
+ const items = this.getInputData();
180
+ const returnData: IDataObject[] = [];
181
+ const credentials = await this.getCredentials('npawApi');
182
+
183
+ for (let i = 0; i < items.length; i++) {
184
+ const resource = this.getNodeParameter('resource', i) as string;
185
+ const params: IDataObject = {};
186
+
187
+ if (resource === 'version') {
188
+ const response = await npawApiRequest.call(this, 'GET', '/version', {});
189
+ returnData.push(response);
190
+ continue;
191
+ }
192
+
193
+ const operation = this.getNodeParameter('operation', i) as string;
194
+
195
+ if (operation === 'get') {
196
+ const fromDate = this.getNodeParameter('fromDate', i) as string;
197
+ params.fromDate = fromDate;
198
+
199
+ let endpoint = '';
200
+
201
+ if (resource === 'data') {
202
+ endpoint = `/${credentials.accountCode}/data`;
203
+ params.metrics = this.getNodeParameter('metrics', i) as string;
204
+ params.granularity = this.getNodeParameter('granularity', i) as string;
205
+ params.version = '2';
206
+
207
+ const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
208
+ if (additionalFields.groupBy) params.groupBy = additionalFields.groupBy;
209
+ if (additionalFields.orderBy) params.orderBy = additionalFields.orderBy;
210
+ if (additionalFields.orderDirection) params.orderDirection = additionalFields.orderDirection;
211
+ if (additionalFields.filter) params.filter = additionalFields.filter;
212
+ } else if (resource === 'events') {
213
+ endpoint = `/${credentials.accountCode}/rawdata/events`;
214
+ params.limit = this.getNodeParameter('limit', i) as number;
215
+ } else if (resource === 'rawData') {
216
+ endpoint = `/${credentials.accountCode}/rawdata`;
217
+ params.limit = this.getNodeParameter('limit', i) as number;
218
+ } else if (resource === 'alerts') {
219
+ endpoint = `/${credentials.accountCode}/rawdata/genericalerts`;
220
+ }
221
+
222
+ const response = await npawApiRequest.call(this, 'GET', endpoint, params);
223
+ returnData.push(response);
224
+ }
225
+ }
226
+
227
+ return [this.helpers.returnJsonArray(returnData)];
228
+ }
229
+ }
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
2
+ <rect width="100" height="100" fill="#00A0DC"/>
3
+ <text x="50" y="60" font-family="Arial" font-size="40" font-weight="bold" fill="white" text-anchor="middle">N</text>
4
+ </svg>
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@lbono/n8n-nodes-npaw",
3
+ "version": "2.0.0",
4
+ "description": "NPAW/Youbora support for n8n",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "Luciano Bono",
8
+ "email": "choncba@gmail.com"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/choncba/n8n-nodes-npaw.git"
13
+ },
14
+ "keywords": [
15
+ "n8n-community-node-package",
16
+ "n8n",
17
+ "npaw",
18
+ "youbora",
19
+ "nodes",
20
+ "workflow",
21
+ "analytics"
22
+ ],
23
+ "main": "index.js",
24
+ "scripts": {
25
+ "build": "tsc && gulp",
26
+ "watch": "tsc --watch",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "credentials",
32
+ "nodes"
33
+ ],
34
+ "n8n": {
35
+ "n8nNodesApiVersion": 1,
36
+ "credentials": [
37
+ "dist/credentials/NpawApi.credentials.js"
38
+ ],
39
+ "nodes": [
40
+ "dist/nodes/Npaw/Npaw.node.js"
41
+ ]
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.0.0",
45
+ "gulp": "^4.0.0",
46
+ "n8n-workflow": "^1.0.0",
47
+ "typescript": "^5.0.0"
48
+ },
49
+ "peerDependencies": {
50
+ "n8n-workflow": "*"
51
+ }
52
+ }