n8n-nodes-influtics 1.0.9 → 1.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 +63 -27
- package/dist/assets/n8n-workflow.png +0 -0
- package/dist/credentials/InfluticsApi.credentials.js +4 -1
- package/dist/credentials/InfluticsApi.credentials.js.map +1 -1
- package/dist/index.js +8 -14
- package/dist/index.js.map +1 -1
- package/dist/nodes/GenericFunctions.js +29 -1
- package/dist/nodes/GenericFunctions.js.map +1 -1
- package/dist/nodes/Influtics/Influtics.node.js +88 -0
- package/dist/nodes/Influtics/Influtics.node.js.map +1 -0
- package/dist/nodes/Influtics/__tests__/dispatcher.test.js +144 -0
- package/dist/nodes/Influtics/__tests__/dispatcher.test.js.map +1 -0
- package/dist/nodes/Influtics/__tests__/helpers/mockContext.js +151 -0
- package/dist/nodes/Influtics/__tests__/helpers/mockContext.js.map +1 -0
- package/dist/nodes/Influtics/__tests__/helpers/mockContext.test.js +68 -0
- package/dist/nodes/Influtics/__tests__/helpers/mockContext.test.js.map +1 -0
- package/dist/nodes/Influtics/__tests__/resources/account.test.js +148 -0
- package/dist/nodes/Influtics/__tests__/resources/account.test.js.map +1 -0
- package/dist/nodes/Influtics/__tests__/resources/blogger.test.js +476 -0
- package/dist/nodes/Influtics/__tests__/resources/blogger.test.js.map +1 -0
- package/dist/nodes/Influtics/__tests__/resources/trend.test.js +286 -0
- package/dist/nodes/Influtics/__tests__/resources/trend.test.js.map +1 -0
- package/dist/nodes/Influtics/__tests__/resources/video.test.js +948 -0
- package/dist/nodes/Influtics/__tests__/resources/video.test.js.map +1 -0
- package/dist/nodes/Influtics/influtics-dark.svg +8517 -0
- package/dist/nodes/Influtics/influtics-light.svg +8517 -0
- package/dist/nodes/Influtics/resources/account.js +54 -0
- package/dist/nodes/Influtics/resources/account.js.map +1 -0
- package/dist/nodes/Influtics/resources/blogger.js +244 -0
- package/dist/nodes/Influtics/resources/blogger.js.map +1 -0
- package/dist/nodes/Influtics/resources/trend.js +180 -0
- package/dist/nodes/Influtics/resources/trend.js.map +1 -0
- package/dist/nodes/Influtics/resources/video.js +479 -0
- package/dist/nodes/Influtics/resources/video.js.map +1 -0
- package/package.json +4 -6
- package/dist/nodes/InfluticsAccount/InfluticsAccount.node.js +0 -143
- package/dist/nodes/InfluticsAccount/InfluticsAccount.node.js.map +0 -1
- package/dist/nodes/InfluticsAccount/influtics-light.svg +0 -5
- package/dist/nodes/InfluticsAccount/influtics.svg +0 -5
- package/dist/nodes/InfluticsBlogger/InfluticsBlogger.node.js +0 -257
- package/dist/nodes/InfluticsBlogger/InfluticsBlogger.node.js.map +0 -1
- package/dist/nodes/InfluticsBlogger/influtics-dark.svg +0 -5
- package/dist/nodes/InfluticsBlogger/influtics-light.svg +0 -5
- package/dist/nodes/InfluticsBlogger/influtics.svg +0 -5
- package/dist/nodes/InfluticsTrend/InfluticsTrend.node.js +0 -208
- package/dist/nodes/InfluticsTrend/InfluticsTrend.node.js.map +0 -1
- package/dist/nodes/InfluticsTrend/influtics-dark.svg +0 -5
- package/dist/nodes/InfluticsTrend/influtics-light.svg +0 -5
- package/dist/nodes/InfluticsTrend/influtics.svg +0 -5
- package/dist/nodes/InfluticsVideo/InfluticsVideo.node.js +0 -420
- package/dist/nodes/InfluticsVideo/InfluticsVideo.node.js.map +0 -1
- package/dist/nodes/InfluticsVideo/influtics-dark.svg +0 -5
- package/dist/nodes/InfluticsVideo/influtics-light.svg +0 -5
- package/dist/nodes/InfluticsVideo/influtics.svg +0 -5
- /package/dist/{nodes/InfluticsAccount/influtics-dark.svg → credentials/influtics.dark.svg} +0 -0
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Official [Influtics](https://influtics.com) integration for [n8n](https://n8n.io) — track influencer videos, bloggers, and trends across TikTok, Instagram, YouTube, VK, and more.
|
|
4
4
|
|
|
5
|
+

|
|
6
|
+
|
|
5
7
|
## About Influtics
|
|
6
8
|
|
|
7
9
|
Influtics is a paid influencer-marketing platform that monitors creators and their videos across TikTok, Instagram, YouTube, VK, and other channels. This node wraps the public Influtics REST API — every endpoint listed under [docs.influtics.com](https://docs.influtics.com/) is reachable from n8n workflows. Use it to: track new campaign videos, pull daily performance metrics into Notion / Sheets, fire alerts on viral spikes, or sync creator rosters across tools.
|
|
@@ -16,38 +18,72 @@ After install, configure the **Influtics API** credential with your API key from
|
|
|
16
18
|
|
|
17
19
|
## Operations
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
> **Heads-up if you're upgrading from ≤ 1.0.10:** the four legacy nodes
|
|
22
|
+
> (`Influtics Video`, `Influtics Blogger`, `Influtics Trend`, `Influtics Account`)
|
|
23
|
+
> have been merged into a single **`Influtics`** node. Each surface is now a
|
|
24
|
+
> **Resource** dropdown. Workflows referencing the old node types must be
|
|
25
|
+
> re-created — see [CHANGELOG → 1.1.0](https://github.com/Influtics/n8n-nodes-influtics/blob/main/CHANGELOG.md#110---2026-08-31) for steps.
|
|
26
|
+
|
|
27
|
+
### Account
|
|
28
|
+
|
|
29
|
+
| Operation | Description |
|
|
30
|
+
|-------------|------------------------------------------------|
|
|
31
|
+
| Get Limits | Read rate limit configuration |
|
|
32
|
+
| Get Usage | Read usage history and subscription summary |
|
|
33
|
+
|
|
34
|
+
### Blogger
|
|
35
|
+
|
|
36
|
+
| Operation | Description |
|
|
37
|
+
|-------------|-------------------------------------------------------------------|
|
|
38
|
+
| By Username | Read a tracked creator by platform + username (read-only) |
|
|
39
|
+
| Get Job | Poll the status of a track-creator job by ID |
|
|
40
|
+
| Track | Start tracking a creator (async — returns `job_id` to poll) |
|
|
41
|
+
|
|
42
|
+
## Supported platforms
|
|
43
|
+
|
|
44
|
+
The Influtics API tracks videos and creators across **9 platforms** (Dzen, Instagram, OK, Pinterest, Telegram, Threads, TikTok, VK, YouTube), but the surfaces ship at different scopes:
|
|
45
|
+
|
|
46
|
+
| Surface | Platforms accepted |
|
|
47
|
+
|---------|--------------------|
|
|
48
|
+
| **Influtics Video** (Track / Get Stats / Get+Update By ID) | All 9 |
|
|
49
|
+
| **Influtics Blogger** (Track / Get Job / By Username) | TikTok, Instagram, YouTube, VK |
|
|
50
|
+
| **Influtics Trend** (Search) | TikTok, YouTube |
|
|
51
|
+
| **Influtics Account** (Get Limits / Get Usage) | n/a |
|
|
52
|
+
|
|
53
|
+
The single source of truth for the 9-platform list lives in `nodes/GenericFunctions.ts` as `VIDEO_PLATFORMS`.
|
|
54
|
+
|
|
55
|
+
### Trend
|
|
20
56
|
|
|
21
|
-
| Operation |
|
|
22
|
-
|
|
23
|
-
|
|
|
24
|
-
| Get Stats | `GET` | `/v1/videos/stats` |
|
|
25
|
-
| Get By ID | `GET` | `/v1/videos/by-id/{id}` |
|
|
26
|
-
| Get By External ID | `GET` | `/v1/videos/by-external-id/{id}` |
|
|
27
|
-
| Update By External ID | `PATCH` | `/v1/videos/by-external-id/{id}` |
|
|
57
|
+
| Operation | Description |
|
|
58
|
+
|-----------|------------------------------------------------------|
|
|
59
|
+
| Search | Search TikTok or YouTube trends by keyword |
|
|
28
60
|
|
|
29
|
-
###
|
|
61
|
+
### Video
|
|
30
62
|
|
|
31
|
-
| Operation
|
|
32
|
-
|
|
33
|
-
|
|
|
34
|
-
| Get
|
|
35
|
-
|
|
|
63
|
+
| Operation | Description |
|
|
64
|
+
|-----------------------|-------------------------------------------------------------|
|
|
65
|
+
| Get By External ID | Read one tracked video by platform + external ID |
|
|
66
|
+
| Get By ID | Read one tracked video by internal ID |
|
|
67
|
+
| Get Stats | Read video-level metrics |
|
|
68
|
+
| Track | Track videos by URL |
|
|
69
|
+
| Update By External ID | Patch metadata on a tracked video |
|
|
36
70
|
|
|
37
|
-
|
|
71
|
+
## Upgrading from ≤ 1.0.10
|
|
38
72
|
|
|
39
|
-
|
|
73
|
+
After installing v1.1.0, an existing workflow errors with
|
|
74
|
+
`Node type influticsVideo is not known` (the exact type name appears in the
|
|
75
|
+
error toast on the failing node).
|
|
40
76
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
| Search | `GET` | `/v1/trends/search` |
|
|
77
|
+
**Cause:** v1.1.0 merges the four legacy nodes into a single `Influtics` action
|
|
78
|
+
node. n8n does not auto-rename community-node types.
|
|
44
79
|
|
|
45
|
-
|
|
80
|
+
**Fix:** Delete the old node from the canvas and drop a new `Influtics` node.
|
|
81
|
+
Pick the matching **Resource** (Video / Blogger / Trend / Account) and the same
|
|
82
|
+
**Operation** you had before. All parameter names and types are unchanged.
|
|
46
83
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
| Get Limits | `GET` | `/v1/account/limits` |
|
|
84
|
+
For the full rationale and migration steps, see the
|
|
85
|
+
[CHANGELOG → 1.1.0](https://github.com/Influtics/n8n-nodes-influtics/blob/main/CHANGELOG.md#110---2026-08-31)
|
|
86
|
+
entry.
|
|
51
87
|
|
|
52
88
|
## Errors
|
|
53
89
|
|
|
@@ -55,7 +91,7 @@ The **Track** operation is async; pair it with **Get Job** using the expression
|
|
|
55
91
|
|------|---------|
|
|
56
92
|
| `UNAUTHORIZED` | API key is missing or invalid. |
|
|
57
93
|
| `PAID_PLAN_REQUIRED` | This endpoint requires a paid subscription. Upgrade at the URL surfaced in the error description. |
|
|
58
|
-
| `BLOGGER_NOT_TRACKED` | Creator isn't tracked by your org — run **Influtics Blogger → Track** first. |
|
|
94
|
+
| `BLOGGER_NOT_TRACKED` | Creator isn't tracked by your org — run **Influtics → Blogger → Track** first. |
|
|
59
95
|
| `JOB_TIMEOUT` | The async job didn't complete in time — poll again or retry. |
|
|
60
96
|
| `VALIDATION_ERROR` | A required field is missing or invalid. |
|
|
61
97
|
|
|
@@ -95,9 +131,9 @@ sudo systemctl start n8n
|
|
|
95
131
|
|
|
96
132
|
#### Confirm the install succeeded
|
|
97
133
|
|
|
98
|
-
Open a workflow, add a node, search for `Influtics`.
|
|
134
|
+
Open a workflow, add a node, search for `Influtics`. A single `Influtics` node should appear in the search.
|
|
99
135
|
|
|
100
|
-
If
|
|
136
|
+
If it still doesn't appear, capture the install log from **Settings → Community Nodes → click the package → View error log** and open an issue at https://github.com/Influtics/n8n-nodes-influtics/issues with the log attached.
|
|
101
137
|
|
|
102
138
|
## Documentation
|
|
103
139
|
|
|
Binary file
|
|
@@ -5,7 +5,10 @@ class InfluticsApi {
|
|
|
5
5
|
name = 'influticsApi';
|
|
6
6
|
displayName = 'Influtics API';
|
|
7
7
|
documentationUrl = 'https://docs.influtics.com/';
|
|
8
|
-
icon =
|
|
8
|
+
icon = {
|
|
9
|
+
light: 'file:influtics.svg',
|
|
10
|
+
dark: 'file:influtics.dark.svg',
|
|
11
|
+
};
|
|
9
12
|
properties = [
|
|
10
13
|
{
|
|
11
14
|
displayName: 'API Key',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InfluticsApi.credentials.js","sourceRoot":"","sources":["../../credentials/InfluticsApi.credentials.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"InfluticsApi.credentials.js","sourceRoot":"","sources":["../../credentials/InfluticsApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,YAAY;IACvB,IAAI,GAAG,cAAc,CAAC;IACtB,WAAW,GAAG,eAAe,CAAC;IAC9B,gBAAgB,GAAG,6BAA6B,CAAC;IACjD,IAAI,GAAS;QACX,KAAK,EAAE,oBAAoB;QAC3B,IAAI,EAAE,yBAAyB;KAChC,CAAC;IACF,UAAU,GAAsB;QAC9B;YACE,WAAW,EAAE,SAAS;YACtB,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC/B,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,oEAAoE;SAClF;KACF,CAAC;IACF,YAAY,GAAyB;QACnC,IAAI,EAAE,SAAS;QACf,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,aAAa,EAAE,mCAAmC;aACnD;SACF;KACF,CAAC;IACF,IAAI,GAA2B;QAC7B,OAAO,EAAE;YACP,OAAO,EAAE,2BAA2B;YACpC,GAAG,EAAE,oBAAoB;YACzB,MAAM,EAAE,KAAK;SACd;KACF,CAAC;CACH;AAlCD,oCAkCC"}
|
package/dist/index.js
CHANGED
|
@@ -2,24 +2,18 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Package entry point.
|
|
4
4
|
*
|
|
5
|
-
* Re-exports
|
|
6
|
-
* (the value `package.json: "main"` resolves
|
|
7
|
-
* surface in one named-import namespace. n8n's
|
|
8
|
-
* `main` to discover the package; without this
|
|
9
|
-
* missing and the loader surfaces a parse error
|
|
5
|
+
* Re-exports the single Influtics action node + credential so
|
|
6
|
+
* `import 'n8n-nodes-influtics'` (the value `package.json: "main"` resolves
|
|
7
|
+
* to) gives consumers the full surface in one named-import namespace. n8n's
|
|
8
|
+
* community-node loader reads `main` to discover the package; without this
|
|
9
|
+
* file `dist/index.js` is missing and the loader surfaces a parse error.
|
|
10
10
|
*
|
|
11
11
|
* Per the official `@n8n/node-cli` template (`npx n8n-node new`).
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.
|
|
14
|
+
exports.Influtics = exports.InfluticsApi = void 0;
|
|
15
15
|
var InfluticsApi_credentials_1 = require("./credentials/InfluticsApi.credentials");
|
|
16
16
|
Object.defineProperty(exports, "InfluticsApi", { enumerable: true, get: function () { return InfluticsApi_credentials_1.InfluticsApi; } });
|
|
17
|
-
var
|
|
18
|
-
Object.defineProperty(exports, "
|
|
19
|
-
var InfluticsBlogger_node_1 = require("./nodes/InfluticsBlogger/InfluticsBlogger.node");
|
|
20
|
-
Object.defineProperty(exports, "InfluticsBlogger", { enumerable: true, get: function () { return InfluticsBlogger_node_1.InfluticsBlogger; } });
|
|
21
|
-
var InfluticsTrend_node_1 = require("./nodes/InfluticsTrend/InfluticsTrend.node");
|
|
22
|
-
Object.defineProperty(exports, "InfluticsTrend", { enumerable: true, get: function () { return InfluticsTrend_node_1.InfluticsTrend; } });
|
|
23
|
-
var InfluticsAccount_node_1 = require("./nodes/InfluticsAccount/InfluticsAccount.node");
|
|
24
|
-
Object.defineProperty(exports, "InfluticsAccount", { enumerable: true, get: function () { return InfluticsAccount_node_1.InfluticsAccount; } });
|
|
17
|
+
var Influtics_node_1 = require("./nodes/Influtics/Influtics.node");
|
|
18
|
+
Object.defineProperty(exports, "Influtics", { enumerable: true, get: function () { return Influtics_node_1.Influtics; } });
|
|
25
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEH,mFAAsE;AAA7D,wHAAA,YAAY,OAAA;AACrB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEH,mFAAsE;AAA7D,wHAAA,YAAY,OAAA;AACrB,mEAA6D;AAApD,2GAAA,SAAS,OAAA"}
|
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CREDENTIAL_NAME = exports.INFLUTICS_API_BASE_URL = void 0;
|
|
3
|
+
exports.VIDEO_PLATFORMS = exports.CREDENTIAL_NAME = exports.INFLUTICS_API_BASE_URL = void 0;
|
|
4
4
|
exports.mapInfluticsError = mapInfluticsError;
|
|
5
5
|
exports.influticsApiRequest = influticsApiRequest;
|
|
6
6
|
exports.influticsApiRequestAllItems = influticsApiRequestAllItems;
|
|
7
7
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
8
8
|
exports.INFLUTICS_API_BASE_URL = 'https://api.influtics.com';
|
|
9
9
|
exports.CREDENTIAL_NAME = 'influticsApi';
|
|
10
|
+
/**
|
|
11
|
+
* Platforms the Influtics video-tracking endpoints (`/v1/videos/track`,
|
|
12
|
+
* `/v1/videos/stats`, `/v1/videos/by-external-id/*`) accept.
|
|
13
|
+
*
|
|
14
|
+
* The 4-platform creator-tracking surface (`/v1/bloggers/track`) is a strict
|
|
15
|
+
* SUBSET of this list — only TikTok / Instagram / YouTube / VK have ongoing
|
|
16
|
+
* creator-scraper coverage. Video tracking is lighter: any URL on any of the
|
|
17
|
+
* 9 supported platforms can be resolved and snapshotted, so the dropdown
|
|
18
|
+
* exposes the full set here while `InfluticsBlogger` keeps the 4-platform list.
|
|
19
|
+
*
|
|
20
|
+
* Single source of truth — the `InfluticsVideo` node imports this constant
|
|
21
|
+
* instead of duplicating the option list per parameter, so adding/removing a
|
|
22
|
+
* platform only touches this one declaration.
|
|
23
|
+
*
|
|
24
|
+
* Order matches the landing-page platform order in /llms.txt (Instagram …
|
|
25
|
+
* Dzen). Keep alphabetical.
|
|
26
|
+
*/
|
|
27
|
+
exports.VIDEO_PLATFORMS = [
|
|
28
|
+
{ name: 'Dzen', value: 'dzen' },
|
|
29
|
+
{ name: 'Instagram', value: 'instagram' },
|
|
30
|
+
{ name: 'OK', value: 'ok' },
|
|
31
|
+
{ name: 'Pinterest', value: 'pinterest' },
|
|
32
|
+
{ name: 'Telegram', value: 'telegram' },
|
|
33
|
+
{ name: 'Threads', value: 'threads' },
|
|
34
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
35
|
+
{ name: 'VK', value: 'vk' },
|
|
36
|
+
{ name: 'YouTube', value: 'youtube' },
|
|
37
|
+
];
|
|
10
38
|
function extractApiErrorBody(error) {
|
|
11
39
|
const body = error?.response?.body;
|
|
12
40
|
const inner = body?.error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenericFunctions.js","sourceRoot":"","sources":["../../nodes/GenericFunctions.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"GenericFunctions.js","sourceRoot":"","sources":["../../nodes/GenericFunctions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Influtics = void 0;
|
|
4
|
+
exports.executeInflutics = executeInflutics;
|
|
5
|
+
/**
|
|
6
|
+
* Influtics single action node (v1.1.0).
|
|
7
|
+
*
|
|
8
|
+
* Consolidates Influtics Account / Blogger / Trend / Video into one node per
|
|
9
|
+
* the n8n verified-nodes "one regular node per package" guideline.
|
|
10
|
+
*
|
|
11
|
+
* Implementation choices:
|
|
12
|
+
* - File lives at nodes/Influtics/Influtics.node.ts — required by
|
|
13
|
+
* eslint-plugin-n8n-nodes-base `node-dirname-against-convention`.
|
|
14
|
+
* - `executeInflutics` is also exported as a named function so unit tests can
|
|
15
|
+
* drive the dispatcher without instantiating the INodeType class.
|
|
16
|
+
* - Per-resource OperationHandler maps live in `resources/{name}.ts`; the
|
|
17
|
+
* dispatcher below looks up `OPERATIONS[resource][operation]`.
|
|
18
|
+
* - The unimplemented-resource / unimplemented-operation branch keeps the
|
|
19
|
+
* executor safe if a future version's parameters somehow leak an unknown
|
|
20
|
+
* value.
|
|
21
|
+
*/
|
|
22
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
23
|
+
const account_1 = require("./resources/account");
|
|
24
|
+
const blogger_1 = require("./resources/blogger");
|
|
25
|
+
const trend_1 = require("./resources/trend");
|
|
26
|
+
const video_1 = require("./resources/video");
|
|
27
|
+
const OPERATIONS = {
|
|
28
|
+
account: account_1.ACCOUNT_OPERATIONS,
|
|
29
|
+
blogger: blogger_1.BLOGGER_OPERATIONS,
|
|
30
|
+
trend: trend_1.TREND_OPERATIONS,
|
|
31
|
+
video: video_1.VIDEO_OPERATIONS,
|
|
32
|
+
};
|
|
33
|
+
async function executeInflutics(_items) {
|
|
34
|
+
const resource = this.getNodeParameter('resource', 0);
|
|
35
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
36
|
+
const handler = OPERATIONS[resource]?.[operation];
|
|
37
|
+
if (!handler) {
|
|
38
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation "${operation}" not implemented for resource "${resource}"`);
|
|
39
|
+
}
|
|
40
|
+
// All eleven ops are single-batch: one HTTP call per workflow run regardless
|
|
41
|
+
// of input item count. All single-batch by design.
|
|
42
|
+
const response = await handler.call(this, 0);
|
|
43
|
+
return [[{ json: response }]];
|
|
44
|
+
}
|
|
45
|
+
class Influtics {
|
|
46
|
+
description = {
|
|
47
|
+
displayName: 'Influtics',
|
|
48
|
+
name: 'influtics',
|
|
49
|
+
icon: { light: 'file:influtics-light.svg', dark: 'file:influtics-dark.svg' },
|
|
50
|
+
group: ['transform'],
|
|
51
|
+
// Bumped from 1 (the four old nodes were version 1). Breaking change is
|
|
52
|
+
// declared in CHANGELOG v1.1.0; existing workflows must be re-created.
|
|
53
|
+
version: 2,
|
|
54
|
+
subtitle: '={{$parameter["resource"]}} → {{$parameter["operation"]}}',
|
|
55
|
+
description: 'Track videos, manage bloggers, search trends, and read account usage',
|
|
56
|
+
defaults: { name: 'Influtics' },
|
|
57
|
+
// eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node -- scanner `@n8n/community-nodes/node-connection-type-literal` requires the enum; the local plugin (1.16.0) wants the literal and is stale against newer n8n-workflow APIs.
|
|
58
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
59
|
+
// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong -- scanner requires the enum (see inputs comment above); satisfying it is what blocks v1.1.0 ship.
|
|
60
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
61
|
+
usableAsTool: true,
|
|
62
|
+
credentials: [{ name: 'influticsApi', required: true }],
|
|
63
|
+
properties: [
|
|
64
|
+
{
|
|
65
|
+
displayName: 'Resource',
|
|
66
|
+
name: 'resource',
|
|
67
|
+
type: 'options',
|
|
68
|
+
noDataExpression: true,
|
|
69
|
+
options: [
|
|
70
|
+
{ name: 'Account', value: 'account' },
|
|
71
|
+
{ name: 'Blogger', value: 'blogger' },
|
|
72
|
+
{ name: 'Trend', value: 'trend' },
|
|
73
|
+
{ name: 'Video', value: 'video' },
|
|
74
|
+
],
|
|
75
|
+
default: 'video',
|
|
76
|
+
},
|
|
77
|
+
...(0, account_1.accountProperties)(),
|
|
78
|
+
...(0, blogger_1.bloggerProperties)(),
|
|
79
|
+
...(0, trend_1.trendProperties)(),
|
|
80
|
+
...(0, video_1.videoProperties)(),
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
async execute() {
|
|
84
|
+
return executeInflutics.call(this, this.getInputData());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.Influtics = Influtics;
|
|
88
|
+
//# sourceMappingURL=Influtics.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Influtics.node.js","sourceRoot":"","sources":["../../../nodes/Influtics/Influtics.node.ts"],"names":[],"mappings":";;;AA6CA,4CAiBC;AA9DD;;;;;;;;;;;;;;;;GAgBG;AACH,+CAQsB;AACtB,iDAA4E;AAC5E,iDAA4E;AAC5E,6CAA0E;AAC1E,6CAA0E;AAS1E,MAAM,UAAU,GAA0D;IACxE,OAAO,EAAE,4BAAkB;IAC3B,OAAO,EAAE,4BAAkB;IAC3B,KAAK,EAAI,wBAAgB;IACzB,KAAK,EAAI,wBAAgB;CAC1B,CAAC;AAEK,KAAK,UAAU,gBAAgB,CAEpC,MAA4B;IAE5B,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAgB,CAAC;IACrE,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAW,CAAC;IAClE,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,iCAAkB,CAC1B,IAAI,CAAC,OAAO,EAAE,EACd,cAAc,SAAS,mCAAmC,QAAQ,GAAG,CACtE,CAAC;IACJ,CAAC;IACD,6EAA6E;IAC7E,mDAAmD;IACnD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,MAAa,SAAS;IACpB,WAAW,GAAyB;QAClC,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,EAAE,KAAK,EAAE,0BAA0B,EAAE,IAAI,EAAE,yBAAyB,EAAE;QAC5E,KAAK,EAAE,CAAC,WAAW,CAAC;QACpB,wEAAwE;QACxE,uEAAuE;QACvE,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,2DAA2D;QACrE,WAAW,EAAE,sEAAsE;QACnF,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;QAC/B,uQAAuQ;QACvQ,MAAM,EAAE,CAAC,kCAAmB,CAAC,IAAI,CAAC;QAClC,kLAAkL;QAClL,OAAO,EAAE,CAAC,kCAAmB,CAAC,IAAI,CAAC;QACnC,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACvD,UAAU,EAAE;YACV;gBACE,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,SAAS;gBACf,gBAAgB,EAAE,IAAI;gBACtB,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;oBACrC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;oBACrC,EAAE,IAAI,EAAE,OAAO,EAAI,KAAK,EAAE,OAAO,EAAI;oBACrC,EAAE,IAAI,EAAE,OAAO,EAAI,KAAK,EAAE,OAAO,EAAI;iBACtC;gBACD,OAAO,EAAE,OAAO;aACjB;YACD,GAAG,IAAA,2BAAiB,GAAE;YACtB,GAAG,IAAA,2BAAiB,GAAE;YACtB,GAAG,IAAA,uBAAe,GAAE;YACpB,GAAG,IAAA,uBAAe,GAAE;SACrB;KACF,CAAC;IAEF,KAAK,CAAC,OAAO;QACX,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IAC1D,CAAC;CACF;AA1CD,8BA0CC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/**
|
|
7
|
+
* Tier 2 dispatcher integration smoke tests.
|
|
8
|
+
*
|
|
9
|
+
* Per-resource handler tests (account/blogger/trend/video.test.ts) cover the
|
|
10
|
+
* per-operation wire contract in isolation. This file proves the dispatcher
|
|
11
|
+
* itself routes every (resource, operation) pair to the right handler and
|
|
12
|
+
* throws `NodeOperationError` on unknown values.
|
|
13
|
+
*
|
|
14
|
+
* Wire shape: the dispatcher calls `influticsApiRequest` which internally
|
|
15
|
+
* hits `this.helpers.httpRequestWithAuthentication`. The `makeMockContext`
|
|
16
|
+
* helper builds a context whose `httpRequestWithAuthentication` IS a vitest
|
|
17
|
+
* mock that records every call and returns a canned happy-path envelope
|
|
18
|
+
* so the dispatcher's `[[{ json: response }]]` return shape is stable.
|
|
19
|
+
*
|
|
20
|
+
* nock interceptors are installed for each route as a hygiene / future-proof
|
|
21
|
+
* measure (a future seam change that swaps the in-memory mock for a real
|
|
22
|
+
* fetch would not need test edits), but with the current `makeMockContext`
|
|
23
|
+
* the interceptor is never hit — `httpMock` short-circuits before any network
|
|
24
|
+
* traffic. `nock.cleanAll()` in afterEach reaps any unused interceptors so
|
|
25
|
+
* no test bleed-over.
|
|
26
|
+
*/
|
|
27
|
+
const vitest_1 = require("vitest");
|
|
28
|
+
const nock_1 = __importDefault(require("nock"));
|
|
29
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
30
|
+
const Influtics_node_1 = require("../Influtics.node");
|
|
31
|
+
const mockContext_1 = require("./helpers/mockContext");
|
|
32
|
+
const ROUTES = [
|
|
33
|
+
{ resource: 'video', operation: 'track', method: 'POST', path: '/v1/videos/track' },
|
|
34
|
+
{ resource: 'video', operation: 'getStats', method: 'GET', path: '/v1/videos/stats' },
|
|
35
|
+
{ resource: 'video', operation: 'getById', method: 'GET', path: '/v1/videos/by-id/abc-123' },
|
|
36
|
+
{ resource: 'video', operation: 'getByExternalId', method: 'GET', path: '/v1/videos/by-external-id/ext-1' },
|
|
37
|
+
{ resource: 'video', operation: 'updateByExternalId', method: 'PATCH', path: '/v1/videos/by-external-id/ext-1' },
|
|
38
|
+
{ resource: 'blogger', operation: 'track', method: 'POST', path: '/v1/bloggers/track' },
|
|
39
|
+
{ resource: 'blogger', operation: 'getJob', method: 'GET', path: '/v1/bloggers/jobs/job-1' },
|
|
40
|
+
{ resource: 'blogger', operation: 'byUsername', method: 'GET', path: '/v1/bloggers/by-username/handle' },
|
|
41
|
+
{ resource: 'trend', operation: 'search', method: 'GET', path: '/v1/trends/search' },
|
|
42
|
+
{ resource: 'account', operation: 'getUsage', method: 'GET', path: '/v1/account/usage' },
|
|
43
|
+
{ resource: 'account', operation: 'getLimits', method: 'GET', path: '/v1/account/limits' },
|
|
44
|
+
];
|
|
45
|
+
/**
|
|
46
|
+
* Per-route param prefill. Each operation reads a known set of
|
|
47
|
+
* getNodeParameter() keys at the top of its handler — supply them here so the
|
|
48
|
+
* handler doesn't fail-fast (e.g. required-id guard) BEFORE reaching the
|
|
49
|
+
* HTTP seam. These are NOT a contract test for the handler — the per-resource
|
|
50
|
+
* tests already pin those — they exist solely so the dispatcher test can
|
|
51
|
+
* prove "the dispatcher routed this op to its handler, which then went out
|
|
52
|
+
* the wire".
|
|
53
|
+
*/
|
|
54
|
+
function paramsFor(route) {
|
|
55
|
+
switch (route.resource) {
|
|
56
|
+
case 'video':
|
|
57
|
+
switch (route.operation) {
|
|
58
|
+
case 'track':
|
|
59
|
+
return { urls: { urls: ['https://tiktok.com/@x/video/1'] } };
|
|
60
|
+
case 'getStats':
|
|
61
|
+
return {};
|
|
62
|
+
case 'getById':
|
|
63
|
+
return { id: 'abc-123' };
|
|
64
|
+
case 'getByExternalId':
|
|
65
|
+
return { externalId: 'ext-1', platform: 'tiktok' };
|
|
66
|
+
case 'updateByExternalId':
|
|
67
|
+
return {
|
|
68
|
+
externalId: 'ext-1',
|
|
69
|
+
platform: 'tiktok',
|
|
70
|
+
updateFields: { notes: 'x' },
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
case 'blogger':
|
|
75
|
+
switch (route.operation) {
|
|
76
|
+
case 'track':
|
|
77
|
+
return { platform: 'tiktok', username: 'handle', initialVideosCount: 10 };
|
|
78
|
+
case 'getJob':
|
|
79
|
+
return { jobId: 'job-1' };
|
|
80
|
+
case 'byUsername':
|
|
81
|
+
return { username: 'handle', platform: 'tiktok' };
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
case 'trend':
|
|
85
|
+
// `additionalFields` is the collection wrapping cursor/region/days.
|
|
86
|
+
// Only `keyword` and `platform` are required for search to fire.
|
|
87
|
+
return { keyword: 'foo', platform: 'tiktok' };
|
|
88
|
+
case 'account':
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
return {};
|
|
92
|
+
}
|
|
93
|
+
(0, vitest_1.describe)('executeInflutics dispatcher — routing', () => {
|
|
94
|
+
(0, vitest_1.beforeAll)(() => {
|
|
95
|
+
// Block real network egress so a future seam change that swaps the
|
|
96
|
+
// in-memory mock for a real fetch surfaces as a clean failure instead
|
|
97
|
+
// of a hanging test. Today the mock short-circuits before any traffic.
|
|
98
|
+
nock_1.default.disableNetConnect();
|
|
99
|
+
});
|
|
100
|
+
(0, vitest_1.afterEach)(() => {
|
|
101
|
+
nock_1.default.cleanAll();
|
|
102
|
+
// Re-enable so tests that intentionally exercise other endpoints (the
|
|
103
|
+
// per-resource suite, e.g.) are not affected across files.
|
|
104
|
+
nock_1.default.enableNetConnect();
|
|
105
|
+
});
|
|
106
|
+
vitest_1.it.each(ROUTES)('$resource.$operation routes to its handler', async (route) => {
|
|
107
|
+
const ctx = (0, mockContext_1.makeMockContext)({
|
|
108
|
+
resource: route.resource,
|
|
109
|
+
operation: route.operation,
|
|
110
|
+
...paramsFor(route),
|
|
111
|
+
});
|
|
112
|
+
// Hygiene-only: install a matching nock interceptor in case the seam is
|
|
113
|
+
// ever swapped for a real fetch. With the current seam it is unused.
|
|
114
|
+
(0, nock_1.default)(mockContext_1.BASE_URL)[route.method.toLowerCase()](route.path)
|
|
115
|
+
.reply(200, { success: true, data: {}, meta: {} });
|
|
116
|
+
const out = await Influtics_node_1.executeInflutics.call(ctx, [{ json: {} }]);
|
|
117
|
+
(0, vitest_1.expect)(out).toHaveLength(1);
|
|
118
|
+
(0, vitest_1.expect)(out[0]).toHaveLength(1);
|
|
119
|
+
(0, vitest_1.expect)(out[0][0].json).toBeDefined();
|
|
120
|
+
// The dispatcher MUST have made exactly one wire call (single-batch).
|
|
121
|
+
(0, vitest_1.expect)(ctx.httpMock).toHaveBeenCalledTimes(1);
|
|
122
|
+
});
|
|
123
|
+
(0, vitest_1.it)('throws NodeOperationError on unknown resource', async () => {
|
|
124
|
+
const ctx = (0, mockContext_1.makeMockContext)({ resource: 'unknown', operation: 'foo' });
|
|
125
|
+
await (0, vitest_1.expect)(Influtics_node_1.executeInflutics.call(ctx, [{ json: {} }])).rejects.toBeInstanceOf(n8n_workflow_1.NodeOperationError);
|
|
126
|
+
});
|
|
127
|
+
(0, vitest_1.it)('throws NodeOperationError on unknown operation', async () => {
|
|
128
|
+
const ctx = (0, mockContext_1.makeMockContext)({ resource: 'video', operation: 'bogus' });
|
|
129
|
+
await (0, vitest_1.expect)(Influtics_node_1.executeInflutics.call(ctx, [{ json: {} }])).rejects.toBeInstanceOf(n8n_workflow_1.NodeOperationError);
|
|
130
|
+
});
|
|
131
|
+
(0, vitest_1.it)('dispatches a single batch — one HTTP call per run regardless of input items', async () => {
|
|
132
|
+
// Guards against silent drift where the dispatcher loops over input
|
|
133
|
+
// items and emits N HTTP calls instead of 1.
|
|
134
|
+
const ctx = (0, mockContext_1.makeMockContext)({
|
|
135
|
+
resource: 'account',
|
|
136
|
+
operation: 'getUsage',
|
|
137
|
+
});
|
|
138
|
+
(0, nock_1.default)(mockContext_1.BASE_URL).get('/v1/account/usage').reply(200, { success: true, data: {} });
|
|
139
|
+
const items = [{ json: {} }, { json: {} }, { json: {} }];
|
|
140
|
+
await Influtics_node_1.executeInflutics.call(ctx, items);
|
|
141
|
+
(0, vitest_1.expect)(ctx.httpMock).toHaveBeenCalledTimes(1);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
//# sourceMappingURL=dispatcher.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.test.js","sourceRoot":"","sources":["../../../../nodes/Influtics/__tests__/dispatcher.test.ts"],"names":[],"mappings":"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"}
|