107 lines
2.5 KiB
JavaScript
Raw Normal View History

'use strict';
/**
* Strapi telemetry package.
* You can learn more at https://strapi.io/documentation/3.0.0-beta.x/global-strapi/usage-information.html#commitment-to-our-users-data-collection
*/
const os = require('os');
const isDocker = require('is-docker');
const { machineIdSync } = require('node-machine-id');
const fetch = require('node-fetch');
const ciEnv = require('ci-info');
const scheduleJob = require('node-schedule');
const createTelemetryInstance = strapi => {
const uuid = strapi.config.uuid;
const deviceId = machineIdSync();
const isDisabled = !uuid;
const anonymous_metadata = {
environment: strapi.config.environment,
os: os.type(),
osPlatform: os.platform(),
osRelease: os.release(),
nodeVersion: process.version,
docker: process.env.DOCKER || isDocker(),
isCI: ciEnv.isCI,
version: strapi.config.info.strapi,
strapiVersion: strapi.config.info.strapi,
};
const sendEvent = async (event, payload) => {
// do not send anything when user has disabled analytics
if (isDisabled) return true;
try {
const res = await fetch('https://analytics.strapi.io/track', {
method: 'POST',
body: JSON.stringify({
event,
uuid,
deviceId,
properties: {
...payload,
...anonymous_metadata,
},
}),
timeout: 1000,
headers: { 'Content-Type': 'application/json' },
});
return res.ok;
} catch (err) {
return false;
}
};
const _state = {
currentDay: null,
counter: 0,
};
return {
initPing() {
if (isDisabled) {
return;
}
scheduleJob('0 0 12 * * *', () => sendEvent('ping'));
},
middleware: async (ctx, next) => {
if (isDisabled) {
return next();
}
const { url, method } = ctx.request;
if (!url.includes('.') && ['GET', 'PUT', 'POST', 'DELETE'].includes(method)) {
const dayOfMonth = new Date().getDate();
if (dayOfMonth !== _state.currentDay) {
_state.currentDay = dayOfMonth;
_state.counter = 0;
}
// Send max. 1000 events per day.
if (_state.counter < 1000) {
await sendEvent('didReceiveRequest', { url: ctx.request.url });
// Increase counter.
_state.counter++;
}
}
await next();
},
async send(event, properties) {
if (isDisabled) {
return true;
}
await sendEvent(event, properties);
},
};
};
module.exports = createTelemetryInstance();