Compare commits

...

3 Commits

Author SHA1 Message Date
Eric Bailey 8237b88638 Add other params 2024-01-30 15:35:03 -06:00
Eric Bailey 186f2b155b Add resources 2024-01-29 16:02:02 -06:00
Eric Bailey 5cc8de9e0e Handle URL params 2024-01-29 15:57:07 -06:00
5 changed files with 117 additions and 2 deletions
+3 -2
View File
@@ -105,6 +105,7 @@
"expo-image": "~1.10.3",
"expo-image-manipulator": "^11.8.0",
"expo-image-picker": "~14.7.1",
"expo-linking": "^6.2.2",
"expo-localization": "~14.8.2",
"expo-media-library": "~15.9.1",
"expo-notifications": "~0.27.3",
@@ -161,6 +162,7 @@
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "~3.29.0",
"react-native-svg": "14.1.0",
"react-native-ui-text-view": "link:./modules/react-native-ui-text-view",
"react-native-url-polyfill": "^1.3.0",
"react-native-uuid": "^2.0.1",
"react-native-version-number": "^0.3.6",
@@ -175,8 +177,7 @@
"tlds": "^1.234.0",
"use-deep-compare": "^1.1.0",
"zeego": "^1.6.2",
"zod": "^3.20.2",
"react-native-ui-text-view": "link:./modules/react-native-ui-text-view"
"zod": "^3.20.2"
},
"devDependencies": {
"@atproto/dev-env": "^0.2.28",
+2
View File
@@ -45,6 +45,7 @@ import {Splash} from '#/Splash'
import {Provider as PortalProvider} from '#/components/Portal'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useUTMSetup} from '#/lib/utm'
SplashScreen.preventAutoHideAsync()
@@ -54,6 +55,7 @@ function InnerApp() {
const {resumeSession} = useSessionApi()
const theme = useColorModeTheme(colorMode)
const {_} = useLingui()
useUTMSetup()
// init
useEffect(() => {
+2
View File
@@ -32,12 +32,14 @@ import {
import {Provider as UnreadNotifsProvider} from 'state/queries/notifications/unread'
import * as persisted from '#/state/persisted'
import {Provider as PortalProvider} from '#/components/Portal'
import {useUTMSetup} from '#/lib/utm'
function InnerApp() {
const {isInitialLoad, currentAccount} = useSession()
const {resumeSession} = useSessionApi()
const colorMode = useColorMode()
const theme = useColorModeTheme(colorMode)
useUTMSetup()
// init
useEffect(() => {
+102
View File
@@ -0,0 +1,102 @@
/**
* Resources
*
* Overview: https://developers.google.com/analytics/devguides/collection/protocol/v1/reference#required
* Param reference: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
* UTM reference: https://support.google.com/analytics/answer/10917952
*/
import React from 'react'
import {nanoid} from 'nanoid/non-secure'
import * as Linking from 'expo-linking'
import {logger} from '#/logger'
import {load, save} from '#/lib/storage'
const STORAGE_KEY = 'BSKY_UTM_PARAMS'
let PARAMS: Record<string, any> = {}
async function loadParams() {
PARAMS = (await load(STORAGE_KEY)) || {}
}
async function upsertParams(params: Record<string, any>) {
await loadParams() // make sure we're ready
for (const key in params) {
const value = params[key]
// only overwrite if we have a new value
if (value !== null && value !== undefined) {
PARAMS[key] = value
}
}
await save(STORAGE_KEY, PARAMS)
logger.debug('utm: updated', {params: PARAMS})
}
export function handleIncomingURL(url: string) {
const {searchParams} = new URL(url, 'http://throwaway.com')
const params = Object.fromEntries(
Array.from(searchParams.entries()).filter(
([key]) =>
// TODO handle others?
key.startsWith('utm_') || key === 'gclid' || key === 'dclid',
),
)
upsertParams(params)
}
export function getParams() {
return PARAMS
}
const UTM_TO_MP: {[key: string]: string} = {
utm_id: 'cid',
utm_source: 'cs',
utm_medium: 'cm',
utm_campaign: 'cn',
utm_term: 'ck',
utm_content: 'cc',
// unsure how to map these
// utm_source_platform: '',
// utm_creative_format: '',
// utm_marketing_tactic: '',
}
export function getUTMParamsAsMeasurementProtocol() {
return Object.entries(PARAMS).reduce(
(acc, [key, value]) => {
acc[UTM_TO_MP[key]] = value
return acc
},
{
v: 1,
tid: 'UA-xxx', // TODO
t: 'event',
} as Record<string, any>,
)
}
export function emitEvent() {
const params = getUTMParamsAsMeasurementProtocol()
// TODO events?
const payload = new URLSearchParams(params).toString()
const url = new URL('/collect', 'https://www.google-analytics.com')
url.searchParams.set('payload_data', encodeURIComponent(payload))
// cache-buster param
url.searchParams.set('z', Date.now().toString() + '-' + nanoid())
fetch(url.toString()).catch(() => {})
}
export function useUTMSetup() {
const url = Linking.useURL()
React.useEffect(() => {
if (url) handleIncomingURL(url)
}, [url])
}
+8
View File
@@ -11725,6 +11725,14 @@ expo-keep-awake@~12.8.1:
resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-12.8.1.tgz#3c8df9d86c265741b5e7bdd36965aa0c6fc17df0"
integrity sha512-P/VZFV02Rzgj13skMwH+ceGOGZSEdaUu5n7pCS3wThh2LppZjPJ7sBxUwyzeLa3DXEVUtwLZi+BiQ91wPwy9Gg==
expo-linking@^6.2.2:
version "6.2.2"
resolved "https://registry.yarnpkg.com/expo-linking/-/expo-linking-6.2.2.tgz#b7e148068ae49fd9ad814428c16fdf7a236e8aca"
integrity sha512-FEe6lP4f7xFT/vjoHRG+tt6EPVtkEGaWNK1smpaUevmNdyCJKqW0PDB8o8sfG6y7fly8ULe8qg3HhKh5J7aqUQ==
dependencies:
expo-constants "~15.4.3"
invariant "^2.2.4"
expo-localization@~14.8.2:
version "14.8.2"
resolved "https://registry.yarnpkg.com/expo-localization/-/expo-localization-14.8.2.tgz#e0bbed2293265834d21a1c58d3a5f8d265bd04ae"