mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-14 21:10:34 +01:00
add subdivision1/2, cities to query logic
This commit is contained in:
parent
6bacfa5892
commit
55a586fe27
@ -15,7 +15,7 @@ CREATE TABLE event
|
|||||||
screen LowCardinality(String),
|
screen LowCardinality(String),
|
||||||
language LowCardinality(String),
|
language LowCardinality(String),
|
||||||
country LowCardinality(String),
|
country LowCardinality(String),
|
||||||
subdivision LowCardinality(String),
|
subdivision1 LowCardinality(String),
|
||||||
subdivision2 LowCardinality(String),
|
subdivision2 LowCardinality(String),
|
||||||
city String,
|
city String,
|
||||||
--pageview
|
--pageview
|
||||||
|
@ -115,6 +115,9 @@ function getFilterQuery(filters = {}, params = {}) {
|
|||||||
case 'os':
|
case 'os':
|
||||||
case 'browser':
|
case 'browser':
|
||||||
case 'device':
|
case 'device':
|
||||||
|
case 'subdivision1':
|
||||||
|
case 'subdivision2':
|
||||||
|
case 'city':
|
||||||
case 'country':
|
case 'country':
|
||||||
arr.push(`and ${key} = {${key}:String}`);
|
arr.push(`and ${key} = {${key}:String}`);
|
||||||
params[key] = filter;
|
params[key] = filter;
|
||||||
@ -147,11 +150,24 @@ function getFilterQuery(filters = {}, params = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseFilters(filters: any = {}, params: any = {}) {
|
function parseFilters(filters: any = {}, params: any = {}) {
|
||||||
const { domain, url, eventUrl, referrer, os, browser, device, country, eventName, query } =
|
const {
|
||||||
filters;
|
domain,
|
||||||
|
url,
|
||||||
|
eventUrl,
|
||||||
|
referrer,
|
||||||
|
os,
|
||||||
|
browser,
|
||||||
|
device,
|
||||||
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
|
eventName,
|
||||||
|
query,
|
||||||
|
} = filters;
|
||||||
|
|
||||||
const pageviewFilters = { domain, url, referrer, query };
|
const pageviewFilters = { domain, url, referrer, query };
|
||||||
const sessionFilters = { os, browser, device, country };
|
const sessionFilters = { os, browser, device, country, subdivision1, subdivision2, city };
|
||||||
const eventFilters = { url: eventUrl, eventName };
|
const eventFilters = { url: eventUrl, eventName };
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -68,17 +68,17 @@ export async function getLocation(ip) {
|
|||||||
|
|
||||||
const result = lookup.get(ip);
|
const result = lookup.get(ip);
|
||||||
const country = result?.country?.iso_code ?? result?.registered_country?.iso_code;
|
const country = result?.country?.iso_code ?? result?.registered_country?.iso_code;
|
||||||
const subdivision1 = result?.subdivisions[0].iso_code;
|
const subdivision1 = result?.subdivisions[0]?.iso_code;
|
||||||
const subdivision2 = result?.subdivisions[1].iso_code;
|
const subdivision2 = result?.subdivisions[1]?.iso_code;
|
||||||
const city = result?.city?.names?.en;
|
const city = result?.city?.names?.en;
|
||||||
|
|
||||||
return { country, subdivision1, subdivision2, city };
|
return { country, subdivision1, subdivision2, city };
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getClientInfo(req, { screen }) {
|
export async function getClientInfo(req, { screen }) {
|
||||||
const location = await getLocation(ip);
|
|
||||||
const userAgent = req.headers['user-agent'];
|
const userAgent = req.headers['user-agent'];
|
||||||
const ip = getIpAddress(req);
|
const ip = getIpAddress(req);
|
||||||
|
const location = await getLocation(ip);
|
||||||
const country = location.country;
|
const country = location.country;
|
||||||
const subdivision1 = location.subdivision1;
|
const subdivision1 = location.subdivision1;
|
||||||
const subdivision2 = location.subdivision2;
|
const subdivision2 = location.subdivision2;
|
||||||
|
@ -135,6 +135,9 @@ function getFilterQuery(filters = {}, params = []): string {
|
|||||||
case 'os':
|
case 'os':
|
||||||
case 'browser':
|
case 'browser':
|
||||||
case 'device':
|
case 'device':
|
||||||
|
case 'subdivision1':
|
||||||
|
case 'subdivision2':
|
||||||
|
case 'city':
|
||||||
case 'country':
|
case 'country':
|
||||||
arr.push(`and ${key}=$${params.length + 1}`);
|
arr.push(`and ${key}=$${params.length + 1}`);
|
||||||
params.push(decodeURIComponent(filter));
|
params.push(decodeURIComponent(filter));
|
||||||
@ -171,11 +174,24 @@ function parseFilters(
|
|||||||
params = [],
|
params = [],
|
||||||
sessionKey = 'session_id',
|
sessionKey = 'session_id',
|
||||||
) {
|
) {
|
||||||
const { domain, url, eventUrl, referrer, os, browser, device, country, eventName, query } =
|
const {
|
||||||
filters;
|
domain,
|
||||||
|
url,
|
||||||
|
eventUrl,
|
||||||
|
referrer,
|
||||||
|
os,
|
||||||
|
browser,
|
||||||
|
device,
|
||||||
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
|
eventName,
|
||||||
|
query,
|
||||||
|
} = filters;
|
||||||
|
|
||||||
const pageviewFilters = { domain, url, referrer, query };
|
const pageviewFilters = { domain, url, referrer, query };
|
||||||
const sessionFilters = { os, browser, device, country };
|
const sessionFilters = { os, browser, device, country, subdivision1, subdivision2, city };
|
||||||
const eventFilters = { url: eventUrl, eventName };
|
const eventFilters = { url: eventUrl, eventName };
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -184,7 +200,7 @@ function parseFilters(
|
|||||||
eventFilters,
|
eventFilters,
|
||||||
event: { eventName },
|
event: { eventName },
|
||||||
joinSession:
|
joinSession:
|
||||||
os || browser || device || country
|
os || browser || device || country || subdivision1 || subdivision2 || city
|
||||||
? `inner join session on website_event.${sessionKey} = session.${sessionKey}`
|
? `inner join session on website_event.${sessionKey} = session.${sessionKey}`
|
||||||
: '',
|
: '',
|
||||||
filterQuery: getFilterQuery(filters, params),
|
filterQuery: getFilterQuery(filters, params),
|
||||||
|
@ -44,7 +44,8 @@ export async function findSession(req) {
|
|||||||
throw new Error(`Website not found: ${websiteId}`);
|
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);
|
const sessionId = uuid(websiteId, hostname, ip, userAgent);
|
||||||
|
|
||||||
// Clickhouse does not require session lookup
|
// Clickhouse does not require session lookup
|
||||||
@ -59,6 +60,9 @@ export async function findSession(req) {
|
|||||||
screen,
|
screen,
|
||||||
language,
|
language,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +88,9 @@ export async function findSession(req) {
|
|||||||
screen,
|
screen,
|
||||||
language,
|
language,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!e.message.toLowerCase().includes('unique constraint')) {
|
if (!e.message.toLowerCase().includes('unique constraint')) {
|
||||||
|
@ -19,6 +19,9 @@ export interface NextApiRequestCollect extends NextApiRequest {
|
|||||||
screen: string;
|
screen: string;
|
||||||
language: string;
|
language: string;
|
||||||
country: string;
|
country: string;
|
||||||
|
subdivision1: string;
|
||||||
|
subdivision2: string;
|
||||||
|
city: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,9 @@ export interface WebsiteMetricsRequestQuery {
|
|||||||
browser: string;
|
browser: string;
|
||||||
device: string;
|
device: string;
|
||||||
country: string;
|
country: string;
|
||||||
|
subdivision1: string;
|
||||||
|
subdivision2: string;
|
||||||
|
city: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async (
|
export default async (
|
||||||
@ -66,6 +69,9 @@ export default async (
|
|||||||
browser,
|
browser,
|
||||||
device,
|
device,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
@ -86,6 +92,9 @@ export default async (
|
|||||||
browser,
|
browser,
|
||||||
device,
|
device,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -131,6 +140,9 @@ export default async (
|
|||||||
browser: type !== 'browser' ? browser : undefined,
|
browser: type !== 'browser' ? browser : undefined,
|
||||||
device: type !== 'device' ? device : undefined,
|
device: type !== 'device' ? device : undefined,
|
||||||
country: type !== 'country' ? country : undefined,
|
country: type !== 'country' ? country : undefined,
|
||||||
|
subdivision1: type !== 'subdivision1' ? subdivision1 : undefined,
|
||||||
|
subdivision2: type !== 'subdivision2' ? subdivision2 : undefined,
|
||||||
|
city: type !== 'city' ? city : undefined,
|
||||||
eventUrl: type !== 'url' && table === 'event' ? url : undefined,
|
eventUrl: type !== 'url' && table === 'event' ? url : undefined,
|
||||||
query: type === 'query' && table !== 'event' ? true : undefined,
|
query: type === 'query' && table !== 'event' ? true : undefined,
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,9 @@ export interface WebsitePageviewRequestQuery {
|
|||||||
browser?: string;
|
browser?: string;
|
||||||
device?: string;
|
device?: string;
|
||||||
country?: string;
|
country?: string;
|
||||||
|
subdivision1?: string;
|
||||||
|
subdivision2?: string;
|
||||||
|
city?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async (
|
export default async (
|
||||||
@ -42,6 +45,9 @@ export default async (
|
|||||||
browser,
|
browser,
|
||||||
device,
|
device,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
} = req.query;
|
} = req.query;
|
||||||
|
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
@ -70,6 +76,9 @@ export default async (
|
|||||||
browser,
|
browser,
|
||||||
device,
|
device,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
getPageviewStats(websiteId, {
|
getPageviewStats(websiteId, {
|
||||||
@ -84,6 +93,9 @@ export default async (
|
|||||||
browser,
|
browser,
|
||||||
device,
|
device,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
@ -17,6 +17,9 @@ export interface WebsiteStatsRequestQuery {
|
|||||||
browser: string;
|
browser: string;
|
||||||
device: string;
|
device: string;
|
||||||
country: string;
|
country: string;
|
||||||
|
subdivision1: string;
|
||||||
|
subdivision2: string;
|
||||||
|
city: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async (
|
export default async (
|
||||||
@ -26,7 +29,20 @@ export default async (
|
|||||||
await useCors(req, res);
|
await useCors(req, res);
|
||||||
await useAuth(req, res);
|
await useAuth(req, res);
|
||||||
|
|
||||||
const { id: websiteId, startAt, endAt, url, referrer, os, browser, device, country } = req.query;
|
const {
|
||||||
|
id: websiteId,
|
||||||
|
startAt,
|
||||||
|
endAt,
|
||||||
|
url,
|
||||||
|
referrer,
|
||||||
|
os,
|
||||||
|
browser,
|
||||||
|
device,
|
||||||
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
|
} = req.query;
|
||||||
|
|
||||||
if (req.method === 'GET') {
|
if (req.method === 'GET') {
|
||||||
if (!(await canViewWebsite(req.auth, websiteId))) {
|
if (!(await canViewWebsite(req.auth, websiteId))) {
|
||||||
@ -50,6 +66,9 @@ export default async (
|
|||||||
browser,
|
browser,
|
||||||
device,
|
device,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const prevPeriod = await getWebsiteStats(websiteId, {
|
const prevPeriod = await getWebsiteStats(websiteId, {
|
||||||
@ -62,6 +81,9 @@ export default async (
|
|||||||
browser,
|
browser,
|
||||||
device,
|
device,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@ export async function saveEvent(args: {
|
|||||||
screen?: string;
|
screen?: string;
|
||||||
language?: string;
|
language?: string;
|
||||||
country?: string;
|
country?: string;
|
||||||
|
subdivision1?: string;
|
||||||
|
subdivision2?: string;
|
||||||
|
city?: string;
|
||||||
}) {
|
}) {
|
||||||
return runQuery({
|
return runQuery({
|
||||||
[PRISMA]: () => relationalQuery(args),
|
[PRISMA]: () => relationalQuery(args),
|
||||||
@ -36,38 +39,33 @@ async function relationalQuery(data: {
|
|||||||
}) {
|
}) {
|
||||||
const { websiteId, id: sessionId, url, eventName, eventData, referrer } = data;
|
const { websiteId, id: sessionId, url, eventName, eventData, referrer } = data;
|
||||||
|
|
||||||
const params = {
|
|
||||||
id: uuid(),
|
|
||||||
websiteId,
|
|
||||||
sessionId,
|
|
||||||
url: url?.substring(0, URL_LENGTH),
|
|
||||||
referrer: referrer?.substring(0, URL_LENGTH),
|
|
||||||
eventType: EVENT_TYPE.customEvent,
|
|
||||||
eventName: eventName?.substring(0, EVENT_NAME_LENGTH),
|
|
||||||
eventData,
|
|
||||||
};
|
|
||||||
|
|
||||||
return prisma.client.websiteEvent.create({
|
return prisma.client.websiteEvent.create({
|
||||||
data: params,
|
data: {
|
||||||
|
id: uuid(),
|
||||||
|
websiteId,
|
||||||
|
sessionId,
|
||||||
|
url: url?.substring(0, URL_LENGTH),
|
||||||
|
referrer: referrer?.substring(0, URL_LENGTH),
|
||||||
|
eventType: EVENT_TYPE.customEvent,
|
||||||
|
eventName: eventName?.substring(0, EVENT_NAME_LENGTH),
|
||||||
|
eventData,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function clickhouseQuery(data: {
|
async function clickhouseQuery(data) {
|
||||||
id: string;
|
const {
|
||||||
websiteId: string;
|
websiteId,
|
||||||
url: string;
|
id: sessionId,
|
||||||
referrer?: string;
|
url,
|
||||||
eventName?: string;
|
eventName,
|
||||||
eventData?: any;
|
eventData,
|
||||||
hostname?: string;
|
country,
|
||||||
browser?: string;
|
subdivision1,
|
||||||
os?: string;
|
subdivision2,
|
||||||
device?: string;
|
city,
|
||||||
screen?: string;
|
...args
|
||||||
language?: string;
|
} = data;
|
||||||
country?: string;
|
|
||||||
}) {
|
|
||||||
const { websiteId, id: sessionId, url, eventName, eventData, country, ...args } = data;
|
|
||||||
const { getDateFormat, sendMessage } = kafka;
|
const { getDateFormat, sendMessage } = kafka;
|
||||||
const website = await cache.fetchWebsite(websiteId);
|
const website = await cache.fetchWebsite(websiteId);
|
||||||
|
|
||||||
@ -75,13 +73,16 @@ async function clickhouseQuery(data: {
|
|||||||
website_id: websiteId,
|
website_id: websiteId,
|
||||||
session_id: sessionId,
|
session_id: sessionId,
|
||||||
event_id: uuid(),
|
event_id: uuid(),
|
||||||
|
rev_id: website?.revId || 0,
|
||||||
|
country: country ? country : null,
|
||||||
|
subdivision1: subdivision1 ? subdivision1 : null,
|
||||||
|
subdivision2: subdivision2 ? subdivision2 : null,
|
||||||
|
city: city ? city : null,
|
||||||
url: url?.substring(0, URL_LENGTH),
|
url: url?.substring(0, URL_LENGTH),
|
||||||
event_type: EVENT_TYPE.customEvent,
|
event_type: EVENT_TYPE.customEvent,
|
||||||
event_name: eventName?.substring(0, EVENT_NAME_LENGTH),
|
event_name: eventName?.substring(0, EVENT_NAME_LENGTH),
|
||||||
event_data: eventData ? JSON.stringify(eventData) : null,
|
event_data: eventData ? JSON.stringify(eventData) : null,
|
||||||
rev_id: website?.revId || 0,
|
|
||||||
created_at: getDateFormat(new Date()),
|
created_at: getDateFormat(new Date()),
|
||||||
country: country ? country : null,
|
|
||||||
...args,
|
...args,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@ export async function savePageView(args: {
|
|||||||
screen?: string;
|
screen?: string;
|
||||||
language?: string;
|
language?: string;
|
||||||
country?: string;
|
country?: string;
|
||||||
|
subdivision1?: string;
|
||||||
|
subdivision2?: string;
|
||||||
|
city?: string;
|
||||||
}) {
|
}) {
|
||||||
return runQuery({
|
return runQuery({
|
||||||
[PRISMA]: () => relationalQuery(args),
|
[PRISMA]: () => relationalQuery(args),
|
||||||
@ -45,19 +48,32 @@ async function relationalQuery(data: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function clickhouseQuery(data) {
|
async function clickhouseQuery(data) {
|
||||||
const { websiteId, id: sessionId, url, referrer, country, ...args } = data;
|
const {
|
||||||
const website = await cache.fetchWebsite(websiteId);
|
websiteId,
|
||||||
|
id: sessionId,
|
||||||
|
url,
|
||||||
|
referrer,
|
||||||
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
|
...args
|
||||||
|
} = data;
|
||||||
const { getDateFormat, sendMessage } = kafka;
|
const { getDateFormat, sendMessage } = kafka;
|
||||||
|
const website = await cache.fetchWebsite(websiteId);
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
session_id: sessionId,
|
|
||||||
website_id: websiteId,
|
website_id: websiteId,
|
||||||
|
session_id: sessionId,
|
||||||
|
rev_id: website?.revId || 0,
|
||||||
|
country: country ? country : null,
|
||||||
|
subdivision1: subdivision1 ? subdivision1 : null,
|
||||||
|
subdivision2: subdivision2 ? subdivision2 : null,
|
||||||
|
city: city ? city : null,
|
||||||
url: url?.substring(0, URL_LENGTH),
|
url: url?.substring(0, URL_LENGTH),
|
||||||
referrer: referrer?.substring(0, URL_LENGTH),
|
referrer: referrer?.substring(0, URL_LENGTH),
|
||||||
rev_id: website?.revId || 0,
|
|
||||||
created_at: getDateFormat(new Date()),
|
|
||||||
country: country ? country : null,
|
|
||||||
event_type: EVENT_TYPE.pageView,
|
event_type: EVENT_TYPE.pageView,
|
||||||
|
created_at: getDateFormat(new Date()),
|
||||||
...args,
|
...args,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,8 +31,24 @@ async function clickhouseQuery(data: {
|
|||||||
screen?: string;
|
screen?: string;
|
||||||
language?: string;
|
language?: string;
|
||||||
country?: string;
|
country?: string;
|
||||||
|
subdivision1?: string;
|
||||||
|
subdivision2?: string;
|
||||||
|
city?: string;
|
||||||
}) {
|
}) {
|
||||||
const { id, websiteId, hostname, browser, os, device, screen, language, country } = data;
|
const {
|
||||||
|
id,
|
||||||
|
websiteId,
|
||||||
|
hostname,
|
||||||
|
browser,
|
||||||
|
os,
|
||||||
|
device,
|
||||||
|
screen,
|
||||||
|
language,
|
||||||
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
|
} = data;
|
||||||
const { getDateFormat, sendMessage } = kafka;
|
const { getDateFormat, sendMessage } = kafka;
|
||||||
const website = await cache.fetchWebsite(websiteId);
|
const website = await cache.fetchWebsite(websiteId);
|
||||||
|
|
||||||
@ -46,6 +62,9 @@ async function clickhouseQuery(data: {
|
|||||||
screen,
|
screen,
|
||||||
language,
|
language,
|
||||||
country,
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city,
|
||||||
rev_id: website?.revId || 0,
|
rev_id: website?.revId || 0,
|
||||||
created_at: getDateFormat(new Date()),
|
created_at: getDateFormat(new Date()),
|
||||||
};
|
};
|
||||||
|
@ -31,7 +31,10 @@ async function clickhouseQuery({ id: sessionId }: { id: string }) {
|
|||||||
device,
|
device,
|
||||||
screen,
|
screen,
|
||||||
language,
|
language,
|
||||||
country
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city
|
||||||
from event
|
from event
|
||||||
where session_id = {sessionId:UUID}
|
where session_id = {sessionId:UUID}
|
||||||
limit 1`,
|
limit 1`,
|
||||||
|
@ -40,7 +40,10 @@ async function clickhouseQuery(websites: string[], startAt: Date) {
|
|||||||
device,
|
device,
|
||||||
screen,
|
screen,
|
||||||
language,
|
language,
|
||||||
country
|
country,
|
||||||
|
subdivision1,
|
||||||
|
subdivision2,
|
||||||
|
city
|
||||||
from event
|
from event
|
||||||
where ${websites && websites.length > 0 ? `website_id in {websites:Array(UUID)}` : '0 = 0'}
|
where ${websites && websites.length > 0 ? `website_id in {websites:Array(UUID)}` : '0 = 0'}
|
||||||
and created_at >= {startAt:DateTime('UTC')}`,
|
and created_at >= {startAt:DateTime('UTC')}`,
|
||||||
|
@ -12,7 +12,7 @@ let url =
|
|||||||
if (process.env.MAXMIND_LICENSE_KEY) {
|
if (process.env.MAXMIND_LICENSE_KEY) {
|
||||||
url =
|
url =
|
||||||
`https://download.maxmind.com/app/geoip_download` +
|
`https://download.maxmind.com/app/geoip_download` +
|
||||||
`?edition_id=GeoLite2-Country&license_key=${process.env.MAXMIND_LICENSE_KEY}&suffix=tar.gz`;
|
`?edition_id=GeoLite2-City&license_key=${process.env.MAXMIND_LICENSE_KEY}&suffix=tar.gz`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dest = path.resolve(__dirname, '../node_modules/.geo');
|
const dest = path.resolve(__dirname, '../node_modules/.geo');
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const https = require('https');
|
|
||||||
const zlib = require('zlib');
|
|
||||||
const tar = require('tar');
|
|
||||||
const maxmind = require('maxmind');
|
const maxmind = require('maxmind');
|
||||||
|
|
||||||
async function getLocation() {
|
async function getLocation() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user