2022-04-19 05:59:36 +00:00
|
|
|
import { Fyo } from 'fyo';
|
2022-07-18 11:13:56 +00:00
|
|
|
import { ConfigKeys } from 'fyo/core/types';
|
|
|
|
import { Noun, Telemetry, Verb } from './types';
|
2022-03-18 10:09:17 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* # Telemetry
|
2022-05-23 08:09:07 +00:00
|
|
|
* Used to check if people are using Books or not. All logging
|
|
|
|
* happens using navigator.sendBeacon
|
2022-03-18 10:09:17 +00:00
|
|
|
*
|
|
|
|
* ## `start`
|
2022-05-23 08:09:07 +00:00
|
|
|
* Used to initialize state. It should be called before any logging and after an
|
|
|
|
* instance has loaded.
|
2022-03-18 10:09:17 +00:00
|
|
|
* It is called on three events:
|
2022-07-18 11:13:56 +00:00
|
|
|
* 1. When Desk is opened, i.e. when the usage starts, this also sends a
|
|
|
|
* Opened instance log.
|
|
|
|
* 2. On visibility change if not started, eg: when user minimizes Books and
|
2022-03-18 10:09:17 +00:00
|
|
|
* then comes back later.
|
2022-07-18 11:13:56 +00:00
|
|
|
* 3. When `log` is called, but telemetry isn't initialized.
|
2022-03-18 10:09:17 +00:00
|
|
|
*
|
|
|
|
* ## `log`
|
2022-05-23 08:09:07 +00:00
|
|
|
* Used to log activity.
|
2022-03-18 10:09:17 +00:00
|
|
|
*
|
|
|
|
* ## `stop`
|
|
|
|
* This is to be called when a session is being stopped. It's called on two events
|
|
|
|
* 1. When the db is being changed.
|
|
|
|
* 2. When the visiblity has changed which happens when either the app is being shut or
|
|
|
|
* the app is hidden.
|
|
|
|
*/
|
2022-03-09 10:13:17 +00:00
|
|
|
|
2022-04-18 11:29:20 +00:00
|
|
|
export class TelemetryManager {
|
2022-03-14 12:56:26 +00:00
|
|
|
#url: string = '';
|
|
|
|
#token: string = '';
|
2022-03-09 10:13:17 +00:00
|
|
|
#started = false;
|
2022-04-19 05:59:36 +00:00
|
|
|
fyo: Fyo;
|
2022-04-18 11:29:20 +00:00
|
|
|
|
2022-04-19 05:59:36 +00:00
|
|
|
constructor(fyo: Fyo) {
|
|
|
|
this.fyo = fyo;
|
2022-04-18 11:29:20 +00:00
|
|
|
}
|
2022-03-09 10:13:17 +00:00
|
|
|
|
2022-03-18 10:09:17 +00:00
|
|
|
get hasCreds() {
|
|
|
|
return !!this.#url && !!this.#token;
|
|
|
|
}
|
|
|
|
|
|
|
|
get started() {
|
|
|
|
return this.#started;
|
|
|
|
}
|
|
|
|
|
2022-07-18 11:13:56 +00:00
|
|
|
async start(isOpened?: boolean) {
|
2022-05-23 08:09:07 +00:00
|
|
|
this.#started = true;
|
|
|
|
await this.#setCreds();
|
2022-03-14 12:56:26 +00:00
|
|
|
|
2022-07-18 11:13:56 +00:00
|
|
|
if (isOpened) {
|
2022-05-28 11:14:38 +00:00
|
|
|
this.log(Verb.Opened, 'instance');
|
2022-05-23 08:09:07 +00:00
|
|
|
} else {
|
2022-05-28 11:14:38 +00:00
|
|
|
this.log(Verb.Resumed, 'instance');
|
2022-03-09 10:13:17 +00:00
|
|
|
}
|
2022-05-23 08:09:07 +00:00
|
|
|
}
|
2022-03-09 10:13:17 +00:00
|
|
|
|
2022-05-23 08:09:07 +00:00
|
|
|
stop() {
|
|
|
|
if (!this.started) {
|
2022-03-10 07:51:29 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-28 11:14:38 +00:00
|
|
|
this.log(Verb.Closed, 'instance');
|
2022-05-23 08:09:07 +00:00
|
|
|
this.#started = false;
|
2022-03-09 10:13:17 +00:00
|
|
|
}
|
2022-03-09 10:54:42 +00:00
|
|
|
|
2022-05-23 08:09:07 +00:00
|
|
|
log(verb: Verb, noun: Noun, more?: Record<string, unknown>) {
|
2022-05-23 09:28:33 +00:00
|
|
|
if (!this.#started && this.fyo.db.isConnected) {
|
2022-05-23 08:09:07 +00:00
|
|
|
this.start().then(() => this.#sendBeacon(verb, noun, more));
|
|
|
|
return;
|
2022-03-09 11:20:48 +00:00
|
|
|
}
|
|
|
|
|
2022-05-23 08:09:07 +00:00
|
|
|
this.#sendBeacon(verb, noun, more);
|
2022-03-09 11:20:48 +00:00
|
|
|
}
|
|
|
|
|
2022-05-28 11:14:38 +00:00
|
|
|
async logOpened() {
|
|
|
|
await this.#setCreds();
|
|
|
|
this.#sendBeacon(Verb.Opened, 'app');
|
|
|
|
}
|
|
|
|
|
2022-05-23 08:09:07 +00:00
|
|
|
#sendBeacon(verb: Verb, noun: Noun, more?: Record<string, unknown>) {
|
2022-05-28 11:14:38 +00:00
|
|
|
if (!this.hasCreds || this.fyo.store.skipTelemetryLogging) {
|
2022-05-23 08:09:07 +00:00
|
|
|
return;
|
|
|
|
}
|
2022-03-10 09:05:47 +00:00
|
|
|
|
2022-05-23 08:09:07 +00:00
|
|
|
const telemetryData: Telemetry = this.#getTelemtryData(verb, noun, more);
|
2022-03-18 10:09:17 +00:00
|
|
|
const data = JSON.stringify({
|
|
|
|
token: this.#token,
|
2022-05-23 08:09:07 +00:00
|
|
|
telemetryData,
|
2022-03-18 10:09:17 +00:00
|
|
|
});
|
2022-03-10 12:06:28 +00:00
|
|
|
|
2022-03-15 10:58:43 +00:00
|
|
|
navigator.sendBeacon(this.#url, data);
|
|
|
|
}
|
|
|
|
|
2022-03-18 10:09:17 +00:00
|
|
|
async #setCreds() {
|
|
|
|
if (this.hasCreds) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-27 09:39:24 +00:00
|
|
|
const { telemetryUrl, tokenString } = await this.fyo.auth.getCreds();
|
|
|
|
this.#url = telemetryUrl;
|
|
|
|
this.#token = tokenString;
|
2022-03-18 10:09:17 +00:00
|
|
|
}
|
|
|
|
|
2022-05-23 08:09:07 +00:00
|
|
|
#getTelemtryData(
|
|
|
|
verb: Verb,
|
|
|
|
noun: Noun,
|
|
|
|
more?: Record<string, unknown>
|
|
|
|
): Telemetry {
|
2022-07-18 11:13:56 +00:00
|
|
|
const countryCode = this.fyo.singles.SystemSettings?.countryCode as
|
|
|
|
| string
|
|
|
|
| undefined;
|
|
|
|
|
2022-05-23 08:09:07 +00:00
|
|
|
return {
|
2022-07-18 11:13:56 +00:00
|
|
|
country: countryCode ?? '',
|
|
|
|
language: this.fyo.store.language,
|
|
|
|
deviceId:
|
|
|
|
this.fyo.store.deviceId ||
|
|
|
|
(this.fyo.config.get(ConfigKeys.DeviceId) as string),
|
|
|
|
instanceId: this.fyo.store.instanceId,
|
|
|
|
version: this.fyo.store.appVersion,
|
|
|
|
openCount: this.fyo.store.openCount,
|
|
|
|
timestamp: new Date().toISOString().replace('T', ' ').slice(0, -1),
|
|
|
|
platform: this.fyo.store.platform,
|
2022-05-23 08:09:07 +00:00
|
|
|
verb,
|
|
|
|
noun,
|
|
|
|
more,
|
|
|
|
};
|
2022-03-18 10:09:17 +00:00
|
|
|
}
|
2022-03-09 10:13:17 +00:00
|
|
|
}
|