@luzconsulting/n8n-nodes-vibetrack 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/LICENSE.md +19 -0
- package/README.md +69 -0
- package/dist/credentials/VibeTrackApi.credentials.d.ts +10 -0
- package/dist/credentials/VibeTrackApi.credentials.js +48 -0
- package/dist/credentials/vibetrack-dark-icon.svg +1 -0
- package/dist/credentials/vibetrack-light-icon.svg +1 -0
- package/dist/nodes/VibeTrack/VibeTrack.node.d.ts +13 -0
- package/dist/nodes/VibeTrack/VibeTrack.node.js +141 -0
- package/dist/nodes/VibeTrack/VibeTrack.node.json +18 -0
- package/dist/nodes/VibeTrack/actions/apiCall/apiCall.actions.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/apiCall/apiCall.actions.js +35 -0
- package/dist/nodes/VibeTrack/actions/apiCall/index.d.ts +3 -0
- package/dist/nodes/VibeTrack/actions/apiCall/index.js +105 -0
- package/dist/nodes/VibeTrack/actions/attribution/attribution.actions.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/attribution/attribution.actions.js +58 -0
- package/dist/nodes/VibeTrack/actions/attribution/index.d.ts +3 -0
- package/dist/nodes/VibeTrack/actions/attribution/index.js +105 -0
- package/dist/nodes/VibeTrack/actions/conversion/conversion.actions.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/conversion/conversion.actions.js +86 -0
- package/dist/nodes/VibeTrack/actions/conversion/index.d.ts +3 -0
- package/dist/nodes/VibeTrack/actions/conversion/index.js +193 -0
- package/dist/nodes/VibeTrack/actions/project/index.d.ts +3 -0
- package/dist/nodes/VibeTrack/actions/project/index.js +22 -0
- package/dist/nodes/VibeTrack/actions/project/project.actions.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/project/project.actions.js +16 -0
- package/dist/nodes/VibeTrack/actions/resource.selector.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/resource.selector.js +47 -0
- package/dist/nodes/VibeTrack/actions/router.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/router.js +31 -0
- package/dist/nodes/VibeTrack/actions/team/index.d.ts +3 -0
- package/dist/nodes/VibeTrack/actions/team/index.js +104 -0
- package/dist/nodes/VibeTrack/actions/team/team.actions.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/team/team.actions.js +37 -0
- package/dist/nodes/VibeTrack/actions/trigger/index.d.ts +3 -0
- package/dist/nodes/VibeTrack/actions/trigger/index.js +88 -0
- package/dist/nodes/VibeTrack/actions/trigger/trigger.actions.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/trigger/trigger.actions.js +31 -0
- package/dist/nodes/VibeTrack/actions/webhook/index.d.ts +3 -0
- package/dist/nodes/VibeTrack/actions/webhook/index.js +129 -0
- package/dist/nodes/VibeTrack/actions/webhook/webhook.actions.d.ts +2 -0
- package/dist/nodes/VibeTrack/actions/webhook/webhook.actions.js +83 -0
- package/dist/nodes/VibeTrack/helpers/apiclient.d.ts +14 -0
- package/dist/nodes/VibeTrack/helpers/apiclient.js +61 -0
- package/dist/nodes/VibeTrack/methods/loadOptions/common.loadOptions.d.ts +5 -0
- package/dist/nodes/VibeTrack/methods/loadOptions/common.loadOptions.js +86 -0
- package/dist/nodes/VibeTrack/methods/loadOptions/index.d.ts +1 -0
- package/dist/nodes/VibeTrack/methods/loadOptions/index.js +37 -0
- package/dist/nodes/VibeTrack/trigger/VibeTrackTrigger.node.d.ts +19 -0
- package/dist/nodes/VibeTrack/trigger/VibeTrackTrigger.node.js +208 -0
- package/dist/nodes/VibeTrack/trigger/VibeTrackTrigger.node.json +18 -0
- package/dist/nodes/VibeTrack/trigger/trigger.instant.properties.d.ts +2 -0
- package/dist/nodes/VibeTrack/trigger/trigger.instant.properties.js +71 -0
- package/dist/nodes/VibeTrack/vibetrack-dark-icon.svg +1 -0
- package/dist/nodes/VibeTrack/vibetrack-light-icon.svg +1 -0
- package/dist/package.json +76 -0
- package/package.json +76 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright 2026 n8n
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8
|
+
so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# @luzconsulting/n8n-nodes-vibetrack
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
Verified against VibeTrack API **v1.0.0** (2026-07-14).
|
|
10
|
+
|
|
11
|
+
An n8n community node for [VibeTrack](https://vibetrack.com) — read online conversions, send offline conversions, aggregate attribution data, manage webhooks, and react to new conversions in real time.
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
The package ships two nodes:
|
|
16
|
+
|
|
17
|
+
- **VibeTrack** — a regular action node for operations against the VibeTrack Public API.
|
|
18
|
+
- **VibeTrack Trigger** — a webhook-based trigger node that starts a workflow when a new conversion is tracked.
|
|
19
|
+
|
|
20
|
+
### VibeTrack (actions)
|
|
21
|
+
|
|
22
|
+
| Resource | Operations |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Conversions | get many online conversions (filter by date range, trigger, email; with pagination), send offline conversion |
|
|
25
|
+
| Projects | get many |
|
|
26
|
+
| Triggers | get many conversion (online) or offline triggers, filter offline triggers by source |
|
|
27
|
+
| Attribution | aggregate attribution data on campaign, adset or ad level |
|
|
28
|
+
| Webhooks | create, update, delete, get many, get by ID |
|
|
29
|
+
| Team Members | add an existing user or send an invitation (project or workspace scope) |
|
|
30
|
+
| Raw API Call | call any VibeTrack endpoint directly with your stored credentials |
|
|
31
|
+
|
|
32
|
+
### VibeTrack Trigger (events)
|
|
33
|
+
|
|
34
|
+
- **Conversion Created** — fires for every new conversion in the selected project, optionally filtered by conversion trigger and/or event name.
|
|
35
|
+
|
|
36
|
+
The trigger registers the webhook subscription automatically when the workflow is activated and removes it on deactivation. Incoming deliveries are verified against the `X-VibeTrack-Signature` header using the subscription secret (can be disabled in the node options).
|
|
37
|
+
|
|
38
|
+
## Setup
|
|
39
|
+
|
|
40
|
+
### Requirements
|
|
41
|
+
|
|
42
|
+
- n8n **2.0.0+**
|
|
43
|
+
- A VibeTrack account with API access enabled
|
|
44
|
+
|
|
45
|
+
### Install
|
|
46
|
+
|
|
47
|
+
In n8n: **Settings → Community Nodes → Install**, then enter:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
@luzconsulting/n8n-nodes-vibetrack
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Restart n8n afterwards — the node appears under both "VibeTrack" and "VibeTrack Trigger".
|
|
54
|
+
|
|
55
|
+
### Credentials
|
|
56
|
+
|
|
57
|
+
The node authenticates with an API key sent as an `X-API-Key` header against `https://api.vibetrack.com/api/v1`. Create a key in VibeTrack, then add it as a new **VibeTrack API** credential in n8n. The credential includes a built-in connection test. See [CREDENTIALS.md](CREDENTIALS.md) for details.
|
|
58
|
+
|
|
59
|
+
## Development
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm install
|
|
63
|
+
npm run build
|
|
64
|
+
npm run lint
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
[MIT](LICENSE.md)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, Icon, INodeProperties } from "n8n-workflow";
|
|
2
|
+
export declare class VibeTrackApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
documentationUrl: string;
|
|
6
|
+
icon: Icon;
|
|
7
|
+
authenticate: IAuthenticateGeneric;
|
|
8
|
+
properties: INodeProperties[];
|
|
9
|
+
test: ICredentialTestRequest;
|
|
10
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VibeTrackApi = void 0;
|
|
4
|
+
class VibeTrackApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = "vibeTrackApi";
|
|
7
|
+
this.displayName = "VibeTrack API";
|
|
8
|
+
this.documentationUrl = "https://github.com/luzconsulting/n8n-nodes-vibetrack/blob/main/CREDENTIALS.md";
|
|
9
|
+
this.icon = {
|
|
10
|
+
light: "file:vibetrack-light-icon.svg",
|
|
11
|
+
dark: "file:vibetrack-dark-icon.svg",
|
|
12
|
+
};
|
|
13
|
+
this.authenticate = {
|
|
14
|
+
type: "generic",
|
|
15
|
+
properties: {
|
|
16
|
+
headers: {
|
|
17
|
+
"X-API-Key": "={{$credentials.apiKey}}",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
this.properties = [
|
|
22
|
+
{
|
|
23
|
+
displayName: "API Base URL",
|
|
24
|
+
name: "baseUrl",
|
|
25
|
+
type: "string",
|
|
26
|
+
default: "https://api.vibetrack.com",
|
|
27
|
+
placeholder: "https://api.vibetrack.com",
|
|
28
|
+
description: "Base URL of the VibeTrack Public API. Use https://api.dev.vibetrack.com for the dev environment.",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
displayName: "API Key",
|
|
32
|
+
name: "apiKey",
|
|
33
|
+
type: "string",
|
|
34
|
+
typeOptions: { password: true },
|
|
35
|
+
default: "",
|
|
36
|
+
description: "VibeTrack API Key",
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
this.test = {
|
|
40
|
+
request: {
|
|
41
|
+
baseURL: "={{String($credentials.baseUrl).replace(/\\/+$/, '').replace(/\\/api(\\/v\\d+)?$/i, '')}}",
|
|
42
|
+
url: "/api/v1/auth",
|
|
43
|
+
method: "GET",
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.VibeTrackApi = VibeTrackApi;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 350.304 383" xmlns="http://www.w3.org/2000/svg" fill="none"><g fill="#6b54ec"><path d="m137.316 370.142-97.114-56.069a77.2 77.2 0 0 1-28.155-28.12A77.2 77.2 0 0 1 1.67 247.537l-.31-110.741a77.16 77.16 0 0 1 10.325-38.75A77.16 77.16 0 0 1 40.08 69.732l96.059-55.103a77.2 77.2 0 0 1 38.458-10.22 77.2 77.2 0 0 1 38.43 10.322L310.141 70.8a77.2 77.2 0 0 1 28.152 28.119 77.15 77.15 0 0 1 10.372 38.412l.311 110.742a77.1 77.1 0 0 1-10.322 38.751 77.13 77.13 0 0 1-28.398 28.315l-96.061 55.101a77.16 77.16 0 0 1-38.452 10.225 77.2 77.2 0 0 1-38.428-10.322M191.55 80.555a35.08 35.08 0 0 0-34.921-.056l-71.541 40.944a35.11 35.11 0 0 0-17.632 30.54l.312 82.428a35.09 35.09 0 0 0 17.51 30.215l72.315 41.751a35.1 35.1 0 0 0 17.456 4.685 35.05 35.05 0 0 0 17.467-4.628l71.541-40.943a35.09 35.09 0 0 0 17.632-30.54l-.312-82.428a35.06 35.06 0 0 0-17.511-30.216z"/><path d="M213.331 157.854a23.34 23.34 0 0 1 11.676 20.154l.094 31.066a23.35 23.35 0 0 1-11.737 20.33l-26.951 15.451a23.36 23.36 0 0 1-23.292-.035l-27.292-15.756a23.36 23.36 0 0 1-11.676-20.155l-.094-31.065a23.35 23.35 0 0 1 11.738-20.33l26.95-15.452a23.36 23.36 0 0 1 23.293.035z"/></g></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg viewBox="0 0 350.304 383" xmlns="http://www.w3.org/2000/svg" fill="none"><g fill="#6b54ec"><path d="m137.316 370.142-97.114-56.069a77.2 77.2 0 0 1-28.155-28.12A77.2 77.2 0 0 1 1.67 247.537l-.31-110.741a77.16 77.16 0 0 1 10.325-38.75A77.16 77.16 0 0 1 40.08 69.732l96.059-55.103a77.2 77.2 0 0 1 38.458-10.22 77.2 77.2 0 0 1 38.43 10.322L310.141 70.8a77.2 77.2 0 0 1 28.152 28.119 77.15 77.15 0 0 1 10.372 38.412l.311 110.742a77.1 77.1 0 0 1-10.322 38.751 77.13 77.13 0 0 1-28.398 28.315l-96.061 55.101a77.16 77.16 0 0 1-38.452 10.225 77.2 77.2 0 0 1-38.428-10.322M191.55 80.555a35.08 35.08 0 0 0-34.921-.056l-71.541 40.944a35.11 35.11 0 0 0-17.632 30.54l.312 82.428a35.09 35.09 0 0 0 17.51 30.215l72.315 41.751a35.1 35.1 0 0 0 17.456 4.685 35.05 35.05 0 0 0 17.467-4.628l71.541-40.943a35.09 35.09 0 0 0 17.632-30.54l-.312-82.428a35.06 35.06 0 0 0-17.511-30.216z"/><path d="M213.331 157.854a23.34 23.34 0 0 1 11.676 20.154l.094 31.066a23.35 23.35 0 0 1-11.737 20.33l-26.951 15.451a23.36 23.36 0 0 1-23.292-.035l-27.292-15.756a23.36 23.36 0 0 1-11.676-20.155l-.094-31.065a23.35 23.35 0 0 1 11.738-20.33l26.95-15.452a23.36 23.36 0 0 1 23.293.035z"/></g></svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from "n8n-workflow";
|
|
2
|
+
export declare class VibeTrack implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
methods: {
|
|
5
|
+
loadOptions: {
|
|
6
|
+
getProjects(this: import("n8n-workflow").ILoadOptionsFunctions): Promise<import("n8n-workflow").INodePropertyOptions[]>;
|
|
7
|
+
getConversionTriggers(this: import("n8n-workflow").ILoadOptionsFunctions): Promise<import("n8n-workflow").INodePropertyOptions[]>;
|
|
8
|
+
getOfflineTriggers(this: import("n8n-workflow").ILoadOptionsFunctions): Promise<import("n8n-workflow").INodePropertyOptions[]>;
|
|
9
|
+
getWebhooks(this: import("n8n-workflow").ILoadOptionsFunctions): Promise<import("n8n-workflow").INodePropertyOptions[]>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.VibeTrack = void 0;
|
|
37
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
38
|
+
const apiCall_1 = require("./actions/apiCall");
|
|
39
|
+
const attribution_1 = require("./actions/attribution");
|
|
40
|
+
const conversion_1 = require("./actions/conversion");
|
|
41
|
+
const project_1 = require("./actions/project");
|
|
42
|
+
const resource_selector_1 = require("./actions/resource.selector");
|
|
43
|
+
const router_1 = require("./actions/router");
|
|
44
|
+
const team_1 = require("./actions/team");
|
|
45
|
+
const trigger_1 = require("./actions/trigger");
|
|
46
|
+
const webhook_1 = require("./actions/webhook");
|
|
47
|
+
const Loaders = __importStar(require("./methods/loadOptions"));
|
|
48
|
+
class VibeTrack {
|
|
49
|
+
constructor() {
|
|
50
|
+
this.description = {
|
|
51
|
+
displayName: "VibeTrack",
|
|
52
|
+
name: "vibeTrack",
|
|
53
|
+
icon: {
|
|
54
|
+
light: "file:vibetrack-light-icon.svg",
|
|
55
|
+
dark: "file:vibetrack-dark-icon.svg",
|
|
56
|
+
},
|
|
57
|
+
group: ["transform"],
|
|
58
|
+
version: 1,
|
|
59
|
+
description: "Interact with the VibeTrack API",
|
|
60
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
61
|
+
defaults: {
|
|
62
|
+
name: "VibeTrack",
|
|
63
|
+
description: "Interact with the VibeTrack API",
|
|
64
|
+
},
|
|
65
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
66
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
67
|
+
credentials: [
|
|
68
|
+
{
|
|
69
|
+
name: "vibeTrackApi",
|
|
70
|
+
required: true,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
usableAsTool: true,
|
|
74
|
+
properties: [
|
|
75
|
+
resource_selector_1.resourceSelector,
|
|
76
|
+
...apiCall_1.apiCallOperations,
|
|
77
|
+
...apiCall_1.apiCallFields,
|
|
78
|
+
...attribution_1.attributionOperations,
|
|
79
|
+
...attribution_1.attributionFields,
|
|
80
|
+
...conversion_1.conversionOperations,
|
|
81
|
+
...conversion_1.conversionFields,
|
|
82
|
+
...project_1.projectOperations,
|
|
83
|
+
...project_1.projectFields,
|
|
84
|
+
...team_1.teamMemberOperations,
|
|
85
|
+
...team_1.teamMemberFields,
|
|
86
|
+
...trigger_1.triggerOperations,
|
|
87
|
+
...trigger_1.triggerFields,
|
|
88
|
+
...webhook_1.webhookOperations,
|
|
89
|
+
...webhook_1.webhookFields,
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
this.methods = {
|
|
93
|
+
loadOptions: {
|
|
94
|
+
...Loaders.commonLoaders,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async execute() {
|
|
99
|
+
const items = this.getInputData();
|
|
100
|
+
const returnData = [];
|
|
101
|
+
for (let i = 0; i < items.length; i++) {
|
|
102
|
+
try {
|
|
103
|
+
const resource = this.getNodeParameter("resource", i);
|
|
104
|
+
const operation = this.getNodeParameter("operation", i);
|
|
105
|
+
const result = (await router_1.route.call(this, i, resource, operation));
|
|
106
|
+
if (Array.isArray(result)) {
|
|
107
|
+
for (const entry of result) {
|
|
108
|
+
returnData.push({
|
|
109
|
+
json: entry,
|
|
110
|
+
pairedItem: { item: i },
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (result && typeof result === "object") {
|
|
115
|
+
returnData.push({
|
|
116
|
+
json: result,
|
|
117
|
+
pairedItem: { item: i },
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (this.continueOnFail()) {
|
|
123
|
+
returnData.push({
|
|
124
|
+
json: items[i].json,
|
|
125
|
+
error: error instanceof n8n_workflow_1.NodeApiError ||
|
|
126
|
+
error instanceof n8n_workflow_1.NodeOperationError
|
|
127
|
+
? error
|
|
128
|
+
: new n8n_workflow_1.NodeOperationError(this.getNode(), error, {
|
|
129
|
+
itemIndex: i,
|
|
130
|
+
}),
|
|
131
|
+
pairedItem: { item: i },
|
|
132
|
+
});
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return [returnData];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.VibeTrack = VibeTrack;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-base.vibetrack",
|
|
3
|
+
"nodeVersion": "1.0.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": ["Analytics", "Marketing"],
|
|
6
|
+
"resources": {
|
|
7
|
+
"credentialDocumentation": [
|
|
8
|
+
{
|
|
9
|
+
"url": "https://github.com/luzconsulting/n8n-nodes-vibetrack/blob/main/CREDENTIALS.md"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"primaryDocumentation": [
|
|
13
|
+
{
|
|
14
|
+
"url": "https://github.com/luzconsulting/n8n-nodes-vibetrack/blob/main/README.md"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleApiCall = handleApiCall;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const apiclient_1 = require("../../helpers/apiclient");
|
|
6
|
+
async function handleApiCall(i, operation) {
|
|
7
|
+
var _a;
|
|
8
|
+
switch (operation) {
|
|
9
|
+
case "getAuthenticationData": {
|
|
10
|
+
return await (0, apiclient_1.vtRequest)(this, "GET", "/v1/auth");
|
|
11
|
+
}
|
|
12
|
+
case "makeRequest": {
|
|
13
|
+
const method = this.getNodeParameter("httpMethod", i);
|
|
14
|
+
const endpoint = this.getNodeParameter("endpoint", i);
|
|
15
|
+
if (!method || !endpoint) {
|
|
16
|
+
throw new n8n_workflow_1.ApplicationError("HTTP method and endpoint are required.");
|
|
17
|
+
}
|
|
18
|
+
const queryParams = (_a = this.getNodeParameter("queryParameters", i)) === null || _a === void 0 ? void 0 : _a.parameter;
|
|
19
|
+
const qs = {};
|
|
20
|
+
for (const param of queryParams !== null && queryParams !== void 0 ? queryParams : []) {
|
|
21
|
+
if (param.name && param.value !== undefined) {
|
|
22
|
+
qs[param.name] = param.value;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
let body;
|
|
26
|
+
if (["POST", "PUT", "PATCH"].includes(method)) {
|
|
27
|
+
const rawBody = this.getNodeParameter("requestBody", i, {});
|
|
28
|
+
body = typeof rawBody === "string" ? JSON.parse(rawBody) : rawBody;
|
|
29
|
+
}
|
|
30
|
+
return (0, apiclient_1.vtRequest)(this, method, endpoint, { qs, body });
|
|
31
|
+
}
|
|
32
|
+
default:
|
|
33
|
+
throw new n8n_workflow_1.ApplicationError(`Unsupported operation: ${operation}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.apiCallFields = exports.apiCallOperations = void 0;
|
|
4
|
+
exports.apiCallOperations = [
|
|
5
|
+
{
|
|
6
|
+
displayName: "Operation",
|
|
7
|
+
name: "operation",
|
|
8
|
+
type: "options",
|
|
9
|
+
noDataExpression: true,
|
|
10
|
+
default: "makeRequest",
|
|
11
|
+
displayOptions: { show: { resource: ["apiCall"] } },
|
|
12
|
+
options: [
|
|
13
|
+
{
|
|
14
|
+
name: "Get Authentication Data",
|
|
15
|
+
value: "getAuthenticationData",
|
|
16
|
+
description: "Validate the API key and retrieve the authenticated user",
|
|
17
|
+
action: "Get authentication data",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "Make Request",
|
|
21
|
+
value: "makeRequest",
|
|
22
|
+
description: "Make a custom API call",
|
|
23
|
+
action: "Custom API call",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
exports.apiCallFields = [
|
|
29
|
+
{
|
|
30
|
+
displayName: "HTTP Method",
|
|
31
|
+
name: "httpMethod",
|
|
32
|
+
type: "options",
|
|
33
|
+
displayOptions: {
|
|
34
|
+
show: { resource: ["apiCall"], operation: ["makeRequest"] },
|
|
35
|
+
},
|
|
36
|
+
options: [
|
|
37
|
+
{ name: "DELETE", value: "DELETE" },
|
|
38
|
+
{ name: "GET", value: "GET" },
|
|
39
|
+
{ name: "PATCH", value: "PATCH" },
|
|
40
|
+
{ name: "POST", value: "POST" },
|
|
41
|
+
{ name: "PUT", value: "PUT" },
|
|
42
|
+
],
|
|
43
|
+
default: "GET",
|
|
44
|
+
required: true,
|
|
45
|
+
description: "HTTP method for the API call",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
displayName: "Endpoint",
|
|
49
|
+
name: "endpoint",
|
|
50
|
+
type: "string",
|
|
51
|
+
displayOptions: {
|
|
52
|
+
show: { resource: ["apiCall"], operation: ["makeRequest"] },
|
|
53
|
+
},
|
|
54
|
+
default: "",
|
|
55
|
+
required: true,
|
|
56
|
+
placeholder: "/v1/projects",
|
|
57
|
+
description: "API endpoint path including version, for example /v1/projects or /v1/conversions",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
displayName: "Request Body",
|
|
61
|
+
name: "requestBody",
|
|
62
|
+
type: "json",
|
|
63
|
+
displayOptions: {
|
|
64
|
+
show: {
|
|
65
|
+
resource: ["apiCall"],
|
|
66
|
+
operation: ["makeRequest"],
|
|
67
|
+
httpMethod: ["POST", "PUT", "PATCH"],
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
default: "{}",
|
|
71
|
+
description: "Request body as JSON",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
displayName: "Query Parameters",
|
|
75
|
+
name: "queryParameters",
|
|
76
|
+
type: "fixedCollection",
|
|
77
|
+
typeOptions: { multipleValues: true },
|
|
78
|
+
displayOptions: {
|
|
79
|
+
show: { resource: ["apiCall"], operation: ["makeRequest"] },
|
|
80
|
+
},
|
|
81
|
+
default: {},
|
|
82
|
+
options: [
|
|
83
|
+
{
|
|
84
|
+
name: "parameter",
|
|
85
|
+
displayName: "Parameter",
|
|
86
|
+
values: [
|
|
87
|
+
{
|
|
88
|
+
displayName: "Name",
|
|
89
|
+
name: "name",
|
|
90
|
+
type: "string",
|
|
91
|
+
default: "",
|
|
92
|
+
description: "Name of the query parameter",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
displayName: "Value",
|
|
96
|
+
name: "value",
|
|
97
|
+
type: "string",
|
|
98
|
+
default: "",
|
|
99
|
+
description: "Value of the query parameter",
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleAttribution = handleAttribution;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const apiclient_1 = require("../../helpers/apiclient");
|
|
6
|
+
function parseJsonOption(value, optionName) {
|
|
7
|
+
if (value === undefined || value === null || value === "")
|
|
8
|
+
return undefined;
|
|
9
|
+
try {
|
|
10
|
+
const parsed = typeof value === "string"
|
|
11
|
+
? JSON.parse(value)
|
|
12
|
+
: value;
|
|
13
|
+
if (Array.isArray(parsed)) {
|
|
14
|
+
return parsed.length ? parsed : undefined;
|
|
15
|
+
}
|
|
16
|
+
return Object.keys(parsed).length ? parsed : undefined;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new n8n_workflow_1.ApplicationError(`${optionName} must be valid JSON.`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function handleAttribution(i, operation) {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
switch (operation) {
|
|
25
|
+
case "aggregate": {
|
|
26
|
+
const projectId = (_a = this.getNodeParameter("projectId", i)) === null || _a === void 0 ? void 0 : _a.trim();
|
|
27
|
+
const level = this.getNodeParameter("level", i);
|
|
28
|
+
const idsRaw = (_b = this.getNodeParameter("ids", i)) !== null && _b !== void 0 ? _b : "";
|
|
29
|
+
const ids = idsRaw
|
|
30
|
+
.split(",")
|
|
31
|
+
.map((id) => id.trim())
|
|
32
|
+
.filter((id) => id.length > 0);
|
|
33
|
+
if (!projectId || !level || !ids.length) {
|
|
34
|
+
throw new n8n_workflow_1.ApplicationError("projectId, level and IDs are required.");
|
|
35
|
+
}
|
|
36
|
+
const additionalOptions = this.getNodeParameter("additionalOptions", i, {});
|
|
37
|
+
const body = { projectId, level, ids };
|
|
38
|
+
if (additionalOptions.from)
|
|
39
|
+
body.from = additionalOptions.from;
|
|
40
|
+
if (additionalOptions.to)
|
|
41
|
+
body.to = additionalOptions.to;
|
|
42
|
+
const selectedConversionTriggers = parseJsonOption(additionalOptions.selectedConversionTriggers, "Selected Conversion Triggers");
|
|
43
|
+
if (selectedConversionTriggers) {
|
|
44
|
+
body.selectedConversionTriggers = selectedConversionTriggers;
|
|
45
|
+
}
|
|
46
|
+
const idParameterMapping = parseJsonOption(additionalOptions.idParameterMapping, "ID Parameter Mapping");
|
|
47
|
+
if (idParameterMapping) {
|
|
48
|
+
body.idParameterMapping = idParameterMapping;
|
|
49
|
+
}
|
|
50
|
+
const data = await (0, apiclient_1.vtRequest)(this, "POST", "/v1/attribution/aggregate", {
|
|
51
|
+
body,
|
|
52
|
+
});
|
|
53
|
+
return data !== null && data !== void 0 ? data : {};
|
|
54
|
+
}
|
|
55
|
+
default:
|
|
56
|
+
throw new n8n_workflow_1.ApplicationError(`Unsupported attribution operation: ${operation}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.attributionFields = exports.attributionOperations = void 0;
|
|
4
|
+
exports.attributionOperations = [
|
|
5
|
+
{
|
|
6
|
+
displayName: "Operation",
|
|
7
|
+
name: "operation",
|
|
8
|
+
type: "options",
|
|
9
|
+
noDataExpression: true,
|
|
10
|
+
displayOptions: { show: { resource: ["attribution"] } },
|
|
11
|
+
options: [
|
|
12
|
+
{
|
|
13
|
+
name: "Aggregate",
|
|
14
|
+
value: "aggregate",
|
|
15
|
+
description: "Return aggregated attribution data for selected campaign, adset or ad identifiers",
|
|
16
|
+
action: "Aggregate attribution data",
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
default: "aggregate",
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
exports.attributionFields = [
|
|
23
|
+
{
|
|
24
|
+
displayName: "Project Name or ID",
|
|
25
|
+
name: "projectId",
|
|
26
|
+
type: "options",
|
|
27
|
+
typeOptions: { loadOptionsMethod: "getProjects" },
|
|
28
|
+
default: "",
|
|
29
|
+
required: true,
|
|
30
|
+
displayOptions: {
|
|
31
|
+
show: { resource: ["attribution"], operation: ["aggregate"] },
|
|
32
|
+
},
|
|
33
|
+
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
displayName: "Level",
|
|
37
|
+
name: "level",
|
|
38
|
+
type: "options",
|
|
39
|
+
options: [
|
|
40
|
+
{ name: "Ad", value: "ad" },
|
|
41
|
+
{ name: "Adset", value: "adset" },
|
|
42
|
+
{ name: "Campaign", value: "campaign" },
|
|
43
|
+
],
|
|
44
|
+
default: "campaign",
|
|
45
|
+
required: true,
|
|
46
|
+
displayOptions: {
|
|
47
|
+
show: { resource: ["attribution"], operation: ["aggregate"] },
|
|
48
|
+
},
|
|
49
|
+
description: "Aggregation level of the requested identifiers",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
displayName: "IDs",
|
|
53
|
+
name: "ids",
|
|
54
|
+
type: "string",
|
|
55
|
+
default: "",
|
|
56
|
+
required: true,
|
|
57
|
+
placeholder: "ID-1, ID-2",
|
|
58
|
+
displayOptions: {
|
|
59
|
+
show: { resource: ["attribution"], operation: ["aggregate"] },
|
|
60
|
+
},
|
|
61
|
+
description: "Comma-separated list of campaign, adset or ad identifiers to aggregate",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
displayName: "Additional Options",
|
|
65
|
+
name: "additionalOptions",
|
|
66
|
+
type: "collection",
|
|
67
|
+
placeholder: "Add Option",
|
|
68
|
+
default: {},
|
|
69
|
+
displayOptions: {
|
|
70
|
+
show: { resource: ["attribution"], operation: ["aggregate"] },
|
|
71
|
+
},
|
|
72
|
+
options: [
|
|
73
|
+
{
|
|
74
|
+
displayName: "From",
|
|
75
|
+
name: "from",
|
|
76
|
+
type: "string",
|
|
77
|
+
default: "",
|
|
78
|
+
placeholder: "2026-01-01",
|
|
79
|
+
description: "Start date (YYYY-MM-DD) of the aggregation window",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
displayName: "ID Parameter Mapping",
|
|
83
|
+
name: "idParameterMapping",
|
|
84
|
+
type: "json",
|
|
85
|
+
default: "{}",
|
|
86
|
+
description: "Mapping of identifiers to URL parameters as JSON object",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
displayName: "Selected Conversion Triggers",
|
|
90
|
+
name: "selectedConversionTriggers",
|
|
91
|
+
type: "json",
|
|
92
|
+
default: "[]",
|
|
93
|
+
description: "Conversion triggers to include as JSON array",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
displayName: "To",
|
|
97
|
+
name: "to",
|
|
98
|
+
type: "string",
|
|
99
|
+
default: "",
|
|
100
|
+
placeholder: "2026-01-31",
|
|
101
|
+
description: "End date (YYYY-MM-DD) of the aggregation window",
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
];
|