UNPKG

@68publishers/amp-client

Version:

JS Client for 68publishers/amp

217 lines (179 loc) 8.6 kB
import { Events as MetricsEvents } from './events.mjs'; import { EventsConfig } from './events-config.mjs'; import { Events } from '../event/events.mjs'; import { State } from '../banner/state.mjs'; export class MetricsEventsListener { #metricsSender; #eventBus; #channelCode; #attached; #beforeAttachedQueue = { started: false, events: [], cleanup: [], }; /** * @param {MetricsSender} metricsSender * @param {EventBus} eventBus * @param {String} channelCode */ constructor(metricsSender, eventBus, channelCode) { this.#metricsSender = metricsSender; this.#eventBus = eventBus; this.#channelCode = channelCode; this.#attached = false; } collectBeforeAttach() { if (this.#beforeAttachedQueue.started || this.#attached) { return; } this.#beforeAttachedQueue.started = true; const eventBus = this.#eventBus; const config = new EventsConfig({}); const bannerLoadedEvent = config.events[MetricsEvents.BANNER_LOADED]; const bannerDisplayedEvent = config.events[MetricsEvents.BANNER_DISPLAYED]; const bannerFullyDisplayedEvent = config.events[MetricsEvents.BANNER_FULLY_DISPLAYED]; const bannerClickedEvent = config.events[MetricsEvents.BANNER_CLICKED]; const bannerClosedEvent = config.events[MetricsEvents.BANNER_CLOSED]; this.#beforeAttachedQueue.cleanup.push( eventBus.subscribe(Events.ON_BANNER_STATE_CHANGED, ({ banner }) => { if (banner.isEmbed() || State.RENDERED !== banner.state || 1 !== banner.stateCounter) { return; } for (let fingerprint of banner.fingerprints) { this.#beforeAttachedQueue.events.push({ name: MetricsEvents.BANNER_LOADED, params: this.#createBaseMetricsParams({ event: bannerLoadedEvent, fingerprint, banner }), }); } }), ); this.#beforeAttachedQueue.cleanup.push( eventBus.subscribe(Events.ON_BANNER_FIRST_TIME_SEEN, ({ fingerprint, banner }) => { this.#beforeAttachedQueue.events.push({ name: MetricsEvents.BANNER_DISPLAYED, params: this.#createBaseMetricsParams({ event: bannerDisplayedEvent, fingerprint, banner }), }); }), ); this.#beforeAttachedQueue.cleanup.push( eventBus.subscribe(Events.ON_BANNER_FIRST_TIME_FULLY_SEEN, ({ fingerprint, banner }) => { this.#beforeAttachedQueue.events.push({ name: MetricsEvents.BANNER_FULLY_DISPLAYED, params: this.#createBaseMetricsParams({ event: bannerFullyDisplayedEvent, fingerprint, banner }), }); }), ); this.#beforeAttachedQueue.cleanup.push( eventBus.subscribe(Events.ON_BANNER_LINK_CLICKED, ({ fingerprint, banner, target }) => { const params = this.#createBaseMetricsParams({ event: bannerClickedEvent, fingerprint, banner }); params[bannerClickedEvent.params.link] = target.href || ''; this.#beforeAttachedQueue.events.push({ name: MetricsEvents.BANNER_CLICKED, params: params, }); }), ); this.#beforeAttachedQueue.cleanup.push( eventBus.subscribe(Events.ON_BANNER_AFTER_CLOSE, ({ fingerprint, banner }) => { this.#beforeAttachedQueue.events.push({ name: MetricsEvents.BANNER_CLOSED, params: this.#createBaseMetricsParams({ event: bannerClosedEvent, fingerprint, banner }), }); }), ); } /** * @param {EventsConfig} config */ attach(config) { if (this.#attached) { return; } this.#attached = true; const eventBus = this.#eventBus; const metricsSender = this.#metricsSender; if (!metricsSender.hasAnyReceiver()) { this.#clearBeforeAttachedQueue(); return; } const bannerLoadedEvent = config.events[MetricsEvents.BANNER_LOADED]; const bannerDisplayedEvent = config.events[MetricsEvents.BANNER_DISPLAYED]; const bannerFullyDisplayedEvent = config.events[MetricsEvents.BANNER_FULLY_DISPLAYED]; const bannerClickedEvent = config.events[MetricsEvents.BANNER_CLICKED]; const bannerClosedEvent = config.events[MetricsEvents.BANNER_CLOSED]; if (this.#beforeAttachedQueue.started) { for (let i in this.#beforeAttachedQueue.events) { const { name, params } = this.#beforeAttachedQueue.events[i]; const event = config.events[name]; if (!event.enabled) { continue; } const mappedParams = {}; for (let paramKey in params) { mappedParams[event.params[paramKey]] = params[paramKey]; } metricsSender.send(event.name, { ...mappedParams, ...event.extraParams }); } this.#clearBeforeAttachedQueue(); } if (bannerLoadedEvent.enabled) { eventBus.subscribe(Events.ON_BANNER_STATE_CHANGED, ({ banner }) => { if (banner.isEmbed() || State.RENDERED !== banner.state || 1 !== banner.stateCounter) { return; } for (let fingerprint of banner.fingerprints) { metricsSender.send(bannerLoadedEvent.name, this.#createBaseMetricsParams({ event: bannerLoadedEvent, fingerprint, banner })); } }); } if (bannerDisplayedEvent.enabled) { eventBus.subscribe(Events.ON_BANNER_FIRST_TIME_SEEN, ({ fingerprint, banner }) => { metricsSender.send(bannerDisplayedEvent.name, this.#createBaseMetricsParams({ event: bannerDisplayedEvent, fingerprint, banner })); }); } if (bannerFullyDisplayedEvent.enabled) { eventBus.subscribe(Events.ON_BANNER_FIRST_TIME_FULLY_SEEN, ({ fingerprint, banner }) => { metricsSender.send(bannerFullyDisplayedEvent.name, this.#createBaseMetricsParams({ event: bannerFullyDisplayedEvent, fingerprint, banner })); }); } if (bannerClickedEvent.enabled) { eventBus.subscribe(Events.ON_BANNER_LINK_CLICKED, ({ fingerprint, banner, target }) => { const params = this.#createBaseMetricsParams({ event: bannerClickedEvent, fingerprint, banner }); params[bannerClickedEvent.params.link] = target.href || ''; metricsSender.send(bannerClickedEvent.name, params); }); } if (bannerClosedEvent.enabled) { eventBus.subscribe(Events.ON_BANNER_AFTER_CLOSE, ({ fingerprint, banner }) => { metricsSender.send(bannerClosedEvent.name, this.#createBaseMetricsParams({ event: bannerClosedEvent, fingerprint, banner })); }); } } #createBaseMetricsParams = ({ event, fingerprint, banner }) => { let breakpoint = banner.getCurrentBreakpoint(fingerprint.bannerId); breakpoint = null === breakpoint ? 'default' : `${'min' === banner.positionData.breakpointType ? '>=' : '<='}${breakpoint}`; const params = {}; params[event.params.channel_code] = this.#channelCode; params[event.params.banner_id] = fingerprint.bannerId; params[event.params.banner_name] = fingerprint.bannerName; params[event.params.position_id] = fingerprint.positionId; params[event.params.position_code] = fingerprint.positionCode; params[event.params.position_name] = fingerprint.positionName; params[event.params.campaign_id] = fingerprint.campaignId; params[event.params.campaign_code] = fingerprint.campaignCode; params[event.params.campaign_name] = fingerprint.campaignName; params[event.params.breakpoint] = breakpoint; return { ...params, ...event.extraParams, }; }; #clearBeforeAttachedQueue() { for (let i in this.#beforeAttachedQueue.cleanup) { this.#beforeAttachedQueue.cleanup[i](); } this.#beforeAttachedQueue.events = []; this.#beforeAttachedQueue.cleanup = []; } }