1+ import { ClusterClient , GatewayClientEvents } from "detritus-client" ;
2+ import { MessageComponentTypes } from "detritus-client/lib/constants" ;
13import { User } from "detritus-client/lib/structures" ;
2- import { Signale , Webhooks } from "." ;
4+ import { Embed } from "detritus-client/lib/utils" ;
5+ import { Config , getGuild , InteractionBot , Signale , Webhooks } from "." ;
6+ import { VCNotifyToggleButtonComponent } from "./Components" ;
37
48/**
59 * @key userId of the user to watch out for
@@ -33,10 +37,12 @@ class VCNotifyManagerClass {
3337 // If a user is already watching for this person, disable the notification
3438 if ( typeof vswIndex !== "undefined" ) {
3539 this . watchers . splice ( vswIndex , 1 ) ;
40+ this . logToggle ( watchedId , notifiedId , false ) ;
3641
3742 return false ;
3843 } else {
3944 this . watchers . push ( [ watchedId , notifiedId ] ) ;
45+ this . logToggle ( watchedId , notifiedId , true ) ;
4046
4147 return true ;
4248 }
@@ -59,14 +65,51 @@ class VCNotifyManagerClass {
5965 }
6066 }
6167
62- logToggle ( watched : User , notified : User , active : boolean ) {
68+ logToggle ( watchedId : string , notifiedId : string , active : boolean ) {
69+ const client = ( InteractionBot . client as ClusterClient ) . shards . first ( ) ! ;
70+ const watched = client . users . get ( watchedId ) ;
71+ const notified = client . users . get ( notifiedId ) ;
72+
73+ if ( ! watched || ! notified ) {
74+ Signale . info ( {
75+ prefix : "vcNotify" ,
76+ message : `${ notifiedId } - VC Notification toggled to "${ active } " for ${ watchedId } ` ,
77+ } ) ;
78+
79+ Webhooks . execute ( Webhooks . ids . vcNotifyLog , {
80+ avatarUrl : client . user ! . avatarUrl ,
81+ embed : {
82+ title : `VC Notification Toggled` ,
83+ fields : [
84+ {
85+ name : "Active" ,
86+ value : String ( active ) ,
87+ inline : true ,
88+ } ,
89+ {
90+ name : "User" ,
91+ value : `<@${ notifiedId } >` ,
92+ inline : true ,
93+ } ,
94+ {
95+ name : "Watching for" ,
96+ value : `<@${ watchedId } >` ,
97+ inline : true ,
98+ } ,
99+ ] ,
100+ } ,
101+ } ) ;
102+
103+ return ;
104+ }
105+
63106 Signale . info ( {
64107 prefix : "vcNotify" ,
65108 message : `${ notified . name } #${ notified . discriminator } - VC Notification toggled to "${ active } " for ${ watched . name } #${ watched . discriminator } ` ,
66109 } ) ;
67110
68111 Webhooks . execute ( Webhooks . ids . vcNotifyLog , {
69- avatarUrl : watched . client . user ? .avatarUrl ,
112+ avatarUrl : client . user ! . avatarUrl ,
70113 embed : {
71114 title : `VC Notification Toggled` ,
72115 author : {
@@ -88,6 +131,92 @@ class VCNotifyManagerClass {
88131 } ,
89132 } ) ;
90133 }
134+
135+ /**
136+ * Resolves everything related to VC notifications with the given VoiceStateUpdate event
137+ *
138+ * @param {GatewayClientEvents.VoiceStateUpdate } vsu
139+ * @returns void
140+ */
141+ handleVoiceStateUpdate ( vsu : GatewayClientEvents . VoiceStateUpdate ) {
142+ if ( ! vsu . joinedChannel || VCNotifyManager . watchers . length === 0 ) return ;
143+
144+ // Get the channel to post the notification in, if it's unavailable don't continue
145+ let notifyChannel = getGuild ( ) . channels . get ( Config . vcNotifyPingChannelId ) ;
146+ if ( ! notifyChannel ) {
147+ Signale . warn ( {
148+ prefix : "vcnotify" ,
149+ message : "The specified channel for VC notifications couldn't be accessed! No notifications were processed." ,
150+ } ) ;
151+
152+ return ;
153+ }
154+
155+ // Set up an embed for logging
156+ const embed = new Embed ( {
157+ title : "VC Notification Triggered" ,
158+ fields : [
159+ {
160+ name : "Triggered by" ,
161+ value : `<@${ vsu . voiceState . userId } >` ,
162+ inline : true ,
163+ } ,
164+ ] ,
165+ } ) ;
166+
167+ // Loop through all waiting notifications, remove any that match and generate the first part of the message
168+ let notifyString = "" ;
169+ let logUserListString = "" ;
170+ let j = 0 ;
171+
172+ for ( var i = VCNotifyManager . watchers . length ; i -- ; ) {
173+ const [ watchedId , notifiedId ] = VCNotifyManager . watchers [ i ] ;
174+
175+ if ( vsu . voiceState . userId === watchedId ) {
176+ j ++ ;
177+ notifyString += `<@${ notifiedId } > ` ;
178+ logUserListString += `<@${ notifiedId } >\n` ;
179+ VCNotifyManager . watchers . splice ( i , 1 ) ;
180+ }
181+ }
182+
183+ // Nobody wanted to be notified for that user
184+ if ( j === 0 ) return ;
185+
186+ // If more than two people were waiting, format notifyString differently
187+ if ( j <= 2 ) {
188+ notifyString += "- " ;
189+ } else {
190+ notifyString += "\n\n" ;
191+ }
192+
193+ notifyString += `<@${ vsu . voiceState . userId } > has joined <#${ vsu . voiceState . channelId } >. (You will not be notified again.)` ;
194+
195+ notifyChannel . createMessage ( {
196+ content : notifyString ,
197+ components : [
198+ {
199+ type : MessageComponentTypes . ACTION_ROW ,
200+ components : [ new VCNotifyToggleButtonComponent ( vsu . voiceState . userId , true ) ] ,
201+ } ,
202+ ] ,
203+ } ) ;
204+
205+ // Logging
206+ Signale . info ( {
207+ prefix : "vcnotify" ,
208+ message : `VC Notification triggered by ${ vsu . voiceState . member ! . name } #${ vsu . voiceState . member ! . discriminator } ` ,
209+ } ) ;
210+
211+ const client = ( InteractionBot . client as ClusterClient ) . shards . first ( ) ! ;
212+
213+ embed . addField ( "Notified Users" , logUserListString , true ) ;
214+
215+ Webhooks . execute ( Webhooks . ids . vcNotifyLog , {
216+ avatarUrl : client . user ! . avatarUrl ,
217+ embed,
218+ } ) ;
219+ }
91220}
92221
93222export const VCNotifyManager = new VCNotifyManagerClass ( ) ;
0 commit comments