@aller/blink
Version:
A library for tracking user behaviour.
200 lines (195 loc) • 5.8 kB
text/typescript
import prepareImpression, {
getAllArticleImpressionEventsPrepared,
} from './events/prepare-impression-event';
import prepareAdEvent, {
getAllAdEventsPrepared,
} from './events/prepare-ad-event';
import prepareActiveTimeEvent, {
getAllActiveTimeEventsPrepared,
} from './events/prepare-active-time-event';
import preparePageloadEvent from './events/prepare-pageload-event';
import prepareClickEvent from './events/prepare-click-event';
import prepareCustomEvent from './events/prepare-custom-event';
import prepareBoxEvent, {
getAllBoxEventsPrepared,
} from './events/prepare-box-event';
import {
DFP_IMPRESSION_VIEWABLE,
DFP_SLOT_ON_LOAD,
DFP_SLOT_RENDER_ENDED,
CLICK,
CUSTOM,
PAGE_INIT,
PAGE_LOAD,
AD_SCREEN_EXIT,
AD_SCREEN_EXIT_0,
ARTICLE_ACTIVITY_STOP,
ARTICLE_PREVIEW_SCREEN_EXIT,
SEND_ALL_EVENTS,
BOX_SCREEN_EXIT,
VIDEO_LOAD,
VIDEO_STOP,
VIDEO_AD,
PLAYER_HIDDEN,
} from './actions';
import { BlinkEvent } from './types';
import prepareVideoLoadForSending from './events/prepare-video-load-event';
import prepareVideoWatchForSending, {
getAllVideoWatchEventsPrepared,
} from './events/prepare-video-watch-event';
import prepareVideoAdForSending from './events/prepare-video-ad-event';
import getPageState from './selectors/get-page-state';
import { getUniqueVideoIdsForPlayer } from './utils/player';
export default function senderMiddleware(
send: (events: BlinkEvent[]) => any,
sendDirect: (events: BlinkEvent[]) => any,
) {
return ({ getState }: { getState: any }) => (next: any) => (action: any) => {
// Send all events if we get a pageInit event
// Make sure we do it before the PAGE_INIT flushes the state
if (action.type === PAGE_INIT) {
const { payload, utils } = action;
const beforePage = getPageState(getState(), payload.pageId).state;
const eventsToSend = [
...getAllAdEventsPrepared(beforePage, utils, payload.time),
...getAllActiveTimeEventsPrepared(beforePage, utils, payload.time),
...getAllArticleImpressionEventsPrepared(beforePage, payload.time),
];
if (eventsToSend.length > 0) {
send(eventsToSend);
}
}
// Execute the action, which might mutate the state
const returnValue = next(action);
const state: any = getState();
const page = getPageState(state, action.payload.pageId);
switch (action.type) {
case DFP_IMPRESSION_VIEWABLE:
case DFP_SLOT_RENDER_ENDED:
case DFP_SLOT_ON_LOAD:
send([
prepareAdEvent({
page,
id: action.payload.id,
utils: action.utils,
}),
]);
break;
case CLICK:
sendDirect([
prepareClickEvent({
page,
url: action.payload.url,
clickId: action.payload.clickId,
externalId: action.payload.id,
context: action.payload.context,
}),
]);
break;
case VIDEO_LOAD:
send([
prepareVideoLoadForSending({
page,
...action.payload,
}),
]);
break;
case VIDEO_STOP:
send(
prepareVideoWatchForSending({
page,
...action.payload,
}),
);
break;
case PLAYER_HIDDEN:
const videoIds = getUniqueVideoIdsForPlayer(
page.state.video.events,
action.payload.playerId,
);
// "Brodcast" player hidden event to all videos with the playerId
videoIds.forEach(videoId => {
send(
prepareVideoWatchForSending({
page: page,
videoId,
...action.payload,
}),
);
});
break;
case VIDEO_AD:
send([
prepareVideoAdForSending({
page,
...action.payload,
}),
]);
break;
case CUSTOM:
send([
prepareCustomEvent({
page,
customDomain: action.payload.customDomain,
customType: action.payload.customType,
customContent: action.payload.customContent,
customValue: action.payload.customValue,
time: action.payload.time,
}),
]);
break;
case PAGE_LOAD:
send([
preparePageloadEvent({
page,
url: action.payload.url,
utils: action.utils,
}),
]);
break;
case ARTICLE_PREVIEW_SCREEN_EXIT:
send([prepareImpression(page, action.payload.id)]);
break;
case BOX_SCREEN_EXIT:
send([prepareBoxEvent(page, action.payload.id)]);
break;
case AD_SCREEN_EXIT:
case AD_SCREEN_EXIT_0:
send([
prepareAdEvent({
page,
id: action.payload.id,
utils: action.utils,
}),
]);
break;
case ARTICLE_ACTIVITY_STOP:
sendDirect([
prepareActiveTimeEvent({
page,
id: action.payload.id,
utils: action.utils,
}),
]);
break;
case SEND_ALL_EVENTS:
{
const { payload, utils } = action;
const eventsToSend = [
...getAllAdEventsPrepared(page, utils, payload.time),
...getAllActiveTimeEventsPrepared(page, utils, payload.time),
...getAllArticleImpressionEventsPrepared(page, payload.time),
...getAllVideoWatchEventsPrepared(page, payload.time),
...getAllBoxEventsPrepared(page, payload.time),
];
if (eventsToSend.length > 0) {
sendDirect(eventsToSend);
}
}
break;
default:
break;
}
return returnValue;
};
}