@comandosai/n8n-nodes-lsi-keys 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/LsiKeys.png +0 -0
- package/README.md +37 -0
- package/credentials/ComandosApi.credentials.ts +19 -0
- package/dist/credentials/ComandosApi.credentials.d.ts +7 -0
- package/dist/credentials/ComandosApi.credentials.js +22 -0
- package/dist/credentials/ComandosApi.credentials.js.map +1 -0
- package/dist/credentials/ComandosWordpressApi.credentials.d.ts +7 -0
- package/dist/credentials/ComandosWordpressApi.credentials.js +46 -0
- package/dist/credentials/ComandosWordpressApi.credentials.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/ComandosLsiKeys.node.d.ts +5 -0
- package/dist/nodes/ComandosLsiKeys.node.js +132 -0
- package/dist/nodes/ComandosLsiKeys.node.js.map +1 -0
- package/dist/nodes/LsiKeys.png +0 -0
- package/index.ts +4 -0
- package/nodes/ComandosLsiKeys.node.ts +142 -0
- package/package.json +25 -0
- package/tsconfig.json +25 -0
package/LsiKeys.png
ADDED
|
Binary file
|
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Commandos LSI Keys (кастомная нода n8n)
|
|
2
|
+
|
|
3
|
+
Кастомная нода для генерации LSI-ключей через Comandos API.
|
|
4
|
+
|
|
5
|
+
## Где находится
|
|
6
|
+
|
|
7
|
+
- Код ноды: `/root/sandbox/nodes/lsi-keys`
|
|
8
|
+
- Пакет: `@comandosai/n8n-nodes-lsi-keys`
|
|
9
|
+
|
|
10
|
+
## Требования
|
|
11
|
+
|
|
12
|
+
- n8n (dev окружение)
|
|
13
|
+
- Node.js 18+
|
|
14
|
+
- Доступ к Commandos API
|
|
15
|
+
|
|
16
|
+
## Подключение в n8n-dev
|
|
17
|
+
|
|
18
|
+
В `docker-compose` нужно:
|
|
19
|
+
- смонтировать `/root/sandbox/nodes` в `/custom/commandos`
|
|
20
|
+
- добавить путь `N8N_CUSTOM_EXTENSIONS=/custom/commandos`
|
|
21
|
+
|
|
22
|
+
## Credentials
|
|
23
|
+
|
|
24
|
+
Тип: `Commandos API` (лицензионный ключ)
|
|
25
|
+
|
|
26
|
+
## Параметры
|
|
27
|
+
|
|
28
|
+
- **Topic**: Основная тема для сбора LSI
|
|
29
|
+
- **Country**: Страна (RU, US и т.д.)
|
|
30
|
+
- **City**: Город
|
|
31
|
+
|
|
32
|
+
## Сборка
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install
|
|
36
|
+
npm run build
|
|
37
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ICredentialType, INodeProperties } from 'n8n-workflow';
|
|
2
|
+
|
|
3
|
+
export class ComandosApi implements ICredentialType {
|
|
4
|
+
name = 'comandosApi';
|
|
5
|
+
displayName = 'Comandos API';
|
|
6
|
+
documentationUrl = 'https://api.comandos.ai';
|
|
7
|
+
properties: INodeProperties[] = [
|
|
8
|
+
{
|
|
9
|
+
displayName: 'License Key',
|
|
10
|
+
name: 'licenseKey',
|
|
11
|
+
type: 'string',
|
|
12
|
+
default: '',
|
|
13
|
+
required: true,
|
|
14
|
+
typeOptions: {
|
|
15
|
+
password: true,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComandosApi = void 0;
|
|
4
|
+
class ComandosApi {
|
|
5
|
+
name = 'comandosApi';
|
|
6
|
+
displayName = 'Comandos API';
|
|
7
|
+
documentationUrl = 'https://api.comandos.ai';
|
|
8
|
+
properties = [
|
|
9
|
+
{
|
|
10
|
+
displayName: 'License Key',
|
|
11
|
+
name: 'licenseKey',
|
|
12
|
+
type: 'string',
|
|
13
|
+
default: '',
|
|
14
|
+
required: true,
|
|
15
|
+
typeOptions: {
|
|
16
|
+
password: true,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
exports.ComandosApi = ComandosApi;
|
|
22
|
+
//# sourceMappingURL=ComandosApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComandosApi.credentials.js","sourceRoot":"","sources":["../../credentials/ComandosApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,WAAW;IACtB,IAAI,GAAG,aAAa,CAAC;IACrB,WAAW,GAAG,cAAc,CAAC;IAC7B,gBAAgB,GAAG,yBAAyB,CAAC;IAC7C,UAAU,GAAsB;QAC9B;YACE,WAAW,EAAE,aAAa;YAC1B,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE;gBACX,QAAQ,EAAE,IAAI;aACf;SACF;KACF,CAAC;CACH;AAhBD,kCAgBC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComandosWordpressApi = void 0;
|
|
4
|
+
class ComandosWordpressApi {
|
|
5
|
+
name = 'comandosWordpressApi';
|
|
6
|
+
displayName = 'Comandos WordPress';
|
|
7
|
+
documentationUrl = 'https://api.comandos.ai';
|
|
8
|
+
properties = [
|
|
9
|
+
{
|
|
10
|
+
displayName: 'Лицензионный ключ',
|
|
11
|
+
name: 'licenseKey',
|
|
12
|
+
type: 'string',
|
|
13
|
+
default: '',
|
|
14
|
+
required: true,
|
|
15
|
+
typeOptions: {
|
|
16
|
+
password: true,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
displayName: 'URL WordPress',
|
|
21
|
+
name: 'wpUrl',
|
|
22
|
+
type: 'string',
|
|
23
|
+
default: '',
|
|
24
|
+
required: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Имя пользователя WordPress',
|
|
28
|
+
name: 'wpUsername',
|
|
29
|
+
type: 'string',
|
|
30
|
+
default: '',
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Пароль приложения WordPress',
|
|
35
|
+
name: 'wpAppPassword',
|
|
36
|
+
type: 'string',
|
|
37
|
+
default: '',
|
|
38
|
+
required: true,
|
|
39
|
+
typeOptions: {
|
|
40
|
+
password: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
exports.ComandosWordpressApi = ComandosWordpressApi;
|
|
46
|
+
//# sourceMappingURL=ComandosWordpressApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComandosWordpressApi.credentials.js","sourceRoot":"","sources":["../../credentials/ComandosWordpressApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,oBAAoB;IAC/B,IAAI,GAAG,sBAAsB,CAAC;IAC9B,WAAW,GAAG,oBAAoB,CAAC;IACnC,gBAAgB,GAAG,yBAAyB,CAAC;IAC7C,UAAU,GAAsB;QAC9B;YACE,WAAW,EAAE,mBAAmB;YAChC,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE;gBACX,QAAQ,EAAE,IAAI;aACf;SACF;QACD;YACE,WAAW,EAAE,eAAe;YAC5B,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;SACf;QACD;YACE,WAAW,EAAE,4BAA4B;YACzC,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;SACf;QACD;YACE,WAAW,EAAE,6BAA6B;YAC1C,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE;gBACX,QAAQ,EAAE,IAAI;aACf;SACF;KACF,CAAC;CACH;AAxCD,oDAwCC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComandosApi = exports.ComandosLsiKeys = void 0;
|
|
4
|
+
const ComandosLsiKeys_node_1 = require("./nodes/ComandosLsiKeys.node");
|
|
5
|
+
Object.defineProperty(exports, "ComandosLsiKeys", { enumerable: true, get: function () { return ComandosLsiKeys_node_1.ComandosLsiKeys; } });
|
|
6
|
+
const ComandosApi_credentials_1 = require("./credentials/ComandosApi.credentials");
|
|
7
|
+
Object.defineProperty(exports, "ComandosApi", { enumerable: true, get: function () { return ComandosApi_credentials_1.ComandosApi; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AAAA,uEAA+D;AAGtD,gGAHA,sCAAe,OAGA;AAFxB,mFAAoE;AAE1C,4FAFjB,qCAAW,OAEiB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class ComandosLsiKeys implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComandosLsiKeys = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const COMANDOS_API_URL = String(process.env.COMANDOS_API_BASE_URL || process.env.COMMANDOS_API_BASE_URL || "https://api.comandos.ai").trim();
|
|
6
|
+
class ComandosLsiKeys {
|
|
7
|
+
description = {
|
|
8
|
+
displayName: 'Comandos LSI Keys',
|
|
9
|
+
name: 'comandosLsiKeys',
|
|
10
|
+
group: ['transform'],
|
|
11
|
+
version: 1,
|
|
12
|
+
description: 'Генерация LSI ключей через Comandos API',
|
|
13
|
+
defaults: {
|
|
14
|
+
name: 'Comandos LSI Keys',
|
|
15
|
+
},
|
|
16
|
+
icon: 'file:LsiKeys.png',
|
|
17
|
+
inputs: ['main'],
|
|
18
|
+
outputs: ['main'],
|
|
19
|
+
credentials: [
|
|
20
|
+
{
|
|
21
|
+
name: 'comandosApi',
|
|
22
|
+
required: true,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
properties: [
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Операция',
|
|
28
|
+
name: 'operation',
|
|
29
|
+
type: 'options',
|
|
30
|
+
noDataExpression: true,
|
|
31
|
+
options: [
|
|
32
|
+
{
|
|
33
|
+
name: 'LSI Ключи',
|
|
34
|
+
value: 'getLsiKeys',
|
|
35
|
+
description: 'Сгенерировать облако семантически связанных слов (LSI) для вашей темы',
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
default: 'getLsiKeys',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
displayName: 'Тема (Topic)',
|
|
42
|
+
name: 'topic',
|
|
43
|
+
type: 'string',
|
|
44
|
+
default: '',
|
|
45
|
+
required: true,
|
|
46
|
+
displayOptions: {
|
|
47
|
+
show: {
|
|
48
|
+
operation: ['getLsiKeys'],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
description: 'Введите тему или запрос, для которого нужно подобрать ключи',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
displayName: 'Страна',
|
|
55
|
+
name: 'country',
|
|
56
|
+
type: 'string',
|
|
57
|
+
default: '',
|
|
58
|
+
displayOptions: {
|
|
59
|
+
show: {
|
|
60
|
+
operation: ['getLsiKeys'],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
description: 'Укажите страну для уточнения семантики (например: Россия)',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
displayName: 'Город',
|
|
67
|
+
name: 'city',
|
|
68
|
+
type: 'string',
|
|
69
|
+
default: '',
|
|
70
|
+
displayOptions: {
|
|
71
|
+
show: {
|
|
72
|
+
operation: ['getLsiKeys'],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
description: 'Укажите город для уточнения семантики (например: Москва)',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
async execute() {
|
|
80
|
+
const items = this.getInputData();
|
|
81
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
82
|
+
const credentials = await this.getCredentials('comandosApi');
|
|
83
|
+
const licenseKey = String(credentials.licenseKey || '').trim();
|
|
84
|
+
if (!licenseKey) {
|
|
85
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Лицензионный ключ обязателен');
|
|
86
|
+
}
|
|
87
|
+
const results = [];
|
|
88
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
89
|
+
try {
|
|
90
|
+
if (operation === 'getLsiKeys') {
|
|
91
|
+
const topic = String(this.getNodeParameter('topic', i) || '').trim();
|
|
92
|
+
const country = String(this.getNodeParameter('country', i) || '').trim();
|
|
93
|
+
const city = String(this.getNodeParameter('city', i) || '').trim();
|
|
94
|
+
if (!topic) {
|
|
95
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Тема обязательна для получения LSI ключей', {
|
|
96
|
+
itemIndex: i,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const response = await this.helpers.request({
|
|
100
|
+
method: 'POST',
|
|
101
|
+
url: `${COMANDOS_API_URL}/tasks`,
|
|
102
|
+
headers: {
|
|
103
|
+
'Content-Type': 'application/json',
|
|
104
|
+
'X-License-Key': licenseKey,
|
|
105
|
+
},
|
|
106
|
+
body: {
|
|
107
|
+
process_type: 'WP_PUBLICATION',
|
|
108
|
+
payload: {
|
|
109
|
+
action: 'get_lsi_keys',
|
|
110
|
+
topic,
|
|
111
|
+
country,
|
|
112
|
+
city,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
json: true,
|
|
116
|
+
});
|
|
117
|
+
results.push({ json: response });
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (error instanceof n8n_workflow_1.NodeOperationError)
|
|
123
|
+
throw error;
|
|
124
|
+
const message = error instanceof Error ? error.message : 'Ошибка при выполнении запроса';
|
|
125
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), message, { itemIndex: i });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return [results];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.ComandosLsiKeys = ComandosLsiKeys;
|
|
132
|
+
//# sourceMappingURL=ComandosLsiKeys.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComandosLsiKeys.node.js","sourceRoot":"","sources":["../../nodes/ComandosLsiKeys.node.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
package/index.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IDataObject,
|
|
3
|
+
IExecuteFunctions,
|
|
4
|
+
INodeExecutionData,
|
|
5
|
+
INodeType,
|
|
6
|
+
INodeTypeDescription,
|
|
7
|
+
} from 'n8n-workflow';
|
|
8
|
+
import { NodeOperationError } from 'n8n-workflow';
|
|
9
|
+
|
|
10
|
+
const COMANDOS_API_URL = String(process.env.COMANDOS_API_BASE_URL || process.env.COMMANDOS_API_BASE_URL || "https://api.comandos.ai").trim();
|
|
11
|
+
|
|
12
|
+
export class ComandosLsiKeys implements INodeType {
|
|
13
|
+
description: INodeTypeDescription = {
|
|
14
|
+
displayName: 'Comandos LSI Keys',
|
|
15
|
+
name: 'comandosLsiKeys',
|
|
16
|
+
group: ['transform'],
|
|
17
|
+
version: 1,
|
|
18
|
+
description: 'Генерация LSI ключей через Comandos API',
|
|
19
|
+
defaults: {
|
|
20
|
+
name: 'Comandos LSI Keys',
|
|
21
|
+
},
|
|
22
|
+
icon: 'file:LsiKeys.png',
|
|
23
|
+
inputs: ['main'],
|
|
24
|
+
outputs: ['main'],
|
|
25
|
+
credentials: [
|
|
26
|
+
{
|
|
27
|
+
name: 'comandosApi',
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
properties: [
|
|
32
|
+
{
|
|
33
|
+
displayName: 'Операция',
|
|
34
|
+
name: 'operation',
|
|
35
|
+
type: 'options',
|
|
36
|
+
noDataExpression: true,
|
|
37
|
+
options: [
|
|
38
|
+
{
|
|
39
|
+
name: 'LSI Ключи',
|
|
40
|
+
value: 'getLsiKeys',
|
|
41
|
+
description: 'Сгенерировать облако семантически связанных слов (LSI) для вашей темы',
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
default: 'getLsiKeys',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
displayName: 'Тема (Topic)',
|
|
48
|
+
name: 'topic',
|
|
49
|
+
type: 'string',
|
|
50
|
+
default: '',
|
|
51
|
+
required: true,
|
|
52
|
+
displayOptions: {
|
|
53
|
+
show: {
|
|
54
|
+
operation: ['getLsiKeys'],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
description: 'Введите тему или запрос, для которого нужно подобрать ключи',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
displayName: 'Страна',
|
|
61
|
+
name: 'country',
|
|
62
|
+
type: 'string',
|
|
63
|
+
default: '',
|
|
64
|
+
displayOptions: {
|
|
65
|
+
show: {
|
|
66
|
+
operation: ['getLsiKeys'],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
description: 'Укажите страну для уточнения семантики (например: Россия)',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
displayName: 'Город',
|
|
73
|
+
name: 'city',
|
|
74
|
+
type: 'string',
|
|
75
|
+
default: '',
|
|
76
|
+
displayOptions: {
|
|
77
|
+
show: {
|
|
78
|
+
operation: ['getLsiKeys'],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
description: 'Укажите город для уточнения семантики (например: Москва)',
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
87
|
+
const items = this.getInputData();
|
|
88
|
+
const operation = this.getNodeParameter('operation', 0) as string;
|
|
89
|
+
const credentials = await this.getCredentials('comandosApi');
|
|
90
|
+
const licenseKey = String(credentials.licenseKey || '').trim();
|
|
91
|
+
|
|
92
|
+
if (!licenseKey) {
|
|
93
|
+
throw new NodeOperationError(this.getNode(), 'Лицензионный ключ обязателен');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const results: INodeExecutionData[] = [];
|
|
97
|
+
|
|
98
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
99
|
+
try {
|
|
100
|
+
if (operation === 'getLsiKeys') {
|
|
101
|
+
const topic = String(this.getNodeParameter('topic', i) || '').trim();
|
|
102
|
+
const country = String(this.getNodeParameter('country', i) || '').trim();
|
|
103
|
+
const city = String(this.getNodeParameter('city', i) || '').trim();
|
|
104
|
+
|
|
105
|
+
if (!topic) {
|
|
106
|
+
throw new NodeOperationError(this.getNode(), 'Тема обязательна для получения LSI ключей', {
|
|
107
|
+
itemIndex: i,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const response = await this.helpers.request({
|
|
112
|
+
method: 'POST',
|
|
113
|
+
url: `${COMANDOS_API_URL}/tasks`,
|
|
114
|
+
headers: {
|
|
115
|
+
'Content-Type': 'application/json',
|
|
116
|
+
'X-License-Key': licenseKey,
|
|
117
|
+
},
|
|
118
|
+
body: {
|
|
119
|
+
process_type: 'WP_PUBLICATION',
|
|
120
|
+
payload: {
|
|
121
|
+
action: 'get_lsi_keys',
|
|
122
|
+
topic,
|
|
123
|
+
country,
|
|
124
|
+
city,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
json: true,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
results.push({ json: response as IDataObject });
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (error instanceof NodeOperationError) throw error;
|
|
135
|
+
const message = error instanceof Error ? error.message : 'Ошибка при выполнении запроса';
|
|
136
|
+
throw new NodeOperationError(this.getNode(), message, { itemIndex: i });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return [results];
|
|
141
|
+
}
|
|
142
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@comandosai/n8n-nodes-lsi-keys",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Comandos LSI Keys custom node",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc -p tsconfig.json && mkdir -p dist/nodes && cp -f LsiKeys.png dist/nodes/"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"n8n-workflow": "^1.0.0"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/node": "^18.19.0",
|
|
15
|
+
"typescript": "^5.4.5"
|
|
16
|
+
},
|
|
17
|
+
"n8n": {
|
|
18
|
+
"nodes": [
|
|
19
|
+
"dist/nodes/ComandosLsiKeys.node.js"
|
|
20
|
+
],
|
|
21
|
+
"credentials": [
|
|
22
|
+
"dist/credentials/ComandosApi.credentials.js"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "CommonJS",
|
|
5
|
+
"lib": [
|
|
6
|
+
"ESNext"
|
|
7
|
+
],
|
|
8
|
+
"declaration": true,
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"outDir": "dist",
|
|
11
|
+
"rootDir": ".",
|
|
12
|
+
"strict": true,
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"moduleResolution": "node"
|
|
17
|
+
},
|
|
18
|
+
"include": [
|
|
19
|
+
"**/*.ts"
|
|
20
|
+
],
|
|
21
|
+
"exclude": [
|
|
22
|
+
"node_modules",
|
|
23
|
+
"dist"
|
|
24
|
+
]
|
|
25
|
+
}
|