From 67be43b6e68b50c10a9e8bbee5a50e7c46d857f0 Mon Sep 17 00:00:00 2001 From: Vini Brasil Date: Mon, 19 Jun 2023 12:59:47 +0100 Subject: [PATCH] Add tagged events support for revenue goals (#3038) * Add tagged events support for revenue goals This commit adds two special classes for tracking revenue with tagged events. The following example sends an event with revenue data when the tracker script has revenue and tagged-events script extensions: ```html ``` * Rename special revenue tracking class name --- tracker/src/customEvents.js | 54 +++++++++++++++++++++++------- tracker/test/fixtures/revenue.html | 8 +++-- tracker/test/revenue.spec.js | 13 +++++-- 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/tracker/src/customEvents.js b/tracker/src/customEvents.js index 98ef7db30..a52f74f17 100644 --- a/tracker/src/customEvents.js +++ b/tracker/src/customEvents.js @@ -58,11 +58,19 @@ function sendLinkClickEvent(event, link, eventAttrs) { } if (shouldFollowLink(event, link)) { - plausible(eventAttrs.name, { props: eventAttrs.props, callback: followLink }) + var attrs = { props: eventAttrs.props, callback: followLink } + {{#if revenue}} + attrs.revenue = eventAttrs.revenue + {{/if}} + plausible(eventAttrs.name, attrs) setTimeout(followLink, 5000) event.preventDefault() } else { - plausible(eventAttrs.name, { props: eventAttrs.props }) + var attrs = { props: eventAttrs.props } + {{#if revenue}} + attrs.revenue = eventAttrs.revenue + {{/if}} + plausible(eventAttrs.name, attrs) } } @@ -97,6 +105,9 @@ function isDownloadToTrack(url) { function getTaggedEventAttributes(htmlElement) { var taggedElement = isTagged(htmlElement) ? htmlElement : htmlElement && htmlElement.parentNode var eventAttrs = { name: null, props: {} } + {{#if revenue}} + eventAttrs.revenue = {} + {{/if}} var classList = taggedElement && taggedElement.classList if (!classList) { return eventAttrs } @@ -105,16 +116,25 @@ function getTaggedEventAttributes(htmlElement) { var className = classList.item(i) var matchList = className.match(/plausible-event-(.+)(=|--)(.+)/) - if (!matchList) { continue } + if (matchList) { + var key = matchList[1] + var value = matchList[3].replace(/\+/g, ' ') - var key = matchList[1] - var value = matchList[3].replace(/\+/g, ' ') - - if (key.toLowerCase() === 'name') { - eventAttrs.name = value - } else { - eventAttrs.props[key] = value + if (key.toLowerCase() == 'name') { + eventAttrs.name = value + } else { + eventAttrs.props[key] = value + } } + + {{#if revenue}} + var revenueMatchList = className.match(/plausible-revenue-(.+)(=|--)(.+)/) + if (revenueMatchList) { + var key = revenueMatchList[1] + var value = revenueMatchList[3] + eventAttrs.revenue[key] = value + } + {{/if}} } return eventAttrs @@ -136,7 +156,12 @@ function handleTaggedFormSubmitEvent(event) { } setTimeout(submitForm, 5000) - plausible(eventAttrs.name, { props: eventAttrs.props, callback: submitForm }) + + var attrs = { props: eventAttrs.props, callback: submitForm } + {{#if revenue}} + attrs.revenue = eventAttrs.revenue + {{/if}} + plausible(eventAttrs.name, attrs) } function isForm(element) { @@ -171,7 +196,12 @@ function handleTaggedElementClickEvent(event) { eventAttrs.props.url = clickedLink.href sendLinkClickEvent(event, clickedLink, eventAttrs) } else { - plausible(eventAttrs.name, { props: eventAttrs.props }) + var attrs = {} + attrs.props = eventAttrs.props + {{#if revenue}} + attrs.revenue = eventAttrs.revenue + {{/if}} + plausible(eventAttrs.name, attrs) } } } diff --git a/tracker/test/fixtures/revenue.html b/tracker/test/fixtures/revenue.html index a36ad43e2..0bb66d538 100644 --- a/tracker/test/fixtures/revenue.html +++ b/tracker/test/fixtures/revenue.html @@ -7,11 +7,15 @@ Plausible Playwright tests - + - + + diff --git a/tracker/test/revenue.spec.js b/tracker/test/revenue.spec.js index d47b55238..3d20b16e5 100644 --- a/tracker/test/revenue.spec.js +++ b/tracker/test/revenue.spec.js @@ -2,12 +2,21 @@ const { mockRequest, expectCustomEvent } = require('./support/test-utils'); const { expect, test } = require('@playwright/test'); test.describe('with revenue script extension', () => { - test('sends revenue currency and amount', async ({ page }) => { + test('sends revenue currency and amount in manual mode', async ({ page }) => { const plausibleRequestMock = mockRequest(page, '/api/event') await page.goto('/revenue.html'); - await page.click('#purchase') + await page.click('#manual-purchase') const plausibleRequest = await plausibleRequestMock expect(plausibleRequest.postDataJSON()["$"]).toEqual({amount: 15.99, currency: "USD"}) }); + + test('sends revenue currency and amount with tagged class name', async ({ page }) => { + const plausibleRequestMock = mockRequest(page, '/api/event') + await page.goto('/revenue.html'); + await page.click('#tagged-purchase') + + const plausibleRequest = await plausibleRequestMock + expect(plausibleRequest.postDataJSON()["$"]).toEqual({amount: "13.32", currency: "EUR"}) + }); });