Skip to content

Instantly share code, notes, and snippets.

@hyoretsu
Created January 6, 2024 03:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hyoretsu/c8e895a37b2134f95527120cb52f0817 to your computer and use it in GitHub Desktop.
Save hyoretsu/c8e895a37b2134f95527120cb52f0817 to your computer and use it in GitHub Desktop.
Maple Helper's MVP Reminder Command (TTS in Voice Chat Example)
import {
AudioPlayerStatus,
VoiceConnectionStatus,
createAudioPlayer,
createAudioResource,
joinVoiceChannel,
} from "@discordjs/voice";
import { sleep } from "@hyoretsu/utils";
import { Guild, GuildMember, SlashCommandBuilder, VoiceChannel } from "discord.js";
import * as googleTTS from "google-tts-api";
import fs from "node:fs";
import path from "node:path";
import { Command } from "../@types";
import tts from "../utils/tts";
const mvpReminderCommand: Command = {
data: new SlashCommandBuilder()
.setName("mvp_reminder")
.setDescription("Starts the MVP bot by hopping into a voice channel.")
.addStringOption(option =>
option
.setName("streamer")
.setDescription("The twitch user that will be streaming and providing data to the bot.")
.setRequired(true),
)
.addChannelOption(option =>
option
.setName("channel")
.setDescription("The channel that will be used. Defaults to your current one."),
)
.addNumberOption(option =>
option
.setName("resolution")
.setDescription("The resolution of MapleStory. Defaults to 1920x1080.")
.addChoices(
{
name: "800x600",
value: 0,
},
{
name: "1024x768",
value: 1,
},
{
name: "1280x720",
value: 2,
},
{
name: "1366x768",
value: 3,
},
{
name: "1920x1080",
value: 4,
},
),
)
.addStringOption(option =>
option.setName("chat-lines").setDescription("The amount of lines being shown in the streamer's chat."),
)
.addNumberOption(option =>
option.setName("font-size").setDescription("The in-game font size you're using.").addChoices(
{
name: "Default",
value: 0,
},
{
name: "Medium",
value: 1,
},
{
name: "Big",
value: 2,
},
{
name: "Large",
value: 3,
},
),
),
async execute(interaction) {
const { id: guildId, voiceAdapterCreator: adapterCreator } = interaction.guild as Guild;
const voiceChannel = (interaction.options.getChannel("channel") ??
(interaction.member as GuildMember).voice.channel) as VoiceChannel | null;
if (!voiceChannel) {
await interaction.reply({
content: "Invalid channel. Try again. (Join a voice channel or send one in the options)",
ephemeral: true,
});
return;
}
const { id: channelId } = voiceChannel;
await interaction.reply({ content: "Hopping on for your grinding's joy.", ephemeral: true });
const connection = joinVoiceChannel({
channelId,
guildId,
adapterCreator,
});
// Clean up generated reminder files on disconnection
connection.on(VoiceConnectionStatus.Disconnected, async () => {
fs.rm(
path.resolve("./tmp"),
{
force: true,
recursive: true,
},
() => {},
);
});
const player = createAudioPlayer();
// Subscribe the connection to the audio player (will play audio on the voice connection)
connection.subscribe(player);
const messagePath = await tts("MVP in 1 minute at channel 22", guildId);
const message = createAudioResource(messagePath);
// voiceChannel.priority
player.play(message);
// Remove later on
player.on(AudioPlayerStatus.Idle, () => connection.disconnect());
},
};
export default mvpReminderCommand;
import * as googleTTS from "google-tts-api";
import fs from "node:fs";
import path from "node:path";
export default async function tts(text: string, guildId: string): Promise<string> {
if (!fs.existsSync("./tmp")) {
fs.mkdirSync("./tmp");
}
const timestamp = new Date().getTime();
const filePath = path.resolve(`./tmp/${guildId}-${timestamp}.mp3`);
fs.writeFileSync(
filePath,
await googleTTS.getAudioBase64(text, {
lang: "pt",
slow: false,
}),
"base64",
);
return filePath;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment