Skip to content

Commit

Permalink
Merge pull request #4164 from mozilla/MNTOR-2908
Browse files Browse the repository at this point in the history
MNTOR-2899: rework the UTM for guided experience and settings
  • Loading branch information
mansaj committed Feb 7, 2024
2 parents bc0612c + 34eec0b commit 6e72b75
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
getSubscriptionBillingAmount,
getPremiumSubscriptionUrl,
} from "../../../../../../../../../functions/server/getPremiumSubscriptionInfo";
import { getAttributionsFromCookiesOrDb } from "../../../../../../../../../functions/server/attributions";

const monthlySubscriptionUrl = getPremiumSubscriptionUrl({ type: "monthly" });
const yearlySubscriptionUrl = getPremiumSubscriptionUrl({ type: "yearly" });
Expand All @@ -32,6 +33,10 @@ export default async function AutomaticRemovePage() {
redirect("/user/dashboard/");
}

const additionalSubplatParams = await getAttributionsFromCookiesOrDb(
session.user.subscriber.id,
);

const profileId = await getOnerepProfileId(session.user.subscriber.id);
const scanData = await getLatestOnerepScanResults(profileId);
const subBreaches = await getSubscriberBreaches(session.user);
Expand All @@ -50,8 +55,8 @@ export default async function AutomaticRemovePage() {
subscriberEmails={subscriberEmails}
nextStep={getNextGuidedStep(data, "Scan")}
currentSection="data-broker-profiles"
monthlySubscriptionUrl={monthlySubscriptionUrl}
yearlySubscriptionUrl={yearlySubscriptionUrl}
monthlySubscriptionUrl={`${monthlySubscriptionUrl}&${additionalSubplatParams.toString()}`}
yearlySubscriptionUrl={`${yearlySubscriptionUrl}&${additionalSubplatParams.toString()}`}
subscriptionBillingAmount={getSubscriptionBillingAmount()}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* 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 { headers, cookies } from "next/headers";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { getServerSession } from "next-auth";
import { View } from "./View";
Expand Down Expand Up @@ -32,10 +32,7 @@ import {
import { refreshStoredScanResults } from "../../../../../../functions/server/refreshStoredScanResults";
import { getEnabledFeatureFlags } from "../../../../../../../db/tables/featureFlags";
import { parseIso8601Datetime } from "../../../../../../../utils/parse";
import {
addAttributionForSubscriber,
getLatestAttributionForSubscriberWithType,
} from "../../../../../../../db/tables/attributions";
import { getAttributionsFromCookiesOrDb } from "../../../../../../functions/server/attributions";
import { getUserId } from "../../../../../../functions/server/getUserId";

export default async function DashboardPage() {
Expand All @@ -45,7 +42,6 @@ export default async function DashboardPage() {
}

const headersList = headers();
const cookiesList = cookies();
const countryCode = getCountryCode(headersList);

const profileId = await getOnerepProfileId(session.user.subscriber.id);
Expand Down Expand Up @@ -117,50 +113,10 @@ export default async function DashboardPage() {
const yearlySubscriptionUrl = getPremiumSubscriptionUrl({ type: "yearly" });
const fxaSettingsUrl = process.env.FXA_SETTINGS_URL!;
const profileStats = await getProfilesStats();
let additionalSubplatParams = new URLSearchParams(
cookiesList.get("attributionsLastTouch")?.value,
const additionalSubplatParams = await getAttributionsFromCookiesOrDb(
session.user.subscriber.id,
);

// store utm attributions if present in cookies
if (cookiesList.get("attributionsFirstTouch")?.value) {
const searchParams = new URLSearchParams(
cookiesList.get("attributionsFirstTouch")?.value,
);
const attribution = {
type: "firstTouch",
entrypoint: searchParams.get("entrypoint") ?? "",
utm_campaign: searchParams.get("utm_campaign") ?? "",
utm_medium: searchParams.get("utm_medium") ?? "",
utm_source: searchParams.get("utm_source") ?? "",
utm_term: searchParams.get("utm_term") ?? "",
};
await addAttributionForSubscriber(session.user.subscriber.id, attribution);
}

if (additionalSubplatParams.size > 0) {
const attribution = {
type: "lastTouch",
entrypoint: additionalSubplatParams.get("entrypoint") ?? "",
utm_campaign: additionalSubplatParams.get("utm_campaign") ?? "",
utm_medium: additionalSubplatParams.get("utm_medium") ?? "",
utm_source: additionalSubplatParams.get("utm_source") ?? "",
utm_term: additionalSubplatParams.get("utm_term") ?? "",
};
await addAttributionForSubscriber(session.user.subscriber.id, attribution);
} else {
// if "attributionsLastTouch" cookie isn't present, try to load the attribution from the db
const attributionLastTouch =
await getLatestAttributionForSubscriberWithType(
session.user.subscriber.id,
"lastTouch",
);
if (attributionLastTouch) {
additionalSubplatParams = new URLSearchParams(
attributionLastTouch as Record<string, string>,
);
}
}

return (
<View
user={session.user}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { getUserEmails } from "../../../../../../../db/tables/emailAddresses";
import { getBreaches } from "../../../../../../functions/server/getBreaches";
import { getBreachesForEmail } from "../../../../../../../utils/hibp";
import { getSha1 } from "../../../../../../../utils/fxa";
import { getAttributionsFromCookiesOrDb } from "../../../../../../functions/server/attributions";

export default async function SettingsPage() {
const session = await getServerSession(authOptions);
Expand All @@ -28,7 +29,9 @@ export default async function SettingsPage() {
const yearlySubscriptionUrl = getPremiumSubscriptionUrl({ type: "yearly" });
const fxaSettingsUrl = process.env.FXA_SETTINGS_URL!;
const fxaSubscriptionsUrl = process.env.FXA_SUBSCRIPTIONS_URL!;

const additionalSubplatParams = await getAttributionsFromCookiesOrDb(
session.user.subscriber.id,
);
const allBreaches = await getBreaches();
const breachCountByEmailAddress: Record<string, number> = {};
const emailAddressStrings = emailAddresses.map(
Expand All @@ -52,8 +55,8 @@ export default async function SettingsPage() {
breachCountByEmailAddress={breachCountByEmailAddress}
fxaSettingsUrl={fxaSettingsUrl}
fxaSubscriptionsUrl={fxaSubscriptionsUrl}
monthlySubscriptionUrl={monthlySubscriptionUrl}
yearlySubscriptionUrl={yearlySubscriptionUrl}
monthlySubscriptionUrl={`${monthlySubscriptionUrl}&${additionalSubplatParams.toString()}`}
yearlySubscriptionUrl={`${yearlySubscriptionUrl}&${additionalSubplatParams.toString()}`}
subscriptionBillingAmount={getSubscriptionBillingAmount()}
/>
);
Expand Down
57 changes: 57 additions & 0 deletions src/app/functions/server/attributions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* 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 { cookies } from "next/headers";
import {
addAttributionForSubscriber,
getLatestAttributionForSubscriberWithType,
} from "../../../db/tables/attributions";

export async function getAttributionsFromCookiesOrDb(subscriberId: number) {
const cookiesList = cookies();
let additionalSubplatParams = new URLSearchParams(
cookiesList.get("attributionsLastTouch")?.value,
);

// store utm attributions if present in cookies
if (cookiesList.get("attributionsFirstTouch")?.value) {
const searchParams = new URLSearchParams(
cookiesList.get("attributionsFirstTouch")?.value,
);
const attribution = {
type: "firstTouch",
entrypoint: searchParams.get("entrypoint") ?? "",
utm_campaign: searchParams.get("utm_campaign") ?? "",
utm_medium: searchParams.get("utm_medium") ?? "",
utm_source: searchParams.get("utm_source") ?? "",
utm_term: searchParams.get("utm_term") ?? "",
};
await addAttributionForSubscriber(subscriberId, attribution);
}

if (additionalSubplatParams.size > 0) {
const attribution = {
type: "lastTouch",
entrypoint: additionalSubplatParams.get("entrypoint") ?? "",
utm_campaign: additionalSubplatParams.get("utm_campaign") ?? "",
utm_medium: additionalSubplatParams.get("utm_medium") ?? "",
utm_source: additionalSubplatParams.get("utm_source") ?? "",
utm_term: additionalSubplatParams.get("utm_term") ?? "",
};
await addAttributionForSubscriber(subscriberId, attribution);
} else {
// if "attributionsLastTouch" cookie isn't present, try to load the attribution from the db
const attributionLastTouch =
await getLatestAttributionForSubscriberWithType(
subscriberId,
"lastTouch",
);
if (attributionLastTouch) {
additionalSubplatParams = new URLSearchParams(
attributionLastTouch as Record<string, string>,
);
}
}
return additionalSubplatParams;
}
5 changes: 4 additions & 1 deletion src/db/tables/attributions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ async function addAttributionForSubscriber(
res = await knex("attributions").insert(attribution).returning("*");
} catch (e) {
if ((e as Error).message.includes("violates unique constraint")) {
logger.info("Ignoring unique constraints");
logger.info("addAttributionForSubscriber", {
subscriberId,
error: (e as Error).message,
});
} else {
logger.error(e);
}
Expand Down

0 comments on commit 6e72b75

Please sign in to comment.