Path: blob/main/frontend/plugins/segmentAnalytics.ts
3855 views
1import {2CtaClickedEventSegmentSchema,3PerformedSearchEventSegmentSchema,4UpdatedObjectEventSegmentSchema5} from '../constants/segment'67/**8* Set of configuration objects and flags required by Bluemix Analytics.9* Main configuration objects are `_analytics`, `bluemixAnalytics` and10* `digitalData`.11*12* See13* https://github.ibm.com/Bluemix/Bluemix.Analytics/blob/master/webpack.constants.js14* for default values.15*/16interface AnalyticsContext {17_analytics?: any18_analyticsReady?: Promise<Event>19bluemixAnalytics?: any20digitalData?: any21}2223interface TextbookAnalytics {24textbookAnalytics: {25url: string,26key: string27}28}2930declare global {31interface Window extends AnalyticsContext, TextbookAnalytics {}32}3334function configureAnalytics (analyticsKey: string) {35window._analytics = {36segment_key: analyticsKey,37coremetrics: false,38optimizely: false,39googleAddServices: false,40fullStory: false,41autoPageEventSpa: false,42autoFormEvents: false,43autoPageView: false44}4546window.digitalData = {47page: {48pageInfo: {49productTitle: 'IBM Q Experience',50analytics: {51category: 'Qiskit.org'52}53}54}55}56}5758function installAnalyticsOnce (59analyticsScriptUrl: string = ''60): Promise<Event|void> {61window._analyticsReady = window._analyticsReady || new Promise<Event>((resolve, reject) => {62const script = document.createElement('script')63script.async = true64script.src = analyticsScriptUrl65document.head.appendChild(script)66script.onload = resolve67script.onerror = (err) => {68console.warn('Error loading Bluemix Analytics script:', err)69reject(err)70}71})72return window._analyticsReady73}7475/**76* Send a page visitation event to segment.77* @param title the title meta tag of the page78*/79function trackPage (title: string) {80const { bluemixAnalytics, digitalData } = window8182if (!bluemixAnalytics || !digitalData) { return }8384const category = getOrFailCategory(digitalData)85const productTitle = getOrFailProductTitle(digitalData)86const routeName = 'project-platypus'8788bluemixAnalytics.pageEvent(category, routeName, {89navigationType: 'pushState',90productTitle,91title92})93}9495/**96* Send the information of a CTA click event to Segment.97* @param cta The call to action98* @param location Location in the UI99*/100function trackClickEvent (cta: string, location: string) {101const { bluemixAnalytics, digitalData } = window102103if (!bluemixAnalytics || !digitalData) { return }104105const productTitle = getOrFailProductTitle(digitalData)106const category = getOrFailCategory(digitalData)107108const segmentOptions: CtaClickedEventSegmentSchema = {109category,110CTA: cta,111location,112productTitle113}114115bluemixAnalytics.trackEvent('CTA Clicked', segmentOptions)116}117118/**119* Send the information of a "Performed Search" event to Segment.120* @param context Bluemix Analytics configuration121* @param uiElement The UI element that was used to trigger this event122* @param field Search input123*/124function trackPerformedSearch (uiElement: string, field: string) {125const { bluemixAnalytics, digitalData } = window126127if (!bluemixAnalytics || !digitalData) { return }128129const productTitle = getOrFailProductTitle(digitalData)130const category = getOrFailCategory(digitalData)131132const eventOptions: PerformedSearchEventSegmentSchema = {133category,134productTitle,135uiElement,136field137}138139bluemixAnalytics.trackEvent('Performed Search', eventOptions)140}141142/**143* Send the information of a "Updated Object" event to Segment.144* @param context Bluemix Analytics configuration145* @param objectType Type of object that was updated146* @param object Object that was updated147*/148function trackUpdatedObject (objectType: string, object: string) {149const { bluemixAnalytics, digitalData } = window150151if (!bluemixAnalytics || !digitalData) { return }152153const productTitle = getOrFailProductTitle(digitalData)154const category = getOrFailCategory(digitalData)155156const eventOptions: UpdatedObjectEventSegmentSchema = {157category,158productTitle,159object,160objectType161}162163bluemixAnalytics.trackEvent('Updated Object', eventOptions)164}165166function getOrFailProductTitle (digitalData: any): string {167return assertCanGet(168() => digitalData.page.pageInfo.productTitle,169'`digitalData.page.pageInfo.productTitle` is missing'170)171}172173function getOrFailCategory (digitalData: any): string {174return assertCanGet(175() => digitalData.page.pageInfo.analytics.category,176'`digitalData.page.pageInfo.analytics.category` is missing'177)178}179180function assertCanGet<T> (getter: () => T, error: string): T {181let result182try {183result = getter()184} catch (ex) { }185if (!result) {186throw new Error(error)187}188return result189}190191function initAnalytics (key: string, url: string): Promise<Event|void> {192configureAnalytics(key)193return installAnalyticsOnce(url)194}195196function install (app: any, _options: any = {}) {197initAnalytics(window.textbookAnalytics.key, window.textbookAnalytics.url)198app.config.globalProperties.$trackClickEvent = trackClickEvent199app.config.globalProperties.$trackPage = trackPage200app.config.globalProperties.$trackPerformedSearch = trackPerformedSearch201app.config.globalProperties.$trackUpdatedObject = trackUpdatedObject202}203204export {205initAnalytics,206install,207trackClickEvent,208trackPage,209trackPerformedSearch,210trackUpdatedObject211}212213export type {214AnalyticsContext215}216217218