const Discord = require('discord.js'); const Voice = require("@discordjs/voice"); const adapterCreator = require("./adapter"); require('dotenv').config(); const fetch = require('node-fetch'); const fs = require('fs'); const sha1 = require('sha1'); const sqlite3 = require('sqlite3'); const { open } = require('sqlite') let joinedVoiceChannels = []; let joinedVoiceChannelConnections = new Map(); let modules = []; let commandHandlers = new Map(); const player = Voice.createAudioPlayer(); const rest = new Discord.REST({ version: '10' }).setToken(process.env["TOKEN"]); const bot = new Discord.Client({ intents: [ Discord.GatewayIntentBits.GuildMembers, Discord.GatewayIntentBits.GuildMessageReactions, Discord.GatewayIntentBits.GuildMessages, Discord.GatewayIntentBits.GuildPresences, Discord.GatewayIntentBits.GuildVoiceStates, Discord.GatewayIntentBits.Guilds, Discord.GatewayIntentBits.MessageContent ] }); async function initDB() { console.log(__dirname); api.db = await open({ filename: process.env["DB_FILE"], driver: sqlite3.Database }); } const api = { player: player, db: undefined, queue: undefined, strings: require('./strings/' + process.env.STRING_SET + '.json'), ttsEngines: (() => { let engines = {}; console.log(`Registering TTS engines...`); const engineDirectories = fs.readdirSync('./tts'); engineDirectories.forEach((dir) => { if (dir.startsWith('.')) return; eng = require(`./tts/${dir}/index.js`); engines[dir] = new eng; console.log(`Loading ./tts/${dir}/index.js`) }) return engines; })(), announcementVoice: process.env.ANNOUNCEMENT_VOICE, announcementEngine: undefined, play: (file) => { return player.play(Voice.createAudioResource(file)); }, respond: (message, text, voiceText) => { let toSend = message.member.displayName + ", " + (voiceText ? voiceText : text); if (message.member.voice.channel) { api.queue.add(__dirname + "/sysmsg.wav"); api.speak(message.member.voice.channel, toSend); } else { message.reply(text); } }, getActiveVoiceChannel: () => joinedVoiceChannels[0], isInVoiceChannel: (channel) => { return joinedVoiceChannels.includes(channel); }, getConnectionForVoiceChannel: (channel) => { return joinedVoiceChannelConnections.get(channel); }, generateVoice: async (string, engine, voice, params) => { const hash = sha1(voice + string); const filepath = process.env.VOICE_TMP_PATH + hash + '.' + engine.fileExtension; if (!fs.existsSync(filepath)) { await engine.getSpeechFile(string, filepath, voice, params); } return filepath; }, joinChannel: async (channel) => { if (!api.isInVoiceChannel(channel)) { const res = Voice.joinVoiceChannel({ channelId: channel.id, guildId: channel.guild.id, adapterCreator: adapterCreator(channel) }); res.subscribe(player); joinedVoiceChannels.push(channel); joinedVoiceChannelConnections.set(channel, res); } }, leaveChannel: async (channel) => { if (joinedVoiceChannels.includes(channel)) { let con = joinedVoiceChannelConnections.get(channel); joinedVoiceChannels = joinedVoiceChannels.filter((chan) => chan !== channel); con.disconnect(); joinedVoiceChannelConnections.delete(channel); } }, speak: async (channel, message, engine = api.announcementEngine, voice = api.announcementVoice, params = {}) => { const filepath = await api.generateVoice(message, engine, voice, params); api.queue.add(filepath); }, registerCommand: async (commandString, commandFunc) => { commandHandlers.set(commandString, commandFunc); } } function registerModules() { console.log(`Registering modules...`); const moduleDirectories = fs.readdirSync('./modules'); moduleDirectories.forEach((dir) => { if (dir.startsWith('.')) return; modules.push(require(`./modules/${dir}`)); console.log(`Loading ./modules/${dir}/index.js`) }) modules.forEach((mod) => mod(bot, api)); } function handleMessage(message) { console.log(`I got message`); if (message.content.startsWith(process.env.PREFIX)) { const args = message.content.split(" "); const command = args[0].substr(1, args[0].length); const execution = commandHandlers.get(command); if (command) { if (execution) execution(args, message); } } } api.announcementEngine = api.ttsEngines[process.env.ANNOUNCEMENT_ENGINE]; async function start() { await initDB(); registerModules(); } bot.login(process.env.TOKEN); bot.on('messageCreate', handleMessage); start();