2323import net .dv8tion .jda .api .hooks .ListenerAdapter ;
2424import net .dv8tion .jda .api .interactions .callbacks .IReplyCallback ;
2525import net .dv8tion .jda .api .interactions .components .ComponentInteraction ;
26- import org .jetbrains .annotations .NotNull ;
2726import org .jetbrains .annotations .Nullable ;
2827import org .jetbrains .annotations .Unmodifiable ;
2928import org .slf4j .Logger ;
4241import org .togetherjava .tjbot .features .UserInteractionType ;
4342import org .togetherjava .tjbot .features .UserInteractor ;
4443import org .togetherjava .tjbot .features .VoiceReceiver ;
44+ import org .togetherjava .tjbot .features .analytics .AnalyticsService ;
4545import org .togetherjava .tjbot .features .componentids .ComponentId ;
4646import org .togetherjava .tjbot .features .componentids .ComponentIdParser ;
4747import org .togetherjava .tjbot .features .componentids .ComponentIdStore ;
@@ -79,13 +79,13 @@ public final class BotCore extends ListenerAdapter implements CommandProvider {
7979 private static final ExecutorService COMMAND_SERVICE = Executors .newCachedThreadPool ();
8080 private static final ScheduledExecutorService ROUTINE_SERVICE =
8181 Executors .newScheduledThreadPool (5 );
82- private final Config config ;
8382 private final Map <String , UserInteractor > prefixedNameToInteractor ;
8483 private final List <Routine > routines ;
8584 private final ComponentIdParser componentIdParser ;
8685 private final ComponentIdStore componentIdStore ;
8786 private final Map <Pattern , MessageReceiver > channelNameToMessageReceiver = new HashMap <>();
8887 private final Map <Pattern , VoiceReceiver > channelNameToVoiceReceiver = new HashMap <>();
88+ private final AnalyticsService analyticsService ;
8989
9090 /**
9191 * Creates a new command system which uses the given database to allow commands to persist data.
@@ -97,9 +97,11 @@ public final class BotCore extends ListenerAdapter implements CommandProvider {
9797 * @param config the configuration to use for this system
9898 */
9999 public BotCore (JDA jda , Database database , Config config ) {
100- this .config = config ;
101100 Collection <Feature > features = Features .createFeatures (jda , database , config );
102101
102+ // Initialize analytics service
103+ analyticsService = new AnalyticsService (database );
104+
103105 // Message receivers
104106 features .stream ()
105107 .filter (MessageReceiver .class ::isInstance )
@@ -300,14 +302,14 @@ private Optional<Channel> selectPreferredAudioChannel(@Nullable AudioChannelUnio
300302 }
301303
302304 @ Override
303- public void onGuildVoiceUpdate (@ NotNull GuildVoiceUpdateEvent event ) {
305+ public void onGuildVoiceUpdate (GuildVoiceUpdateEvent event ) {
304306 selectPreferredAudioChannel (event .getChannelJoined (), event .getChannelLeft ())
305307 .ifPresent (channel -> getVoiceReceiversSubscribedTo (channel )
306308 .forEach (voiceReceiver -> voiceReceiver .onVoiceUpdate (event )));
307309 }
308310
309311 @ Override
310- public void onGuildVoiceVideo (@ NotNull GuildVoiceVideoEvent event ) {
312+ public void onGuildVoiceVideo (GuildVoiceVideoEvent event ) {
311313 AudioChannelUnion channel = event .getVoiceState ().getChannel ();
312314
313315 if (channel == null ) {
@@ -319,7 +321,7 @@ public void onGuildVoiceVideo(@NotNull GuildVoiceVideoEvent event) {
319321 }
320322
321323 @ Override
322- public void onGuildVoiceStream (@ NotNull GuildVoiceStreamEvent event ) {
324+ public void onGuildVoiceStream (GuildVoiceStreamEvent event ) {
323325 AudioChannelUnion channel = event .getVoiceState ().getChannel ();
324326
325327 if (channel == null ) {
@@ -331,7 +333,7 @@ public void onGuildVoiceStream(@NotNull GuildVoiceStreamEvent event) {
331333 }
332334
333335 @ Override
334- public void onGuildVoiceMute (@ NotNull GuildVoiceMuteEvent event ) {
336+ public void onGuildVoiceMute (GuildVoiceMuteEvent event ) {
335337 AudioChannelUnion channel = event .getVoiceState ().getChannel ();
336338
337339 if (channel == null ) {
@@ -343,7 +345,7 @@ public void onGuildVoiceMute(@NotNull GuildVoiceMuteEvent event) {
343345 }
344346
345347 @ Override
346- public void onGuildVoiceDeafen (@ NotNull GuildVoiceDeafenEvent event ) {
348+ public void onGuildVoiceDeafen (GuildVoiceDeafenEvent event ) {
347349 AudioChannelUnion channel = event .getVoiceState ().getChannel ();
348350
349351 if (channel == null ) {
@@ -380,10 +382,24 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
380382
381383 logger .debug ("Received slash command '{}' (#{}) on guild '{}'" , name , event .getId (),
382384 event .getGuild ());
383- COMMAND_SERVICE .execute (
384- () -> requireUserInteractor (UserInteractionType .SLASH_COMMAND .getPrefixedName (name ),
385+ COMMAND_SERVICE .execute (() -> {
386+ try {
387+ requireUserInteractor (UserInteractionType .SLASH_COMMAND .getPrefixedName (name ),
385388 SlashCommand .class )
386- .onSlashCommand (event ));
389+ .onSlashCommand (event );
390+
391+
392+ analyticsService .recordCommandSuccess (event .getChannel ().getIdLong (), name ,
393+ event .getUser ().getIdLong ());
394+ } catch (Exception ex ) {
395+
396+ analyticsService .recordCommandFailure (event .getChannel ().getIdLong (), name ,
397+ event .getUser ().getIdLong (),
398+ ex .getMessage () != null ? ex .getMessage () : ex .getClass ().getSimpleName ());
399+
400+ throw ex ;
401+ }
402+ });
387403 }
388404
389405 @ Override
0 commit comments