2021-04-05 13:50:51 +00:00
|
|
|
const Discord = require('discord.js');
|
|
|
|
require('dotenv').config();
|
|
|
|
const fetch = require('node-fetch');
|
|
|
|
const fs = require('fs');
|
|
|
|
const sha1 = require('sha1');
|
2021-04-09 01:00:55 +00:00
|
|
|
const sqlite3 = require('sqlite3');
|
|
|
|
const { open } = require('sqlite')
|
2021-04-05 13:50:51 +00:00
|
|
|
|
|
|
|
let joinedVoiceChannels = [];
|
2021-04-05 14:09:36 +00:00
|
|
|
let modules = [];
|
2021-04-05 17:11:08 +00:00
|
|
|
let commandHandlers = new Map();
|
2021-04-05 13:50:51 +00:00
|
|
|
|
2021-04-05 15:49:04 +00:00
|
|
|
const bot = new Discord.Client();
|
2021-04-05 13:50:51 +00:00
|
|
|
|
2021-04-09 01:00:55 +00:00
|
|
|
async function initDB() {
|
|
|
|
api.db = await open({
|
|
|
|
filename: 'database/tardis.db',
|
|
|
|
driver: sqlite3.Database
|
|
|
|
});
|
|
|
|
}
|
2021-04-05 13:50:51 +00:00
|
|
|
|
2021-04-05 14:09:36 +00:00
|
|
|
const api = {
|
2021-04-09 01:00:55 +00:00
|
|
|
db: undefined,
|
2021-04-06 00:16:09 +00:00
|
|
|
ttsEngines: (() => {
|
2021-04-06 23:36:35 +00:00
|
|
|
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;
|
2021-04-06 00:16:09 +00:00
|
|
|
})(),
|
2021-04-06 23:36:35 +00:00
|
|
|
announcementVoice: process.env.ANNOUNCEMENT_VOICE,
|
|
|
|
announcementEngine: undefined,
|
|
|
|
|
|
|
|
respond: (message, text, voiceText) => {
|
|
|
|
let toSend = message.member.displayName + ", " + (voiceText ? voiceText : text);
|
|
|
|
if (message.member.voice.channel) {
|
|
|
|
api.speak(message.member.voice.channel, toSend);
|
|
|
|
} else {
|
|
|
|
message.reply(text);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2021-04-05 14:09:36 +00:00
|
|
|
isInVoiceChannel: (channel) => {
|
|
|
|
return joinedVoiceChannels.includes(channel);
|
|
|
|
},
|
|
|
|
|
|
|
|
getConnectionForVoiceChannel: (channel) => {
|
|
|
|
return bot.voice.connections.find((conn) => conn.channel === channel);
|
|
|
|
},
|
|
|
|
|
2021-04-06 00:16:09 +00:00
|
|
|
generateVoice: async (string, engine, voice, params) => {
|
2021-04-06 23:36:35 +00:00
|
|
|
const hash = sha1(voice + string);
|
2021-04-06 00:16:09 +00:00
|
|
|
const filepath = process.env.VOICE_TMP_PATH + hash + '.' + engine.fileExtension;
|
2021-04-05 14:09:36 +00:00
|
|
|
if (!fs.existsSync(filepath)) {
|
2021-04-06 00:16:09 +00:00
|
|
|
await engine.getSpeechFile(string, filepath, voice, params);
|
2021-04-05 14:09:36 +00:00
|
|
|
}
|
|
|
|
return filepath;
|
|
|
|
},
|
2021-04-05 13:50:51 +00:00
|
|
|
|
2021-04-05 14:09:36 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2021-04-06 23:36:35 +00:00
|
|
|
speak: async (channel, message, engine = api.announcementEngine, voice = api.announcementVoice, params = {}) => {
|
2021-04-05 14:09:36 +00:00
|
|
|
const conn = api.getConnectionForVoiceChannel(channel);
|
2021-04-06 00:16:09 +00:00
|
|
|
const filepath = await api.generateVoice(message, engine, voice, params);
|
2021-04-05 14:09:36 +00:00
|
|
|
if (conn) conn.play(filepath);
|
2021-04-05 17:11:08 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
registerCommand: async (commandString, commandFunc) => {
|
|
|
|
commandHandlers.set(commandString, commandFunc);
|
2021-04-05 13:50:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-05 14:09:36 +00:00
|
|
|
function registerModules() {
|
2021-04-06 23:36:35 +00:00
|
|
|
console.log(`Registering modules...`);
|
2021-04-05 14:09:36 +00:00
|
|
|
const moduleDirectories = fs.readdirSync('./modules');
|
|
|
|
moduleDirectories.forEach((dir) => {
|
2021-04-06 23:36:35 +00:00
|
|
|
if (dir.startsWith('.')) return;
|
2021-04-05 14:09:36 +00:00
|
|
|
modules.push(require(`./modules/${dir}/index.js`));
|
|
|
|
console.log(`Loading ./modules/${dir}/index.js`)
|
|
|
|
})
|
|
|
|
modules.forEach((mod) => mod(bot, api));
|
2021-04-05 13:50:51 +00:00
|
|
|
}
|
2021-04-05 14:09:36 +00:00
|
|
|
|
2021-04-05 17:11:08 +00:00
|
|
|
function handleMessage(message) {
|
2021-04-05 21:21:47 +00:00
|
|
|
if (message.content.startsWith(process.env.PREFIX)) {
|
2021-04-06 23:33:47 +00:00
|
|
|
const args = message.content.split(" ");
|
2021-04-05 17:11:08 +00:00
|
|
|
const command = args[0].substr(1, args[0].length);
|
|
|
|
const execution = commandHandlers.get(command);
|
|
|
|
if (command) {
|
2021-04-06 23:36:35 +00:00
|
|
|
if (execution) execution(args, message);
|
2021-04-05 17:11:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-06 23:33:47 +00:00
|
|
|
|
|
|
|
api.announcementEngine = api.ttsEngines[process.env.ANNOUNCEMENT_ENGINE];
|
2021-04-09 01:00:55 +00:00
|
|
|
(async () => {
|
|
|
|
await initDB();
|
|
|
|
registerModules();
|
|
|
|
})()
|
2021-04-05 17:11:08 +00:00
|
|
|
bot.login(process.env.TOKEN);
|
|
|
|
bot.on('message', handleMessage);
|