Skip to content

Commit

Permalink
Fix: Analytics are not send
Browse files Browse the repository at this point in the history
  • Loading branch information
nkokla committed Nov 2, 2023
1 parent 78771fa commit 95ad874
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 58 deletions.
69 changes: 46 additions & 23 deletions lib/api/legacy-routes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const {
ADMIN_TOKEN = '',
API_IDFIX_URL = 'https://plateforme.adresse.data.gouv.fr/api-idfix',
API_IDFIX_TOKEN = '',
BAN_API_URL = '',
} = process.env

const prepareMethode = {
Expand All @@ -56,10 +57,25 @@ const getLegacyTypeFromId = id => {
}
}

let sendToTracker = () => console.warn('Legacy-routes: sendToTracker not yet implemented')
import('../util/analytics-tracker.js').then(s => {
sendToTracker = s.sendToTracker
})
const sendToTracker = async ({url: paramUrl, download: paramDownload, ...params} = {}, ...args) => {
const module = await import('../util/analytics-tracker.js')
if (!module.sendToTracker) {
console.warn('Legacy-routes: sendToTracker not found')
return
}

const url = paramUrl && `${BAN_API_URL}${paramUrl}`
const download = paramDownload && `${BAN_API_URL}${paramDownload}`

return module.sendToTracker(
{
...(url ? {url} : {}),
...(download ? {download} : {}),
...params
},
...args)
}

const trackEventDefault = {
category: 'API Legacy',
value: 1,
Expand Down Expand Up @@ -133,12 +149,13 @@ const analyticsMiddleware = {
next?.()
},
downloadCommuneData(req, res, next) {
const {url} = req
const {url, commune = {}} = req
const {codeCommune, downloadFormat, downloadType} = req.params
const nomCommune = commune?.nomCommune
const trackEvent = {
category: 'Download Commune DATA API (From Legacy)',
action: `Download ${downloadType} (Format ${downloadFormat})`,
name: codeCommune,
category: 'Download',
action: `Download Commune ${downloadType} (Format ${downloadFormat})`,
name: `${codeCommune}${nomCommune ? ` - ${nomCommune}` : ''}`,
value: 1,
}
sendToTracker({url, download: url, trackEvent})
Expand Down Expand Up @@ -186,6 +203,7 @@ app.param(
})
)

// API Download Commune Data
app.get(
'/ban/communes/:codeCommune/download/:downloadFormat/:downloadType',
analyticsMiddleware.downloadCommuneData,
Expand Down Expand Up @@ -213,6 +231,7 @@ app.get(
})
)

// API-Legacy
app.post(
'/ban/communes/:codeCommune/compose',
ensureIsAdmin,
Expand Down Expand Up @@ -367,6 +386,7 @@ app.get(
})
)

// BAN Stats
app.get(
'/ban/stats',
w(async (req, res) => {
Expand All @@ -375,23 +395,26 @@ app.get(
})
)

app.post('/ban/stats', w(async (req, res) => {
const {codesCommune} = req.body
if (!codesCommune || codesCommune.length === 0) {
return res
.status(404)
.send({code: 404, message: 'Paramètre codesCommune manquant ou invalide'})
}
app.post(
'/ban/stats',
w(async (req, res) => {
const {codesCommune} = req.body
if (!codesCommune || codesCommune.length === 0) {
return res
.status(404)
.send({code: 404, message: 'Paramètre codesCommune manquant ou invalide'})
}

try {
const stats = await computeFilteredStats(codesCommune)
res.send(stats)
} catch (error) {
console.error(error)
res.status(500).send({code: 500, message: 'Une erreur est survenu lors du calcul des statistiques'})
}
}))
try {
const stats = await computeFilteredStats(codesCommune)
res.send(stats)
} catch (error) {
console.error(error)
res.status(500).send({code: 500, message: 'Une erreur est survenu lors du calcul des statistiques'})
}
}))

// BAN Carto Tiles
app.get(
'/tiles/ban/:z/:x/:y.pbf',
w(async (req, res) => {
Expand Down
85 changes: 50 additions & 35 deletions lib/util/analytics-tracker.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,66 @@
/* eslint-disable camelcase */

import os from 'node:os'
import MatomoTracker from 'matomo-tracker'

const {MATOMO_URL, MATOMO_SITE_ID, NODE_ENV} = process.env

let MATOMO_ERROR = false
// CF. Tracking HTTP API documentation :
// https://developer.matomo.org/api-reference/tracking-api

let matomo
import os from 'node:os'
import fetch from '../util/fetch.cjs'

const isDevMode = () => NODE_ENV !== 'production'
const {
MATOMO_URL,
MATOMO_SITE_ID,
MATOMO_TOKEN_AUTH,
NODE_ENV
} = process.env
const isDevMode = NODE_ENV !== 'production'
const matomoUrl = `${MATOMO_URL}/matomo.php`

const logMatomoError = err => {
MATOMO_ERROR = true
console.warn('[WARNING] tracking request:', err)
console.log('error tracking request:', err)
}

const matomoUrl = `${MATOMO_URL}/matomo.php`
const encodeParams = params => Object.fromEntries(
Object
.entries(params || {})
.map(([key, value]) => [key, typeof value === 'string' ? encodeURIComponent(value) : value]),
)

try {
const matomo = new MatomoTracker(MATOMO_SITE_ID, matomoUrl)
matomo.on('error', logMatomoError)
} catch (error) {
logMatomoError(error)
}
export const getTrackEvent = ({category, action, name, value = 1}) => ({
e_c: encodeURIComponent(`${isDevMode ? 'DEVMODE - ' : ''}${category}`), // Category name
e_a: encodeURIComponent(action), // Action name
e_n: encodeURIComponent(name), // Name
e_v: value, // Value
})

export const getTrackEvent = ({category, action, name, value}) => {
const DEVMODE = isDevMode()
export const sendToTracker = async (params = {}) => {
const {url, ua, download, trackEvent, ...otherParams} = params
const safeOtherParams = encodeParams(otherParams)
const requiredParams = {
idsite: MATOMO_SITE_ID,
rec: 1,
ua: ua || encodeURIComponent(`${os.hostname()} / Node.JS ${process.version} / ${os.version()}`),
...(MATOMO_TOKEN_AUTH ? {token_auth: MATOMO_TOKEN_AUTH} : {}),
}
const urlSearchParams = new URLSearchParams({
...requiredParams,
...safeOtherParams,
...(url ? {url: encodeURIComponent(url)} : {}),
...(download ? {download: encodeURIComponent(download)} : {}),
...(trackEvent ? getTrackEvent(trackEvent) : {}),
})

// CF. Tracking HTTP API documentation :
// https://developer.matomo.org/api-reference/tracking-api
try {
const sentToMatomoWithHTTP = await fetch(matomoUrl, {
method: 'POST',
body: urlSearchParams,
})

return {
e_c: `${DEVMODE ? 'DEVMODE - ' : ''}${category}`, // Category name
e_a: action, // Action name
e_n: name, // Name
...(value ? {e_v: value} : {}), // Value
if (sentToMatomoWithHTTP.status !== 200) {
throw new Error(`Matomo HTTP API returned ${sentToMatomoWithHTTP.status}`)
}
} catch (error) {
logMatomoError(error)
}
}

export const sendToTracker = ({url, download, trackEvent}) =>
!MATOMO_ERROR
&& matomo?.track({
ua: `${os.hostname()} / Node.JS ${process.version} / ${os.version()}`,
...(url ? {url} : {}),
...(download ? {download} : {}),
...(trackEvent ? getTrackEvent(trackEvent) : {})
})

export default sendToTracker

0 comments on commit 95ad874

Please sign in to comment.