diff options
-rw-r--r-- | src/logger/metrics.ts | 2 | ||||
-rw-r--r-- | src/state/geolocation.tsx | 54 |
2 files changed, 50 insertions, 6 deletions
diff --git a/src/logger/metrics.ts b/src/logger/metrics.ts index 4a09d8593..e51905f84 100644 --- a/src/logger/metrics.ts +++ b/src/logger/metrics.ts @@ -480,4 +480,6 @@ export type MetricEvents = { * Specifically for the `BlockedGeoOverlay` */ 'blockedGeoOverlay:shown': {} + + 'geo:debug': {} } diff --git a/src/state/geolocation.tsx b/src/state/geolocation.tsx index a69161324..6229c6f2c 100644 --- a/src/state/geolocation.tsx +++ b/src/state/geolocation.tsx @@ -5,6 +5,9 @@ import {networkRetry} from '#/lib/async/retry' import {logger} from '#/logger' import {type Device, device} from '#/storage' +const IPCC_URL = `https://bsky.app/ipcc` +const BAPP_CONFIG_URL = `https://bapp-config.bsky.workers.dev/config` + const events = new EventEmitter() const EVENT = 'geolocation-updated' const emitGeolocationUpdate = (geolocation: Device['geolocation']) => { @@ -29,8 +32,18 @@ export const DEFAULT_GEOLOCATION: Device['geolocation'] = { isAgeRestrictedGeo: false, } -async function getGeolocation(): Promise<Device['geolocation']> { - const res = await fetch(`https://bsky.app/ipcc`) +function sanitizeGeolocation( + geolocation: Device['geolocation'], +): Device['geolocation'] { + return { + countryCode: geolocation?.countryCode ?? undefined, + isAgeBlockedGeo: geolocation?.isAgeBlockedGeo ?? false, + isAgeRestrictedGeo: geolocation?.isAgeRestrictedGeo ?? false, + } +} + +async function getGeolocation(url: string): Promise<Device['geolocation']> { + const res = await fetch(url) if (!res.ok) { throw new Error(`geolocation: lookup failed ${res.status}`) @@ -43,12 +56,39 @@ async function getGeolocation(): Promise<Device['geolocation']> { countryCode: json.countryCode, isAgeBlockedGeo: json.isAgeBlockedGeo ?? false, isAgeRestrictedGeo: json.isAgeRestrictedGeo ?? false, + // @ts-ignore + regionCode: json.regionCode ?? undefined, } } else { return undefined } } +async function compareWithIPCC(bapp: Device['geolocation']) { + try { + const ipcc = await getGeolocation(IPCC_URL) + + if (!ipcc || !bapp) return + + logger.metric( + 'geo:debug', + { + bappCountryCode: bapp.countryCode, + // @ts-ignore + bappRegionCode: bapp.regionCode, + bappIsAgeBlockedGeo: bapp.isAgeBlockedGeo, + bappIsAgeRestrictedGeo: bapp.isAgeRestrictedGeo, + ipccCountryCode: ipcc.countryCode, + ipccIsAgeBlockedGeo: ipcc.isAgeBlockedGeo, + ipccIsAgeRestrictedGeo: ipcc.isAgeRestrictedGeo, + }, + { + statsig: false, + }, + ) + } catch {} +} + /** * Local promise used within this file only. */ @@ -81,11 +121,12 @@ export function beginResolveGeolocation() { try { // Try once, fail fast - const geolocation = await getGeolocation() + const geolocation = await getGeolocation(BAPP_CONFIG_URL) if (geolocation) { - device.set(['geolocation'], geolocation) + device.set(['geolocation'], sanitizeGeolocation(geolocation)) emitGeolocationUpdate(geolocation) logger.debug(`geolocation: success`, {geolocation}) + compareWithIPCC(geolocation) } else { // endpoint should throw on all failures, this is insurance throw new Error(`geolocation: nothing returned from initial request`) @@ -101,13 +142,14 @@ export function beginResolveGeolocation() { device.set(['geolocation'], DEFAULT_GEOLOCATION) // retry 3 times, but don't await, proceed with default - networkRetry(3, getGeolocation) + networkRetry(3, () => getGeolocation(BAPP_CONFIG_URL)) .then(geolocation => { if (geolocation) { - device.set(['geolocation'], geolocation) + device.set(['geolocation'], sanitizeGeolocation(geolocation)) emitGeolocationUpdate(geolocation) logger.debug(`geolocation: success`, {geolocation}) success = true + compareWithIPCC(geolocation) } else { // endpoint should throw on all failures, this is insurance throw new Error(`geolocation: nothing returned from retries`) |