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
<button class="plausible-event-revenue-amount=10.29 plausible-event-revenue-currency=EUR"></button>
```

* Rename special revenue tracking class name
This commit is contained in:
Vini Brasil 2023-06-19 12:59:47 +01:00 committed by GitHub
parent 94591a5a20
commit 67be43b6e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 16 deletions

View File

@ -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)
}
}
}

View File

@ -7,11 +7,15 @@
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Plausible Playwright tests</title>
<script defer src="/tracker/js/plausible.local.manual.revenue.js"></script>
<script defer src="/tracker/js/plausible.local.manual.revenue.tagged-events.js"></script>
</head>
<body>
<button id="purchase" onclick="window.plausible('Purchase', {revenue: {amount: 15.99, currency: 'USD'}})">
<button id="manual-purchase" onclick="window.plausible('Purchase', {revenue: {amount: 15.99, currency: 'USD'}})">
Click me
</button>
<button id="tagged-purchase" class="plausible-event-name=Purchase plausible-revenue-currency=EUR plausible-revenue-amount=13.32">
Click me
</button>
</body>

View File

@ -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"})
});
});