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