|
|
|
|
@@ -1,19 +1,23 @@
|
|
|
|
|
/* eslint-disable import/no-cycle */
|
|
|
|
|
import { BinaryDataManager } from 'n8n-core';
|
|
|
|
|
import { IDataObject, IRun, TelemetryHelpers } from 'n8n-workflow';
|
|
|
|
|
import { IDataObject, INodeTypes, IRun, TelemetryHelpers } from 'n8n-workflow';
|
|
|
|
|
import {
|
|
|
|
|
IDiagnosticInfo,
|
|
|
|
|
IInternalHooksClass,
|
|
|
|
|
IPersonalizationSurveyAnswers,
|
|
|
|
|
IWorkflowBase,
|
|
|
|
|
IWorkflowDb,
|
|
|
|
|
} from '.';
|
|
|
|
|
import { Telemetry } from './telemetry';
|
|
|
|
|
|
|
|
|
|
export class InternalHooksClass implements IInternalHooksClass {
|
|
|
|
|
private versionCli: string;
|
|
|
|
|
|
|
|
|
|
constructor(private telemetry: Telemetry, versionCli: string) {
|
|
|
|
|
private nodeTypes: INodeTypes;
|
|
|
|
|
|
|
|
|
|
constructor(private telemetry: Telemetry, versionCli: string, nodeTypes: INodeTypes) {
|
|
|
|
|
this.versionCli = versionCli;
|
|
|
|
|
this.nodeTypes = nodeTypes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async onServerStarted(
|
|
|
|
|
@@ -53,7 +57,7 @@ export class InternalHooksClass implements IInternalHooksClass {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async onWorkflowCreated(workflow: IWorkflowBase): Promise<void> {
|
|
|
|
|
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow);
|
|
|
|
|
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes);
|
|
|
|
|
return this.telemetry.track('User created workflow', {
|
|
|
|
|
workflow_id: workflow.id,
|
|
|
|
|
node_graph: nodeGraph,
|
|
|
|
|
@@ -67,14 +71,15 @@ export class InternalHooksClass implements IInternalHooksClass {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async onWorkflowSaved(workflow: IWorkflowBase): Promise<void> {
|
|
|
|
|
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow);
|
|
|
|
|
async onWorkflowSaved(workflow: IWorkflowDb): Promise<void> {
|
|
|
|
|
const { nodeGraph } = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes);
|
|
|
|
|
|
|
|
|
|
return this.telemetry.track('User saved workflow', {
|
|
|
|
|
workflow_id: workflow.id,
|
|
|
|
|
node_graph: nodeGraph,
|
|
|
|
|
node_graph_string: JSON.stringify(nodeGraph),
|
|
|
|
|
version_cli: this.versionCli,
|
|
|
|
|
num_tags: workflow.tags.length,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -83,6 +88,7 @@ export class InternalHooksClass implements IInternalHooksClass {
|
|
|
|
|
workflow: IWorkflowBase,
|
|
|
|
|
runData?: IRun,
|
|
|
|
|
): Promise<void> {
|
|
|
|
|
const promises = [Promise.resolve()];
|
|
|
|
|
const properties: IDataObject = {
|
|
|
|
|
workflow_id: workflow.id,
|
|
|
|
|
is_manual: false,
|
|
|
|
|
@@ -91,11 +97,10 @@ export class InternalHooksClass implements IInternalHooksClass {
|
|
|
|
|
|
|
|
|
|
if (runData !== undefined) {
|
|
|
|
|
properties.execution_mode = runData.mode;
|
|
|
|
|
if (runData.mode === 'manual') {
|
|
|
|
|
properties.is_manual = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
properties.success = !!runData.finished;
|
|
|
|
|
properties.is_manual = runData.mode === 'manual';
|
|
|
|
|
|
|
|
|
|
let nodeGraphResult;
|
|
|
|
|
|
|
|
|
|
if (!properties.success && runData?.data.resultData.error) {
|
|
|
|
|
properties.error_message = runData?.data.resultData.error.message;
|
|
|
|
|
@@ -115,7 +120,7 @@ export class InternalHooksClass implements IInternalHooksClass {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (properties.is_manual) {
|
|
|
|
|
const nodeGraphResult = TelemetryHelpers.generateNodesGraph(workflow);
|
|
|
|
|
nodeGraphResult = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes);
|
|
|
|
|
properties.node_graph = nodeGraphResult.nodeGraph;
|
|
|
|
|
properties.node_graph_string = JSON.stringify(nodeGraphResult.nodeGraph);
|
|
|
|
|
|
|
|
|
|
@@ -124,9 +129,51 @@ export class InternalHooksClass implements IInternalHooksClass {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (properties.is_manual) {
|
|
|
|
|
if (!nodeGraphResult) {
|
|
|
|
|
nodeGraphResult = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const manualExecEventProperties = {
|
|
|
|
|
workflow_id: workflow.id,
|
|
|
|
|
status: properties.success ? 'success' : 'failed',
|
|
|
|
|
error_message: properties.error_message,
|
|
|
|
|
error_node_type: properties.error_node_type,
|
|
|
|
|
node_graph: properties.node_graph,
|
|
|
|
|
node_graph_string: properties.node_graph_string,
|
|
|
|
|
error_node_id: properties.error_node_id,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!manualExecEventProperties.node_graph) {
|
|
|
|
|
nodeGraphResult = TelemetryHelpers.generateNodesGraph(workflow, this.nodeTypes);
|
|
|
|
|
manualExecEventProperties.node_graph = nodeGraphResult.nodeGraph;
|
|
|
|
|
manualExecEventProperties.node_graph_string = JSON.stringify(
|
|
|
|
|
manualExecEventProperties.node_graph,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (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],
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
promises.push(
|
|
|
|
|
this.telemetry.track('Manual workflow exec finished', manualExecEventProperties),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Promise.all([
|
|
|
|
|
...promises,
|
|
|
|
|
BinaryDataManager.getInstance().persistBinaryDataForExecutionId(executionId),
|
|
|
|
|
this.telemetry.trackWorkflowExecution(properties),
|
|
|
|
|
]).then(() => {});
|
|
|
|
|
|