argus-discord-analytics 0.2.0 → 0.2.2
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/dist/index.d.mts +78 -3
- package/dist/index.d.ts +78 -3
- package/dist/index.js +117 -11
- package/dist/index.mjs +117 -11
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* argus.trackRevenue({ source: 'patreon', amount: 500, tier: 'Premium' });
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
declare const SDK_VERSION = "0.2.
|
|
24
|
+
declare const SDK_VERSION = "0.2.2";
|
|
25
25
|
interface ArgusConfig {
|
|
26
26
|
/** Your Argus API key (starts with arg_live_ or arg_test_) */
|
|
27
27
|
apiKey: string;
|
|
@@ -37,6 +37,12 @@ interface ArgusConfig {
|
|
|
37
37
|
hashUserIds?: boolean;
|
|
38
38
|
/** Heartbeat interval in ms (default: 30000) */
|
|
39
39
|
heartbeatInterval?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Discord Application ID to filter events.
|
|
42
|
+
* If set on both SDK and dashboard, only matching events are accepted.
|
|
43
|
+
* Use `client.user?.id` to get this from your Discord.js bot.
|
|
44
|
+
*/
|
|
45
|
+
discordBotId?: string;
|
|
40
46
|
}
|
|
41
47
|
interface TrackEvent {
|
|
42
48
|
type: 'command' | 'error' | 'custom';
|
|
@@ -81,6 +87,7 @@ declare class Argus {
|
|
|
81
87
|
private flushInterval;
|
|
82
88
|
private hashUserIds;
|
|
83
89
|
private heartbeatInterval;
|
|
90
|
+
private discordBotId;
|
|
84
91
|
private queue;
|
|
85
92
|
private serverQueue;
|
|
86
93
|
private revenueQueue;
|
|
@@ -94,17 +101,32 @@ declare class Argus {
|
|
|
94
101
|
private startFlushTimer;
|
|
95
102
|
/**
|
|
96
103
|
* Track a Discord.js interaction automatically
|
|
97
|
-
*
|
|
104
|
+
* Auto-detects interaction type and routes to appropriate tracking method:
|
|
105
|
+
* - Commands → trackCommand (with subcommand extraction)
|
|
106
|
+
* - Buttons → trackButton
|
|
107
|
+
* - Select menus → trackSelectMenu
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* // One line for everything!
|
|
112
|
+
* client.on('interactionCreate', (interaction) => {
|
|
113
|
+
* argus.track(interaction);
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
98
116
|
*/
|
|
99
117
|
track(interaction: {
|
|
100
118
|
commandName?: string;
|
|
101
119
|
customId?: string;
|
|
120
|
+
values?: string[];
|
|
102
121
|
guildId?: string | null;
|
|
103
122
|
user?: {
|
|
104
123
|
id: string;
|
|
105
124
|
};
|
|
106
125
|
type?: number;
|
|
107
126
|
options?: unknown;
|
|
127
|
+
message?: {
|
|
128
|
+
id: string;
|
|
129
|
+
};
|
|
108
130
|
}): void;
|
|
109
131
|
/**
|
|
110
132
|
* Track a custom event
|
|
@@ -131,7 +153,15 @@ declare class Argus {
|
|
|
131
153
|
* });
|
|
132
154
|
* ```
|
|
133
155
|
*/
|
|
134
|
-
trackCommand(commandOrInteraction: string |
|
|
156
|
+
trackCommand(commandOrInteraction: string | {
|
|
157
|
+
commandName?: string;
|
|
158
|
+
customId?: string;
|
|
159
|
+
guildId?: string | null;
|
|
160
|
+
user?: {
|
|
161
|
+
id: string;
|
|
162
|
+
};
|
|
163
|
+
options?: unknown;
|
|
164
|
+
}, options?: {
|
|
135
165
|
serverId?: string;
|
|
136
166
|
userId?: string;
|
|
137
167
|
metadata?: Record<string, unknown>;
|
|
@@ -145,6 +175,51 @@ declare class Argus {
|
|
|
145
175
|
userId?: string;
|
|
146
176
|
metadata?: Record<string, unknown>;
|
|
147
177
|
}): void;
|
|
178
|
+
/**
|
|
179
|
+
* Track a button click interaction
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```typescript
|
|
183
|
+
* client.on('interactionCreate', (interaction) => {
|
|
184
|
+
* if (interaction.isButton()) {
|
|
185
|
+
* argus.trackButton(interaction);
|
|
186
|
+
* // Tracked as: "button:buy_premium"
|
|
187
|
+
* }
|
|
188
|
+
* });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
trackButton(interaction: {
|
|
192
|
+
customId: string;
|
|
193
|
+
guildId?: string | null;
|
|
194
|
+
user?: {
|
|
195
|
+
id: string;
|
|
196
|
+
};
|
|
197
|
+
message?: {
|
|
198
|
+
id: string;
|
|
199
|
+
};
|
|
200
|
+
}): void;
|
|
201
|
+
/**
|
|
202
|
+
* Track a select menu interaction
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* client.on('interactionCreate', (interaction) => {
|
|
207
|
+
* if (interaction.isStringSelectMenu()) {
|
|
208
|
+
* argus.trackSelectMenu(interaction);
|
|
209
|
+
* // Tracked as: "select:role_picker"
|
|
210
|
+
* // Metadata includes: selectedValues
|
|
211
|
+
* }
|
|
212
|
+
* });
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
trackSelectMenu(interaction: {
|
|
216
|
+
customId: string;
|
|
217
|
+
values: string[];
|
|
218
|
+
guildId?: string | null;
|
|
219
|
+
user?: {
|
|
220
|
+
id: string;
|
|
221
|
+
};
|
|
222
|
+
}): void;
|
|
148
223
|
/**
|
|
149
224
|
* Track server join or leave events
|
|
150
225
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* argus.trackRevenue({ source: 'patreon', amount: 500, tier: 'Premium' });
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
declare const SDK_VERSION = "0.2.
|
|
24
|
+
declare const SDK_VERSION = "0.2.2";
|
|
25
25
|
interface ArgusConfig {
|
|
26
26
|
/** Your Argus API key (starts with arg_live_ or arg_test_) */
|
|
27
27
|
apiKey: string;
|
|
@@ -37,6 +37,12 @@ interface ArgusConfig {
|
|
|
37
37
|
hashUserIds?: boolean;
|
|
38
38
|
/** Heartbeat interval in ms (default: 30000) */
|
|
39
39
|
heartbeatInterval?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Discord Application ID to filter events.
|
|
42
|
+
* If set on both SDK and dashboard, only matching events are accepted.
|
|
43
|
+
* Use `client.user?.id` to get this from your Discord.js bot.
|
|
44
|
+
*/
|
|
45
|
+
discordBotId?: string;
|
|
40
46
|
}
|
|
41
47
|
interface TrackEvent {
|
|
42
48
|
type: 'command' | 'error' | 'custom';
|
|
@@ -81,6 +87,7 @@ declare class Argus {
|
|
|
81
87
|
private flushInterval;
|
|
82
88
|
private hashUserIds;
|
|
83
89
|
private heartbeatInterval;
|
|
90
|
+
private discordBotId;
|
|
84
91
|
private queue;
|
|
85
92
|
private serverQueue;
|
|
86
93
|
private revenueQueue;
|
|
@@ -94,17 +101,32 @@ declare class Argus {
|
|
|
94
101
|
private startFlushTimer;
|
|
95
102
|
/**
|
|
96
103
|
* Track a Discord.js interaction automatically
|
|
97
|
-
*
|
|
104
|
+
* Auto-detects interaction type and routes to appropriate tracking method:
|
|
105
|
+
* - Commands → trackCommand (with subcommand extraction)
|
|
106
|
+
* - Buttons → trackButton
|
|
107
|
+
* - Select menus → trackSelectMenu
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* // One line for everything!
|
|
112
|
+
* client.on('interactionCreate', (interaction) => {
|
|
113
|
+
* argus.track(interaction);
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
98
116
|
*/
|
|
99
117
|
track(interaction: {
|
|
100
118
|
commandName?: string;
|
|
101
119
|
customId?: string;
|
|
120
|
+
values?: string[];
|
|
102
121
|
guildId?: string | null;
|
|
103
122
|
user?: {
|
|
104
123
|
id: string;
|
|
105
124
|
};
|
|
106
125
|
type?: number;
|
|
107
126
|
options?: unknown;
|
|
127
|
+
message?: {
|
|
128
|
+
id: string;
|
|
129
|
+
};
|
|
108
130
|
}): void;
|
|
109
131
|
/**
|
|
110
132
|
* Track a custom event
|
|
@@ -131,7 +153,15 @@ declare class Argus {
|
|
|
131
153
|
* });
|
|
132
154
|
* ```
|
|
133
155
|
*/
|
|
134
|
-
trackCommand(commandOrInteraction: string |
|
|
156
|
+
trackCommand(commandOrInteraction: string | {
|
|
157
|
+
commandName?: string;
|
|
158
|
+
customId?: string;
|
|
159
|
+
guildId?: string | null;
|
|
160
|
+
user?: {
|
|
161
|
+
id: string;
|
|
162
|
+
};
|
|
163
|
+
options?: unknown;
|
|
164
|
+
}, options?: {
|
|
135
165
|
serverId?: string;
|
|
136
166
|
userId?: string;
|
|
137
167
|
metadata?: Record<string, unknown>;
|
|
@@ -145,6 +175,51 @@ declare class Argus {
|
|
|
145
175
|
userId?: string;
|
|
146
176
|
metadata?: Record<string, unknown>;
|
|
147
177
|
}): void;
|
|
178
|
+
/**
|
|
179
|
+
* Track a button click interaction
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```typescript
|
|
183
|
+
* client.on('interactionCreate', (interaction) => {
|
|
184
|
+
* if (interaction.isButton()) {
|
|
185
|
+
* argus.trackButton(interaction);
|
|
186
|
+
* // Tracked as: "button:buy_premium"
|
|
187
|
+
* }
|
|
188
|
+
* });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
trackButton(interaction: {
|
|
192
|
+
customId: string;
|
|
193
|
+
guildId?: string | null;
|
|
194
|
+
user?: {
|
|
195
|
+
id: string;
|
|
196
|
+
};
|
|
197
|
+
message?: {
|
|
198
|
+
id: string;
|
|
199
|
+
};
|
|
200
|
+
}): void;
|
|
201
|
+
/**
|
|
202
|
+
* Track a select menu interaction
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* client.on('interactionCreate', (interaction) => {
|
|
207
|
+
* if (interaction.isStringSelectMenu()) {
|
|
208
|
+
* argus.trackSelectMenu(interaction);
|
|
209
|
+
* // Tracked as: "select:role_picker"
|
|
210
|
+
* // Metadata includes: selectedValues
|
|
211
|
+
* }
|
|
212
|
+
* });
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
trackSelectMenu(interaction: {
|
|
216
|
+
customId: string;
|
|
217
|
+
values: string[];
|
|
218
|
+
guildId?: string | null;
|
|
219
|
+
user?: {
|
|
220
|
+
id: string;
|
|
221
|
+
};
|
|
222
|
+
}): void;
|
|
148
223
|
/**
|
|
149
224
|
* Track server join or leave events
|
|
150
225
|
*
|
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
default: () => index_default
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(index_exports);
|
|
28
|
-
var SDK_VERSION = "0.2.
|
|
28
|
+
var SDK_VERSION = "0.2.2";
|
|
29
29
|
function hashString(str) {
|
|
30
30
|
let hash = 0;
|
|
31
31
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -37,21 +37,50 @@ function hashString(str) {
|
|
|
37
37
|
}
|
|
38
38
|
function extractFullCommandName(interaction) {
|
|
39
39
|
let command = interaction.commandName || interaction.customId || "unknown";
|
|
40
|
+
let foundSubcommand = false;
|
|
40
41
|
const options = interaction.options;
|
|
41
42
|
if (options && typeof options.getSubcommandGroup === "function") {
|
|
42
43
|
try {
|
|
43
44
|
const group = options.getSubcommandGroup(false);
|
|
44
|
-
if (group)
|
|
45
|
+
if (group) {
|
|
46
|
+
command += ` ${group}`;
|
|
47
|
+
foundSubcommand = true;
|
|
48
|
+
}
|
|
45
49
|
} catch {
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
if (options && typeof options.getSubcommand === "function") {
|
|
49
53
|
try {
|
|
50
54
|
const sub = options.getSubcommand(false);
|
|
51
|
-
if (sub)
|
|
55
|
+
if (sub) {
|
|
56
|
+
command += ` ${sub}`;
|
|
57
|
+
foundSubcommand = true;
|
|
58
|
+
}
|
|
52
59
|
} catch {
|
|
53
60
|
}
|
|
54
61
|
}
|
|
62
|
+
if (!foundSubcommand && options) {
|
|
63
|
+
const optionsData = options.data;
|
|
64
|
+
if (Array.isArray(optionsData)) {
|
|
65
|
+
for (const opt of optionsData) {
|
|
66
|
+
if (opt.type === 2) {
|
|
67
|
+
command += ` ${opt.name}`;
|
|
68
|
+
if (Array.isArray(opt.options)) {
|
|
69
|
+
for (const subOpt of opt.options) {
|
|
70
|
+
if (subOpt.type === 1) {
|
|
71
|
+
command += ` ${subOpt.name}`;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
} else if (opt.type === 1) {
|
|
78
|
+
command += ` ${opt.name}`;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
55
84
|
return command;
|
|
56
85
|
}
|
|
57
86
|
var Argus = class {
|
|
@@ -78,8 +107,9 @@ var Argus = class {
|
|
|
78
107
|
this.flushInterval = config.flushInterval || 1e4;
|
|
79
108
|
this.hashUserIds = config.hashUserIds !== false;
|
|
80
109
|
this.heartbeatInterval = config.heartbeatInterval || 3e4;
|
|
110
|
+
this.discordBotId = config.discordBotId;
|
|
81
111
|
this.startFlushTimer();
|
|
82
|
-
this.log("Argus initialized");
|
|
112
|
+
this.log("Argus initialized", this.discordBotId ? `(Discord Bot ID: ${this.discordBotId})` : "");
|
|
83
113
|
}
|
|
84
114
|
log(...args) {
|
|
85
115
|
if (this.debug) {
|
|
@@ -94,9 +124,36 @@ var Argus = class {
|
|
|
94
124
|
}
|
|
95
125
|
/**
|
|
96
126
|
* Track a Discord.js interaction automatically
|
|
97
|
-
*
|
|
127
|
+
* Auto-detects interaction type and routes to appropriate tracking method:
|
|
128
|
+
* - Commands → trackCommand (with subcommand extraction)
|
|
129
|
+
* - Buttons → trackButton
|
|
130
|
+
* - Select menus → trackSelectMenu
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* // One line for everything!
|
|
135
|
+
* client.on('interactionCreate', (interaction) => {
|
|
136
|
+
* argus.track(interaction);
|
|
137
|
+
* });
|
|
138
|
+
* ```
|
|
98
139
|
*/
|
|
99
140
|
track(interaction) {
|
|
141
|
+
if (interaction.customId && !interaction.commandName) {
|
|
142
|
+
if (Array.isArray(interaction.values)) {
|
|
143
|
+
return this.trackSelectMenu({
|
|
144
|
+
customId: interaction.customId,
|
|
145
|
+
values: interaction.values,
|
|
146
|
+
guildId: interaction.guildId,
|
|
147
|
+
user: interaction.user
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return this.trackButton({
|
|
151
|
+
customId: interaction.customId,
|
|
152
|
+
guildId: interaction.guildId,
|
|
153
|
+
user: interaction.user,
|
|
154
|
+
message: interaction.message
|
|
155
|
+
});
|
|
156
|
+
}
|
|
100
157
|
const name = extractFullCommandName(interaction);
|
|
101
158
|
const serverId = interaction.guildId || void 0;
|
|
102
159
|
const userId = interaction.user?.id;
|
|
@@ -155,10 +212,9 @@ var Argus = class {
|
|
|
155
212
|
} else {
|
|
156
213
|
commandName = extractFullCommandName(commandOrInteraction);
|
|
157
214
|
if (!extractedOptions) {
|
|
158
|
-
const interaction = commandOrInteraction;
|
|
159
215
|
extractedOptions = {
|
|
160
|
-
serverId:
|
|
161
|
-
userId:
|
|
216
|
+
serverId: commandOrInteraction.guildId || void 0,
|
|
217
|
+
userId: commandOrInteraction.user?.id
|
|
162
218
|
};
|
|
163
219
|
}
|
|
164
220
|
}
|
|
@@ -180,6 +236,56 @@ var Argus = class {
|
|
|
180
236
|
}
|
|
181
237
|
});
|
|
182
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Track a button click interaction
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* client.on('interactionCreate', (interaction) => {
|
|
245
|
+
* if (interaction.isButton()) {
|
|
246
|
+
* argus.trackButton(interaction);
|
|
247
|
+
* // Tracked as: "button:buy_premium"
|
|
248
|
+
* }
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
trackButton(interaction) {
|
|
253
|
+
this.trackEvent("custom", `button:${interaction.customId}`, {
|
|
254
|
+
serverId: interaction.guildId || void 0,
|
|
255
|
+
userId: interaction.user?.id,
|
|
256
|
+
metadata: {
|
|
257
|
+
interactionType: "button",
|
|
258
|
+
customId: interaction.customId,
|
|
259
|
+
messageId: interaction.message?.id
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Track a select menu interaction
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```typescript
|
|
268
|
+
* client.on('interactionCreate', (interaction) => {
|
|
269
|
+
* if (interaction.isStringSelectMenu()) {
|
|
270
|
+
* argus.trackSelectMenu(interaction);
|
|
271
|
+
* // Tracked as: "select:role_picker"
|
|
272
|
+
* // Metadata includes: selectedValues
|
|
273
|
+
* }
|
|
274
|
+
* });
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
trackSelectMenu(interaction) {
|
|
278
|
+
this.trackEvent("custom", `select:${interaction.customId}`, {
|
|
279
|
+
serverId: interaction.guildId || void 0,
|
|
280
|
+
userId: interaction.user?.id,
|
|
281
|
+
metadata: {
|
|
282
|
+
interactionType: "select_menu",
|
|
283
|
+
customId: interaction.customId,
|
|
284
|
+
selectedValues: interaction.values,
|
|
285
|
+
selectionCount: interaction.values.length
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
183
289
|
/**
|
|
184
290
|
* Track server join or leave events
|
|
185
291
|
*
|
|
@@ -274,7 +380,7 @@ var Argus = class {
|
|
|
274
380
|
"Content-Type": "application/json",
|
|
275
381
|
"Authorization": `Bearer ${this.apiKey}`
|
|
276
382
|
},
|
|
277
|
-
body: JSON.stringify({ events, sdkVersion: SDK_VERSION })
|
|
383
|
+
body: JSON.stringify({ events, sdkVersion: SDK_VERSION, discordBotId: this.discordBotId })
|
|
278
384
|
});
|
|
279
385
|
if (!response.ok) {
|
|
280
386
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
@@ -299,7 +405,7 @@ var Argus = class {
|
|
|
299
405
|
"Content-Type": "application/json",
|
|
300
406
|
"Authorization": `Bearer ${this.apiKey}`
|
|
301
407
|
},
|
|
302
|
-
body: JSON.stringify({ events })
|
|
408
|
+
body: JSON.stringify({ events, discordBotId: this.discordBotId })
|
|
303
409
|
});
|
|
304
410
|
if (!response.ok) {
|
|
305
411
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
@@ -324,7 +430,7 @@ var Argus = class {
|
|
|
324
430
|
"Content-Type": "application/json",
|
|
325
431
|
"Authorization": `Bearer ${this.apiKey}`
|
|
326
432
|
},
|
|
327
|
-
body: JSON.stringify({ events })
|
|
433
|
+
body: JSON.stringify({ events, discordBotId: this.discordBotId })
|
|
328
434
|
});
|
|
329
435
|
if (!response.ok) {
|
|
330
436
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
var SDK_VERSION = "0.2.
|
|
2
|
+
var SDK_VERSION = "0.2.2";
|
|
3
3
|
function hashString(str) {
|
|
4
4
|
let hash = 0;
|
|
5
5
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -11,21 +11,50 @@ function hashString(str) {
|
|
|
11
11
|
}
|
|
12
12
|
function extractFullCommandName(interaction) {
|
|
13
13
|
let command = interaction.commandName || interaction.customId || "unknown";
|
|
14
|
+
let foundSubcommand = false;
|
|
14
15
|
const options = interaction.options;
|
|
15
16
|
if (options && typeof options.getSubcommandGroup === "function") {
|
|
16
17
|
try {
|
|
17
18
|
const group = options.getSubcommandGroup(false);
|
|
18
|
-
if (group)
|
|
19
|
+
if (group) {
|
|
20
|
+
command += ` ${group}`;
|
|
21
|
+
foundSubcommand = true;
|
|
22
|
+
}
|
|
19
23
|
} catch {
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
if (options && typeof options.getSubcommand === "function") {
|
|
23
27
|
try {
|
|
24
28
|
const sub = options.getSubcommand(false);
|
|
25
|
-
if (sub)
|
|
29
|
+
if (sub) {
|
|
30
|
+
command += ` ${sub}`;
|
|
31
|
+
foundSubcommand = true;
|
|
32
|
+
}
|
|
26
33
|
} catch {
|
|
27
34
|
}
|
|
28
35
|
}
|
|
36
|
+
if (!foundSubcommand && options) {
|
|
37
|
+
const optionsData = options.data;
|
|
38
|
+
if (Array.isArray(optionsData)) {
|
|
39
|
+
for (const opt of optionsData) {
|
|
40
|
+
if (opt.type === 2) {
|
|
41
|
+
command += ` ${opt.name}`;
|
|
42
|
+
if (Array.isArray(opt.options)) {
|
|
43
|
+
for (const subOpt of opt.options) {
|
|
44
|
+
if (subOpt.type === 1) {
|
|
45
|
+
command += ` ${subOpt.name}`;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
} else if (opt.type === 1) {
|
|
52
|
+
command += ` ${opt.name}`;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
29
58
|
return command;
|
|
30
59
|
}
|
|
31
60
|
var Argus = class {
|
|
@@ -52,8 +81,9 @@ var Argus = class {
|
|
|
52
81
|
this.flushInterval = config.flushInterval || 1e4;
|
|
53
82
|
this.hashUserIds = config.hashUserIds !== false;
|
|
54
83
|
this.heartbeatInterval = config.heartbeatInterval || 3e4;
|
|
84
|
+
this.discordBotId = config.discordBotId;
|
|
55
85
|
this.startFlushTimer();
|
|
56
|
-
this.log("Argus initialized");
|
|
86
|
+
this.log("Argus initialized", this.discordBotId ? `(Discord Bot ID: ${this.discordBotId})` : "");
|
|
57
87
|
}
|
|
58
88
|
log(...args) {
|
|
59
89
|
if (this.debug) {
|
|
@@ -68,9 +98,36 @@ var Argus = class {
|
|
|
68
98
|
}
|
|
69
99
|
/**
|
|
70
100
|
* Track a Discord.js interaction automatically
|
|
71
|
-
*
|
|
101
|
+
* Auto-detects interaction type and routes to appropriate tracking method:
|
|
102
|
+
* - Commands → trackCommand (with subcommand extraction)
|
|
103
|
+
* - Buttons → trackButton
|
|
104
|
+
* - Select menus → trackSelectMenu
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* // One line for everything!
|
|
109
|
+
* client.on('interactionCreate', (interaction) => {
|
|
110
|
+
* argus.track(interaction);
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
72
113
|
*/
|
|
73
114
|
track(interaction) {
|
|
115
|
+
if (interaction.customId && !interaction.commandName) {
|
|
116
|
+
if (Array.isArray(interaction.values)) {
|
|
117
|
+
return this.trackSelectMenu({
|
|
118
|
+
customId: interaction.customId,
|
|
119
|
+
values: interaction.values,
|
|
120
|
+
guildId: interaction.guildId,
|
|
121
|
+
user: interaction.user
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return this.trackButton({
|
|
125
|
+
customId: interaction.customId,
|
|
126
|
+
guildId: interaction.guildId,
|
|
127
|
+
user: interaction.user,
|
|
128
|
+
message: interaction.message
|
|
129
|
+
});
|
|
130
|
+
}
|
|
74
131
|
const name = extractFullCommandName(interaction);
|
|
75
132
|
const serverId = interaction.guildId || void 0;
|
|
76
133
|
const userId = interaction.user?.id;
|
|
@@ -129,10 +186,9 @@ var Argus = class {
|
|
|
129
186
|
} else {
|
|
130
187
|
commandName = extractFullCommandName(commandOrInteraction);
|
|
131
188
|
if (!extractedOptions) {
|
|
132
|
-
const interaction = commandOrInteraction;
|
|
133
189
|
extractedOptions = {
|
|
134
|
-
serverId:
|
|
135
|
-
userId:
|
|
190
|
+
serverId: commandOrInteraction.guildId || void 0,
|
|
191
|
+
userId: commandOrInteraction.user?.id
|
|
136
192
|
};
|
|
137
193
|
}
|
|
138
194
|
}
|
|
@@ -154,6 +210,56 @@ var Argus = class {
|
|
|
154
210
|
}
|
|
155
211
|
});
|
|
156
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Track a button click interaction
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* client.on('interactionCreate', (interaction) => {
|
|
219
|
+
* if (interaction.isButton()) {
|
|
220
|
+
* argus.trackButton(interaction);
|
|
221
|
+
* // Tracked as: "button:buy_premium"
|
|
222
|
+
* }
|
|
223
|
+
* });
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
trackButton(interaction) {
|
|
227
|
+
this.trackEvent("custom", `button:${interaction.customId}`, {
|
|
228
|
+
serverId: interaction.guildId || void 0,
|
|
229
|
+
userId: interaction.user?.id,
|
|
230
|
+
metadata: {
|
|
231
|
+
interactionType: "button",
|
|
232
|
+
customId: interaction.customId,
|
|
233
|
+
messageId: interaction.message?.id
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Track a select menu interaction
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* client.on('interactionCreate', (interaction) => {
|
|
243
|
+
* if (interaction.isStringSelectMenu()) {
|
|
244
|
+
* argus.trackSelectMenu(interaction);
|
|
245
|
+
* // Tracked as: "select:role_picker"
|
|
246
|
+
* // Metadata includes: selectedValues
|
|
247
|
+
* }
|
|
248
|
+
* });
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
trackSelectMenu(interaction) {
|
|
252
|
+
this.trackEvent("custom", `select:${interaction.customId}`, {
|
|
253
|
+
serverId: interaction.guildId || void 0,
|
|
254
|
+
userId: interaction.user?.id,
|
|
255
|
+
metadata: {
|
|
256
|
+
interactionType: "select_menu",
|
|
257
|
+
customId: interaction.customId,
|
|
258
|
+
selectedValues: interaction.values,
|
|
259
|
+
selectionCount: interaction.values.length
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
157
263
|
/**
|
|
158
264
|
* Track server join or leave events
|
|
159
265
|
*
|
|
@@ -248,7 +354,7 @@ var Argus = class {
|
|
|
248
354
|
"Content-Type": "application/json",
|
|
249
355
|
"Authorization": `Bearer ${this.apiKey}`
|
|
250
356
|
},
|
|
251
|
-
body: JSON.stringify({ events, sdkVersion: SDK_VERSION })
|
|
357
|
+
body: JSON.stringify({ events, sdkVersion: SDK_VERSION, discordBotId: this.discordBotId })
|
|
252
358
|
});
|
|
253
359
|
if (!response.ok) {
|
|
254
360
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
@@ -273,7 +379,7 @@ var Argus = class {
|
|
|
273
379
|
"Content-Type": "application/json",
|
|
274
380
|
"Authorization": `Bearer ${this.apiKey}`
|
|
275
381
|
},
|
|
276
|
-
body: JSON.stringify({ events })
|
|
382
|
+
body: JSON.stringify({ events, discordBotId: this.discordBotId })
|
|
277
383
|
});
|
|
278
384
|
if (!response.ok) {
|
|
279
385
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
@@ -298,7 +404,7 @@ var Argus = class {
|
|
|
298
404
|
"Content-Type": "application/json",
|
|
299
405
|
"Authorization": `Bearer ${this.apiKey}`
|
|
300
406
|
},
|
|
301
|
-
body: JSON.stringify({ events })
|
|
407
|
+
body: JSON.stringify({ events, discordBotId: this.discordBotId })
|
|
302
408
|
});
|
|
303
409
|
if (!response.ok) {
|
|
304
410
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
package/package.json
CHANGED