Bug 1619694 - Send Impression telemetry for respective multistage welcome screen r=Mardak
authorPunam Dahiya <punamdahiya@yahoo.com>
Sat, 23 May 2020 20:11:34 +0000
changeset 2913080 37589d46631054e814a39fe6e1762ba151fc1521
parent 2913079 232da017dc6a5887047fd235600ee0175ad43f92
child 2913081 8912e3abc78133dbf7ffba380f3c80306780275a
push id542231
push userbclary@mozilla.com
push dateSun, 24 May 2020 06:08:15 +0000
treeherdertry@5bd349510b42 [default view] [failures only]
reviewersMardak
bugs1619694
milestone78.0a1
Bug 1619694 - Send Impression telemetry for respective multistage welcome screen r=Mardak Differential Revision: https://phabricator.services.mozilla.com/D76552
browser/components/newtab/aboutwelcome/content/aboutwelcome.bundle.js
browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx
browser/components/newtab/content-src/aboutwelcome/components/MultiStageAboutWelcome.jsx
browser/components/newtab/content-src/lib/aboutwelcome-utils.js
--- a/browser/components/newtab/aboutwelcome/content/aboutwelcome.bundle.js
+++ b/browser/components/newtab/aboutwelcome/content/aboutwelcome.bundle.js
@@ -121,111 +121,127 @@ function _extends() { _extends = Object.
 class AboutWelcome extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.state = {
       metricsFlowUri: null
     };
     this.fetchFxAFlowUri = this.fetchFxAFlowUri.bind(this);
     this.handleStartBtnClick = this.handleStartBtnClick.bind(this);
-    this.messageId = "ABOUT_WELCOME";
   }
 
   async fetchFxAFlowUri() {
     this.setState({
       metricsFlowUri: await window.AWGetFxAMetricsFlowURI()
     });
   }
 
   componentDidMount() {
-    if (this.props.experiment && this.props.branchId) {
-      this.messageId = `ABOUT_WELCOME_${this.props.experiment}_${this.props.branchId}`.toUpperCase();
-    } else if (this.props.id && this.props.screens) {
-      this.messageId = this.props.id;
-    }
-
     this.fetchFxAFlowUri();
     window.AWSendEventTelemetry({
       event: "IMPRESSION",
-      message_id: this.messageId
+      message_id: this.props.messageId
     }); // Captures user has seen about:welcome by setting
     // firstrun.didSeeAboutWelcome pref to true and capturing welcome UI unique messageId
 
-    window.AWSendToParent("SET_WELCOME_MESSAGE_SEEN", this.messageId);
+    window.AWSendToParent("SET_WELCOME_MESSAGE_SEEN", this.props.messageId);
   }
 
   handleStartBtnClick() {
     _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_6__["AboutWelcomeUtils"].handleUserAction(this.props.startButton.action);
     const ping = {
       event: "CLICK_BUTTON",
       event_context: {
         source: this.props.startButton.message_id,
         page: "about:welcome"
       },
-      message_id: this.messageId,
+      message_id: this.props.messageId,
       id: "ABOUT_WELCOME"
     };
     window.AWSendEventTelemetry(ping);
   }
 
   render() {
     const {
       props
     } = this; // TBD: Refactor to redirect based off template value
     // inside props.template
     // Create SimpleAboutWelcome that renders default about welcome
     // See Bug 1638087
 
     if (props.screens) {
       return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_MultiStageAboutWelcome__WEBPACK_IMPORTED_MODULE_2__["MultiStageAboutWelcome"], {
         screens: props.screens,
-        metricsFlowUri: this.state.metricsFlowUri
+        metricsFlowUri: this.state.metricsFlowUri,
+        message_id: props.messageId
       });
     }
 
-    let UTMTerm = this.props.experiment && this.props.branchId ? `${this.props.experiment}-${this.props.branchId}` : "default";
     return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
       className: "outer-wrapper welcomeContainer"
     }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
       className: "welcomeContainerInner"
     }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("main", null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_HeroText__WEBPACK_IMPORTED_MODULE_3__["HeroText"], {
       title: props.title,
       subtitle: props.subtitle
     }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_FxCards__WEBPACK_IMPORTED_MODULE_4__["FxCards"], {
       cards: props.cards,
       metricsFlowUri: this.state.metricsFlowUri,
       sendTelemetry: window.AWSendEventTelemetry,
-      utm_term: UTMTerm
+      utm_term: props.UTMTerm
     }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_components_MSLocalized__WEBPACK_IMPORTED_MODULE_5__["Localized"], {
       text: props.startButton.label
     }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", {
       className: "start-button",
       onClick: this.handleStartBtnClick
     })))));
   }
 
 }
 
 AboutWelcome.defaultProps = _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_6__["DEFAULT_WELCOME_CONTENT"];
 
+function ComputeMessageId(experimentId, branchId, settings) {
+  let messageId = "ABOUT_WELCOME";
+  let UTMTerm = "default";
+
+  if (settings.id && settings.screens) {
+    messageId = settings.id.toUpperCase();
+  }
+
+  if (experimentId && branchId) {
+    messageId += `_${experimentId}_${branchId}`.toUpperCase();
+    UTMTerm = `${experimentId}-${branchId}`.toLowerCase();
+  }
+
+  return {
+    messageId,
+    UTMTerm
+  };
+}
+
 async function mount() {
   const {
     slug,
     branch
   } = await window.AWGetStartupData();
   let settings = branch && branch.value ? branch.value : {};
 
   if (!(branch && branch.value)) {
     // Check for override content in pref browser.aboutwelcome.overrideContent
     settings = await window.AWGetMultiStageScreens();
   }
 
+  let {
+    messageId,
+    UTMTerm
+  } = ComputeMessageId(slug, branch && branch.slug, settings);
   react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(AboutWelcome, _extends({
-    experiment: slug,
-    branchId: branch && branch.slug
+    messageId: messageId,
+    UTMTerm: UTMTerm
   }, settings)), document.getElementById("root"));
 }
 
 mount();
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports) {
@@ -252,17 +268,25 @@ module.exports = ReactDOM;
 /* harmony import */ var _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 
 
 const MultiStageAboutWelcome = props => {
-  const [index, setScreenIndex] = Object(react__WEBPACK_IMPORTED_MODULE_0__["useState"])(0); // Transition to next screen, opening about:home on last screen button CTA
+  const [index, setScreenIndex] = Object(react__WEBPACK_IMPORTED_MODULE_0__["useState"])(0);
+  Object(react__WEBPACK_IMPORTED_MODULE_0__["useEffect"])(() => {
+    // Send impression ping when respective screen first renders
+    props.screens.forEach(screen => {
+      if (index === screen.order) {
+        _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].sendImpressionTelemetry(`${props.message_id}_${screen.id}`);
+      }
+    });
+  }, [index]); // Transition to next screen, opening about:home on last screen button CTA
 
   const handleTransition = index < props.screens.length ? Object(react__WEBPACK_IMPORTED_MODULE_0__["useCallback"])(() => setScreenIndex(prevState => prevState + 1), []) : _lib_aboutwelcome_utils__WEBPACK_IMPORTED_MODULE_2__["AboutWelcomeUtils"].handleUserAction({
     type: "OPEN_ABOUT_PAGE",
     data: {
       args: "home",
       where: "current"
     }
   });
@@ -437,16 +461,23 @@ const Localized = ({
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 const AboutWelcomeUtils = {
   handleUserAction(action) {
     window.AWSendToParent("SPECIAL_ACTION", action);
   },
 
+  sendImpressionTelemetry(messageId) {
+    window.AWSendEventTelemetry({
+      event: "IMPRESSION",
+      message_id: messageId
+    });
+  },
+
   sendEvent(type, detail) {
     document.dispatchEvent(new CustomEvent(`AWPage:${type}`, {
       bubbles: true,
       detail
     }));
   }
 
 };
--- a/browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx
+++ b/browser/components/newtab/content-src/aboutwelcome/aboutwelcome.jsx
@@ -15,110 +15,121 @@ import {
 } from "../lib/aboutwelcome-utils";
 
 class AboutWelcome extends React.PureComponent {
   constructor(props) {
     super(props);
     this.state = { metricsFlowUri: null };
     this.fetchFxAFlowUri = this.fetchFxAFlowUri.bind(this);
     this.handleStartBtnClick = this.handleStartBtnClick.bind(this);
-    this.messageId = "ABOUT_WELCOME";
   }
 
   async fetchFxAFlowUri() {
     this.setState({ metricsFlowUri: await window.AWGetFxAMetricsFlowURI() });
   }
 
   componentDidMount() {
-    if (this.props.experiment && this.props.branchId) {
-      this.messageId = `ABOUT_WELCOME_${this.props.experiment}_${this.props.branchId}`.toUpperCase();
-    } else if (this.props.id && this.props.screens) {
-      this.messageId = this.props.id;
-    }
     this.fetchFxAFlowUri();
     window.AWSendEventTelemetry({
       event: "IMPRESSION",
-      message_id: this.messageId,
+      message_id: this.props.messageId,
     });
     // Captures user has seen about:welcome by setting
     // firstrun.didSeeAboutWelcome pref to true and capturing welcome UI unique messageId
-    window.AWSendToParent("SET_WELCOME_MESSAGE_SEEN", this.messageId);
+    window.AWSendToParent("SET_WELCOME_MESSAGE_SEEN", this.props.messageId);
   }
 
   handleStartBtnClick() {
     AboutWelcomeUtils.handleUserAction(this.props.startButton.action);
     const ping = {
       event: "CLICK_BUTTON",
       event_context: {
         source: this.props.startButton.message_id,
         page: "about:welcome",
       },
-      message_id: this.messageId,
+      message_id: this.props.messageId,
       id: "ABOUT_WELCOME",
     };
     window.AWSendEventTelemetry(ping);
   }
 
   render() {
     const { props } = this;
     // TBD: Refactor to redirect based off template value
     // inside props.template
     // Create SimpleAboutWelcome that renders default about welcome
     // See Bug 1638087
     if (props.screens) {
       return (
         <MultiStageAboutWelcome
           screens={props.screens}
           metricsFlowUri={this.state.metricsFlowUri}
+          message_id={props.messageId}
         />
       );
     }
 
-    let UTMTerm =
-      this.props.experiment && this.props.branchId
-        ? `${this.props.experiment}-${this.props.branchId}`
-        : "default";
     return (
       <div className="outer-wrapper welcomeContainer">
         <div className="welcomeContainerInner">
           <main>
             <HeroText title={props.title} subtitle={props.subtitle} />
             <FxCards
               cards={props.cards}
               metricsFlowUri={this.state.metricsFlowUri}
               sendTelemetry={window.AWSendEventTelemetry}
-              utm_term={UTMTerm}
+              utm_term={props.UTMTerm}
             />
             <Localized text={props.startButton.label}>
               <button
                 className="start-button"
                 onClick={this.handleStartBtnClick}
               />
             </Localized>
           </main>
         </div>
       </div>
     );
   }
 }
 
 AboutWelcome.defaultProps = DEFAULT_WELCOME_CONTENT;
 
+function ComputeMessageId(experimentId, branchId, settings) {
+  let messageId = "ABOUT_WELCOME";
+  let UTMTerm = "default";
+
+  if (settings.id && settings.screens) {
+    messageId = settings.id.toUpperCase();
+  }
+
+  if (experimentId && branchId) {
+    messageId += `_${experimentId}_${branchId}`.toUpperCase();
+    UTMTerm = `${experimentId}-${branchId}`.toLowerCase();
+  }
+  return {
+    messageId,
+    UTMTerm,
+  };
+}
+
 async function mount() {
   const { slug, branch } = await window.AWGetStartupData();
   let settings = branch && branch.value ? branch.value : {};
 
   if (!(branch && branch.value)) {
     // Check for override content in pref browser.aboutwelcome.overrideContent
     settings = await window.AWGetMultiStageScreens();
   }
 
+  let { messageId, UTMTerm } = ComputeMessageId(
+    slug,
+    branch && branch.slug,
+    settings
+  );
+
   ReactDOM.render(
-    <AboutWelcome
-      experiment={slug}
-      branchId={branch && branch.slug}
-      {...settings}
-    />,
+    <AboutWelcome messageId={messageId} UTMTerm={UTMTerm} {...settings} />,
     document.getElementById("root")
   );
 }
 
 mount();
--- a/browser/components/newtab/content-src/aboutwelcome/components/MultiStageAboutWelcome.jsx
+++ b/browser/components/newtab/content-src/aboutwelcome/components/MultiStageAboutWelcome.jsx
@@ -1,18 +1,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-import React, { useState, useCallback } from "react";
+import React, { useState, useCallback, useEffect } from "react";
 import { Localized } from "./MSLocalized";
 import { AboutWelcomeUtils } from "../../lib/aboutwelcome-utils";
 
 export const MultiStageAboutWelcome = props => {
   const [index, setScreenIndex] = useState(0);
+
+  useEffect(() => {
+    // Send impression ping when respective screen first renders
+    props.screens.forEach(screen => {
+      if (index === screen.order) {
+        AboutWelcomeUtils.sendImpressionTelemetry(
+          `${props.message_id}_${screen.id}`
+        );
+      }
+    });
+  }, [index]);
   // Transition to next screen, opening about:home on last screen button CTA
   const handleTransition =
     index < props.screens.length
       ? useCallback(() => setScreenIndex(prevState => prevState + 1), [])
       : AboutWelcomeUtils.handleUserAction({
           type: "OPEN_ABOUT_PAGE",
           data: { args: "home", where: "current" },
         });
--- a/browser/components/newtab/content-src/lib/aboutwelcome-utils.js
+++ b/browser/components/newtab/content-src/lib/aboutwelcome-utils.js
@@ -1,16 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 export const AboutWelcomeUtils = {
   handleUserAction(action) {
     window.AWSendToParent("SPECIAL_ACTION", action);
   },
+  sendImpressionTelemetry(messageId) {
+    window.AWSendEventTelemetry({
+      event: "IMPRESSION",
+      message_id: messageId,
+    });
+  },
   sendEvent(type, detail) {
     document.dispatchEvent(
       new CustomEvent(`AWPage:${type}`, {
         bubbles: true,
         detail,
       })
     );
   },