mirror of
				https://github.com/keanuplayz/TravBot-v3.git
				synced 2024-08-15 02:33:12 +00:00 
			
		
		
		
	Prototyped stream notifications like CheeseBot
This commit is contained in:
		
							parent
							
								
									4012d2e1cd
								
							
						
					
					
						commit
						3362f9fbbe
					
				
					 5 changed files with 128 additions and 0 deletions
				
			
		|  | @ -164,6 +164,26 @@ export default new Command({ | ||||||
|                             }) |                             }) | ||||||
|                         }) |                         }) | ||||||
|                     } |                     } | ||||||
|  |                 }), | ||||||
|  |                 stream: new Command({ | ||||||
|  |                     description: "Set a channel to send stream notifications.", | ||||||
|  |                     async run($) { | ||||||
|  |                         if ($.guild) { | ||||||
|  |                             const guild = Storage.getGuild($.guild.id); | ||||||
|  | 
 | ||||||
|  |                             if (guild.streamingChannel) { | ||||||
|  |                                 guild.streamingChannel = null; | ||||||
|  |                                 $.channel.send("Removed your server's stream notifications channel."); | ||||||
|  |                             } else { | ||||||
|  |                                 guild.streamingChannel = $.channel.id; | ||||||
|  |                                 $.channel.send(`Set your server's stream notifications channel to ${$.channel}.`); | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             Storage.save(); | ||||||
|  |                         } else { | ||||||
|  |                             $.channel.send("You must use this command in a server."); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|         }), |         }), | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								src/commands/utilities/streaminfo.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/commands/utilities/streaminfo.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | import Command from "../../core/command"; | ||||||
|  | import {streamList, getStreamEmbed} from "../../events/voiceStateUpdate"; | ||||||
|  | 
 | ||||||
|  | export default new Command({ | ||||||
|  |     description: "Sets the description of your stream. You can embed links by writing `[some name](some link)`", | ||||||
|  |     async run($) { | ||||||
|  |         const userID = $.author.id; | ||||||
|  | 
 | ||||||
|  |         if (streamList.has(userID)) { | ||||||
|  |             const stream = streamList.get(userID)!; | ||||||
|  |             stream.description = $.args.join(" ") || undefined; | ||||||
|  |             stream.message.edit(getStreamEmbed(stream.streamer, stream.channel, stream.description)); | ||||||
|  |         } else { | ||||||
|  |             // Alternatively, I could make descriptions last outside of just one stream.
 | ||||||
|  |             $.channel.send("You can only use this command when streaming."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  | @ -58,11 +58,13 @@ class Guild { | ||||||
|     public welcomeType: "none" | "text" | "graphical"; |     public welcomeType: "none" | "text" | "graphical"; | ||||||
|     public welcomeChannel: string | null; |     public welcomeChannel: string | null; | ||||||
|     public welcomeMessage: string | null; |     public welcomeMessage: string | null; | ||||||
|  |     public streamingChannel: string | null; | ||||||
| 
 | 
 | ||||||
|     constructor(data?: GenericJSON) { |     constructor(data?: GenericJSON) { | ||||||
|         this.prefix = select(data?.prefix, null, String); |         this.prefix = select(data?.prefix, null, String); | ||||||
|         this.welcomeChannel = select(data?.welcomeChannel, null, String); |         this.welcomeChannel = select(data?.welcomeChannel, null, String); | ||||||
|         this.welcomeMessage = select(data?.welcomeMessage, null, String); |         this.welcomeMessage = select(data?.welcomeMessage, null, String); | ||||||
|  |         this.streamingChannel = select(data?.streamingChannel, null, String); | ||||||
| 
 | 
 | ||||||
|         switch (data?.welcomeType) { |         switch (data?.welcomeType) { | ||||||
|             case "text": |             case "text": | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								src/events/channelUpdate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/events/channelUpdate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | import Event from "../core/event"; | ||||||
|  | import {streamList, getStreamEmbed} from "./voiceStateUpdate"; | ||||||
|  | 
 | ||||||
|  | export default new Event<"channelUpdate">({ | ||||||
|  |     async on(before, after) { | ||||||
|  |         if (before.type === "voice" && after.type === "voice") { | ||||||
|  |             for (const {streamer, channel, description, message} of streamList.values()) { | ||||||
|  |                 if (after.id === channel.id) { | ||||||
|  |                     message.edit(getStreamEmbed(streamer, channel, description)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }); | ||||||
							
								
								
									
										74
									
								
								src/events/voiceStateUpdate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/events/voiceStateUpdate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,74 @@ | ||||||
|  | import {GuildMember, VoiceChannel, MessageEmbed, TextChannel, Permissions, Message, Collection} from "discord.js"; | ||||||
|  | import Event from "../core/event"; | ||||||
|  | import $ from "../core/lib"; | ||||||
|  | import {Storage} from "../core/structures"; | ||||||
|  | import {client} from "../index"; | ||||||
|  | 
 | ||||||
|  | type Stream = { | ||||||
|  |     streamer: GuildMember; | ||||||
|  |     channel: VoiceChannel; | ||||||
|  |     description?: string; | ||||||
|  |     message: Message; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // A list of user IDs and message embeds.
 | ||||||
|  | export const streamList = new Collection<string, Stream>(); | ||||||
|  | 
 | ||||||
|  | // Probably find a better, DRY way of doing this.
 | ||||||
|  | export function getStreamEmbed(streamer: GuildMember, channel: VoiceChannel, description?: string): MessageEmbed { | ||||||
|  |     const user = streamer.user; | ||||||
|  |     const embed = new MessageEmbed() | ||||||
|  |         .setTitle(`Stream: \`#${channel.name}\``) | ||||||
|  |         .setAuthor( | ||||||
|  |             streamer.nickname ?? user.username, | ||||||
|  |             user.avatarURL({ | ||||||
|  |                 dynamic: true, | ||||||
|  |                 format: "png" | ||||||
|  |             }) ?? user.defaultAvatarURL | ||||||
|  |         ) | ||||||
|  |         .setColor(streamer.displayColor); | ||||||
|  | 
 | ||||||
|  |     if (description) { | ||||||
|  |         embed.setDescription(description); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return embed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default new Event<"voiceStateUpdate">({ | ||||||
|  |     async on(before, after) { | ||||||
|  |         const isStartStreamEvent = !before.streaming && after.streaming; | ||||||
|  |         const isStopStreamEvent = before.streaming && (!after.streaming || !after.channel); // If you were streaming before but now are either not streaming or have left the channel.
 | ||||||
|  |         // Note: isStopStreamEvent can be called twice in a row - If Discord crashes/quits while you're streaming, it'll call once with a null channel and a second time with a channel.
 | ||||||
|  | 
 | ||||||
|  |         if (isStartStreamEvent || isStopStreamEvent) { | ||||||
|  |             const {streamingChannel} = Storage.getGuild(after.guild.id); | ||||||
|  | 
 | ||||||
|  |             if (streamingChannel) { | ||||||
|  |                 const member = after.member!; | ||||||
|  |                 const voiceChannel = after.channel!; | ||||||
|  |                 const textChannel = client.channels.cache.get(streamingChannel); | ||||||
|  | 
 | ||||||
|  |                 if (textChannel && textChannel instanceof TextChannel) { | ||||||
|  |                     if (isStartStreamEvent) { | ||||||
|  |                         streamList.set(member.id, { | ||||||
|  |                             streamer: member, | ||||||
|  |                             channel: voiceChannel, | ||||||
|  |                             message: await textChannel.send(getStreamEmbed(member, voiceChannel)) | ||||||
|  |                         }); | ||||||
|  |                     } else if (isStopStreamEvent) { | ||||||
|  |                         if (streamList.has(member.id)) { | ||||||
|  |                             const {message} = streamList.get(member.id)!; | ||||||
|  |                             message.delete(); | ||||||
|  |                             streamList.delete(member.id); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     $.error( | ||||||
|  |                         `The streaming notifications channel ${streamingChannel} for guild ${after.guild.id} either doesn't exist or isn't a text channel.` | ||||||
|  |                     ); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | }); | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue