@aller/blink
Version:
A library for tracking user behaviour.
465 lines (438 loc) • 12.4 kB
text/typescript
import createStore from './store';
import {
PAGE_INIT,
CLICK,
CUSTOM,
AD_SCREEN_ENTER_0,
AD_SCREEN_ENTER,
AD_SCREEN_EXIT_0,
AD_SCREEN_EXIT,
ARTICLE_PREVIEW_SCREEN_EXIT,
PAGE_LOAD,
ARTICLE_PREVIEW_SCREEN_ENTER,
ARTICLE_ACTIVITY_START,
ARTICLE_ACTIVITY_STOP,
DFP_IMPRESSION_VIEWABLE,
DFP_SLOT_ON_LOAD,
DFP_SLOT_RENDER_ENDED,
AD_LOAD_START,
SEND_ALL_EVENTS,
SCREEN_HIDE,
SCREEN_SHOW,
BOX_SCREEN_ENTER,
BOX_SCREEN_EXIT,
VIDEO_LOAD,
VIDEO_PLAY,
VIDEO_STOP,
VIDEO_AD,
PLAYER_SHOWN,
PLAYER_HIDDEN,
} from './actions';
import getIdFromUrl from './utils/get-id-from-url';
import getActivity from './selectors/get-activity';
import getInscreenTime from './selectors/get-inscreen-time';
import { BlinkEvent } from './types';
import getPageState from './selectors/get-page-state';
import { PlayerEvent } from './reducers/player';
export interface PageInitInput {
abCookie?: number;
commercialSegments?: string;
pageId?: string;
pageType?: string;
pageView?: string;
previousPageView?: string;
referrer?: string;
site: string;
url: string;
userId: string;
}
export interface PageLoadInput {
cmId: string;
pageId?: string;
plussData: {
hasAccess: boolean;
customerNumber: string;
};
url: string;
}
export interface VideoLoadInput {
videoId: string;
duration: number;
position: number;
title?: string;
width: number;
height: number;
viewable: boolean;
muted: boolean;
quality?: string;
withAdBlock: boolean;
time?: Date;
}
export interface VideoInteractionInput {
videoId: string;
playerId: string;
time?: Date;
pageId?: string;
}
export interface VideoPlayInput extends VideoInteractionInput {
muted: boolean;
volume: number;
position: number;
reason: 'autostart' | 'interaction' | 'related-auto'; // interaction is 'play' button press
}
export interface VideoStopInput extends VideoInteractionInput {
muted: boolean;
volume: number;
position: number;
reason: 'pause' | 'complete' | 'exit';
}
export interface VideoAdInput extends VideoInteractionInput {
adPosition: 'pre' | 'mid' | 'post';
system?: string;
title?: string;
client?: string;
viewable?: number;
adId?: string;
isBumper?: boolean;
creativeId?: string;
duration?: number;
}
export interface PlayerHiddenInput extends PlayerEvent {
playerId: string;
reason: 'viewable' | 'tabclose' | 'tabhide';
pageId?: string;
}
export interface PlayerShownInput extends PlayerEvent {
playerId: string;
reason: 'viewable' | 'tabactive';
pageId?: string;
}
export interface ClickInput {
id?: string;
url?: string;
context?: string[];
pageId?: string;
}
export interface CustomInput {
customDomain: string;
customType: string;
customContent?: string;
customValue?: number;
pageId?: string;
time?: Date;
}
export interface ArticlePreviewScreenEnterInput {
context?: string[];
height?: number;
pageId?: string;
personalizationSystemUsed?: string;
personalizationParametersRequested?: string;
position?: number;
time?: Date;
title: string;
url: string;
width?: number;
}
export interface ArticlePreviewScreenExitInput {
url: string;
pageId?: string;
time?: Date;
}
export interface BoxScreenEnterInput {
id: string;
title?: string;
height?: number;
width?: number;
pageId?: string;
time?: Date;
}
export interface DFPSlotRenderEndedInput {
adUnitPath: string;
advertiserId: number;
bidder: string;
campaignId: number;
creativeId: number;
id: string;
lineItemId: number;
scrollTop: number;
size: number[];
sourceAgnosticCreativeId: number;
sourceAgnosticLineItemId: number;
}
export interface DfpImpressionViewableInput {
id: string;
scrollTop: number;
time?: Date;
}
export interface DfpSlotOnloadInput {
id: string;
name: string;
scrollTop: number;
time?: Date;
}
export interface AdLoadInput {
id: string;
offsetHeight: number;
offsetTop: number;
scrollTop: number;
}
export interface ArticlePreviewInfo {
id: string;
clicked: boolean;
inscreenTime: number;
title: string;
}
export interface PageActivityStartInput {
url: string;
pageId?: string;
maxScroll?: number;
time?: Date;
}
export interface PageActivityStopInput {
url: string;
pageId?: string;
time?: Date;
}
export interface GetPageInput {
url: string;
pageId?: string;
time?: Date;
}
export interface BlinkProps {
send: (events: BlinkEvent[]) => void;
sendDirect: (events: BlinkEvent[]) => void;
persistState: (key: string, state: any) => void;
utils: {
getPersistedState: (key: string) => any;
getArticleBodyTop: () => number;
getArticleBodyHeight: () => number;
getClientWidth: () => number;
getClientHeight: () => number;
getScrollHeight: () => number;
};
useDevTools?: boolean;
}
export interface Blink {
pageInit(input: PageInitInput): void;
pageLoad(input: PageLoadInput): void;
click(input: ClickInput): void;
custom(input: CustomInput): void;
adScreenEnter(input: { id: string; pageId?: string; time?: Date }): void;
adScreenExit(input: { id: string; pageId?: string; time?: Date }): void;
adScreenEnter0(input: { id: string; pageId?: string; time?: Date }): void;
adScreenExit0(input: { id: string; pageId?: string; time?: Date }): void;
articlePreviewScreenEnter(input: ArticlePreviewScreenEnterInput): void;
articlePreviewScreenExit(input: ArticlePreviewScreenExitInput): void;
pageActivityStart(input: PageActivityStartInput): void;
pageActivityStop(input: PageActivityStopInput): void;
boxScreenEnter(input: BoxScreenEnterInput): void;
boxScreenExit(input: { id: string; pageId?: string; time?: Date }): void;
dfpSlotRenderEnded(input: DFPSlotRenderEndedInput): void;
dfpImpressionViewable(input: DfpImpressionViewableInput): void;
dfpSlotOnload(input: DfpSlotOnloadInput): void;
adLoad(input: AdLoadInput): void;
sendAllEvents(time?: Date): void;
getStore(): any;
getPage(input: GetPageInput): any;
getArticlePreview(input: { url: string; pageId?: string; time?: Date }): any;
getBox(input: { id: string; pageId?: string; time?: Date }): any;
screenHide(time?: Date): void;
screenShow(time?: Date): void;
videoLoad(input: VideoLoadInput): void;
videoPlay(input: VideoPlayInput): void;
videoStop(input: VideoStopInput): void;
videoAd(input: VideoAdInput): void;
playerShown(input: PlayerShownInput): void;
playerHidden(input: PlayerHiddenInput): void;
}
export default function createBlink({
send,
sendDirect,
persistState,
utils,
useDevTools,
}: BlinkProps): Blink {
const store = createStore(send, sendDirect, persistState, useDevTools);
return {
pageInit(input: PageInitInput) {
store.dispatch({ type: PAGE_INIT, payload: input, utils });
},
pageLoad(input: PageLoadInput) {
store.dispatch({ type: PAGE_LOAD, payload: input, utils });
},
click(input: ClickInput) {
const { site } = getPageState(
store.getState(),
input.pageId,
).state.general;
store.dispatch({
type: CLICK,
payload: {
id: getIdFromUrl(input.url || '', site),
clickId: input.id,
url: input.url,
context: input.context,
pageId: input.pageId,
},
});
},
videoLoad(input: VideoLoadInput) {
store.dispatch({ type: VIDEO_LOAD, payload: { ...input } });
},
videoPlay(input: VideoPlayInput) {
store.dispatch({ type: VIDEO_PLAY, payload: { ...input } });
},
videoStop(input: VideoStopInput) {
store.dispatch({ type: VIDEO_STOP, payload: { ...input } });
},
playerShown(input: PlayerShownInput) {
store.dispatch({ type: PLAYER_SHOWN, payload: { ...input } });
},
playerHidden(input: PlayerHiddenInput) {
store.dispatch({ type: PLAYER_HIDDEN, payload: { ...input } });
},
videoAd(input: VideoAdInput) {
store.dispatch({ type: VIDEO_AD, payload: { ...input } });
},
custom(input: CustomInput) {
store.dispatch({ type: CUSTOM, payload: { ...input } });
},
adScreenEnter({ id, time, pageId }) {
store.dispatch({
type: AD_SCREEN_ENTER,
payload: { id, time, pageId },
utils,
});
},
adScreenExit({ id, time, pageId }) {
store.dispatch({
type: AD_SCREEN_EXIT,
payload: { id, time, pageId },
utils,
});
},
adScreenEnter0({ id, time, pageId }) {
store.dispatch({
type: AD_SCREEN_ENTER_0,
payload: { id, time, pageId },
utils,
});
},
adScreenExit0({ id, time, pageId }) {
store.dispatch({
type: AD_SCREEN_EXIT_0,
payload: { id, time, pageId },
utils,
});
},
articlePreviewScreenEnter(input: ArticlePreviewScreenEnterInput) {
const { site } = getPageState(
store.getState(),
input.pageId,
).state.general;
const id = getIdFromUrl(input.url, site);
store.dispatch({
type: ARTICLE_PREVIEW_SCREEN_ENTER,
payload: { ...input, id },
utils,
});
},
articlePreviewScreenExit({ url, pageId, time }) {
const { site } = getPageState(store.getState(), pageId).state.general;
const id = getIdFromUrl(url, site);
store.dispatch({
type: ARTICLE_PREVIEW_SCREEN_EXIT,
payload: { id, url, time, pageId },
utils,
});
},
boxScreenEnter(input: BoxScreenEnterInput) {
store.dispatch({
type: BOX_SCREEN_ENTER,
payload: { ...input },
utils,
});
},
boxScreenExit({ id, time, pageId }) {
store.dispatch({
type: BOX_SCREEN_EXIT,
payload: { id, time, pageId },
utils,
});
},
pageActivityStart({ url, maxScroll, pageId, time }) {
const { site } = getPageState(store.getState(), pageId).state.general;
const id = getIdFromUrl(url, site);
store.dispatch({
type: ARTICLE_ACTIVITY_START,
payload: { id, time, url, maxScroll, pageId },
utils,
});
},
pageActivityStop({ url, pageId, time }) {
const { site } = getPageState(store.getState(), pageId).state.general;
const id = getIdFromUrl(url, site);
store.dispatch({
type: ARTICLE_ACTIVITY_STOP,
payload: { id, time, url, pageId },
utils,
});
},
dfpSlotRenderEnded(input: DFPSlotRenderEndedInput) {
store.dispatch({ type: DFP_SLOT_RENDER_ENDED, payload: input, utils });
},
dfpImpressionViewable(input: DfpImpressionViewableInput) {
store.dispatch({
type: DFP_IMPRESSION_VIEWABLE,
payload: input,
utils,
});
},
dfpSlotOnload(input: DfpSlotOnloadInput) {
store.dispatch({ type: DFP_SLOT_ON_LOAD, payload: input, utils });
},
adLoad(input: AdLoadInput) {
store.dispatch({ type: AD_LOAD_START, payload: input, utils });
},
sendAllEvents(time?: Date) {
store.dispatch({ type: SEND_ALL_EVENTS, payload: { time }, utils });
},
screenHide(time?: Date) {
store.dispatch({ type: SCREEN_HIDE, payload: { time }, utils });
},
screenShow(time?: Date) {
store.dispatch({ type: SCREEN_SHOW, payload: { time }, utils });
},
getStore() {
return store;
},
getPage({ url, pageId, time }) {
const page = getPageState(this.getStore().getState(), pageId);
const id = getIdFromUrl(url, page.state.general.site) || '';
const activity = getActivity(page.state, id, time || new Date());
return {
...page.state.general,
activeTime: activity.activeTime,
isActive: activity.isActive,
};
},
getArticlePreview({ url, pageId, time }) {
const page = getPageState(this.getStore().getState(), pageId);
const { site } = page.state.general;
const id = getIdFromUrl(url, site) || '';
const ap = page.state.articlePreview[id] || {};
return {
...ap,
inscreenTime: getInscreenTime(page.state, id, time || new Date()),
};
},
getBox({ id, pageId, time }) {
const page = getPageState(this.getStore().getState(), pageId);
const box = page.state.box[id] || {};
return {
...box,
inscreenTime: getInscreenTime(page.state, id, time || new Date()),
};
},
};
}