From 04cabafef7acbc30cba647732e2ca8ae8a02d29a Mon Sep 17 00:00:00 2001 From: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com> Date: Thu, 7 Dec 2023 16:22:41 +0100 Subject: [PATCH] feat(editor): Add AppCues tracking for onboarding event (#7945) ## Summary We want to trigger a flow, every time the template onboarding event is triggered. AppCues no longer supports flows triggering through Segment, except directly. #### How to test the change: 1. Open on Cloud, where AppCues scripts are available 2. import workflow through /workflows/onboarding/1946 3. Ensure event is sent.. if flow is enabled, flow should show Screenshot 2023-12-07 at 14 39 51 ## Issues fixed Include links to Github issue or Community forum post or **Linear ticket**: > Important in order to close automatically and provide context to reviewers https://linear.app/n8n/issue/ADO-1455/bug-appcues-trigger ## Review / Merge checklist - [X] PR title and summary are descriptive. **Remember, the title automatically goes into the changelog. Use `(no-changelog)` otherwise.** ([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md)) - [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up ticket created. - [x] Tests included. > A bug is not considered fixed, unless a test is added to prevent it from happening again. A feature is not complete without tests. > > *(internal)* You can use Slack commands to trigger [e2e tests](https://www.notion.so/n8n/How-to-use-Test-Instances-d65f49dfc51f441ea44367fb6f67eb0a?pvs=4#a39f9e5ba64a48b58a71d81c837e8227) or [deploy test instance](https://www.notion.so/n8n/How-to-use-Test-Instances-d65f49dfc51f441ea44367fb6f67eb0a?pvs=4#f6a177d32bde4b57ae2da0b8e454bfce) or [deploy early access version on Cloud](https://www.notion.so/n8n/Cloudbot-3dbe779836004972b7057bc989526998?pvs=4#fef2d36ab02247e1a0f65a74f6fb534e). --- packages/editor-ui/src/Interface.ts | 3 ++ .../src/plugins/__tests__/telemetry.test.ts | 42 +++++++++++++++++++ .../editor-ui/src/plugins/telemetry/index.ts | 8 +++- packages/editor-ui/src/views/NodeView.vue | 1 + 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index 7e8b6cb587..0107bc16a0 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -104,6 +104,9 @@ declare global { }; // eslint-disable-next-line @typescript-eslint/naming-convention Cypress: unknown; + Appcues?: { + track(event: string, properties?: ITelemetryTrackProperties): void; + }; } } diff --git a/packages/editor-ui/src/plugins/__tests__/telemetry.test.ts b/packages/editor-ui/src/plugins/__tests__/telemetry.test.ts index 9693f86cbb..b9faf7489c 100644 --- a/packages/editor-ui/src/plugins/__tests__/telemetry.test.ts +++ b/packages/editor-ui/src/plugins/__tests__/telemetry.test.ts @@ -8,6 +8,8 @@ let telemetry: Telemetry; let settingsStore: ReturnType; +const MOCK_VERSION_CLI = '0.0.0'; + describe('telemetry', () => { beforeAll(() => { telemetry = new Telemetry(); @@ -137,4 +139,44 @@ describe('telemetry', () => { expect(resetFunction).toHaveBeenCalledTimes(1); }); }); + + describe('track function', () => { + it('should call Rudderstack track method with correct parameters and', () => { + const trackFunction = vi.spyOn(window.rudderanalytics, 'track'); + + const event = 'testEvent'; + const properties = { test: '1' }; + const options = { withPostHog: false, withAppCues: false }; + + telemetry.track(event, properties, options); + + expect(trackFunction).toHaveBeenCalledTimes(1); + expect(trackFunction).toHaveBeenCalledWith(event, { + ...properties, + version_cli: MOCK_VERSION_CLI, + }); + }); + + it('should call Rudderstack track method with correct parameters and withAppCues option set to true', () => { + window.Appcues = { track: () => {} }; + const trackFunction = vi.spyOn(window.rudderanalytics, 'track'); + const appCuesTrackFunction = vi.spyOn(window.Appcues, 'track'); + + const event = 'testEvent'; + const properties = { test: '1' }; + const options = { withPostHog: false, withAppCues: true }; + + telemetry.track(event, properties, options); + + expect(trackFunction).toHaveBeenCalledTimes(1); + expect(trackFunction).toHaveBeenCalledWith(event, { + ...properties, + version_cli: MOCK_VERSION_CLI, + }); + expect(appCuesTrackFunction).toHaveBeenCalledWith(event, { + ...properties, + version_cli: MOCK_VERSION_CLI, + }); + }); + }); }); diff --git a/packages/editor-ui/src/plugins/telemetry/index.ts b/packages/editor-ui/src/plugins/telemetry/index.ts index ad33ab9cd2..dda799d279 100644 --- a/packages/editor-ui/src/plugins/telemetry/index.ts +++ b/packages/editor-ui/src/plugins/telemetry/index.ts @@ -99,7 +99,7 @@ export class Telemetry { track( event: string, properties?: ITelemetryTrackProperties, - { withPostHog } = { withPostHog: false }, + options: { withPostHog?: boolean; withAppCues?: boolean } = {}, ) { if (!this.rudderStack) return; @@ -110,9 +110,13 @@ export class Telemetry { this.rudderStack.track(event, updatedProperties); - if (withPostHog) { + if (options.withPostHog) { usePostHog().capture(event, updatedProperties); } + + if (options.withAppCues && window.Appcues) { + window.Appcues.track(event, updatedProperties); + } } page(route: Route) { diff --git a/packages/editor-ui/src/views/NodeView.vue b/packages/editor-ui/src/views/NodeView.vue index d35da15ba4..93ee597da4 100644 --- a/packages/editor-ui/src/views/NodeView.vue +++ b/packages/editor-ui/src/views/NodeView.vue @@ -3218,6 +3218,7 @@ export default defineComponent({ }, { withPostHog: true, + withAppCues: true, }, ); }