diff --git a/README.md b/README.md index 01ff3a7..b43ecf8 100755 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Immoscout has implemented advanced bot detection. In order to work around this, Fredy is completely free (and will always remain free). However, it would be a huge help if you’d allow me to collect some analytical data. Before you freak out, let me explain... -If you agree, Fredy will send a ping to my Mixpanel project each time it runs. +If you agree, Fredy will send a ping once every 6 hours to my internal tracking project (Will be open sourced soon). The data includes: names of active adapters/providers, OS, architecture, Node version, and language. The information is entirely anonymous and helps me understand which adapters/providers are most frequently used.

**Thanks**🤘 diff --git a/lib/api/routes/jobRouter.js b/lib/api/routes/jobRouter.js index 077aa48..f906444 100644 --- a/lib/api/routes/jobRouter.js +++ b/lib/api/routes/jobRouter.js @@ -3,7 +3,6 @@ import * as jobStorage from '../../services/storage/jobStorage.js'; import * as userStorage from '../../services/storage/userStorage.js'; import { config } from '../../utils.js'; import { isAdmin } from '../security.js'; -import { trackDemoJobCreated } from '../../services/tracking/Tracker.js'; const service = restana(); const jobRouter = service.newRouter(); function doesJobBelongsToUser(job, req) { @@ -46,11 +45,6 @@ jobRouter.post('/', async (req, res) => { res.send(new Error(error)); console.error(error); } - trackDemoJobCreated({ - name, - provider, - adapter: notificationAdapter, - }); res.send(); }); jobRouter.delete('', async (req, res) => { diff --git a/lib/api/routes/loginRoute.js b/lib/api/routes/loginRoute.js index 0a2626d..061b274 100644 --- a/lib/api/routes/loginRoute.js +++ b/lib/api/routes/loginRoute.js @@ -27,7 +27,7 @@ loginRouter.post('/', async (req, res) => { } if (user.password === hasher.hash(password)) { if (config.demoMode) { - trackDemoAccessed(); + await trackDemoAccessed(); } req.session.currentUser = user.id; diff --git a/lib/services/tracking/Tracker.js b/lib/services/tracking/Tracker.js index 04e6b60..e99ad65 100644 --- a/lib/services/tracking/Tracker.js +++ b/lib/services/tracking/Tracker.js @@ -1,65 +1,77 @@ -import Mixpanel from 'mixpanel'; import { getJobs } from '../storage/jobStorage.js'; import { getUniqueId } from './uniqueId.js'; import { config, inDevMode } from '../../utils.js'; import os from 'os'; import { readFileSync } from 'fs'; import { packageUp } from 'package-up'; +import fetch from 'node-fetch'; -const mixpanelTracker = Mixpanel.init('718670ef1c58c0208256c1e408a3d75e'); -const distinct_id = getUniqueId() || 'N/A'; +const deviceId = getUniqueId() || 'N/A'; const version = await getPackageVersion(); +const FREDY_TRACKING_URL = 'https://fredy.orange-coding.net/tracking'; -export const track = function () { - //only send tracking information if the user allowed to do so. - if (config.analyticsEnabled && !inDevMode()) { - const activeProvider = new Set(); - const activeAdapter = new Set(); +let cached = null; +let lastSent = 0; +const SIX_HOURS = 6 * 3_600_000; - const jobs = getJobs(); +export const track = async () => { + try { + if (config.analyticsEnabled && !inDevMode()) { + const activeProvider = new Set(); + const activeAdapter = new Set(); - if (jobs != null && jobs.length > 0) { - jobs.forEach((job) => { - job.provider.forEach((provider) => { - activeProvider.add(provider.id); + const jobs = getJobs(); + + if (jobs != null && jobs.length > 0) { + jobs.forEach((job) => { + job.provider.forEach((provider) => activeProvider.add(provider.id)); + job.notificationAdapter.forEach((adapter) => activeAdapter.add(adapter.id)); }); - job.notificationAdapter.forEach((adapter) => { - activeAdapter.add(adapter.id); - }); - }); - mixpanelTracker.track( - 'fredy_tracking', - enrichTrackingObject({ + const trackingObj = enrichTrackingObject({ adapter: Array.from(activeAdapter), provider: Array.from(activeProvider), - }), - ); + }); + + const stringify = JSON.stringify(trackingObj); + const now = Date.now(); + + // send if changed OR six hours passed since last send + if (stringify !== cached || now - lastSent >= SIX_HOURS) { + await fetch(`${FREDY_TRACKING_URL}/main`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: stringify, + }); + cached = stringify; + lastSent = now; + } + } } + } catch (error) { + console.warn('Error sending tracking data', error); } }; /** * Note, this will only be used when Fredy runs in demo mode */ -export function trackDemoJobCreated(jobData) { +export async function trackDemoAccessed() { if (config.analyticsEnabled && !inDevMode() && config.demoMode) { - mixpanelTracker.track('demoJobCreated', enrichTrackingObject(jobData)); - } -} - -/** - * Note, this will only be used when Fredy runs in demo mode - */ -export function trackDemoAccessed() { - if (config.analyticsEnabled && !inDevMode() && config.demoMode) { - mixpanelTracker.track('demoAccessed', enrichTrackingObject({})); + try { + await fetch(`${FREDY_TRACKING_URL}/demo/accessed`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + }); + } catch (error) { + console.warn('Error sending tracking data', error); + } } } function enrichTrackingObject(trackingObject) { - const operating_system = os.platform(); - const os_version = os.release(); + const operatingSystem = os.platform(); + const osVersion = os.release(); const arch = process.arch; const language = process.env.LANG || 'en'; const nodeVersion = process.version || 'N/A'; @@ -67,13 +79,13 @@ function enrichTrackingObject(trackingObject) { return { ...trackingObject, isDemo: config.demoMode, - operating_system, - os_version, + operatingSystem, + osVersion, arch, nodeVersion, language, - distinct_id, - fredy_version: version, + deviceId, + version, }; } diff --git a/package.json b/package.json index a711d70..ff92ef8 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fredy", - "version": "11.6.0", + "version": "11.6.1", "description": "[F]ind [R]eal [E]states [d]amn eas[y].", "scripts": { "prepare": "husky", @@ -70,7 +70,6 @@ "lodash": "4.17.21", "lowdb": "7.0.1", "markdown": "^0.5.0", - "mixpanel": "^0.18.1", "nanoid": "5.1.5", "node-fetch": "3.3.2", "node-mailjet": "6.0.9", diff --git a/ui/src/components/tracking/TrackingModal.jsx b/ui/src/components/tracking/TrackingModal.jsx index 80383b5..7ec8460 100644 --- a/ui/src/components/tracking/TrackingModal.jsx +++ b/ui/src/components/tracking/TrackingModal.jsx @@ -43,7 +43,8 @@ export default function TrackingModal() {

However, it would be a huge help if you’d allow me to collect some analytical data. Wait, before you click - "no", let me explain. If you agree, Fredy will send a ping to my Mixpanel project each time it runs. + "no", let me explain. If you agree, Fredy will send a ping once every 6 hours to my internal tracking project. + (Will be open-sourced soon)

The data includes: names of active adapters/providers, OS, architecture, Node version, and language. The diff --git a/yarn.lock b/yarn.lock index 33a8f1c..58da8d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1979,13 +1979,6 @@ acorn@^8.0.0, acorn@^8.15.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - agent-base@^7.1.0, agent-base@^7.1.2: version "7.1.4" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" @@ -4056,14 +4049,6 @@ http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1: agent-base "^7.1.0" debug "^4.3.4" -https-proxy-agent@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - https-proxy-agent@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" @@ -5450,13 +5435,6 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mixpanel@^0.18.1: - version "0.18.1" - resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.18.1.tgz#beefdce6c260165f4e2059c8cdd34c5c557162f7" - integrity sha512-YD1xfn6WP6ZLQ6Pmgh0KgdXhueJEsrodThMTsHzHMH0VbWa9ck8s+ynDtM83OSgt+yQ61W/SQNrH8Y4wIwocGg== - dependencies: - https-proxy-agent "5.0.0" - mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"