UNPKG

@causalfoundry/js-sdk

Version:

Causal Foundry WEB SDK (JS/TS)

157 lines (133 loc) 5.86 kB
import {CTAType, INudgesRepository, Nudge} from './repositories/nudges/typings' import { EventEmitter } from 'events'; import { NotificationAction, NotificationDispatcher } from '../drivers/notifications/typings' import { DateTime } from 'luxon' import { INudgeManager, NudgeManagerAction } from './CfNudgeManager.typings'; import {ExceptionObject} from "./typings"; import {toISOLocal} from "../utils"; import CfCore from "./CfCore"; import CfExceptionHandler from "./CfExceptionHandler"; import Navigation from "../modules/Navigation/index"; import {NudgeAction} from "../modules/Navigation/typings"; import {NudgeScreenType} from "./commonTypes"; interface IndexedNudge { [key: string]: Nudge } export default class NudgeManager extends EventEmitter implements INudgeManager { private timersId = [] private notificationDispatcher private nudgesRepository private refreshInterval = 5 * 60 * 1000 private isOneTimeOnly = false private nudgeScreenType = NudgeScreenType.None private indexedNudges: IndexedNudge = {} public constructor( userId: string, notificationDispatcher: NotificationDispatcher, nudgesRepository: INudgesRepository, nudgeScreenType = NudgeScreenType.None, isOneTimeOnly = false, refreshInterval = 5 * 60 * 1000 ) { super() this.notificationDispatcher = notificationDispatcher this.nudgesRepository = nudgesRepository this.refreshInterval = refreshInterval this.nudgeScreenType = nudgeScreenType this.isOneTimeOnly = isOneTimeOnly /* - nudges are retrieved periodically, each 5min. - in the future this timeout will be configurable - dispatched_at will be: - current time less 1 hour the first time - time of last shown nudge, if exists, or current time next times */ this.notificationDispatcher.on(NotificationAction.Open, (id) => { this.emit(NudgeManagerAction.Open, this.indexedNudges[id].ref, this.indexedNudges[id].time) if (!this.indexedNudges[id]) { return } const hasActions = () => { return (this.indexedNudges[id].nd.cta !== CTAType.None && this.indexedNudges[id].extra && this.indexedNudges[id].extra.item_pair && this.indexedNudges[id].extra.item_pair.ids.length == 2 && this.indexedNudges[id].nd.message.tmpl_cfg && this.indexedNudges[id].nd.message.tmpl_cfg.item_pair_cfg && this.indexedNudges[id].nd.message.tmpl_cfg.tmpl_type === "item_pair" && this.indexedNudges[id].extra.item_pair.ids.length === 2) } if (!hasActions()) { return } const ctaObject = { type: this.indexedNudges[id].nd.cta.toLowerCase(), cta_resource: { type: this.indexedNudges[id].nd.message.tmpl_cfg.item_pair_cfg.item_type, id: this.indexedNudges[id].extra.item_pair.ids[0] } } this.emit( NudgeManagerAction.Action, ctaObject) }) this.notificationDispatcher.on(NotificationAction.Discard, id => { this.emit(NudgeManagerAction.Discard, this.indexedNudges[id].ref, this.indexedNudges[id].time) }) this.notificationDispatcher.on(NotificationAction.Block, id => { this.emit(NudgeManagerAction.Block, this.indexedNudges[id].ref, this.indexedNudges[id].time) }) this.notificationDispatcher.on(NotificationAction.Shown, id => { this.emit(NudgeManagerAction.Shown, this.indexedNudges[id].ref, this.indexedNudges[id].time) }) const oneHourAgo = new Date() oneHourAgo.setHours(oneHourAgo.getHours() - 1) // get nudge item: this.fetchNudges(userId, this.nudgeScreenType) if(!this.isOneTimeOnly){ setInterval(() => { this.fetchNudges(userId, this.nudgeScreenType) }, this.refreshInterval) } } private async fetchNudges(userId: string, nudgeScreenType : NudgeScreenType) { let nudges; try { nudges = await this.nudgesRepository.getNudges(userId, nudgeScreenType) } catch (e) { console.error('Error fetching nudges: ', e) return } nudges // .filter(({ ref }) => { // const alreadyShown = this.nudgesRepository.haveBeenAlreadyShown(ref) // return !alreadyShown // }) .forEach((nudge, index) => { nudge.internalId = index this.indexedNudges[index] = nudge this.processNudge(nudge) }) } private processNudge(nudge: Nudge) { if(!nudge.expire_at){ nudge.expire_at = "0001-01-01T00:00:00Z" } const expirationNotDefined = nudge.expire_at === "0001-01-01T00:00:00Z" const notExpired = nudge.expire_at > new Date().toISOString() if (nudge.nd.message.tmpl_cfg.tmpl_type !== "item_pair" && nudge.nd.message.tmpl_cfg.tmpl_type !== "traits" && nudge.nd.message.tmpl_cfg.tmpl_type !== "") { new CfExceptionHandler().throwNudgeException("Invalid template type provided", nudge) return } if (notExpired || expirationNotDefined) { this.notificationDispatcher.show(nudge, nudge.internalId) }else{ Navigation.logPushNotificationEvent({ ref: nudge.ref, response: NudgeAction.Expired, time: nudge.time }) } } }