import { BaseGather, EventMeta, PageMeta, ScreenMeta, ConfigMeta, UserMeta } from './base' import { warn, loadMixpanel } from '../utils' declare global { interface Window { dataLayer?: Record[] } } export interface MixpanelGatherOptions { token: string } // Vendor Docs: https://developer.mixpanel.com/docs/javascript export class MixpanelGather extends BaseGather { public name = 'mixpanel' public $vendor: any private static VENDOR_NAMESPACE = 'mixpanel' constructor(private options: MixpanelGatherOptions) { super() } public async init(): Promise { await loadMixpanel() window[MixpanelGather.VENDOR_NAMESPACE].init(this.options.token, { batch_requests: true }) this.$vendor = window[MixpanelGather.VENDOR_NAMESPACE] this.tagCalled = true } public setUser(userMeta: UserMeta) { if (!this.$vendor) { return warn(`${MixpanelGather.VENDOR_NAMESPACE} was undefined`) } const { id, ...rest } = userMeta this.$vendor.reset() if (id) { this.$vendor.identify(id) this.$vendor.people.set({ ...rest }) } } public query(type: string, id: string, params: ConfigMeta) { if (!this.$vendor) { return warn(`${MixpanelGather.VENDOR_NAMESPACE} was undefined`) } if (type === 'config') { Object.entries(params).map(([key, value]) => { if (value) { this.$vendor.register({ [key]: value }) } else { this.$vendor.unregister(key) } }) } else { this.$vendor.track(id, params) } return { type, id, params } } public config(configMeta: ConfigMeta) { return this.query('config', this.options.token, configMeta) } public event(eventMeta: EventMeta) { const { action, category, page, ...params } = eventMeta const eventParams = { category: category || page, ...params } return this.query('event', action, eventParams) } public page(pageMeta: PageMeta) { const pageParams = { title: pageMeta.title || document.title, location: pageMeta.href || location.href, path: pageMeta.path || location.pathname } return this.query('event', 'Page View', pageParams) } public screen(screenMeta: ScreenMeta) { const screenParams = { screen: screenMeta.name } return this.query('event', 'Screen View', screenParams) } }