-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.ts
67 lines (61 loc) · 2.77 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { Plugin } from '@posthog/plugin-scaffold'
declare var posthog: {
capture: (eventName: string, properties: Record<string, any>) => void
}
type SessionTrackerPlugin = Plugin<{
config: {
sessionLength: string
sessionStartEvent: string
sessionEndEvent: string
}
global: {
sessionLength: number
sessionStartEvent: string
sessionEndEvent: string
}
jobs: {
checkIfSessionIsOver: { distinct_id: string }
}
}>
export const setupPlugin: SessionTrackerPlugin['setupPlugin'] = ({ global, config }) => {
global.sessionLength = parseInt(config.sessionLength) || 30
global.sessionStartEvent = config.sessionStartEvent || 'Session start'
global.sessionEndEvent = config.sessionEndEvent || 'Session end'
}
export const onEvent: SessionTrackerPlugin['onEvent'] = async (event, { cache, global, jobs }) => {
// skip this for the session start/end events
if (event.event === global.sessionStartEvent || event.event === global.sessionEndEvent) {
return
}
// check if we're the first one to increment this key in the last ${global.sessionLength} minutes
if ((await cache.incr(`session_${event.distinct_id}`)) === 1) {
// if so, dispatch a session start event
posthog.capture(global.sessionStartEvent, { distinct_id: event.distinct_id, timestamp: event.timestamp })
// and launch a job to check in 30min if the session is still alive
await jobs.checkIfSessionIsOver({ distinct_id: event.distinct_id }).runIn(global.sessionLength, 'minutes')
}
// make the key expire in ${global.sessionLength} min
await cache.expire(`session_${event.distinct_id}`, global.sessionLength * 60)
await cache.set(
`last_timestamp_${event.distinct_id}`,
event.timestamp || event.now || event.sent_at || new Date().toISOString()
)
}
export const jobs: SessionTrackerPlugin['jobs'] = {
// a background job to check if a session is still in progress
checkIfSessionIsOver: async ({ distinct_id }, { jobs, cache, global }) => {
// check if there's a key that has not expired
const ping = await cache.get(`session_${distinct_id}`, undefined)
if (!ping) {
// if it expired, dispatch the session end event
const timestamp =
(await cache.get(`last_timestamp_${distinct_id}`, undefined)) ||
new Date(new Date().valueOf() - global.sessionLength * 60000).toISOString()
await cache.set(`last_timestamp_${distinct_id}`, undefined)
posthog.capture(global.sessionEndEvent, { distinct_id, timestamp })
} else {
// if the key is still there, check again in a minute
await jobs.checkIfSessionIsOver({ distinct_id }).runIn(1, 'minute')
}
},
}