diff --git a/package-lock.json b/package-lock.json
index 72b3f9e3a2..fbc83c10eb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "n8n",
- "version": "0.189.1",
+ "version": "0.191.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "n8n",
- "version": "0.189.1",
+ "version": "0.191.0",
"workspaces": [
"packages/*"
],
@@ -41214,6 +41214,35 @@
"node": ">=0.10.0"
}
},
+ "node_modules/posthog-node": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-1.3.0.tgz",
+ "integrity": "sha512-2+VhqiY/rKIqKIXyvemBFHbeijHE25sP7eKltnqcFqAssUE6+sX6vusN9A4luzToOqHQkUZexiCKxvuGagh7JA==",
+ "dependencies": {
+ "axios": "0.24.0",
+ "axios-retry": "^3.1.9",
+ "component-type": "^1.2.1",
+ "join-component": "^1.1.0",
+ "md5": "^2.3.0",
+ "ms": "^2.1.3",
+ "remove-trailing-slash": "^0.1.1",
+ "uuid": "^8.3.2"
+ },
+ "bin": {
+ "posthog": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/posthog-node/node_modules/axios": {
+ "version": "0.24.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
+ "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
+ "dependencies": {
+ "follow-redirects": "^1.14.4"
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -53609,7 +53638,7 @@
},
"packages/cli": {
"name": "n8n",
- "version": "0.189.1",
+ "version": "0.191.0",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"@apidevtools/swagger-cli": "4.0.0",
@@ -53660,10 +53689,10 @@
"lodash.split": "^4.4.2",
"lodash.unset": "^4.5.2",
"mysql2": "~2.3.0",
- "n8n-core": "~0.129.0",
- "n8n-editor-ui": "~0.155.0",
- "n8n-nodes-base": "~0.187.0",
- "n8n-workflow": "~0.111.0",
+ "n8n-core": "~0.131.0",
+ "n8n-editor-ui": "~0.157.0",
+ "n8n-nodes-base": "~0.189.0",
+ "n8n-workflow": "~0.113.0",
"nodemailer": "^6.7.1",
"oauth-1.0a": "^2.2.6",
"open": "^7.0.0",
@@ -53673,6 +53702,7 @@
"passport-cookie": "^1.0.9",
"passport-jwt": "^4.0.0",
"pg": "^8.3.0",
+ "posthog-node": "^1.3.0",
"prom-client": "^13.1.0",
"psl": "^1.8.0",
"shelljs": "^0.8.5",
@@ -53733,7 +53763,7 @@
},
"packages/core": {
"name": "n8n-core",
- "version": "0.129.0",
+ "version": "0.131.0",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"axios": "^0.21.1",
@@ -53745,7 +53775,7 @@
"form-data": "^4.0.0",
"lodash.get": "^4.4.2",
"mime-types": "^2.1.27",
- "n8n-workflow": "~0.111.0",
+ "n8n-workflow": "~0.113.0",
"oauth-1.0a": "^2.2.6",
"p-cancelable": "^2.0.0",
"qs": "^6.10.1",
@@ -53771,7 +53801,7 @@
},
"packages/design-system": {
"name": "n8n-design-system",
- "version": "0.29.0",
+ "version": "0.31.0",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"element-ui": "~2.15.7",
@@ -53847,14 +53877,14 @@
},
"packages/editor-ui": {
"name": "n8n-editor-ui",
- "version": "0.155.0",
+ "version": "0.157.0",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"@fontsource/open-sans": "^4.5.0",
"@fortawesome/free-regular-svg-icons": "^6.1.1",
"luxon": "^2.3.0",
"monaco-editor": "^0.30.1",
- "n8n-design-system": "~0.29.0",
+ "n8n-design-system": "~0.31.0",
"timeago.js": "^4.0.2",
"v-click-outside": "^3.1.2",
"vue-fragment": "1.5.1",
@@ -53906,7 +53936,7 @@
"lodash.get": "^4.4.2",
"lodash.set": "^4.3.2",
"monaco-editor-webpack-plugin": "^5.0.0",
- "n8n-workflow": "~0.111.0",
+ "n8n-workflow": "~0.113.0",
"normalize-wheel": "^1.0.1",
"prismjs": "^1.17.1",
"quill": "^2.0.0-dev.3",
@@ -53932,7 +53962,7 @@
},
"packages/node-dev": {
"name": "n8n-node-dev",
- "version": "0.68.0",
+ "version": "0.70.0",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"@oclif/command": "^1.5.18",
@@ -53942,8 +53972,8 @@
"change-case": "^4.1.1",
"copyfiles": "^2.1.1",
"inquirer": "^7.0.1",
- "n8n-core": "~0.129.0",
- "n8n-workflow": "~0.111.0",
+ "n8n-core": "~0.131.0",
+ "n8n-workflow": "~0.113.0",
"oauth-1.0a": "^2.2.6",
"replace-in-file": "^6.0.0",
"request": "^2.88.2",
@@ -53963,7 +53993,7 @@
},
"packages/nodes-base": {
"name": "n8n-nodes-base",
- "version": "0.187.0",
+ "version": "0.189.0",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"@kafkajs/confluent-schema-registry": "1.0.6",
@@ -54001,7 +54031,7 @@
"mqtt": "4.2.6",
"mssql": "^8.1.2",
"mysql2": "~2.3.0",
- "n8n-core": "~0.129.0",
+ "n8n-core": "~0.131.0",
"node-html-markdown": "^1.1.3",
"node-ssh": "^12.0.0",
"nodemailer": "^6.7.1",
@@ -54055,7 +54085,7 @@
"eslint-plugin-n8n-nodes-base": "^1.5.4",
"gulp": "^4.0.0",
"jest": "^27.4.7",
- "n8n-workflow": "~0.111.0",
+ "n8n-workflow": "~0.113.0",
"ts-jest": "^27.1.3",
"tslint": "^6.1.2",
"typescript": "~4.6.0"
@@ -54063,7 +54093,7 @@
},
"packages/workflow": {
"name": "n8n-workflow",
- "version": "0.111.0",
+ "version": "0.113.0",
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
"@n8n_io/riot-tmpl": "^1.0.1",
@@ -84006,10 +84036,10 @@
"lodash.split": "^4.4.2",
"lodash.unset": "^4.5.2",
"mysql2": "~2.3.0",
- "n8n-core": "~0.129.0",
- "n8n-editor-ui": "~0.155.0",
- "n8n-nodes-base": "~0.187.0",
- "n8n-workflow": "~0.111.0",
+ "n8n-core": "~0.131.0",
+ "n8n-editor-ui": "~0.157.0",
+ "n8n-nodes-base": "~0.189.0",
+ "n8n-workflow": "~0.113.0",
"nodemailer": "^6.7.1",
"nodemon": "^2.0.2",
"oauth-1.0a": "^2.2.6",
@@ -84020,6 +84050,7 @@
"passport-cookie": "^1.0.9",
"passport-jwt": "^4.0.0",
"pg": "^8.3.0",
+ "posthog-node": "^1.3.0",
"prom-client": "^13.1.0",
"psl": "^1.8.0",
"run-script-os": "^1.0.7",
@@ -84061,7 +84092,7 @@
"jest": "^27.4.7",
"lodash.get": "^4.4.2",
"mime-types": "^2.1.27",
- "n8n-workflow": "~0.111.0",
+ "n8n-workflow": "~0.113.0",
"oauth-1.0a": "^2.2.6",
"p-cancelable": "^2.0.0",
"qs": "^6.10.1",
@@ -84187,8 +84218,8 @@
"luxon": "^2.3.0",
"monaco-editor": "^0.30.1",
"monaco-editor-webpack-plugin": "^5.0.0",
- "n8n-design-system": "~0.29.0",
- "n8n-workflow": "~0.111.0",
+ "n8n-design-system": "~0.31.0",
+ "n8n-workflow": "~0.113.0",
"normalize-wheel": "^1.0.1",
"prismjs": "^1.17.1",
"quill": "^2.0.0-dev.3",
@@ -84234,8 +84265,8 @@
"change-case": "^4.1.1",
"copyfiles": "^2.1.1",
"inquirer": "^7.0.1",
- "n8n-core": "~0.129.0",
- "n8n-workflow": "~0.111.0",
+ "n8n-core": "~0.131.0",
+ "n8n-workflow": "~0.113.0",
"oauth-1.0a": "^2.2.6",
"replace-in-file": "^6.0.0",
"request": "^2.88.2",
@@ -84312,8 +84343,8 @@
"mqtt": "4.2.6",
"mssql": "^8.1.2",
"mysql2": "~2.3.0",
- "n8n-core": "~0.129.0",
- "n8n-workflow": "~0.111.0",
+ "n8n-core": "~0.131.0",
+ "n8n-workflow": "~0.113.0",
"node-html-markdown": "^1.1.3",
"node-ssh": "^12.0.0",
"nodemailer": "^6.7.1",
@@ -87238,6 +87269,31 @@
"xtend": "^4.0.0"
}
},
+ "posthog-node": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/posthog-node/-/posthog-node-1.3.0.tgz",
+ "integrity": "sha512-2+VhqiY/rKIqKIXyvemBFHbeijHE25sP7eKltnqcFqAssUE6+sX6vusN9A4luzToOqHQkUZexiCKxvuGagh7JA==",
+ "requires": {
+ "axios": "0.24.0",
+ "axios-retry": "^3.1.9",
+ "component-type": "^1.2.1",
+ "join-component": "^1.1.0",
+ "md5": "^2.3.0",
+ "ms": "^2.1.3",
+ "remove-trailing-slash": "^0.1.1",
+ "uuid": "^8.3.2"
+ },
+ "dependencies": {
+ "axios": {
+ "version": "0.24.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
+ "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
+ "requires": {
+ "follow-redirects": "^1.14.4"
+ }
+ }
+ }
+ },
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
diff --git a/packages/cli/config/schema.ts b/packages/cli/config/schema.ts
index 6eb277754c..5885728454 100644
--- a/packages/cli/config/schema.ts
+++ b/packages/cli/config/schema.ts
@@ -681,6 +681,13 @@ export const schema = {
},
},
+ externalFrontendHooksUrls: {
+ doc: 'URLs to external frontend hooks files, ; separated',
+ format: String,
+ default: 'https://public-stage.n8n.cloud/posthog-hooks.js',
+ env: 'EXTERNAL_FRONTEND_HOOKS_URLS',
+ },
+
externalHookFiles: {
doc: 'Files containing external hooks. Multiple files can be separated by colon (":")',
format: String,
@@ -888,6 +895,26 @@ export const schema = {
env: 'N8N_DIAGNOSTICS_ENABLED',
},
config: {
+ posthog: {
+ apiKey: {
+ doc: 'API key for PostHog',
+ format: String,
+ default: 'phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo',
+ env: 'N8N_DIAGNOSTICS_POSTHOG_API_KEY',
+ },
+ apiHost: {
+ doc: 'API host for PostHog',
+ format: String,
+ default: 'https://app.posthog.com',
+ env: 'N8N_DIAGNOSTICS_POSTHOG_API_HOST',
+ },
+ disableSessionRecording: {
+ doc: 'Disable posthog session recording',
+ format: Boolean,
+ default: true,
+ env: 'N8N_DIAGNOSTICS_POSTHOG_DISABLE_RECORDING',
+ },
+ },
frontend: {
doc: 'Diagnostics config for frontend.',
format: String,
diff --git a/packages/cli/package.json b/packages/cli/package.json
index eb681cd6ac..025354c122 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -157,6 +157,7 @@
"passport-cookie": "^1.0.9",
"passport-jwt": "^4.0.0",
"pg": "^8.3.0",
+ "posthog-node": "^1.3.0",
"prom-client": "^13.1.0",
"psl": "^1.8.0",
"shelljs": "^0.8.5",
diff --git a/packages/cli/src/Interfaces.ts b/packages/cli/src/Interfaces.ts
index 984cc79839..3794ada3e2 100644
--- a/packages/cli/src/Interfaces.ts
+++ b/packages/cli/src/Interfaces.ts
@@ -516,6 +516,9 @@ export interface IN8nUISettings {
missingPackages?: boolean;
executionMode: 'regular' | 'queue';
communityNodesEnabled: boolean;
+ deployment: {
+ type: string;
+ };
isNpmAvailable: boolean;
}
diff --git a/packages/cli/src/InternalHooks.ts b/packages/cli/src/InternalHooks.ts
index 7a39e75948..e250063051 100644
--- a/packages/cli/src/InternalHooks.ts
+++ b/packages/cli/src/InternalHooks.ts
@@ -106,16 +106,20 @@ export class InternalHooksClass implements IInternalHooksClass {
(note) => note.overlapping,
).length;
- return this.telemetry.track('User saved workflow', {
- user_id: userId,
- workflow_id: workflow.id,
- node_graph_string: JSON.stringify(nodeGraph),
- notes_count_overlapping: overlappingCount,
- notes_count_non_overlapping: notesCount - overlappingCount,
- version_cli: this.versionCli,
- num_tags: workflow.tags?.length ?? 0,
- public_api: publicApi,
- });
+ return this.telemetry.track(
+ 'User saved workflow',
+ {
+ user_id: userId,
+ workflow_id: workflow.id,
+ node_graph_string: JSON.stringify(nodeGraph),
+ notes_count_overlapping: overlappingCount,
+ notes_count_non_overlapping: notesCount - overlappingCount,
+ version_cli: this.versionCli,
+ num_tags: workflow.tags?.length ?? 0,
+ public_api: publicApi,
+ },
+ { withPostHog: true },
+ );
}
async onWorkflowPostExecute(
@@ -197,14 +201,18 @@ export class InternalHooksClass implements IInternalHooksClass {
}
if (runData.data.startData?.destinationNode) {
+ const telemetryPayload = {
+ ...manualExecEventProperties,
+ node_type: TelemetryHelpers.getNodeTypeForName(
+ workflow,
+ runData.data.startData?.destinationNode,
+ )?.type,
+ node_id: nodeGraphResult.nameIndices[runData.data.startData?.destinationNode],
+ };
+
promises.push(
- this.telemetry.track('Manual node exec finished', {
- ...manualExecEventProperties,
- node_type: TelemetryHelpers.getNodeTypeForName(
- workflow,
- runData.data.startData?.destinationNode,
- )?.type,
- node_id: nodeGraphResult.nameIndices[runData.data.startData?.destinationNode],
+ this.telemetry.track('Manual node exec finished', telemetryPayload, {
+ withPostHog: true,
}),
);
} else {
@@ -219,7 +227,9 @@ export class InternalHooksClass implements IInternalHooksClass {
});
promises.push(
- this.telemetry.track('Manual workflow exec finished', manualExecEventProperties),
+ this.telemetry.track('Manual workflow exec finished', manualExecEventProperties, {
+ withPostHog: true,
+ }),
);
}
}
diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts
index 712f3a4e2d..cfcdd23cfb 100644
--- a/packages/cli/src/Server.ts
+++ b/packages/cli/src/Server.ts
@@ -166,6 +166,8 @@ import {
isUserManagementEnabled,
} from './UserManagement/UserManagementHelper';
import { loadPublicApiVersions } from './PublicApi';
+import { SharedWorkflow } from './databases/entities/SharedWorkflow';
+import * as telemetryScripts from './telemetry/scripts';
require('body-parser-xml')(bodyParser);
@@ -334,6 +336,9 @@ class App {
onboardingCallPromptEnabled: config.getEnv('onboardingCallPrompt.enabled'),
executionMode: config.getEnv('executions.mode'),
communityNodesEnabled: config.getEnv('nodes.communityPackages.enabled'),
+ deployment: {
+ type: config.getEnv('deployment.type'),
+ },
isNpmAvailable: false,
};
}
@@ -2611,6 +2616,36 @@ class App {
readIndexFile = readIndexFile.replace(/\/%BASE_PATH%\//g, n8nPath);
readIndexFile = readIndexFile.replace(/\/favicon.ico/g, `${n8nPath}favicon.ico`);
+ const hooksUrls = config.getEnv('externalFrontendHooksUrls');
+
+ let scriptsString = '';
+
+ if (hooksUrls) {
+ scriptsString = hooksUrls.split(';').reduce((acc, curr) => {
+ return `${acc}`;
+ }, '');
+ }
+
+ if (this.frontendSettings.telemetry.enabled) {
+ const phLoadingScript = telemetryScripts.createPostHogLoadingScript({
+ apiKey: config.getEnv('diagnostics.config.posthog.apiKey'),
+ apiHost: config.getEnv('diagnostics.config.posthog.apiHost'),
+ autocapture: false,
+ disableSessionRecording: config.getEnv(
+ 'diagnostics.config.posthog.disableSessionRecording',
+ ),
+ debug: config.getEnv('logs.level') === 'debug',
+ });
+
+ scriptsString += phLoadingScript;
+ }
+
+ const firstLinkedScriptSegment = '`;
diff --git a/packages/cli/test/unit/Telemetry.test.ts b/packages/cli/test/unit/Telemetry.test.ts
index 040ca916c5..888aec6166 100644
--- a/packages/cli/test/unit/Telemetry.test.ts
+++ b/packages/cli/test/unit/Telemetry.test.ts
@@ -1,7 +1,7 @@
import { Telemetry } from '../../src/telemetry';
import config from '../../config';
-jest.spyOn(Telemetry.prototype as any, 'createTelemetryClient').mockImplementation(() => {
+jest.spyOn(Telemetry.prototype as any, 'initRudderStack').mockImplementation(() => {
return {
flush: () => {},
identify: () => {},
diff --git a/packages/design-system/src/components/N8nUserInfo/UserInfo.vue b/packages/design-system/src/components/N8nUserInfo/UserInfo.vue
index e6acb476ea..a9c2d214c7 100644
--- a/packages/design-system/src/components/N8nUserInfo/UserInfo.vue
+++ b/packages/design-system/src/components/N8nUserInfo/UserInfo.vue
@@ -8,7 +8,7 @@