11import Bun from "bun" ;
22import { heapStats } from "bun:jsc" ;
33import {
4+ ApplicationCommandOptionType ,
45 ApplicationCommandType ,
56 AutocompleteInteraction ,
67 ChannelType ,
@@ -15,7 +16,6 @@ import { PermissionFlagsBits } from "discord-api-types/v8";
1516
1617import checkIfChannelIdIsValid from "./utils/youtube/checkIfChannelIdIsValid" ;
1718import {
18- addNewGuildToTrackChannel ,
1919 getAllTrackedInGuild ,
2020 stopGuildTrackingChannel ,
2121 twitchAddNewChannelToTrack ,
@@ -31,8 +31,11 @@ import {
3131 addNewChannelToTrack ,
3232} from "./utils/db/youtube" ;
3333import search from "./utils/youtube/search" ;
34- import { checkIfGuildIsTrackingUserAlready } from "./utils/db/discord" ;
35- import { Platform } from "./types/types.d" ;
34+ import {
35+ checkIfGuildIsTrackingUserAlready ,
36+ discordAddGuildTrackingUser ,
37+ } from "./utils/db/discord" ;
38+ import { Platform , YouTubeContentType } from "./types/types.d" ;
3639
3740import client from "." ;
3841
@@ -165,41 +168,73 @@ const commands: Record<string, Command> = {
165168 data : {
166169 options : [
167170 {
168- name : "platform" ,
169- description : "Select a supported platform to track" ,
170- type : 3 ,
171- required : true ,
172- choices : [
171+ type : ApplicationCommandOptionType . Subcommand ,
172+ name : "youtube" ,
173+ description : "Track a YouTube channel" ,
174+ options : [
173175 {
174- name : "Twitch" ,
175- value : "twitch" ,
176+ type : ApplicationCommandOptionType . String ,
177+ name : "channel_id" ,
178+ description : "Enter the YouTube channel ID" ,
179+ required : true ,
180+ autocomplete : true ,
176181 } ,
177182 {
178- name : "YouTube" ,
179- value : "youtube" ,
183+ type : ApplicationCommandOptionType . Integer ,
184+ name : "content_type" ,
185+ description : "Select what content to track" ,
186+ required : true ,
187+ choices : [
188+ { name : "Videos Only" , value : 1 } ,
189+ { name : "Shorts Only" , value : 2 } ,
190+ { name : "Streams Only" , value : 4 } ,
191+ { name : "Videos & Shorts" , value : 3 } ,
192+ { name : "Videos & Streams" , value : 5 } ,
193+ { name : "Shorts & Streams" , value : 6 } ,
194+ { name : "Videos, Shorts, Streams" , value : 7 } ,
195+ ] ,
196+ } ,
197+ {
198+ type : ApplicationCommandOptionType . Channel ,
199+ name : "updates_channel" ,
200+ description :
201+ "Channel to receive updates. If not specified, the current channel will be used." ,
202+ required : false ,
203+ } ,
204+ {
205+ type : ApplicationCommandOptionType . Role ,
206+ name : "role" ,
207+ description : "Role to mention (optional)" ,
208+ required : false ,
180209 } ,
181210 ] ,
182211 } ,
183212 {
184- name : "user_id" ,
185- description :
186- "Enter the YouTube channel ID or Twitch Streamer to track" ,
187- type : 3 ,
188- required : true ,
189- autocomplete : true ,
190- } ,
191- {
192- name : "updates_channel" ,
193- description :
194- "Enter the Guild channel to receive updates in." ,
195- type : 7 ,
196- required : false ,
197- } ,
198- {
199- name : "role" ,
200- description : "Enter the role to mention (optional)" ,
201- type : 8 ,
202- required : false ,
213+ type : 1 ,
214+ name : "twitch" ,
215+ description : "Track a Twitch streamer" ,
216+ options : [
217+ {
218+ type : ApplicationCommandOptionType . String ,
219+ name : "streamer_id" ,
220+ description : "Enter the Twitch streamer username" ,
221+ required : true ,
222+ autocomplete : true ,
223+ } ,
224+ {
225+ type : ApplicationCommandOptionType . Channel ,
226+ name : "updates_channel" ,
227+ description :
228+ "Channel to receive updates. If not specified, the current channel will be used." ,
229+ required : false ,
230+ } ,
231+ {
232+ type : ApplicationCommandOptionType . Role ,
233+ name : "role" ,
234+ description : "Role to mention (optional)" ,
235+ required : false ,
236+ } ,
237+ ] ,
203238 } ,
204239 ] ,
205240 name : "track" ,
@@ -210,10 +245,13 @@ const commands: Record<string, Command> = {
210245 } ,
211246 execute : async ( interaction : CommandInteraction ) => {
212247 // Get the YouTube Channel ID
213- const targetPlatform = interaction . options . get ( "platform" )
214- ?. value as string ;
215- const platformUserId = interaction . options . get ( "user_id" )
216- ?. value as string ;
248+ const targetPlatform = (
249+ interaction as ChatInputCommandInteraction
250+ ) . options . getSubcommand ( ) ;
251+ const platformUserId =
252+ targetPlatform === "youtube"
253+ ? ( interaction . options . get ( "channel_id" ) ?. value as string )
254+ : ( interaction . options . get ( "streamer_id" ) ?. value as string ) ;
217255 const discordChannelId =
218256 ( interaction . options . get ( "updates_channel" ) ?. value as string ) ??
219257 interaction . channelId ;
@@ -250,7 +288,9 @@ const commands: Record<string, Command> = {
250288 }
251289
252290 // TODO: Enable DMs :)
253- if ( ! guildId || interaction . channel ?. isDMBased ( ) ) {
291+ const isDm = interaction . channel ?. isDMBased ( ) ;
292+
293+ if ( ! guildId || isDm || isDm === undefined ) {
254294 await interaction . reply ( {
255295 flags : MessageFlags . Ephemeral ,
256296 content :
@@ -339,6 +379,18 @@ const commands: Record<string, Command> = {
339379
340380 switch ( targetPlatform ) {
341381 case "youtube" : {
382+ const contentType = interaction . options . get ( "content_type" )
383+ ?. value as number ;
384+
385+ if ( ! contentType ) {
386+ await interaction . reply ( {
387+ flags : MessageFlags . Ephemeral ,
388+ content : "Please specify a valid content type!" ,
389+ } ) ;
390+
391+ return ;
392+ }
393+
342394 // Check that the channel ID is in a valid format
343395 if (
344396 platformUserId . length != 24 ||
@@ -363,14 +415,40 @@ const commands: Record<string, Command> = {
363415 return ;
364416 }
365417
418+ // Check content type
419+ const shouldTrackVideos =
420+ ( contentType & YouTubeContentType . Videos ) !== 0 ;
421+ const shouldTrackShorts =
422+ ( contentType & YouTubeContentType . Shorts ) !== 0 ;
423+ const shouldTrackStreams =
424+ ( contentType & YouTubeContentType . Streams ) !== 0 ;
425+
426+ console . log ( `Tracking Videos: ${ shouldTrackVideos } ` ) ;
427+ console . log ( `Tracking Shorts: ${ shouldTrackShorts } ` ) ;
428+ console . log ( `Tracking Streams: ${ shouldTrackStreams } ` ) ;
429+
430+ // Optional: prevent empty tracking (e.g., bitmask = 0)
431+ if (
432+ ! shouldTrackVideos &&
433+ ! shouldTrackShorts &&
434+ ! shouldTrackStreams
435+ ) {
436+ await interaction . reply ( {
437+ flags : MessageFlags . Ephemeral ,
438+ content : `You must select at least one type of content to track.` ,
439+ } ) ;
440+
441+ return ;
442+ }
443+
444+ // Check if the channel is already being tracked in the guild
366445 const trackedChannels =
367446 await checkIfGuildIsTrackingUserAlready (
368447 Platform . YouTube ,
369448 platformUserId ,
370449 guildId ,
371450 ) ;
372451
373- // Check if the channel is already being tracked in the guild
374452 console . log ( trackedChannels ) ;
375453 if ( ! trackedChannels || ! trackedChannels . success ) {
376454 // TODO: Embed
@@ -394,14 +472,35 @@ const commands: Record<string, Command> = {
394472 }
395473
396474 // Check if the channel is already being tracked globally
397- if (
398- ! ( await checkIfChannelIsAlreadyTracked ( platformUserId ) )
475+ const isChannelTracked =
476+ await checkIfChannelIsAlreadyTracked ( platformUserId ) ;
477+
478+ console . log (
479+ `Is channel ${ platformUserId } tracked globally?` ,
480+ isChannelTracked ,
481+ ) ;
482+
483+ if ( ! isChannelTracked . success ) {
484+ await interaction . reply ( {
485+ flags : MessageFlags . Ephemeral ,
486+ content :
487+ "An error occurred while trying to check if the channel is already being tracked globally! Please report this error!" ,
488+ } ) ;
489+ } else if (
490+ isChannelTracked . success &&
491+ isChannelTracked . data . length == 0
399492 ) {
400- if ( ! ( await addNewChannelToTrack ( platformUserId ) ) ) {
493+ console . log (
494+ `Channel ${ platformUserId } is not tracked globally, adding it now...` ,
495+ ) ;
496+ const channelAdded =
497+ await addNewChannelToTrack ( platformUserId ) ;
498+
499+ if ( ! channelAdded . success ) {
401500 await interaction . reply ( {
402501 flags : MessageFlags . Ephemeral ,
403502 content :
404- "An error occurred while trying to add the channel to track! This is a new channel being tracked globally, please report this error !" ,
503+ "An error occurred while trying to add the channel to track to the main YouTube database. Please report this issue !" ,
405504 } ) ;
406505
407506 return ;
@@ -410,12 +509,17 @@ const commands: Record<string, Command> = {
410509
411510 // Add the guild to the database
412511 if (
413- await addNewGuildToTrackChannel (
512+ await discordAddGuildTrackingUser (
414513 guildId ,
514+ Platform . YouTube ,
415515 platformUserId ,
416516 discordChannelId ,
417517 ( interaction . options . get ( "role" )
418518 ?. value as string ) ?? null ,
519+ isDm ,
520+ shouldTrackVideos ,
521+ shouldTrackShorts ,
522+ shouldTrackStreams ,
419523 )
420524 ) {
421525 const youtubeChannelInfo =
@@ -521,7 +625,7 @@ const commands: Record<string, Command> = {
521625 autoComplete : async ( interaction : AutocompleteInteraction ) => {
522626 try {
523627 const platform = interaction . options . get ( "platform" ) ?. value ;
524- const query = interaction . options . get ( "user_id " ) ?. value ;
628+ const query = interaction . options . get ( "channel_id " ) ?. value ;
525629
526630 // If the query is empty or not a string, return an empty array
527631 if ( ! query || typeof query !== "string" ) {
0 commit comments