Merge branch 'dev' into feat/um-185-event-data-redirect

This commit is contained in:
Brian Cao 2023-03-01 16:40:06 -08:00
commit 53a6a8924d
23 changed files with 3791 additions and 98 deletions

View file

@ -74,9 +74,13 @@ function getFilterQuery(filters = {}, params = {}) {
switch (key) {
case 'url':
case 'pageTitle':
case 'os':
case 'browser':
case 'device':
case 'subdivision1':
case 'subdivision2':
case 'city':
case 'country':
arr.push(`and ${key} = {${key}:String}`);
params[key] = filter;
@ -109,11 +113,25 @@ function getFilterQuery(filters = {}, params = {}) {
}
function parseFilters(filters: any = {}, params: any = {}) {
const { domain, url, eventUrl, referrer, os, browser, device, country, eventName, query } =
filters;
const {
domain,
url,
eventUrl,
referrer,
pageTitle,
os,
browser,
device,
country,
subdivision1,
subdivision2,
city,
eventName,
query,
} = filters;
const pageviewFilters = { domain, url, referrer, query };
const sessionFilters = { os, browser, device, country };
const pageviewFilters = { domain, url, referrer, query, pageTitle };
const sessionFilters = { os, browser, device, country, subdivision1, subdivision2, city };
const eventFilters = { url: eventUrl, eventName };
return {

View file

@ -27,7 +27,7 @@ export function getIpAddress(req) {
return requestIp.getClientIp(req);
}
export function getDevice(screen, browser, os) {
export function getDevice(screen, os) {
if (!screen) return;
const [width] = screen.split('x');
@ -55,12 +55,7 @@ export function getDevice(screen, browser, os) {
}
}
export async function getCountry(req, ip) {
// Cloudflare
if (req.headers['cf-ipcountry']) {
return req.headers['cf-ipcountry'];
}
export async function getLocation(ip) {
// Ignore local ips
if (await isLocalhost(ip)) {
return;
@ -68,23 +63,31 @@ export async function getCountry(req, ip) {
// Database lookup
if (!lookup) {
lookup = await maxmind.open(path.resolve('node_modules/.geo/GeoLite2-Country.mmdb'));
lookup = await maxmind.open(path.resolve('node_modules/.geo/GeoLite2-City.mmdb'));
}
const result = lookup.get(ip);
const country = result?.country?.iso_code ?? result?.registered_country?.iso_code;
const subdivision1 = result?.subdivisions[0]?.iso_code;
const subdivision2 = result?.subdivisions[1]?.names?.en;
const city = result?.city?.names?.en;
return result?.country?.iso_code;
return { country, subdivision1, subdivision2, city };
}
export async function getClientInfo(req, { screen }) {
const userAgent = req.headers['user-agent'];
const ip = getIpAddress(req);
const country = await getCountry(req, ip);
const location = await getLocation(ip);
const country = location.country;
const subdivision1 = location.subdivision1;
const subdivision2 = location.subdivision2;
const city = location.city;
const browser = browserName(userAgent);
const os = detectOS(userAgent);
const device = getDevice(screen, browser, os);
return { userAgent, browser, os, ip, country, device };
return { userAgent, browser, os, ip, country, subdivision1, subdivision2, city, device };
}
export function getJsonBody(req) {

View file

@ -75,8 +75,12 @@ function getFilterQuery(filters = {}, params = []): string {
switch (key) {
case 'url':
case 'os':
case 'pageTitle':
case 'browser':
case 'device':
case 'subdivision1':
case 'subdivision2':
case 'city':
case 'country':
arr.push(`and ${key}=$${params.length + 1}`);
params.push(decodeURIComponent(filter));
@ -113,11 +117,25 @@ function parseFilters(
params = [],
sessionKey = 'session_id',
) {
const { domain, url, eventUrl, referrer, os, browser, device, country, eventName, query } =
filters;
const {
domain,
url,
eventUrl,
referrer,
pageTitle,
os,
browser,
device,
country,
subdivision1,
subdivision2,
city,
eventName,
query,
} = filters;
const pageviewFilters = { domain, url, referrer, query };
const sessionFilters = { os, browser, device, country };
const pageviewFilters = { domain, url, referrer, query, pageTitle };
const sessionFilters = { os, browser, device, country, subdivision1, subdivision2, city };
const eventFilters = { url: eventUrl, eventName };
return {
@ -126,7 +144,7 @@ function parseFilters(
eventFilters,
event: { eventName },
joinSession:
os || browser || device || country
os || browser || device || country || subdivision1 || subdivision2 || city
? `inner join session on website_event.${sessionKey} = session.${sessionKey}`
: '',
filterQuery: getFilterQuery(filters, params),

View file

@ -44,7 +44,8 @@ export async function findSession(req) {
throw new Error(`Website not found: ${websiteId}`);
}
const { userAgent, browser, os, ip, country, device } = await getClientInfo(req, payload);
const { userAgent, browser, os, ip, country, subdivision1, subdivision2, city, device } =
await getClientInfo(req, payload);
const sessionId = uuid(websiteId, hostname, ip, userAgent);
// Clickhouse does not require session lookup
@ -59,6 +60,9 @@ export async function findSession(req) {
screen,
language,
country,
subdivision1,
subdivision2,
city,
};
}
@ -84,6 +88,9 @@ export async function findSession(req) {
screen,
language,
country,
subdivision1,
subdivision2,
city,
});
} catch (e) {
if (!e.message.toLowerCase().includes('unique constraint')) {