const Discord = require('discord.js'); require('dotenv').config(); const fetch = require('node-fetch'); const fs = require('fs'); const sha1 = require('sha1'); const sqlite = require('sqlite3'); let joinedVoiceChannels = []; let modules = []; let commandHandlers = new Map(); const bot = new Discord.Client(); const db = new sqlite.Database(process.env.DB_FILE); const api = { db: db, 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; })(), isInVoiceChannel: (channel) => { return joinedVoiceChannels.includes(channel); }, getConnectionForVoiceChannel: (channel) => { return bot.voice.connections.find((conn) => conn.channel === 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 = await channel.join(); joinedVoiceChannels.push(channel); } }, leaveChannel: async (channel) => { if (joinedVoiceChannels.includes(channel)) { joinedVoiceChannels = joinedVoiceChannels.filter((chan) => chan !== channel); await channel.leave(); } }, speak: async (channel, message, engine=api.ttsEngines.gtranslate, voice='en-us', params={}) => { const conn = api.getConnectionForVoiceChannel(channel); const filepath = await api.generateVoice(message, engine, voice, params); if (conn) conn.play(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}/index.js`)); console.log(`Loading ./modules/${dir}/index.js`) }) modules.forEach((mod) => mod(bot, api)); } function handleMessage(message) { if (message.contents.startsWith(process.env.PREFIX)) { const args = message.contents.split(" "); const command = args[0].substr(1, args[0].length); const execution = commandHandlers.get(command); if (command) { command(args, message); } } } registerModules(); bot.login(process.env.TOKEN); bot.on('message', handleMessage);