Skip to content

Commit

Permalink
Metric events renaming
Browse files Browse the repository at this point in the history
- added configuration options `metrics.events` and `metrics.params`
- removed configuration option `metrics.disabledEvents`
- events can be now disabled also via the option `metrics.events`
- updated docs
- updated changelog
  • Loading branch information
tg666 committed Oct 1, 2024
1 parent 62cbc64 commit bd87b46
Show file tree
Hide file tree
Showing 10 changed files with 264 additions and 62 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added support for banners closing.
- HTML banners can be simply closed via any element with a data attribute `data-amp-banner-close=""`.
- Added the ability to rename events and their parameters using the `metrics.events` and `metrics.params` options.

### Changed
- Changed arguments that are passed to the listeners `amp:banner:attached`, `amp:banner:state-changed`, `amp:fetch:error` and `amp:fetch:success`. Arguments are now passed as an object, so instead of `(banner) => {}` it is necessary to write `({ banner }) => {}`, respectively `({ response }) => {}` in case of events `amp:fetch:error` and `amp:fetch:success`.
- Updated docs.

### Removed
- Removed the `metrics.disabledEvents` option. Events can now be disabled by putting `false` next to the event name in the `metrics.events` option.

## [1.6.0] - 2024-09-19
### Added
- Added support for new banner option `fetchpriority`.
Expand Down
24 changes: 22 additions & 2 deletions docs/integration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ const AMPClient = AMPClientFactory.create({
| **interaction.intersectionRatioMap** | `object` | `{}` | No | The "map" of intersection ratios. Keys must be numeric and represents a number of pixels. The values must match the same criteria as the option `interaction.defaultIntersectionRatio`. If a banner does not have an equal or greater pixel count than any option, then `defaultIntersectionRatio` is used. |
| **interaction.firstTimeSeenTimeout** | `integer` | `1000` | No | The value indicates, in milliseconds, how long the banner must be visible in the user's viewport before it is evaluated as having been seen for the first time. The minimum allowed value is 500. |
| **metrics.receiver** | `null/string/function/array<string/function>` | `null` | No | Metrics are sent to the selected receiver if the value is set. The value can be a custom function, or one of the following strings: `"plausible"`, `"gtag"`, `"gtm"` or `"debug"`. Alternatively, an array can be passed if we would like to send metrics to multiple receivers. For example, `["plausible", "gtag"]`. |
| **metrics.disabledEvents** | `array<string>` | `[]` | No | Names of metric events that should not be sent. |
| **metrics.events** | `object` | `{}` | No | Used to rename metric events, or to disable them completely if `false` is specified instead of an event name. |
| **metrics.params** | `object` | `{}` | No | Used to rename metric event parameters. |
| **closing.storage** | `string` | `"memoryStorage"` | No | The storage where information about banners closed by the user is stored. Allowed values are `memoryStorage` (default, banners are not closed permanently), `localStorage` and `sessionStorage`. |
| **closing.key** | `string` | `"amp-closed-banners"` | No | The storage key under which information about closed banners is stored. |
| **closing.maxItems** | `integer` | `500` | No | Maximum number of closed items (banners) in the storage. |
Expand Down Expand Up @@ -81,7 +82,26 @@ const AMPClient = AMPClientFactory.create({
},
metrics: {
receiver: 'gtm',
disabledEvents: ['amp:banner:loaded'],
events: {
'amp:banner:loaded': 'BannerLoaded',
'amp:banner:displayed': 'BannerDisplayed',
'amp:banner:fully-displayed': false,
'amp:banner:clicked': 'BannerClicked',
'amp:banner:closed': 'BannerClosed',
},
params: {
channel_code: 'amp_channelCode',
banner_id: 'amp_bannerId',
banner_name: 'amp_bannerName',
position_id: 'amp_positionId',
position_code: 'amp_positionCode',
position_name: 'amp_positionName',
campaign_id: 'amp_campaignId',
campaign_code: 'amp_campaignCode',
campaign_name: 'amp_campaignName',
breakpoint: 'amp_breakpoint',
link: 'amp_clickedLink',
}
},
closing: {
storage: 'localStorage',
Expand Down
6 changes: 4 additions & 2 deletions src/client/embed/client.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { ParentFrameMessenger } from '../../frame/parent-frame-messenger.mjs';
import { BannerInteractionWatcher } from '../../interaction/banner-interaction-watcher.mjs';
import { MetricsSender } from '../../metrics/metrics-sender.mjs';
import { MetricsEventsListener } from '../../metrics/metrics-events-listener.mjs';
import { EventsConfig } from '../../metrics/events-config.mjs';
import { State } from '../../banner/state.mjs';
import {ClosingManager} from "../../banner/closing/closing-manager.mjs";
import { ClosingManager } from '../../banner/closing/closing-manager.mjs';

export class Client {
#version;
Expand Down Expand Up @@ -73,6 +74,7 @@ export class Client {

this.#redrawBanners();
this.#bannerInteractionWatcher.start();
this.#metricsEventsListener.attach(new EventsConfig(this.#extendedConfig.metrics));
});

this.#frameMessenger.on('windowResized', ({ data }) => {
Expand All @@ -81,7 +83,7 @@ export class Client {
});

this.#frameMessenger.listen();
this.#metricsEventsListener.attach();
this.#metricsEventsListener.collectBeforeAttach();
this.#closingManager.attachUi();
}

Expand Down
17 changes: 17 additions & 0 deletions src/client/embed/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export function createExtendedConfig(options) {
intersectionRatioMap: {},
firstTimeSeenTimeout: 1000,
},
metrics: {
events: {},
params: {},
},
}, options);

// interaction
Expand Down Expand Up @@ -56,5 +60,18 @@ export function createExtendedConfig(options) {
throw new Error(`The option "interaction.firstTimeSeenTimeout" must be a int with a minimum value of 500, "${config.interaction.firstTimeSeenTimeout}" passed.`);
}

// metrics
if ('object' !== typeof config.metrics) {
throw new Error(`The option "metrics" must be an object of the format { events: object{ *: string|false }, params: object{ *: string } }, ${JSON.stringify(config.metrics)} passed.`);
}

if ('object' !== typeof config.metrics.events) {
throw new Error(`The option "metrics.event" must be an object of the format { *: string|false }, ${JSON.stringify(config.metrics.events)} passed.`);
}

if ('object' !== typeof config.metrics.params) {
throw new Error(`The option "metrics.params" must be an object of the format { *: string }, ${JSON.stringify(config.metrics.params)} passed.`);
}

return config;
}
7 changes: 5 additions & 2 deletions src/client/standard/client.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { BannerRenderer } from '../../renderer/banner-renderer.mjs';
import { BannerInteractionWatcher } from '../../interaction/banner-interaction-watcher.mjs';
import { MetricsEventsListener } from '../../metrics/metrics-events-listener.mjs';
import { MetricsSender } from '../../metrics/metrics-sender.mjs';
import { EventsConfig } from '../../metrics/events-config.mjs';
import { BannerFrameMessenger } from '../../frame/banner-frame-messenger.mjs';
import { getHtmlElement } from '../../utils/dom-helpers.mjs';

Expand Down Expand Up @@ -68,7 +69,6 @@ export class Client {

this.#metricsSender = MetricsSender.createFromReceivers(
options.metrics.receiver,
options.metrics.disabledEvents,
);
this.#metricsEventsListener = new MetricsEventsListener(
this.#metricsSender,
Expand Down Expand Up @@ -119,7 +119,10 @@ export class Client {
});

this.#frameMessenger.listen();
this.#metricsEventsListener.attach();
this.#metricsEventsListener.attach(new EventsConfig({
events: options.metrics.events,
params: options.metrics.params,
}));
this.#bannerInteractionWatcher.start();
this.#closingManager.attachUi();
}
Expand Down
15 changes: 7 additions & 8 deletions src/client/standard/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export function createConfig(options) {
},
metrics: {
receiver: null,
disabledEvents: [],
events: {},
params: {},
},
closing: {
storage: 'memoryStorage',
Expand Down Expand Up @@ -118,7 +119,7 @@ export function createConfig(options) {

// metrics
if ('object' !== typeof config.metrics) {
throw new Error(`The option "metrics" must be an object of the format { receiver: null|string|function|array<string|function>, disabledEvents: array<string> }, ${config.metrics} passed.`);
throw new Error(`The option "metrics" must be an object of the format { receiver: null|string|function|array<string|function>, events: object{ *: string|false }, params: object{ *: string } }, ${config.metrics} passed.`);
}

if (null !== config.metrics.receiver && -1 === ['string', 'function'].indexOf(typeof config.metrics.receiver) && !Array.isArray(config.metrics.receiver)) {
Expand All @@ -135,14 +136,12 @@ export function createConfig(options) {
config.metrics.receiver = null !== config.metrics.receiver ? [config.metrics.receiver] : [];
}

if (!Array.isArray(config.metrics.disabledEvents)) {
throw new Error(`The option "metrics.disabledEvents" must an array of strings (event names), "${config.metrics.disabledEvents}" passed.`);
if ('object' !== typeof config.metrics.events) {
throw new Error(`The option "metrics.event" must be an object of the format { *: string|false }, ${JSON.stringify(config.metrics.events)} passed.`);
}

for (let disabledEventIndex in config.metrics.disabledEvents) {
if ('string' !== typeof config.metrics.disabledEvents[disabledEventIndex]) {
throw new Error(`The option "metrics.disabledEvents.${disabledEventIndex}" must be a string, "${config.metrics.disabledEvents[disabledEventIndex]}" passed.`);
}
if ('object' !== typeof config.metrics.params) {
throw new Error(`The option "metrics.params" must be an object of the format { *: string }, ${JSON.stringify(config.metrics.params)} passed.`);
}

// closing
Expand Down
2 changes: 1 addition & 1 deletion src/frame/banner-frame-messenger.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export class BannerFrameMessenger extends FrameMessenger {
#onMetricsMessage({ data }) {
const { eventName, eventArgs } = data;

if (this.#metricsSender.hasAnyReceiver() && this.#metricsSender.isEventEnabled(eventName)) {
if (this.#metricsSender.hasAnyReceiver()) {
this.#metricsSender.send(eventName, eventArgs);
}
}
Expand Down
51 changes: 51 additions & 0 deletions src/metrics/events-config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Events } from './events.mjs';

export class EventsConfig {
constructor(config) {
const events = {};
events[Events.BANNER_LOADED] = Events.BANNER_LOADED;
events[Events.BANNER_DISPLAYED] = Events.BANNER_DISPLAYED;
events[Events.BANNER_FULLY_DISPLAYED] = Events.BANNER_FULLY_DISPLAYED;
events[Events.BANNER_CLICKED] = Events.BANNER_CLICKED;
events[Events.BANNER_CLOSED] = Events.BANNER_CLOSED;

const params = {
channel_code: 'channel_code',
banner_id: 'banner_id',
banner_name: 'banner_name',
position_id: 'position_id',
position_code: 'position_code',
position_name: 'position_name',
campaign_id: 'campaign_id',
campaign_code: 'campaign_code',
campaign_name: 'campaign_name',
breakpoint: 'breakpoint',
link: 'link',
};

if ('events' in config) {
for (let eventKey in config.events) {
const eventValue = config.events[eventKey];

if (true === eventValue || !(eventKey in events)) {
continue;
}

if (false === eventValue || 'string' === typeof eventValue) {
events[eventKey] = eventValue;
}
}
}

if ('params' in config) {
for (let paramKey in config.params) {
if (paramKey in params && 'string' === typeof config.params[paramKey]) {
params[paramKey] = config.params[paramKey];
}
}
}

this.events = events;
this.params = params;
}
}
Loading

0 comments on commit bd87b46

Please sign in to comment.