@causalfoundry/js-sdk
Version:
Causal Foundry WEB SDK (JS/TS)
162 lines (146 loc) • 5.46 kB
text/typescript
import {INudgesRepository, Nudge, NudgeAction} from './repositories/nudges/typings'
import {EventEmitter} from 'events';
import {NotificationAction, NotificationDispatcher} from '../drivers/notifications/typings'
import {INudgeManager, NudgeManagerAction} from './CfNudgeManager.typings';
import Navigation from "../modules/Navigation/index";
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, (nudge: Nudge) => {
if (!nudge) {
return
}
Navigation.logPushNotificationEvent({
response: NudgeAction.Open,
details: "",
internal: nudge.internal
})
const hasActions = () => {
return (!!nudge.attr?.cta_id)
}
if (!hasActions()) {
return
}
const ctaObject = {
type: nudge.attr?.cta_type.toLowerCase(),
cta_resource: {
type: "drug",
id: nudge.attr?.cta_id
}
}
this.emit(
NudgeManagerAction.Action,
ctaObject)
})
this.notificationDispatcher.on(NotificationAction.Discard, (nudge: Nudge) => {
if (!nudge) {
return
}
Navigation.logPushNotificationEvent({
response: NudgeAction.Discard,
details: "",
internal: nudge.internal
})
})
this.notificationDispatcher.on(NotificationAction.Block, (nudge: Nudge) => {
if (!nudge) {
return
}
Navigation.logPushNotificationEvent({
response: NudgeAction.Block,
details: "",
internal: nudge.internal
})
})
this.notificationDispatcher.on(NotificationAction.Shown, (nudge: Nudge) => {
if (!nudge) {
return
}
Navigation.logPushNotificationEvent({
response: NudgeAction.Shown,
details: "",
internal: nudge.internal
})
})
// 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) => {
if (nudge.payload.error) {
Navigation.logPushNotificationEvent({
response: NudgeAction.Error,
details: nudge.payload.error,
internal: nudge.internal
});
return;
} else {
this.indexedNudges[index] = nudge.payload
this.processNudge(nudge.payload)
}
})
}
private processNudge(nudge: Nudge) {
if (!nudge.internal.expired_at) {
nudge.internal.expired_at = "0001-01-01T00:00:00Z"
}
const expirationNotDefined = nudge.internal.expired_at === "0001-01-01T00:00:00Z"
const notExpired = nudge.internal.expired_at > new Date().toISOString()
if (notExpired || expirationNotDefined) {
this.notificationDispatcher.show(nudge)
} else {
Navigation.logPushNotificationEvent({
response: NudgeAction.Expired,
details: "",
internal: nudge.internal
})
}
}
}