@seranking/n8n-nodes-seranking 1.3.8 → 1.4.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 +2 -2
- package/dist/nodes/SeRanking/dataApi/descriptions/AiSearchDescription.js +107 -103
- package/dist/nodes/SeRanking/dataApi/descriptions/DomainAnalysisDescription.js +35 -0
- package/dist/nodes/SeRanking/dataApi/operations/AiSearchOperations.js +54 -8
- package/dist/nodes/SeRanking/dataApi/operations/DomainAnalysisOperations.js +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -574,7 +574,7 @@ For detailed API specifications, visit [SE Ranking API Documentation](https://se
|
|
|
574
574
|
- ✅ **NEW: Get Domain Pages** - Page-level keyword and traffic analysis with intent breakdown
|
|
575
575
|
- ✅ **NEW: Get Domain Subdomains** - Subdomain traffic and keyword metrics
|
|
576
576
|
- ✅ **Total: 62 operations across 6 resources**
|
|
577
|
-
- ✅ Advanced filtering for pages/subdomains (traffic %, keywords count, traffic sum)
|
|
577
|
+
- ✅ Advanced filtering for pages/subdomains (traffic %, keywords count, traffic sum,)
|
|
578
578
|
- ✅ Search intent breakdown (Informational, Navigational, Transactional, Commercial, Local)
|
|
579
579
|
|
|
580
580
|
### v1.3.0
|
|
@@ -659,7 +659,7 @@ For detailed API specifications, visit [SE Ranking API Documentation](https://se
|
|
|
659
659
|
|
|
660
660
|
✅ **SERP Tracking** - Keyword ranking and SERP features analysis
|
|
661
661
|
|
|
662
|
-
✅ **Advanced Filtering** - Volume, position, CPC, difficulty, traffic, search intent, SERP features, keyword word count, and include/exclude keyword pattern filters
|
|
662
|
+
✅ **Advanced Filtering** - Volume, position, CPC, difficulty, traffic, search intent, SERP features, keyword word count, and include/exclude keyword pattern filters, and the new SERP Feature Link filter (filter[serp_features_2]) — which lets you filter keywords where your domain is specifically linked within a SERP feature (e.g. AI Overviews, Reviews), distinct from the existing serpFeatures filter which only checks for feature presence on the SERP.
|
|
663
663
|
|
|
664
664
|
---
|
|
665
665
|
|
|
@@ -90,31 +90,11 @@ exports.aiSearchFields = [
|
|
|
90
90
|
},
|
|
91
91
|
},
|
|
92
92
|
options: [
|
|
93
|
-
{
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'ChatGPT',
|
|
100
|
-
value: 'chatgpt',
|
|
101
|
-
description: 'OpenAI ChatGPT results',
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: 'Perplexity',
|
|
105
|
-
value: 'perplexity',
|
|
106
|
-
description: 'Perplexity AI results',
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
name: 'Gemini',
|
|
110
|
-
value: 'gemini',
|
|
111
|
-
description: 'Google Gemini results',
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
name: 'AI Mode',
|
|
115
|
-
value: 'ai-mode',
|
|
116
|
-
description: 'AI Mode results',
|
|
117
|
-
},
|
|
93
|
+
{ name: 'AI Overview', value: 'ai-overview', description: 'Google AI Overview results' },
|
|
94
|
+
{ name: 'ChatGPT', value: 'chatgpt', description: 'OpenAI ChatGPT results' },
|
|
95
|
+
{ name: 'Perplexity', value: 'perplexity', description: 'Perplexity AI results' },
|
|
96
|
+
{ name: 'Gemini', value: 'gemini', description: 'Google Gemini results' },
|
|
97
|
+
{ name: 'AI Mode', value: 'ai-mode', description: 'AI Mode results' },
|
|
118
98
|
],
|
|
119
99
|
default: 'chatgpt',
|
|
120
100
|
description: 'The LLM engine to query',
|
|
@@ -144,24 +124,35 @@ exports.aiSearchFields = [
|
|
|
144
124
|
},
|
|
145
125
|
},
|
|
146
126
|
options: [
|
|
147
|
-
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
127
|
+
{ name: 'Base Domain', value: 'base_domain', description: 'Aggregate by registrable domain, includes all subdomains' },
|
|
128
|
+
{ name: 'Domain', value: 'domain', description: 'Exact host only, no subdomain aggregation' },
|
|
129
|
+
{ name: 'URL', value: 'url', description: 'Exact URL including path and query' },
|
|
130
|
+
],
|
|
131
|
+
default: 'base_domain',
|
|
132
|
+
description: 'Scope of analysis - base_domain is recommended for most use cases',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
displayName: 'Additional Fields',
|
|
136
|
+
name: 'additionalFields',
|
|
137
|
+
type: 'collection',
|
|
138
|
+
placeholder: 'Add Field',
|
|
139
|
+
default: {},
|
|
140
|
+
displayOptions: {
|
|
141
|
+
show: {
|
|
142
|
+
resource: ['aiSearch'],
|
|
143
|
+
operation: ['getOverview'],
|
|
156
144
|
},
|
|
145
|
+
},
|
|
146
|
+
options: [
|
|
157
147
|
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
148
|
+
displayName: 'Brand',
|
|
149
|
+
name: 'brand',
|
|
150
|
+
type: 'string',
|
|
151
|
+
default: '',
|
|
152
|
+
placeholder: 'SE Ranking',
|
|
153
|
+
description: 'Brand name to filter the brand presence analysis',
|
|
161
154
|
},
|
|
162
155
|
],
|
|
163
|
-
default: 'base_domain',
|
|
164
|
-
description: 'Scope of analysis - base_domain is recommended for most use cases',
|
|
165
156
|
},
|
|
166
157
|
{
|
|
167
158
|
displayName: 'Additional Fields',
|
|
@@ -181,21 +172,9 @@ exports.aiSearchFields = [
|
|
|
181
172
|
name: 'sort',
|
|
182
173
|
type: 'options',
|
|
183
174
|
options: [
|
|
184
|
-
{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
description: 'Sort by search volume',
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
name: 'Type',
|
|
191
|
-
value: 'type',
|
|
192
|
-
description: 'Sort by appearance type (Link, Brand, etc.)',
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
name: 'Snippet Length',
|
|
196
|
-
value: 'snippet_length',
|
|
197
|
-
description: 'Sort by length of the LLM snippet',
|
|
198
|
-
},
|
|
175
|
+
{ name: 'Volume', value: 'volume', description: 'Sort by search volume' },
|
|
176
|
+
{ name: 'Type', value: 'type', description: 'Sort by appearance type (Link, Brand, etc.)' },
|
|
177
|
+
{ name: 'Snippet Length', value: 'snippet_length', description: 'Sort by length of the LLM snippet' },
|
|
199
178
|
],
|
|
200
179
|
default: 'volume',
|
|
201
180
|
description: 'Field to sort results by',
|
|
@@ -205,16 +184,8 @@ exports.aiSearchFields = [
|
|
|
205
184
|
name: 'sortOrder',
|
|
206
185
|
type: 'options',
|
|
207
186
|
options: [
|
|
208
|
-
{
|
|
209
|
-
|
|
210
|
-
value: 'desc',
|
|
211
|
-
description: 'Highest to lowest',
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
name: 'Ascending',
|
|
215
|
-
value: 'asc',
|
|
216
|
-
description: 'Lowest to highest',
|
|
217
|
-
},
|
|
187
|
+
{ name: 'Descending', value: 'desc', description: 'Highest to lowest' },
|
|
188
|
+
{ name: 'Ascending', value: 'asc', description: 'Lowest to highest' },
|
|
218
189
|
],
|
|
219
190
|
default: 'desc',
|
|
220
191
|
description: 'Order of sorting',
|
|
@@ -225,10 +196,7 @@ exports.aiSearchFields = [
|
|
|
225
196
|
type: 'number',
|
|
226
197
|
default: 100,
|
|
227
198
|
description: 'Maximum number of results to return per page (max 1000)',
|
|
228
|
-
typeOptions: {
|
|
229
|
-
minValue: 1,
|
|
230
|
-
maxValue: 1000,
|
|
231
|
-
},
|
|
199
|
+
typeOptions: { minValue: 1, maxValue: 1000 },
|
|
232
200
|
},
|
|
233
201
|
{
|
|
234
202
|
displayName: 'Offset',
|
|
@@ -236,9 +204,67 @@ exports.aiSearchFields = [
|
|
|
236
204
|
type: 'number',
|
|
237
205
|
default: 0,
|
|
238
206
|
description: 'Number of results to skip for pagination',
|
|
239
|
-
typeOptions: {
|
|
240
|
-
|
|
241
|
-
|
|
207
|
+
typeOptions: { minValue: 0 },
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
displayName: 'Volume From',
|
|
211
|
+
name: 'volumeFrom',
|
|
212
|
+
type: 'number',
|
|
213
|
+
default: 0,
|
|
214
|
+
description: 'Minimum monthly search volume for prompts',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
displayName: 'Volume To',
|
|
218
|
+
name: 'volumeTo',
|
|
219
|
+
type: 'number',
|
|
220
|
+
default: 0,
|
|
221
|
+
description: 'Maximum monthly search volume (0 = no limit)',
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
displayName: 'Keyword Word Count From',
|
|
225
|
+
name: 'keywordCountFrom',
|
|
226
|
+
type: 'number',
|
|
227
|
+
default: 0,
|
|
228
|
+
description: 'Minimum number of words in a prompt',
|
|
229
|
+
typeOptions: { minValue: 1 },
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
displayName: 'Keyword Word Count To',
|
|
233
|
+
name: 'keywordCountTo',
|
|
234
|
+
type: 'number',
|
|
235
|
+
default: 0,
|
|
236
|
+
description: 'Maximum number of words in a prompt (0 = no limit)',
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
displayName: 'Characters Count From',
|
|
240
|
+
name: 'charactersCountFrom',
|
|
241
|
+
type: 'number',
|
|
242
|
+
default: 0,
|
|
243
|
+
description: 'Minimum character length of a prompt',
|
|
244
|
+
typeOptions: { minValue: 1 },
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
displayName: 'Characters Count To',
|
|
248
|
+
name: 'charactersCountTo',
|
|
249
|
+
type: 'number',
|
|
250
|
+
default: 0,
|
|
251
|
+
description: 'Maximum character length of a prompt (0 = no limit)',
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
displayName: 'Include Keywords Containing',
|
|
255
|
+
name: 'multiKeywordIncluded',
|
|
256
|
+
type: 'string',
|
|
257
|
+
default: '',
|
|
258
|
+
placeholder: 'best, top, review',
|
|
259
|
+
description: 'Comma-separated words that must appear in the prompt text',
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
displayName: 'Exclude Keywords Containing',
|
|
263
|
+
name: 'multiKeywordExcluded',
|
|
264
|
+
type: 'string',
|
|
265
|
+
default: '',
|
|
266
|
+
placeholder: 'free, cheap',
|
|
267
|
+
description: 'Comma-separated words that must NOT appear in the prompt text',
|
|
242
268
|
},
|
|
243
269
|
],
|
|
244
270
|
},
|
|
@@ -261,7 +287,7 @@ exports.aiSearchFields = [
|
|
|
261
287
|
displayName: 'Primary Brand',
|
|
262
288
|
name: 'primaryBrand',
|
|
263
289
|
type: 'string',
|
|
264
|
-
required:
|
|
290
|
+
required: false,
|
|
265
291
|
displayOptions: {
|
|
266
292
|
show: {
|
|
267
293
|
resource: ['aiSearch'],
|
|
@@ -306,7 +332,7 @@ exports.aiSearchFields = [
|
|
|
306
332
|
type: 'string',
|
|
307
333
|
default: '',
|
|
308
334
|
placeholder: 'Semrush',
|
|
309
|
-
description: 'Competitor brand name',
|
|
335
|
+
description: 'Competitor brand name (optional)',
|
|
310
336
|
},
|
|
311
337
|
],
|
|
312
338
|
},
|
|
@@ -325,16 +351,9 @@ exports.aiSearchFields = [
|
|
|
325
351
|
},
|
|
326
352
|
},
|
|
327
353
|
options: [
|
|
328
|
-
{
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
description: 'Aggregate by registrable domain',
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
name: 'Exact URL',
|
|
335
|
-
value: 'exact_url',
|
|
336
|
-
description: 'Exact URL matching',
|
|
337
|
-
},
|
|
354
|
+
{ name: 'Base Domain', value: 'base_domain', description: 'Aggregate by registrable domain, includes all subdomains' },
|
|
355
|
+
{ name: 'Domain', value: 'domain', description: 'Exact host only, no subdomain aggregation' },
|
|
356
|
+
{ name: 'URL', value: 'url', description: 'Exact URL including path and query' },
|
|
338
357
|
],
|
|
339
358
|
default: 'base_domain',
|
|
340
359
|
description: 'Scope of analysis',
|
|
@@ -351,26 +370,11 @@ exports.aiSearchFields = [
|
|
|
351
370
|
},
|
|
352
371
|
},
|
|
353
372
|
options: [
|
|
354
|
-
{
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
name: 'ChatGPT',
|
|
360
|
-
value: 'chatgpt',
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
name: 'Perplexity',
|
|
364
|
-
value: 'perplexity',
|
|
365
|
-
},
|
|
366
|
-
{
|
|
367
|
-
name: 'Gemini',
|
|
368
|
-
value: 'gemini',
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
name: 'AI Mode',
|
|
372
|
-
value: 'ai-mode',
|
|
373
|
-
},
|
|
373
|
+
{ name: 'AI Overview (Google)', value: 'ai-overview' },
|
|
374
|
+
{ name: 'ChatGPT', value: 'chatgpt' },
|
|
375
|
+
{ name: 'Perplexity', value: 'perplexity' },
|
|
376
|
+
{ name: 'Gemini', value: 'gemini' },
|
|
377
|
+
{ name: 'AI Mode', value: 'ai-mode' },
|
|
374
378
|
],
|
|
375
379
|
default: ['ai-overview', 'chatgpt', 'perplexity'],
|
|
376
380
|
description: 'LLM engines to compare across',
|
|
@@ -943,6 +943,41 @@ exports.domainAnalysisFields = [
|
|
|
943
943
|
default: [],
|
|
944
944
|
description: 'Filter keywords by search intent',
|
|
945
945
|
},
|
|
946
|
+
{
|
|
947
|
+
displayName: 'Include Keywords Containing',
|
|
948
|
+
name: 'multiKeywordIncluded',
|
|
949
|
+
type: 'string',
|
|
950
|
+
default: '',
|
|
951
|
+
placeholder: 'best, top, review',
|
|
952
|
+
description: 'Comma-separated words that must appear in results',
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
displayName: 'Exclude Keywords Containing',
|
|
956
|
+
name: 'multiKeywordExcluded',
|
|
957
|
+
type: 'string',
|
|
958
|
+
default: '',
|
|
959
|
+
placeholder: 'free, cheap',
|
|
960
|
+
description: 'Comma-separated words that must NOT appear in results',
|
|
961
|
+
},
|
|
962
|
+
{
|
|
963
|
+
displayName: 'SERP Feature Link Mode',
|
|
964
|
+
name: 'serpFeatures2Mode',
|
|
965
|
+
type: 'options',
|
|
966
|
+
options: [
|
|
967
|
+
{ name: 'With Link', value: 'with_link' },
|
|
968
|
+
{ name: 'Without Link', value: 'without_link' },
|
|
969
|
+
],
|
|
970
|
+
default: 'with_link',
|
|
971
|
+
description: 'Filter by whether the analyzed domain is linked inside a SERP feature. Must be used together with SERP Feature Link Value.',
|
|
972
|
+
},
|
|
973
|
+
{
|
|
974
|
+
displayName: 'SERP Feature Link Value',
|
|
975
|
+
name: 'serpFeatures2Value',
|
|
976
|
+
type: 'string',
|
|
977
|
+
default: '',
|
|
978
|
+
placeholder: 'sge,reviews',
|
|
979
|
+
description: 'Comma-separated SERP feature codes to check domain linkage for. Must be used together with SERP Feature Link Mode.',
|
|
980
|
+
},
|
|
946
981
|
],
|
|
947
982
|
},
|
|
948
983
|
{
|
|
@@ -3,6 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AiSearchOperations = AiSearchOperations;
|
|
4
4
|
const apiRequest_1 = require("../../utils/apiRequest");
|
|
5
5
|
const validators_1 = require("../../utils/validators");
|
|
6
|
+
function buildMultiKeywordFilter(csv) {
|
|
7
|
+
return csv
|
|
8
|
+
.split(',')
|
|
9
|
+
.map((w) => w.trim())
|
|
10
|
+
.filter(Boolean)
|
|
11
|
+
.map((word) => [{ type: 'contains', value: word }]);
|
|
12
|
+
}
|
|
6
13
|
async function AiSearchOperations(index) {
|
|
7
14
|
const operation = this.getNodeParameter('operation', index);
|
|
8
15
|
let endpoint = '';
|
|
@@ -13,11 +20,14 @@ async function AiSearchOperations(index) {
|
|
|
13
20
|
const engine = this.getNodeParameter('engine', index);
|
|
14
21
|
const source = this.getNodeParameter('source', index);
|
|
15
22
|
const scope = this.getNodeParameter('scope', index, 'base_domain');
|
|
23
|
+
const additionalFields = this.getNodeParameter('additionalFields', index, {});
|
|
16
24
|
endpoint = '/ai-search/overview/by-engine/time-series';
|
|
17
25
|
params.target = (0, validators_1.validateDomain)(domain);
|
|
18
26
|
params.engine = engine;
|
|
19
27
|
params.source = (0, validators_1.validateSource)(source);
|
|
20
28
|
params.scope = scope;
|
|
29
|
+
if (additionalFields.brand)
|
|
30
|
+
params.brand = additionalFields.brand;
|
|
21
31
|
break;
|
|
22
32
|
}
|
|
23
33
|
case 'discoverBrand': {
|
|
@@ -49,6 +59,24 @@ async function AiSearchOperations(index) {
|
|
|
49
59
|
params.limit = additionalFields.limit;
|
|
50
60
|
if (additionalFields.offset)
|
|
51
61
|
params.offset = additionalFields.offset;
|
|
62
|
+
if (additionalFields.volumeFrom)
|
|
63
|
+
params['filter[volume][from]'] = additionalFields.volumeFrom;
|
|
64
|
+
if (additionalFields.volumeTo)
|
|
65
|
+
params['filter[volume][to]'] = additionalFields.volumeTo;
|
|
66
|
+
if (additionalFields.keywordCountFrom)
|
|
67
|
+
params['filter[keyword_count][from]'] = additionalFields.keywordCountFrom;
|
|
68
|
+
if (additionalFields.keywordCountTo)
|
|
69
|
+
params['filter[keyword_count][to]'] = additionalFields.keywordCountTo;
|
|
70
|
+
if (additionalFields.charactersCountFrom)
|
|
71
|
+
params['filter[characters_count][from]'] = additionalFields.charactersCountFrom;
|
|
72
|
+
if (additionalFields.charactersCountTo)
|
|
73
|
+
params['filter[characters_count][to]'] = additionalFields.charactersCountTo;
|
|
74
|
+
if (additionalFields.multiKeywordIncluded) {
|
|
75
|
+
params['filter[multi_keyword_included]'] = JSON.stringify(buildMultiKeywordFilter(additionalFields.multiKeywordIncluded));
|
|
76
|
+
}
|
|
77
|
+
if (additionalFields.multiKeywordExcluded) {
|
|
78
|
+
params['filter[multi_keyword_excluded]'] = JSON.stringify(buildMultiKeywordFilter(additionalFields.multiKeywordExcluded));
|
|
79
|
+
}
|
|
52
80
|
break;
|
|
53
81
|
}
|
|
54
82
|
case 'getPromptsByBrand': {
|
|
@@ -71,6 +99,24 @@ async function AiSearchOperations(index) {
|
|
|
71
99
|
params.limit = additionalFields.limit;
|
|
72
100
|
if (additionalFields.offset)
|
|
73
101
|
params.offset = additionalFields.offset;
|
|
102
|
+
if (additionalFields.volumeFrom)
|
|
103
|
+
params['filter[volume][from]'] = additionalFields.volumeFrom;
|
|
104
|
+
if (additionalFields.volumeTo)
|
|
105
|
+
params['filter[volume][to]'] = additionalFields.volumeTo;
|
|
106
|
+
if (additionalFields.keywordCountFrom)
|
|
107
|
+
params['filter[keyword_count][from]'] = additionalFields.keywordCountFrom;
|
|
108
|
+
if (additionalFields.keywordCountTo)
|
|
109
|
+
params['filter[keyword_count][to]'] = additionalFields.keywordCountTo;
|
|
110
|
+
if (additionalFields.charactersCountFrom)
|
|
111
|
+
params['filter[characters_count][from]'] = additionalFields.charactersCountFrom;
|
|
112
|
+
if (additionalFields.charactersCountTo)
|
|
113
|
+
params['filter[characters_count][to]'] = additionalFields.charactersCountTo;
|
|
114
|
+
if (additionalFields.multiKeywordIncluded) {
|
|
115
|
+
params['filter[multi_keyword_included]'] = JSON.stringify(buildMultiKeywordFilter(additionalFields.multiKeywordIncluded));
|
|
116
|
+
}
|
|
117
|
+
if (additionalFields.multiKeywordExcluded) {
|
|
118
|
+
params['filter[multi_keyword_excluded]'] = JSON.stringify(buildMultiKeywordFilter(additionalFields.multiKeywordExcluded));
|
|
119
|
+
}
|
|
74
120
|
break;
|
|
75
121
|
}
|
|
76
122
|
case 'getLeaderboard': {
|
|
@@ -83,30 +129,30 @@ async function AiSearchOperations(index) {
|
|
|
83
129
|
if (!primaryTarget || primaryTarget.trim() === '') {
|
|
84
130
|
throw new Error('Primary target domain is required');
|
|
85
131
|
}
|
|
86
|
-
if (!primaryBrand || primaryBrand.trim() === '') {
|
|
87
|
-
throw new Error('Primary brand name is required');
|
|
88
|
-
}
|
|
89
132
|
const competitors = [];
|
|
90
133
|
if (competitorsData.competitorValues && Array.isArray(competitorsData.competitorValues)) {
|
|
91
134
|
for (const comp of competitorsData.competitorValues) {
|
|
92
|
-
if (comp.target
|
|
93
|
-
|
|
135
|
+
if (comp.target) {
|
|
136
|
+
const entry = {
|
|
94
137
|
target: (0, validators_1.validateDomain)(comp.target),
|
|
95
|
-
|
|
96
|
-
|
|
138
|
+
};
|
|
139
|
+
if (comp.brand)
|
|
140
|
+
entry.brand = comp.brand.trim();
|
|
141
|
+
competitors.push(entry);
|
|
97
142
|
}
|
|
98
143
|
}
|
|
99
144
|
}
|
|
100
145
|
const body = {
|
|
101
146
|
primary: {
|
|
102
147
|
target: (0, validators_1.validateDomain)(primaryTarget),
|
|
103
|
-
brand: primaryBrand.trim(),
|
|
104
148
|
},
|
|
105
149
|
competitors,
|
|
106
150
|
scope,
|
|
107
151
|
source: (0, validators_1.validateSource)(source),
|
|
108
152
|
engines,
|
|
109
153
|
};
|
|
154
|
+
if (primaryBrand)
|
|
155
|
+
body.primary.brand = primaryBrand.trim();
|
|
110
156
|
return await apiRequest_1.apiRequest.call(this, 'POST', '/ai-search/overview/leaderboard', body, {}, index);
|
|
111
157
|
}
|
|
112
158
|
default:
|
|
@@ -3,6 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DomainAnalysisOperations = DomainAnalysisOperations;
|
|
4
4
|
const apiRequest_1 = require("../../utils/apiRequest");
|
|
5
5
|
const validators_1 = require("../../utils/validators");
|
|
6
|
+
function buildMultiKeywordFilter(csv) {
|
|
7
|
+
return csv
|
|
8
|
+
.split(',')
|
|
9
|
+
.map((w) => w.trim())
|
|
10
|
+
.filter(Boolean)
|
|
11
|
+
.map((word) => [{ type: 'contains', value: word }]);
|
|
12
|
+
}
|
|
6
13
|
async function DomainAnalysisOperations(index) {
|
|
7
14
|
const operation = this.getNodeParameter('operation', index);
|
|
8
15
|
let endpoint = '';
|
|
@@ -238,6 +245,22 @@ async function DomainAnalysisOperations(index) {
|
|
|
238
245
|
if (additionalFields.intents && additionalFields.intents.length > 0) {
|
|
239
246
|
params['filter[intents]'] = additionalFields.intents.join(',');
|
|
240
247
|
}
|
|
248
|
+
if (additionalFields.multiKeywordIncluded) {
|
|
249
|
+
params['filter[multi_keyword_included]'] = JSON.stringify(buildMultiKeywordFilter(additionalFields.multiKeywordIncluded));
|
|
250
|
+
}
|
|
251
|
+
if (additionalFields.multiKeywordExcluded) {
|
|
252
|
+
params['filter[multi_keyword_excluded]'] = JSON.stringify(buildMultiKeywordFilter(additionalFields.multiKeywordExcluded));
|
|
253
|
+
}
|
|
254
|
+
if (additionalFields.serpFeatures2Mode && additionalFields.serpFeatures2Value) {
|
|
255
|
+
params['filter[serp_features_2][mode]'] = additionalFields.serpFeatures2Mode;
|
|
256
|
+
additionalFields.serpFeatures2Value
|
|
257
|
+
.split(',')
|
|
258
|
+
.map((v) => v.trim())
|
|
259
|
+
.filter(Boolean)
|
|
260
|
+
.forEach((val, i) => {
|
|
261
|
+
params[`filter[serp_features_2][value][${i}]`] = val;
|
|
262
|
+
});
|
|
263
|
+
}
|
|
241
264
|
break;
|
|
242
265
|
}
|
|
243
266
|
case 'getKeywordsComparison': {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seranking/n8n-nodes-seranking",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "n8n connector for SE Ranking API - AI Search, Backlinks, Domain Analysis, Keyword Research, and Website Audit",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/seranking/n8n-nodes-seranking",
|