feat: Add segments events (#1001)

Add segments events to track popular and trending recommendations stats.

VAN-1569

Co-authored-by: Syed Sajjad Hussain Shah <52817156+syedsajjadkazmii@users.noreply.github.com>
This commit is contained in:
Mubbshar Anwar
2023-07-27 17:04:08 +05:00
committed by GitHub
parent 5542311c95
commit a392395876
7 changed files with 54 additions and 39 deletions

View File

@@ -124,11 +124,11 @@ const ProgressiveProfiling = (props) => {
trackRecommendationsGroup(variation, authenticatedUser.userId);
setShowRecommendationsPage(showRecommendations);
if (!showRecommendations) {
trackRecommendationsViewed([], true, authenticatedUser.userId);
trackRecommendationsViewed([], '', true, authenticatedUser.userId);
}
}
}
}, [authenticatedUser, enablePopularAndTrendingRecommendations, registrationResult, queryParams]);
}, [authenticatedUser, enablePopularAndTrendingRecommendations, registrationResult, queryParams?.next]);
if (
!(location.state?.registrationResult || registrationEmbedded)

View File

@@ -231,8 +231,8 @@ describe('ProgressiveProfilingTests', () => {
it('should fire segments recommendations viewed and variation group events', async () => {
const viewedEventProperties = {
page: 'authn_recommendations',
course_key_array: [],
amplitude_recommendations: false,
products: [],
recommendation_type: '',
is_control: true,
user_id: 3,
};

View File

@@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
import { truncateText } from '../../data/utils';
const BaseCard = ({
url,
customHeaderImage,
schoolLogo,
title,
@@ -20,7 +19,6 @@ const BaseCard = ({
}) => (
<div className="mr-4 recommendation-card" key={`container-${uuid}`}>
<Hyperlink
destination={url}
target="_blank"
className="card-box"
showLaunchIcon={false}
@@ -29,7 +27,6 @@ const BaseCard = ({
<Card
className={`base-card ${variant}`}
variant={variant}
onClick={handleOnClick}
isLoading={isLoading}
>
<Card.ImageCap
@@ -67,7 +64,6 @@ BaseCard.propTypes = {
productTypeCopy: PropTypes.string.isRequired,
subtitle: PropTypes.string.isRequired,
variant: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
customHeaderImage: PropTypes.string.isRequired,
schoolLogo: PropTypes.string.isRequired,
isLoading: PropTypes.bool,

View File

@@ -9,8 +9,7 @@ import { createCodeFriendlyProduct, getVariant, useProductType } from '../data/u
import {
cardBadgesMessages,
} from '../messages';
import { trackRecommendationCardClickOptimizely } from '../optimizelyExperiment';
import { trackRecommendationsClicked } from '../track';
import { trackRecommendationClick } from '../track';
const ProductCard = ({
product,
@@ -64,20 +63,16 @@ const ProductCard = ({
],
);
const handleCardClick = () => {
trackRecommendationCardClickOptimizely(userId?.toString());
trackRecommendationsClicked(
product.courseKey,
false,
trackRecommendationClick(
product,
position + 1,
false,
userId,
product.marketingUrl,
product.recommendationType || 'algolia',
);
};
return (
<BaseCard
url={product.url}
customHeaderImage={headerImage}
schoolLogo={isMultipleOwner ? '' : schoolLogo}
title={product.title}

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
@@ -8,8 +8,10 @@ import {
import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet';
import { POPULAR, TRENDING } from './data/constants';
import messages from './messages';
import RecommendationsList from './RecommendationsList';
import { trackRecommendationsViewed } from './track';
import { DEFAULT_REDIRECT_URL } from '../data/constants';
const RecommendationsPage = ({ location }) => {
@@ -22,6 +24,10 @@ const RecommendationsPage = ({ location }) => {
const POPULAR_PRODUCTS = JSON.parse(getConfig().POPULAR_PRODUCTS);
const TRENDING_PRODUCTS = JSON.parse(getConfig().TRENDING_PRODUCTS);
useEffect(() => {
trackRecommendationsViewed(POPULAR_PRODUCTS, POPULAR, false, userId);
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const handleRedirection = () => {
window.history.replaceState(location.state, null, '');
if (registrationResponse) {
@@ -45,6 +51,11 @@ const RecommendationsPage = ({ location }) => {
handleRedirection();
}
const handleOnSelect = (tabKey) => {
const recommendations = tabKey === POPULAR ? POPULAR_PRODUCTS : TRENDING_PRODUCTS;
trackRecommendationsViewed(recommendations, tabKey, false, userId);
};
return (
<>
<Helmet>
@@ -66,16 +77,17 @@ const RecommendationsPage = ({ location }) => {
</h2>
<Tabs
variant="tabs"
defaultActiveKey="popular"
defaultActiveKey={POPULAR}
id="recommendations-selection"
onSelect={handleOnSelect}
>
<Tab tabClassName="mb-3" eventKey="popular" title={formatMessage(messages['recommendation.option.popular'])}>
<Tab tabClassName="mb-3" eventKey={POPULAR} title={formatMessage(messages['recommendation.option.popular'])}>
<RecommendationsList
recommendations={POPULAR_PRODUCTS}
userId={userId}
/>
</Tab>
<Tab tabClassName="mb-3" eventKey="trending" title={formatMessage(messages['recommendation.option.trending'])}>
<Tab tabClassName="mb-3" eventKey={TRENDING} title={formatMessage(messages['recommendation.option.trending'])}>
<RecommendationsList
recommendations={TRENDING_PRODUCTS}
userId={userId}

View File

@@ -9,3 +9,6 @@ export const EDUCATION_LEVEL_MAPPING = {
hs: 'Introductory',
jhs: 'Introductory',
};
export const POPULAR = 'popular';
export const TRENDING = 'trending';

View File

@@ -3,7 +3,7 @@ import { sendTrackEvent } from '@edx/frontend-platform/analytics';
export const LINK_TIMEOUT = 300;
export const eventNames = {
recommendedCourseClicked: 'edx.bi.user.recommended.course.click',
recommendedProductClicked: 'edx.bi.user.recommended.product.clicked',
recommendationsGroup: 'edx.bi.user.recommendations.group',
recommendationsViewed: 'edx.bi.user.recommendations.viewed',
};
@@ -17,27 +17,36 @@ export const createLinkTracker = (tracker, href, openInNewTab = false) => (e) =>
return setTimeout(() => { global.location.href = href; }, LINK_TIMEOUT);
};
export const trackRecommendationsClicked = (courseKey, isControl, position, userId, href, recommendationType) => {
createLinkTracker(
sendTrackEvent(eventNames.recommendedCourseClicked, {
page: 'authn_recommendations',
position,
recommendation_type: recommendationType,
course_key: courseKey,
is_control: isControl,
user_id: userId,
}),
href,
true,
);
const generateProductKey = (product) => {
const productKey = product.cardType === 'program' ? `${product.title} [${product.uuid}]` : product.activeRunKey;
return productKey;
};
export const trackRecommendationsViewed = (recommendedCourseKeys, isControl, userId) => {
export const trackRecommendationClick = (product, position, isControl, userId) => {
sendTrackEvent(eventNames.recommendedProductClicked, {
page: 'authn_recommendations',
position,
recommendation_type: product.recommendationType,
product_key: generateProductKey(product),
product_line: product.cardType,
product_source: product.productSource.name,
is_control: isControl,
user_id: userId,
});
return setTimeout(() => { global.open(product.url, '_blank'); }, LINK_TIMEOUT);
};
export const trackRecommendationsViewed = (recommendedProducts, type, isControl, userId) => {
const viewedProductsList = recommendedProducts.map((product) => ({
product_key: generateProductKey(product),
product_line: product.cardType,
product_source: product.productSource.name,
}));
sendTrackEvent(
eventNames.recommendationsViewed, {
page: 'authn_recommendations',
course_key_array: recommendedCourseKeys,
amplitude_recommendations: false,
recommendation_type: type,
products: viewedProductsList,
is_control: isControl,
user_id: userId,
},
@@ -55,7 +64,7 @@ export const trackRecommendationsGroup = (variation, userId) => {
};
export default {
trackRecommendationsClicked,
trackRecommendationClick,
trackRecommendationsGroup,
trackRecommendationsViewed,
};