Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TAS-2590] 📈 Add GRE pixel #1953

Merged
merged 2 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/deploy-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ jobs:
GA_TRACKING_ID: ${{ vars.GA_TRACKING_ID }}
AD_CONVERSION_ID: ${{ vars.AD_CONVERSION_ID }}
FACEBOOK_PIXEL_ID: ${{ vars.FACEBOOK_PIXEL_ID }}
GRE_API_KEY: ${{ vars.GRE_API_KEY }}
GRE_PROJECT_ID: ${{ vars.GRE_PROJECT_ID }}
STRIPE_PUBLIC_KEY: ${{ vars.STRIPE_PUBLIC_KEY }}
CRISP_WEBSITE_ID: ${{ vars.CRISP_WEBSITE_ID }}
SENTRY_DSN: ${{ vars.SENTRY_DSN }}
Expand Down
6 changes: 6 additions & 0 deletions src/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const {
STRIPE_PUBLIC_KEY,
GA_TRACKING_ID,
AD_CONVERSION_ID,
GRE_API_KEY,
GRE_PROJECT_ID,
EXTERNAL_URL,
FACEBOOK_PIXEL_ID,
} = process.env;
Expand All @@ -25,6 +27,8 @@ const nuxtConfig = {
GA_TRACKING_ID,
AD_CONVERSION_ID,
FACEBOOK_PIXEL_ID,
GRE_API_KEY,
GRE_PROJECT_ID,
SITE_NAME,
EXTERNAL_URL,
},
Expand Down Expand Up @@ -234,6 +238,7 @@ const nuxtConfig = {
"'wasm-unsafe-eval'",
'*.google-analytics.com',
'www.googletagmanager.com',
'www.gstatic.com',
'www.google.com',
'googleads.g.doubleclick.net',
'www.googleadservices.com',
Expand Down Expand Up @@ -312,6 +317,7 @@ const nuxtConfig = {
'~/plugins/axios.js',
'~/plugins/likecoin-ui-vue.js',
'~/plugins/portal-vue.js',
{ src: '~/plugins/gre.client.js', mode: 'client' },
{ src: '~/plugins/gtag.client.js', mode: 'client' },
{ src: '~/plugins/ui-plugin.client.js', ssr: false },
{ src: '~/plugins/vue-cookie.client.js', ssr: false },
Expand Down
3 changes: 2 additions & 1 deletion src/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@
{{ faq.question }}
</template>
<template #answer>
<div v-html="faq.answer" />

Check warning on line 701 in src/pages/index.vue

View workflow job for this annotation

GitHub Actions / CI

'v-html' directive can lead to XSS attack
</template>
</IndexPageFAQItem>
</li>
Expand Down Expand Up @@ -756,7 +756,7 @@

import bookstoreMixin from '~/mixins/bookstore';

import { logTrackerEvent } from '~/util/EventLogger';
import { logTrackerEvent, logRetailEvent } from '~/util/EventLogger';
import { fisherShuffle } from '~/util/misc';

const SIGNATURE_BANNER_NAMES = [
Expand Down Expand Up @@ -944,6 +944,7 @@
},
},
mounted() {
logRetailEvent(this, 'home-page-view');
window.addEventListener('scroll', this.handleScroll);
},
beforeDestroy() {
Expand Down
74 changes: 74 additions & 0 deletions src/plugins/gre.client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* eslint-disable no-underscore-dangle */

class GoogleRetailPixel {
userId;
visitorId;
apiKey;
projectId;

constructor(apiKey, projectId) {
this.apiKey = apiKey;
this.projectId = projectId;
window._gre = window._gre || [];
window._gre.push(['apiKey', apiKey]);
window._gre.push(['projectId', projectId]);
window._gre.push(['locationId', 'global']);
window._gre.push(['catalogId', 'default_catalog']);
}

setUserId(userId) {
this.userId = userId;
}

setVisitorId(visitorId) {
this.visitorId = visitorId;
}

logEvent(eventType, payload = {}, { attributionToken, experimentIds } = {}) {
if (!this.visitorId) {
return;
}
const event = {
eventType,
attributionToken,
experimentIds,
visitorId: this.visitorId,
userInfo: this.userId
? {
userId: this.userId,
}
: undefined,
...payload,
};
// HACK: cloud_retail does not replace _gre on init
// cloud_retail only calls logEvent once on _gre and
// it does not even clear _gre after that
if (window.cloud_retail) {
window.cloud_retail.logEvent([
['apiKey', this.apiKey],
['projectId', this.projectId],
['locationId', 'global'],
['catalogId', 'default_catalog'],
['logEvent', event],
]);
} else {
window._gre.push(['logEvent', event]);
}
}
}

export default (ctx, inject) => {
if (process.env.GRE_API_KEY && process.env.GRE_PROJECT_ID) {
const gre = new GoogleRetailPixel(
process.env.GRE_API_KEY,
process.env.GRE_PROJECT_ID
);
const d = document;
const s = d.createElement('script');
s.src = 'https://www.gstatic.com/retail/v2_event.js';
s.async = 1;
d.getElementsByTagName('head')[0].appendChild(s);

inject('gre', gre);
}
};
3 changes: 3 additions & 0 deletions src/store/modules/actions/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export function setUserCivicLiker({ commit }, { civicLikerVersion = 1 } = {}) {

export function setGaClientId({ commit }, gaClientId) {
commit(types.USER_SET_GA_CLIENT_ID, gaClientId);
if (this.$gre) {
this.$gre.setVisitorId(gaClientId);
}
}

export function setGaSessionId({ commit }, gaSessionId) {
Expand Down
62 changes: 48 additions & 14 deletions src/util/EventLogger.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export function resetLoggerUser(vue) {
if (vue.$sentry) {
vue.$sentry.setUser({});
}
if (vue.$gre) {
vue.$gre.setUserId(null);
}
if (vue.$gtag) {
vue.$gtag.set({ userId: null });
vue.$gtag.set({ user_id: null });
Expand All @@ -54,27 +57,29 @@ export async function setLoggerUser(
vue.$sentry.setUser(opt);
}
try {
let hashedId = await digestMessage(wallet);
hashedId = hexString(hashedId);
if (vue.$gre) {
vue.$gre.setUserId(hashedId);
}
if (vue.$gtag) {
if (event === 'signup') {
vue.$gtag.event('sign_up', { method });
} else if (event === 'login') {
vue.$gtag.event('login', { method });
}
}
if (!hasDoNotTrack()) {
if (vue.$gtag) {
const hashedId = await getHashedUserId(wallet);
vue.$gtag.set({ userId: hashedId });
// HACK: use .set to mitigate connected site user_id issue
// https://support.google.com/analytics/answer/9973999?hl=en
// vue.$gtag.config({ user_id: hashedId });
vue.$gtag.set({ user_id: hashedId });
}
if (vue.$fb && FACEBOOK_PIXEL_ID) {
vue.$fb.init(FACEBOOK_PIXEL_ID, {
external_id: wallet,
});
}
if (vue.$gtag) {
vue.$gtag.set({ userId: hashedId });
// HACK: use .set to mitigate connected site user_id issue
// https://support.google.com/analytics/answer/9973999?hl=en
// vue.$gtag.config({ user_id: hashedId });
vue.$gtag.set({ user_id: hashedId });
}
if (vue.$fb && FACEBOOK_PIXEL_ID) {
vue.$fb.init(FACEBOOK_PIXEL_ID, {
external_id: wallet,
});
}
if (vue.$crisp) {
vue.$crisp.push(['set', 'session:data', [[['like_wallet', wallet]]]]);
Expand Down Expand Up @@ -154,6 +159,35 @@ export function logTrackerEvent(
}
}

export function logRetailEvent(vue, eventType, payload) {
try {
if (vue.$gre) {
if (!vue.$gre.visitorId) {
// HACK: query in gtag if no visitor Id
// multiple concurrent queries might occur
// if logRetailEvent is called multiple times
// but all should yield same result anyway
if (vue.$gtag && process.env.GA_TRACKING_ID) {
vue.$gtag.query(
'get',
process.env.GA_TRACKING_ID,
'client_id',
id => {
vue.$gre.setVisitorId(id);
vue.$gre.logEvent(eventType, payload);
}
);
}
} else {
vue.$gre.logEvent(eventType, payload);
}
}
} catch (err) {
console.error('logging error:'); // eslint-disable-line no-console
console.error(err); // eslint-disable-line no-console
}
}

export function logPurchaseFlowEvent(
vue,
event,
Expand Down
Loading