@discordanalytics/discordjs 2.8.2 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # DiscordAnalytics for Discord.js
2
2
 
3
3
  ## Overview
4
+
4
5
  This package is a wrapper for the Discord Analytics API made for Discord.js. It allows you to track events and send them to the Discord Analytics API.
5
6
 
6
7
  ## Installation
8
+
7
9
  ```bash
8
10
  npm install @discordanalytics/discordjs
9
11
  # or
@@ -13,18 +15,20 @@ pnpm add @discordanalytics/discordjs
13
15
  ```
14
16
 
15
17
  ## Usage
18
+
16
19
  > **Note:** To use Discord Analytics, you need to have an API key. Check the docs for more informations : https://discordanalytics.xyz/docs/main/get-started/bot-registration
17
20
 
18
21
  ### Example
22
+
19
23
  ```js
20
24
  // Import Discord.js's client and intents
21
- const { Client, IntentsBitField } = require("discord.js")
25
+ const { Client, IntentsBitField } = require('discord.js');
22
26
  // import discord-analytics
23
- const { default: DiscordAnalytics } = require("@discordanalytics/discordjs")
27
+ const { default: DiscordAnalytics } = require('@discordanalytics/discordjs');
24
28
 
25
29
  // Create Discord client
26
30
  const client = new Client({
27
- intents: [IntentsBitField.Flags.Guilds] // This intent is required
31
+ intents: [IntentsBitField.Flags.Guilds], // This intent is required
28
32
  });
29
33
 
30
34
  // Create Discord Analytics instance
@@ -32,14 +36,14 @@ const client = new Client({
32
36
  const analytics = new DiscordAnalytics({
33
37
  client: client,
34
38
  api_key: 'YOUR_API_KEY',
35
- sharded: false // Set it to true if your bot use shards
39
+ sharded: false, // Set it to true if your bot use shards
36
40
  });
37
41
 
38
42
  // start tracking selected events
39
43
 
40
44
  // When Discord client is ready
41
45
  client.on('clientReady', async () => {
42
- console.log("Bot is ready!");
46
+ console.log('Bot is ready!');
43
47
  await analytics.init(); // Initialize the analytics
44
48
  analytics.trackEvents(); // Start tracking events
45
49
  });
package/dist/index.cjs ADDED
@@ -0,0 +1,131 @@
1
+ let _discordanalytics_core = require("@discordanalytics/core");
2
+ //#region package.json
3
+ var version = "2.8.2";
4
+ //#endregion
5
+ //#region src/index.ts
6
+ /**
7
+ * @class DiscordAnalytics
8
+ * @description The Discord.js class for the DiscordAnalytics library.
9
+ * @param {AnalyticsOptions} options Configuration options.
10
+ * @property {Client} options.client The Discord.js client to track events for.
11
+ * @property {string} options.api_key The API token for DiscordAnalytics.
12
+ * @property {boolean} options.sharded Whether the Discord.js client is sharded.
13
+ * @property {boolean} options.debug Enable or not the debug mode /!\ MUST BE USED ONLY FOR DEVELOPMENT PURPOSES /!\
14
+ * @example
15
+ * const { default: DiscordAnalytics } = require('discord-analytics/discordjs');
16
+ * const { Client, IntentsBitField } = require('discord.js');
17
+ * const client = new Client({
18
+ * intents: [IntentsBitField.Flags.Guilds]
19
+ * })
20
+ * client.on('ready', () => {
21
+ * const analytics = new DiscordAnalytics({
22
+ * client: client,
23
+ * api_key: 'YOUR_API_TOKEN'
24
+ * });
25
+ * analytics.init();
26
+ * analytics.trackEvents();
27
+ * });
28
+ * client.login('YOUR_BOT_TOKEN');
29
+ * @link https://discordanalytics.xyz/docs/main/get-started/installation/discord.js Check docs for more informations about advanced usages
30
+ */
31
+ var DiscordAnalytics = class extends _discordanalytics_core.AnalyticsBase {
32
+ constructor(options) {
33
+ super(options.api_key, options.api_url, options.debug);
34
+ this._sharded = false;
35
+ this._isReady = false;
36
+ this._client = options.client;
37
+ this._sharded = options.sharded || false;
38
+ }
39
+ /**
40
+ * Initialize DiscordAnalytics on your bot
41
+ * /!\ Advanced users only
42
+ * /!\ Required to use DiscordAnalytics
43
+ * /!\ Must be used when the client is ready (recommended to use in ready event to prevent problems)
44
+ */
45
+ async init() {
46
+ if (process.env.NODE_ENV !== "production") return console.log("[DISCORDANALYTICS] NODE_ENV != 'production', initialization skipped");
47
+ if (!this._client.user) return console.log("[DISCORDANALYTICS] client is not ready, initialization skipped");
48
+ this.client_id = this._client.user.id;
49
+ await this.updateBotInformations(this._client.user.username, "discord.js", version, this._client.user.avatar);
50
+ this.debug("[DISCORDANALYTICS] Instance successfully initialized");
51
+ this._isReady = true;
52
+ const fast_mode = process.argv[2] === "--fast";
53
+ this.debug(`[DISCORDANALYTICS] Fast mode is ${fast_mode ? "enabled" : "disabled"}. Stats will be sent every ${fast_mode ? "30s" : "5min"}.`);
54
+ setInterval(async () => {
55
+ this.debug("[DISCORDANALYTICS] Sending stats...");
56
+ const guildCount = this._sharded ? (await this._client.shard?.broadcastEval((c) => c.guilds.cache.size))?.reduce((a, b) => a + b, 0) || 0 : this._client.guilds.cache.size;
57
+ const userCount = this._sharded ? (await this._client.shard?.broadcastEval((c) => c.guilds.cache.reduce((a, g) => a + (g.memberCount || 0), 0)))?.reduce((a, b) => a + b, 0) || 0 : this._client.guilds.cache.reduce((a, g) => a + (g.memberCount || 0), 0);
58
+ const userInstallCount = this._sharded ? (await this._client.shard?.broadcastEval((c) => c.application.approximateUserInstallCount))?.reduce((a, b) => a + b, 0) || 0 : this._client.application.approximateUserInstallCount || 0;
59
+ const guildMembers = !this._sharded ? this._client.guilds.cache.map((guild) => guild.memberCount) : (await this._client.shard?.broadcastEval((c) => c.guilds.cache.map((guild) => guild.memberCount)))?.flat() ?? [];
60
+ const guildLocales = [];
61
+ this._client.guilds.cache.map((current) => guildLocales.find((x) => x.locale === current.preferredLocale) ? ++guildLocales.find((x) => x.locale === current.preferredLocale).number : guildLocales.push({
62
+ locale: current.preferredLocale,
63
+ number: 1
64
+ }));
65
+ this.stats_data.guildLocales = guildLocales;
66
+ await this.sendStats(this._client.user.id, guildCount, userCount, userInstallCount, guildMembers);
67
+ }, fast_mode ? 3e4 : 3e5);
68
+ }
69
+ /**
70
+ * Track interactions
71
+ * /!\ Advanced users only
72
+ * /!\ You need to initialize the class first
73
+ * @param interaction BaseInteraction class and its extensions only
74
+ * @param interactionNameResolver A function that will resolve the name of the interaction
75
+ */
76
+ async trackInteractions(interaction, interactionNameResolver) {
77
+ this.debug(`[DISCORDANALYTICS] trackInteractions(${interaction.type}) triggered`);
78
+ if (!this._isReady) return this.error(_discordanalytics_core.ErrorCodes.INSTANCE_NOT_INITIALIZED);
79
+ this.updateOrInsert(this.stats_data.interactionsLocales, (x) => x.locale === interaction.locale, (x) => x.number++, () => ({
80
+ locale: interaction.locale,
81
+ number: 1
82
+ }));
83
+ if (interaction.type === _discordanalytics_core.InteractionType.ApplicationCommand) {
84
+ const commandType = interaction.command ? interaction.command.type : _discordanalytics_core.ApplicationCommandType.ChatInputCommand;
85
+ const commandName = interactionNameResolver ? interactionNameResolver(interaction) : interaction.commandName;
86
+ this.updateOrInsert(this.stats_data.interactions, (x) => x.name === commandName && x.type === interaction.type && x.commandType === commandType, (x) => x.number++, () => ({
87
+ name: commandName,
88
+ number: 1,
89
+ type: interaction.type,
90
+ commandType
91
+ }));
92
+ } else if (interaction.type === _discordanalytics_core.InteractionType.MessageComponent || interaction.type === _discordanalytics_core.InteractionType.ModalSubmit) {
93
+ const interactionName = interactionNameResolver ? interactionNameResolver(interaction) : interaction.customId;
94
+ this.updateOrInsert(this.stats_data.interactions, (x) => x.name === interactionName && x.type === interaction.type, (x) => x.number++, () => ({
95
+ name: interactionName,
96
+ number: 1,
97
+ type: interaction.type
98
+ }));
99
+ }
100
+ this.updateOrInsert(this.stats_data.guilds, (x) => x.guildId === (interaction.guild ? interaction.guild.id : "dm"), (x) => x.interactions++, () => ({
101
+ guildId: interaction.guild ? interaction.guild.id : "dm",
102
+ name: interaction.guild ? interaction.guild.name : "DM",
103
+ icon: interaction.guild && interaction.guild.icon,
104
+ interactions: 1,
105
+ members: interaction.guild ? interaction.guild.memberCount : 0
106
+ }));
107
+ const oneWeekAgo = /* @__PURE__ */ new Date();
108
+ oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
109
+ if (!interaction.inGuild() || !interaction.guild) ++this.stats_data.usersType.privateMessage;
110
+ else if (interaction.member && interaction.memberPermissions.has(8n) || interaction.memberPermissions.has(32n)) ++this.stats_data.usersType.admin;
111
+ else if (interaction.member && interaction.memberPermissions.has(8192n) || interaction.memberPermissions.has(2n) || interaction.memberPermissions.has(4n) || interaction.memberPermissions.has(4194304n) || interaction.memberPermissions.has(8388608n) || interaction.memberPermissions.has(16777216n) || interaction.memberPermissions.has(1099511627776n)) ++this.stats_data.usersType.moderator;
112
+ else if (interaction.member && interaction.member.joinedAt && interaction.member.joinedAt > oneWeekAgo) ++this.stats_data.usersType.newMember;
113
+ }
114
+ /**
115
+ * Let DiscordAnalytics declare the events necessary for its operation.
116
+ * /!\ Not recommended for big bots
117
+ * /!\ Not compatible with other functions
118
+ * @param interactionNameResolver A function that will resolve the name of the interaction
119
+ */
120
+ trackEvents(interactionNameResolver) {
121
+ this.debug("[DISCORDANALYTICS] trackEvents() triggered");
122
+ if (!this._isReady) return this.error(_discordanalytics_core.ErrorCodes.INSTANCE_NOT_INITIALIZED);
123
+ this._client.on("interactionCreate", async (interaction) => await this.trackInteractions(interaction, interactionNameResolver));
124
+ this._client.on("guildCreate", () => this.trackGuilds("create"));
125
+ this._client.on("guildDelete", () => this.trackGuilds("delete"));
126
+ }
127
+ };
128
+ //#endregion
129
+ module.exports = DiscordAnalytics;
130
+
131
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["AnalyticsBase","npmPackageData.version","ErrorCodes","InteractionType","ApplicationCommandType"],"sources":["../package.json","../src/index.ts"],"sourcesContent":["","import {\n AnalyticsBase,\n ApplicationCommandType,\n AnalyticsOptions,\n ErrorCodes,\n InteractionType,\n LocaleData,\n Locale,\n InteractionData,\n GuildData,\n} from '@discordanalytics/core';\nimport type { CacheType, Client, GuildMember, Interaction } from 'discord.js';\nimport npmPackageData from '../package.json';\n\n/**\n * @class DiscordAnalytics\n * @description The Discord.js class for the DiscordAnalytics library.\n * @param {AnalyticsOptions} options Configuration options.\n * @property {Client} options.client The Discord.js client to track events for.\n * @property {string} options.api_key The API token for DiscordAnalytics.\n * @property {boolean} options.sharded Whether the Discord.js client is sharded.\n * @property {boolean} options.debug Enable or not the debug mode /!\\ MUST BE USED ONLY FOR DEVELOPMENT PURPOSES /!\\\n * @example\n * const { default: DiscordAnalytics } = require('discord-analytics/discordjs');\n * const { Client, IntentsBitField } = require('discord.js');\n * const client = new Client({\n * intents: [IntentsBitField.Flags.Guilds]\n * })\n * client.on('ready', () => {\n * const analytics = new DiscordAnalytics({\n * client: client,\n * api_key: 'YOUR_API_TOKEN'\n * });\n * analytics.init();\n * analytics.trackEvents();\n * });\n * client.login('YOUR_BOT_TOKEN');\n * @link https://discordanalytics.xyz/docs/main/get-started/installation/discord.js Check docs for more informations about advanced usages\n */\nexport default class DiscordAnalytics extends AnalyticsBase {\n private readonly _client: Client;\n private readonly _sharded: boolean = false;\n private _isReady: boolean = false;\n\n constructor(options: AnalyticsOptions<Client>) {\n super(options.api_key, options.api_url, options.debug);\n this._client = options.client;\n this._sharded = options.sharded || false;\n }\n\n /**\n * Initialize DiscordAnalytics on your bot\n * /!\\ Advanced users only\n * /!\\ Required to use DiscordAnalytics\n * /!\\ Must be used when the client is ready (recommended to use in ready event to prevent problems)\n */\n public async init(): Promise<void> {\n if (process.env.NODE_ENV !== 'production')\n return console.log(\"[DISCORDANALYTICS] NODE_ENV != 'production', initialization skipped\");\n\n if (!this._client.user)\n return console.log('[DISCORDANALYTICS] client is not ready, initialization skipped');\n\n this.client_id = this._client.user.id;\n\n await this.updateBotInformations(\n this._client.user.username,\n 'discord.js',\n npmPackageData.version,\n this._client.user.avatar,\n );\n\n this.debug('[DISCORDANALYTICS] Instance successfully initialized');\n this._isReady = true;\n\n const fast_mode = process.argv[2] === '--fast';\n this.debug(\n `[DISCORDANALYTICS] Fast mode is ${fast_mode ? 'enabled' : 'disabled'}. Stats will be sent every ${fast_mode ? '30s' : '5min'}.`,\n );\n\n setInterval(\n async () => {\n this.debug('[DISCORDANALYTICS] Sending stats...');\n\n const guildCount = this._sharded\n ? (await this._client.shard?.broadcastEval((c) => c.guilds.cache.size))?.reduce(\n (a: number, b: number) => a + b,\n 0,\n ) || 0\n : this._client.guilds.cache.size;\n\n const userCount = this._sharded\n ? (\n await this._client.shard?.broadcastEval((c) =>\n c.guilds.cache.reduce((a: number, g) => a + (g.memberCount || 0), 0),\n )\n )?.reduce((a: number, b: number) => a + b, 0) || 0\n : this._client.guilds.cache.reduce((a: number, g) => a + (g.memberCount || 0), 0);\n\n const userInstallCount = this._sharded\n ? (\n await this._client.shard?.broadcastEval(\n (c) => c.application!.approximateUserInstallCount,\n )\n )?.reduce((a, b) => a! + b!, 0) || 0\n : this._client.application!.approximateUserInstallCount || 0;\n\n const guildMembers: number[] = !this._sharded\n ? this._client.guilds.cache.map((guild) => guild.memberCount)\n : ((\n await this._client.shard?.broadcastEval((c) =>\n c.guilds.cache.map((guild) => guild.memberCount),\n )\n )?.flat() ?? []);\n\n const guildLocales: LocaleData[] = [];\n this._client.guilds.cache.map((current) =>\n guildLocales.find((x) => x.locale === current.preferredLocale)\n ? ++guildLocales.find((x) => x.locale === current.preferredLocale)!.number\n : guildLocales.push({ locale: current.preferredLocale as Locale, number: 1 }),\n );\n\n this.stats_data.guildLocales = guildLocales;\n\n await this.sendStats(\n this._client.user!.id,\n guildCount,\n userCount,\n userInstallCount,\n guildMembers,\n );\n },\n fast_mode ? 30000 : 300000,\n );\n }\n\n /**\n * Track interactions\n * /!\\ Advanced users only\n * /!\\ You need to initialize the class first\n * @param interaction BaseInteraction class and its extensions only\n * @param interactionNameResolver A function that will resolve the name of the interaction\n */\n public async trackInteractions(\n interaction: Interaction<CacheType>,\n interactionNameResolver?: (interaction: Interaction<CacheType>) => string,\n ): Promise<void> {\n this.debug(`[DISCORDANALYTICS] trackInteractions(${interaction.type}) triggered`);\n if (!this._isReady) return this.error(ErrorCodes.INSTANCE_NOT_INITIALIZED);\n\n this.updateOrInsert(\n this.stats_data.interactionsLocales,\n (x) => x.locale === interaction.locale,\n (x) => x.number++,\n (): LocaleData => ({ locale: interaction.locale as Locale, number: 1 }),\n );\n\n if (interaction.type === InteractionType.ApplicationCommand) {\n const commandType = interaction.command\n ? interaction.command.type\n : ApplicationCommandType.ChatInputCommand;\n const commandName = interactionNameResolver\n ? interactionNameResolver(interaction)\n : interaction.commandName;\n this.updateOrInsert(\n this.stats_data.interactions,\n (x) =>\n x.name === commandName && x.type === interaction.type && x.commandType === commandType,\n (x) => x.number++,\n (): InteractionData => ({\n name: commandName,\n number: 1,\n type: interaction.type,\n commandType: commandType as ApplicationCommandType,\n }),\n );\n } else if (\n interaction.type === InteractionType.MessageComponent ||\n interaction.type === InteractionType.ModalSubmit\n ) {\n const interactionName = interactionNameResolver\n ? interactionNameResolver(interaction)\n : interaction.customId;\n this.updateOrInsert(\n this.stats_data.interactions,\n (x) => x.name === interactionName && x.type === interaction.type,\n (x) => x.number++,\n (): InteractionData => ({\n name: interactionName,\n number: 1,\n type: interaction.type,\n }),\n );\n }\n\n this.updateOrInsert(\n this.stats_data.guilds,\n (x) => x.guildId === (interaction.guild ? interaction.guild.id : 'dm'),\n (x) => x.interactions++,\n (): GuildData => ({\n guildId: interaction.guild ? interaction.guild.id : 'dm',\n name: interaction.guild ? interaction.guild.name : 'DM',\n icon: interaction.guild && interaction.guild.icon,\n interactions: 1,\n members: interaction.guild ? interaction.guild.memberCount : 0,\n }),\n );\n\n const oneWeekAgo = new Date();\n oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);\n\n if (!interaction.inGuild() || !interaction.guild) ++this.stats_data.usersType.privateMessage;\n else if (\n (interaction.member && interaction.memberPermissions.has(8n)) ||\n interaction.memberPermissions.has(32n)\n )\n ++this.stats_data.usersType.admin;\n else if (\n (interaction.member && interaction.memberPermissions.has(8192n)) ||\n interaction.memberPermissions.has(2n) ||\n interaction.memberPermissions.has(4n) ||\n interaction.memberPermissions.has(4194304n) ||\n interaction.memberPermissions.has(8388608n) ||\n interaction.memberPermissions.has(16777216n) ||\n interaction.memberPermissions.has(1099511627776n)\n )\n ++this.stats_data.usersType.moderator;\n else if (\n interaction.member &&\n (interaction.member as GuildMember).joinedAt &&\n (interaction.member as GuildMember).joinedAt! > oneWeekAgo\n )\n ++this.stats_data.usersType.newMember;\n }\n\n /**\n * Let DiscordAnalytics declare the events necessary for its operation.\n * /!\\ Not recommended for big bots\n * /!\\ Not compatible with other functions\n * @param interactionNameResolver A function that will resolve the name of the interaction\n */\n public trackEvents(\n interactionNameResolver?: (interaction: Interaction<CacheType>) => string,\n ): void {\n this.debug('[DISCORDANALYTICS] trackEvents() triggered');\n if (!this._isReady) return this.error(ErrorCodes.INSTANCE_NOT_INITIALIZED);\n\n this._client.on(\n 'interactionCreate',\n async (interaction) => await this.trackInteractions(interaction, interactionNameResolver),\n );\n this._client.on('guildCreate', () => this.trackGuilds('create'));\n this._client.on('guildDelete', () => this.trackGuilds('delete'));\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { AnalyticsBase, AnalyticsOptions } from "@discordanalytics/core";
2
+ import { CacheType, Client, Interaction } from "discord.js";
3
+
4
+ //#region src/index.d.ts
5
+ /**
6
+ * @class DiscordAnalytics
7
+ * @description The Discord.js class for the DiscordAnalytics library.
8
+ * @param {AnalyticsOptions} options Configuration options.
9
+ * @property {Client} options.client The Discord.js client to track events for.
10
+ * @property {string} options.api_key The API token for DiscordAnalytics.
11
+ * @property {boolean} options.sharded Whether the Discord.js client is sharded.
12
+ * @property {boolean} options.debug Enable or not the debug mode /!\ MUST BE USED ONLY FOR DEVELOPMENT PURPOSES /!\
13
+ * @example
14
+ * const { default: DiscordAnalytics } = require('discord-analytics/discordjs');
15
+ * const { Client, IntentsBitField } = require('discord.js');
16
+ * const client = new Client({
17
+ * intents: [IntentsBitField.Flags.Guilds]
18
+ * })
19
+ * client.on('ready', () => {
20
+ * const analytics = new DiscordAnalytics({
21
+ * client: client,
22
+ * api_key: 'YOUR_API_TOKEN'
23
+ * });
24
+ * analytics.init();
25
+ * analytics.trackEvents();
26
+ * });
27
+ * client.login('YOUR_BOT_TOKEN');
28
+ * @link https://discordanalytics.xyz/docs/main/get-started/installation/discord.js Check docs for more informations about advanced usages
29
+ */
30
+ declare class DiscordAnalytics extends AnalyticsBase {
31
+ private readonly _client;
32
+ private readonly _sharded;
33
+ private _isReady;
34
+ constructor(options: AnalyticsOptions<Client>);
35
+ /**
36
+ * Initialize DiscordAnalytics on your bot
37
+ * /!\ Advanced users only
38
+ * /!\ Required to use DiscordAnalytics
39
+ * /!\ Must be used when the client is ready (recommended to use in ready event to prevent problems)
40
+ */
41
+ init(): Promise<void>;
42
+ /**
43
+ * Track interactions
44
+ * /!\ Advanced users only
45
+ * /!\ You need to initialize the class first
46
+ * @param interaction BaseInteraction class and its extensions only
47
+ * @param interactionNameResolver A function that will resolve the name of the interaction
48
+ */
49
+ trackInteractions(interaction: Interaction<CacheType>, interactionNameResolver?: (interaction: Interaction<CacheType>) => string): Promise<void>;
50
+ /**
51
+ * Let DiscordAnalytics declare the events necessary for its operation.
52
+ * /!\ Not recommended for big bots
53
+ * /!\ Not compatible with other functions
54
+ * @param interactionNameResolver A function that will resolve the name of the interaction
55
+ */
56
+ trackEvents(interactionNameResolver?: (interaction: Interaction<CacheType>) => string): void;
57
+ }
58
+ export = DiscordAnalytics;
59
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1,60 @@
1
+ import { AnalyticsBase, AnalyticsOptions } from "@discordanalytics/core";
2
+ import { CacheType, Client, Interaction } from "discord.js";
3
+
4
+ //#region src/index.d.ts
5
+ /**
6
+ * @class DiscordAnalytics
7
+ * @description The Discord.js class for the DiscordAnalytics library.
8
+ * @param {AnalyticsOptions} options Configuration options.
9
+ * @property {Client} options.client The Discord.js client to track events for.
10
+ * @property {string} options.api_key The API token for DiscordAnalytics.
11
+ * @property {boolean} options.sharded Whether the Discord.js client is sharded.
12
+ * @property {boolean} options.debug Enable or not the debug mode /!\ MUST BE USED ONLY FOR DEVELOPMENT PURPOSES /!\
13
+ * @example
14
+ * const { default: DiscordAnalytics } = require('discord-analytics/discordjs');
15
+ * const { Client, IntentsBitField } = require('discord.js');
16
+ * const client = new Client({
17
+ * intents: [IntentsBitField.Flags.Guilds]
18
+ * })
19
+ * client.on('ready', () => {
20
+ * const analytics = new DiscordAnalytics({
21
+ * client: client,
22
+ * api_key: 'YOUR_API_TOKEN'
23
+ * });
24
+ * analytics.init();
25
+ * analytics.trackEvents();
26
+ * });
27
+ * client.login('YOUR_BOT_TOKEN');
28
+ * @link https://discordanalytics.xyz/docs/main/get-started/installation/discord.js Check docs for more informations about advanced usages
29
+ */
30
+ declare class DiscordAnalytics extends AnalyticsBase {
31
+ private readonly _client;
32
+ private readonly _sharded;
33
+ private _isReady;
34
+ constructor(options: AnalyticsOptions<Client>);
35
+ /**
36
+ * Initialize DiscordAnalytics on your bot
37
+ * /!\ Advanced users only
38
+ * /!\ Required to use DiscordAnalytics
39
+ * /!\ Must be used when the client is ready (recommended to use in ready event to prevent problems)
40
+ */
41
+ init(): Promise<void>;
42
+ /**
43
+ * Track interactions
44
+ * /!\ Advanced users only
45
+ * /!\ You need to initialize the class first
46
+ * @param interaction BaseInteraction class and its extensions only
47
+ * @param interactionNameResolver A function that will resolve the name of the interaction
48
+ */
49
+ trackInteractions(interaction: Interaction<CacheType>, interactionNameResolver?: (interaction: Interaction<CacheType>) => string): Promise<void>;
50
+ /**
51
+ * Let DiscordAnalytics declare the events necessary for its operation.
52
+ * /!\ Not recommended for big bots
53
+ * /!\ Not compatible with other functions
54
+ * @param interactionNameResolver A function that will resolve the name of the interaction
55
+ */
56
+ trackEvents(interactionNameResolver?: (interaction: Interaction<CacheType>) => string): void;
57
+ }
58
+ //#endregion
59
+ export { DiscordAnalytics as default };
60
+ //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs ADDED
@@ -0,0 +1,131 @@
1
+ import { AnalyticsBase, ApplicationCommandType, ErrorCodes, InteractionType } from "@discordanalytics/core";
2
+ //#region package.json
3
+ var version = "2.8.2";
4
+ //#endregion
5
+ //#region src/index.ts
6
+ /**
7
+ * @class DiscordAnalytics
8
+ * @description The Discord.js class for the DiscordAnalytics library.
9
+ * @param {AnalyticsOptions} options Configuration options.
10
+ * @property {Client} options.client The Discord.js client to track events for.
11
+ * @property {string} options.api_key The API token for DiscordAnalytics.
12
+ * @property {boolean} options.sharded Whether the Discord.js client is sharded.
13
+ * @property {boolean} options.debug Enable or not the debug mode /!\ MUST BE USED ONLY FOR DEVELOPMENT PURPOSES /!\
14
+ * @example
15
+ * const { default: DiscordAnalytics } = require('discord-analytics/discordjs');
16
+ * const { Client, IntentsBitField } = require('discord.js');
17
+ * const client = new Client({
18
+ * intents: [IntentsBitField.Flags.Guilds]
19
+ * })
20
+ * client.on('ready', () => {
21
+ * const analytics = new DiscordAnalytics({
22
+ * client: client,
23
+ * api_key: 'YOUR_API_TOKEN'
24
+ * });
25
+ * analytics.init();
26
+ * analytics.trackEvents();
27
+ * });
28
+ * client.login('YOUR_BOT_TOKEN');
29
+ * @link https://discordanalytics.xyz/docs/main/get-started/installation/discord.js Check docs for more informations about advanced usages
30
+ */
31
+ var DiscordAnalytics = class extends AnalyticsBase {
32
+ constructor(options) {
33
+ super(options.api_key, options.api_url, options.debug);
34
+ this._sharded = false;
35
+ this._isReady = false;
36
+ this._client = options.client;
37
+ this._sharded = options.sharded || false;
38
+ }
39
+ /**
40
+ * Initialize DiscordAnalytics on your bot
41
+ * /!\ Advanced users only
42
+ * /!\ Required to use DiscordAnalytics
43
+ * /!\ Must be used when the client is ready (recommended to use in ready event to prevent problems)
44
+ */
45
+ async init() {
46
+ if (process.env.NODE_ENV !== "production") return console.log("[DISCORDANALYTICS] NODE_ENV != 'production', initialization skipped");
47
+ if (!this._client.user) return console.log("[DISCORDANALYTICS] client is not ready, initialization skipped");
48
+ this.client_id = this._client.user.id;
49
+ await this.updateBotInformations(this._client.user.username, "discord.js", version, this._client.user.avatar);
50
+ this.debug("[DISCORDANALYTICS] Instance successfully initialized");
51
+ this._isReady = true;
52
+ const fast_mode = process.argv[2] === "--fast";
53
+ this.debug(`[DISCORDANALYTICS] Fast mode is ${fast_mode ? "enabled" : "disabled"}. Stats will be sent every ${fast_mode ? "30s" : "5min"}.`);
54
+ setInterval(async () => {
55
+ this.debug("[DISCORDANALYTICS] Sending stats...");
56
+ const guildCount = this._sharded ? (await this._client.shard?.broadcastEval((c) => c.guilds.cache.size))?.reduce((a, b) => a + b, 0) || 0 : this._client.guilds.cache.size;
57
+ const userCount = this._sharded ? (await this._client.shard?.broadcastEval((c) => c.guilds.cache.reduce((a, g) => a + (g.memberCount || 0), 0)))?.reduce((a, b) => a + b, 0) || 0 : this._client.guilds.cache.reduce((a, g) => a + (g.memberCount || 0), 0);
58
+ const userInstallCount = this._sharded ? (await this._client.shard?.broadcastEval((c) => c.application.approximateUserInstallCount))?.reduce((a, b) => a + b, 0) || 0 : this._client.application.approximateUserInstallCount || 0;
59
+ const guildMembers = !this._sharded ? this._client.guilds.cache.map((guild) => guild.memberCount) : (await this._client.shard?.broadcastEval((c) => c.guilds.cache.map((guild) => guild.memberCount)))?.flat() ?? [];
60
+ const guildLocales = [];
61
+ this._client.guilds.cache.map((current) => guildLocales.find((x) => x.locale === current.preferredLocale) ? ++guildLocales.find((x) => x.locale === current.preferredLocale).number : guildLocales.push({
62
+ locale: current.preferredLocale,
63
+ number: 1
64
+ }));
65
+ this.stats_data.guildLocales = guildLocales;
66
+ await this.sendStats(this._client.user.id, guildCount, userCount, userInstallCount, guildMembers);
67
+ }, fast_mode ? 3e4 : 3e5);
68
+ }
69
+ /**
70
+ * Track interactions
71
+ * /!\ Advanced users only
72
+ * /!\ You need to initialize the class first
73
+ * @param interaction BaseInteraction class and its extensions only
74
+ * @param interactionNameResolver A function that will resolve the name of the interaction
75
+ */
76
+ async trackInteractions(interaction, interactionNameResolver) {
77
+ this.debug(`[DISCORDANALYTICS] trackInteractions(${interaction.type}) triggered`);
78
+ if (!this._isReady) return this.error(ErrorCodes.INSTANCE_NOT_INITIALIZED);
79
+ this.updateOrInsert(this.stats_data.interactionsLocales, (x) => x.locale === interaction.locale, (x) => x.number++, () => ({
80
+ locale: interaction.locale,
81
+ number: 1
82
+ }));
83
+ if (interaction.type === InteractionType.ApplicationCommand) {
84
+ const commandType = interaction.command ? interaction.command.type : ApplicationCommandType.ChatInputCommand;
85
+ const commandName = interactionNameResolver ? interactionNameResolver(interaction) : interaction.commandName;
86
+ this.updateOrInsert(this.stats_data.interactions, (x) => x.name === commandName && x.type === interaction.type && x.commandType === commandType, (x) => x.number++, () => ({
87
+ name: commandName,
88
+ number: 1,
89
+ type: interaction.type,
90
+ commandType
91
+ }));
92
+ } else if (interaction.type === InteractionType.MessageComponent || interaction.type === InteractionType.ModalSubmit) {
93
+ const interactionName = interactionNameResolver ? interactionNameResolver(interaction) : interaction.customId;
94
+ this.updateOrInsert(this.stats_data.interactions, (x) => x.name === interactionName && x.type === interaction.type, (x) => x.number++, () => ({
95
+ name: interactionName,
96
+ number: 1,
97
+ type: interaction.type
98
+ }));
99
+ }
100
+ this.updateOrInsert(this.stats_data.guilds, (x) => x.guildId === (interaction.guild ? interaction.guild.id : "dm"), (x) => x.interactions++, () => ({
101
+ guildId: interaction.guild ? interaction.guild.id : "dm",
102
+ name: interaction.guild ? interaction.guild.name : "DM",
103
+ icon: interaction.guild && interaction.guild.icon,
104
+ interactions: 1,
105
+ members: interaction.guild ? interaction.guild.memberCount : 0
106
+ }));
107
+ const oneWeekAgo = /* @__PURE__ */ new Date();
108
+ oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
109
+ if (!interaction.inGuild() || !interaction.guild) ++this.stats_data.usersType.privateMessage;
110
+ else if (interaction.member && interaction.memberPermissions.has(8n) || interaction.memberPermissions.has(32n)) ++this.stats_data.usersType.admin;
111
+ else if (interaction.member && interaction.memberPermissions.has(8192n) || interaction.memberPermissions.has(2n) || interaction.memberPermissions.has(4n) || interaction.memberPermissions.has(4194304n) || interaction.memberPermissions.has(8388608n) || interaction.memberPermissions.has(16777216n) || interaction.memberPermissions.has(1099511627776n)) ++this.stats_data.usersType.moderator;
112
+ else if (interaction.member && interaction.member.joinedAt && interaction.member.joinedAt > oneWeekAgo) ++this.stats_data.usersType.newMember;
113
+ }
114
+ /**
115
+ * Let DiscordAnalytics declare the events necessary for its operation.
116
+ * /!\ Not recommended for big bots
117
+ * /!\ Not compatible with other functions
118
+ * @param interactionNameResolver A function that will resolve the name of the interaction
119
+ */
120
+ trackEvents(interactionNameResolver) {
121
+ this.debug("[DISCORDANALYTICS] trackEvents() triggered");
122
+ if (!this._isReady) return this.error(ErrorCodes.INSTANCE_NOT_INITIALIZED);
123
+ this._client.on("interactionCreate", async (interaction) => await this.trackInteractions(interaction, interactionNameResolver));
124
+ this._client.on("guildCreate", () => this.trackGuilds("create"));
125
+ this._client.on("guildDelete", () => this.trackGuilds("delete"));
126
+ }
127
+ };
128
+ //#endregion
129
+ export { DiscordAnalytics as default };
130
+
131
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["npmPackageData.version"],"sources":["../package.json","../src/index.ts"],"sourcesContent":["","import {\n AnalyticsBase,\n ApplicationCommandType,\n AnalyticsOptions,\n ErrorCodes,\n InteractionType,\n LocaleData,\n Locale,\n InteractionData,\n GuildData,\n} from '@discordanalytics/core';\nimport type { CacheType, Client, GuildMember, Interaction } from 'discord.js';\nimport npmPackageData from '../package.json';\n\n/**\n * @class DiscordAnalytics\n * @description The Discord.js class for the DiscordAnalytics library.\n * @param {AnalyticsOptions} options Configuration options.\n * @property {Client} options.client The Discord.js client to track events for.\n * @property {string} options.api_key The API token for DiscordAnalytics.\n * @property {boolean} options.sharded Whether the Discord.js client is sharded.\n * @property {boolean} options.debug Enable or not the debug mode /!\\ MUST BE USED ONLY FOR DEVELOPMENT PURPOSES /!\\\n * @example\n * const { default: DiscordAnalytics } = require('discord-analytics/discordjs');\n * const { Client, IntentsBitField } = require('discord.js');\n * const client = new Client({\n * intents: [IntentsBitField.Flags.Guilds]\n * })\n * client.on('ready', () => {\n * const analytics = new DiscordAnalytics({\n * client: client,\n * api_key: 'YOUR_API_TOKEN'\n * });\n * analytics.init();\n * analytics.trackEvents();\n * });\n * client.login('YOUR_BOT_TOKEN');\n * @link https://discordanalytics.xyz/docs/main/get-started/installation/discord.js Check docs for more informations about advanced usages\n */\nexport default class DiscordAnalytics extends AnalyticsBase {\n private readonly _client: Client;\n private readonly _sharded: boolean = false;\n private _isReady: boolean = false;\n\n constructor(options: AnalyticsOptions<Client>) {\n super(options.api_key, options.api_url, options.debug);\n this._client = options.client;\n this._sharded = options.sharded || false;\n }\n\n /**\n * Initialize DiscordAnalytics on your bot\n * /!\\ Advanced users only\n * /!\\ Required to use DiscordAnalytics\n * /!\\ Must be used when the client is ready (recommended to use in ready event to prevent problems)\n */\n public async init(): Promise<void> {\n if (process.env.NODE_ENV !== 'production')\n return console.log(\"[DISCORDANALYTICS] NODE_ENV != 'production', initialization skipped\");\n\n if (!this._client.user)\n return console.log('[DISCORDANALYTICS] client is not ready, initialization skipped');\n\n this.client_id = this._client.user.id;\n\n await this.updateBotInformations(\n this._client.user.username,\n 'discord.js',\n npmPackageData.version,\n this._client.user.avatar,\n );\n\n this.debug('[DISCORDANALYTICS] Instance successfully initialized');\n this._isReady = true;\n\n const fast_mode = process.argv[2] === '--fast';\n this.debug(\n `[DISCORDANALYTICS] Fast mode is ${fast_mode ? 'enabled' : 'disabled'}. Stats will be sent every ${fast_mode ? '30s' : '5min'}.`,\n );\n\n setInterval(\n async () => {\n this.debug('[DISCORDANALYTICS] Sending stats...');\n\n const guildCount = this._sharded\n ? (await this._client.shard?.broadcastEval((c) => c.guilds.cache.size))?.reduce(\n (a: number, b: number) => a + b,\n 0,\n ) || 0\n : this._client.guilds.cache.size;\n\n const userCount = this._sharded\n ? (\n await this._client.shard?.broadcastEval((c) =>\n c.guilds.cache.reduce((a: number, g) => a + (g.memberCount || 0), 0),\n )\n )?.reduce((a: number, b: number) => a + b, 0) || 0\n : this._client.guilds.cache.reduce((a: number, g) => a + (g.memberCount || 0), 0);\n\n const userInstallCount = this._sharded\n ? (\n await this._client.shard?.broadcastEval(\n (c) => c.application!.approximateUserInstallCount,\n )\n )?.reduce((a, b) => a! + b!, 0) || 0\n : this._client.application!.approximateUserInstallCount || 0;\n\n const guildMembers: number[] = !this._sharded\n ? this._client.guilds.cache.map((guild) => guild.memberCount)\n : ((\n await this._client.shard?.broadcastEval((c) =>\n c.guilds.cache.map((guild) => guild.memberCount),\n )\n )?.flat() ?? []);\n\n const guildLocales: LocaleData[] = [];\n this._client.guilds.cache.map((current) =>\n guildLocales.find((x) => x.locale === current.preferredLocale)\n ? ++guildLocales.find((x) => x.locale === current.preferredLocale)!.number\n : guildLocales.push({ locale: current.preferredLocale as Locale, number: 1 }),\n );\n\n this.stats_data.guildLocales = guildLocales;\n\n await this.sendStats(\n this._client.user!.id,\n guildCount,\n userCount,\n userInstallCount,\n guildMembers,\n );\n },\n fast_mode ? 30000 : 300000,\n );\n }\n\n /**\n * Track interactions\n * /!\\ Advanced users only\n * /!\\ You need to initialize the class first\n * @param interaction BaseInteraction class and its extensions only\n * @param interactionNameResolver A function that will resolve the name of the interaction\n */\n public async trackInteractions(\n interaction: Interaction<CacheType>,\n interactionNameResolver?: (interaction: Interaction<CacheType>) => string,\n ): Promise<void> {\n this.debug(`[DISCORDANALYTICS] trackInteractions(${interaction.type}) triggered`);\n if (!this._isReady) return this.error(ErrorCodes.INSTANCE_NOT_INITIALIZED);\n\n this.updateOrInsert(\n this.stats_data.interactionsLocales,\n (x) => x.locale === interaction.locale,\n (x) => x.number++,\n (): LocaleData => ({ locale: interaction.locale as Locale, number: 1 }),\n );\n\n if (interaction.type === InteractionType.ApplicationCommand) {\n const commandType = interaction.command\n ? interaction.command.type\n : ApplicationCommandType.ChatInputCommand;\n const commandName = interactionNameResolver\n ? interactionNameResolver(interaction)\n : interaction.commandName;\n this.updateOrInsert(\n this.stats_data.interactions,\n (x) =>\n x.name === commandName && x.type === interaction.type && x.commandType === commandType,\n (x) => x.number++,\n (): InteractionData => ({\n name: commandName,\n number: 1,\n type: interaction.type,\n commandType: commandType as ApplicationCommandType,\n }),\n );\n } else if (\n interaction.type === InteractionType.MessageComponent ||\n interaction.type === InteractionType.ModalSubmit\n ) {\n const interactionName = interactionNameResolver\n ? interactionNameResolver(interaction)\n : interaction.customId;\n this.updateOrInsert(\n this.stats_data.interactions,\n (x) => x.name === interactionName && x.type === interaction.type,\n (x) => x.number++,\n (): InteractionData => ({\n name: interactionName,\n number: 1,\n type: interaction.type,\n }),\n );\n }\n\n this.updateOrInsert(\n this.stats_data.guilds,\n (x) => x.guildId === (interaction.guild ? interaction.guild.id : 'dm'),\n (x) => x.interactions++,\n (): GuildData => ({\n guildId: interaction.guild ? interaction.guild.id : 'dm',\n name: interaction.guild ? interaction.guild.name : 'DM',\n icon: interaction.guild && interaction.guild.icon,\n interactions: 1,\n members: interaction.guild ? interaction.guild.memberCount : 0,\n }),\n );\n\n const oneWeekAgo = new Date();\n oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);\n\n if (!interaction.inGuild() || !interaction.guild) ++this.stats_data.usersType.privateMessage;\n else if (\n (interaction.member && interaction.memberPermissions.has(8n)) ||\n interaction.memberPermissions.has(32n)\n )\n ++this.stats_data.usersType.admin;\n else if (\n (interaction.member && interaction.memberPermissions.has(8192n)) ||\n interaction.memberPermissions.has(2n) ||\n interaction.memberPermissions.has(4n) ||\n interaction.memberPermissions.has(4194304n) ||\n interaction.memberPermissions.has(8388608n) ||\n interaction.memberPermissions.has(16777216n) ||\n interaction.memberPermissions.has(1099511627776n)\n )\n ++this.stats_data.usersType.moderator;\n else if (\n interaction.member &&\n (interaction.member as GuildMember).joinedAt &&\n (interaction.member as GuildMember).joinedAt! > oneWeekAgo\n )\n ++this.stats_data.usersType.newMember;\n }\n\n /**\n * Let DiscordAnalytics declare the events necessary for its operation.\n * /!\\ Not recommended for big bots\n * /!\\ Not compatible with other functions\n * @param interactionNameResolver A function that will resolve the name of the interaction\n */\n public trackEvents(\n interactionNameResolver?: (interaction: Interaction<CacheType>) => string,\n ): void {\n this.debug('[DISCORDANALYTICS] trackEvents() triggered');\n if (!this._isReady) return this.error(ErrorCodes.INSTANCE_NOT_INITIALIZED);\n\n this._client.on(\n 'interactionCreate',\n async (interaction) => await this.trackInteractions(interaction, interactionNameResolver),\n );\n this._client.on('guildCreate', () => this.trackGuilds('create'));\n this._client.on('guildDelete', () => this.trackGuilds('delete'));\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,26 @@
1
1
  {
2
2
  "name": "@discordanalytics/discordjs",
3
- "version": "2.8.2",
3
+ "version": "2.9.0",
4
4
  "description": "Discord.js package for working with Discord Analytics",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
8
- "main": "dist/index.js",
9
- "types": "dist/index.d.ts",
8
+ "type": "module",
9
+ "main": "dist/index.cjs",
10
+ "module": "dist/index.mjs",
11
+ "types": "dist/index.d.mts",
12
+ "exports": {
13
+ ".": {
14
+ "import": {
15
+ "types": "./dist/index.d.mts",
16
+ "default": "./dist/index.mjs"
17
+ },
18
+ "require": {
19
+ "types": "./dist/index.d.cts",
20
+ "default": "./dist/index.cjs"
21
+ }
22
+ }
23
+ },
10
24
  "author": "Discord Analytics",
11
25
  "homepage": "https://discordanalytics.xyz",
12
26
  "readme": "README.md",
@@ -18,10 +32,11 @@
18
32
  "url": "https://github.com/DiscordAnalytics/node-package/issues"
19
33
  },
20
34
  "dependencies": {
21
- "@discordanalytics/core": "2.8.2"
35
+ "@discordanalytics/core": "2.9.0"
22
36
  },
23
37
  "devDependencies": {
24
- "discord.js": "14.25.1",
38
+ "discord.js": "14.26.2",
39
+ "tsdown": "*",
25
40
  "typescript": "*"
26
41
  },
27
42
  "peerDependencies": {
@@ -29,6 +44,6 @@
29
44
  },
30
45
  "scripts": {
31
46
  "prebuild": "pnpm --filter @discordanalytics/core build",
32
- "build": "tsc"
47
+ "build": "tsdown"
33
48
  }
34
49
  }
package/dist/index.d.ts DELETED
@@ -1,54 +0,0 @@
1
- import { AnalyticsBase, AnalyticsOptions } from '@discordanalytics/core';
2
- /**
3
- * @class DiscordAnalytics
4
- * @description The Discord.js class for the DiscordAnalytics library.
5
- * @param {AnalyticsOptions} options Configuration options.
6
- * @property {any} options.client The Discord.js client to track events for.
7
- * @property {string} options.api_key The API token for DiscordAnalytics.
8
- * @property {boolean} options.sharded Whether the Discord.js client is sharded.
9
- * @property {boolean} options.debug Enable or not the debug mode /!\ MUST BE USED ONLY FOR DEVELOPMENT PURPOSES /!\
10
- * @example
11
- * const { default: DiscordAnalytics } = require('discord-analytics/discordjs');
12
- * const { Client, IntentsBitField } = require('discord.js');
13
- * const client = new Client({
14
- * intents: [IntentsBitField.Flags.Guilds]
15
- * })
16
- * client.on('ready', () => {
17
- * const analytics = new DiscordAnalytics({
18
- * client: client,
19
- * api_key: 'YOUR_API_TOKEN'
20
- * });
21
- * analytics.init();
22
- * analytics.trackEvents();
23
- * });
24
- * client.login('YOUR_BOT_TOKEN');
25
- * @link https://discordanalytics.xyz/docs/main/get-started/installation/discord.js Check docs for more informations about advanced usages
26
- */
27
- export default class DiscordAnalytics extends AnalyticsBase {
28
- private readonly _client;
29
- private readonly _sharded;
30
- private _isReady;
31
- constructor(options: AnalyticsOptions);
32
- /**
33
- * Initialize DiscordAnalytics on your bot
34
- * /!\ Advanced users only
35
- * /!\ Required to use DiscordAnalytics
36
- * /!\ Must be used when the client is ready (recommended to use in ready event to prevent problems)
37
- */
38
- init(): Promise<void>;
39
- /**
40
- * Track interactions
41
- * /!\ Advanced users only
42
- * /!\ You need to initialize the class first
43
- * @param interaction BaseInteraction class and its extensions only
44
- * @param interactionNameResolver A function that will resolve the name of the interaction
45
- */
46
- trackInteractions(interaction: any, interactionNameResolver?: (interaction: any) => string): Promise<void>;
47
- /**
48
- * Let DiscordAnalytics declare the events necessary for its operation.
49
- * /!\ Not recommended for big bots
50
- * /!\ Not compatible with other functions
51
- * @param interactionNameResolver A function that will resolve the name of the interaction
52
- */
53
- trackEvents(interactionNameResolver?: (interaction: any) => string): void;
54
- }