diff --git a/.gitignore b/.gitignore index 6f22041..3ce9093 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules voice_tmp .env -*.db \ No newline at end of file +*.db +.ds_store \ No newline at end of file diff --git a/index.js b/index.js index 3e27dbb..5186a81 100644 --- a/index.js +++ b/index.js @@ -27,6 +27,17 @@ const api = { }) return engines; })(), + 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); + } + }, isInVoiceChannel: (channel) => { return joinedVoiceChannels.includes(channel); @@ -59,7 +70,7 @@ const api = { } }, - speak: async (channel, message, engine=api.ttsEngines.gtranslate, voice='en-us', params={}) => { + speak: async (channel, message, engine=api.announcementEngine, voice=api.announcementVoice, params={}) => { const conn = api.getConnectionForVoiceChannel(channel); const filepath = await api.generateVoice(message, engine, voice, params); if (conn) conn.play(filepath); @@ -83,15 +94,17 @@ function registerModules() { function handleMessage(message) { if (message.content.startsWith(process.env.PREFIX)) { - const args = message.contents.split(" "); + const args = message.content.split(" "); const command = args[0].substr(1, args[0].length); const execution = commandHandlers.get(command); if (command) { - command(args, message); + if(execution) execution(args, message); } } } + +api.announcementEngine = api.ttsEngines[process.env.ANNOUNCEMENT_ENGINE]; registerModules(); bot.login(process.env.TOKEN); bot.on('message', handleMessage); \ No newline at end of file diff --git a/modules/.DS_Store b/modules/.DS_Store index db591ff..5be33a5 100644 Binary files a/modules/.DS_Store and b/modules/.DS_Store differ diff --git a/modules/ttsSettings/index.js b/modules/ttsSettings/index.js new file mode 100644 index 0000000..1c52379 --- /dev/null +++ b/modules/ttsSettings/index.js @@ -0,0 +1,18 @@ +module.exports = function(bot, api) { + api.registerCommand('announcevoice', (args, message) => { + let channel = bot.voice.connections.first().channel; + if(args.length>3) { + return api.respond(message, "You tried to change my voice with too many arguments."); + } + if(api.ttsEngines[args[1]]) { + api.announcementEngine=api.ttsEngines[args[1]]; + if(api.announcementEngine.validateVoice(args[2])) { + api.announcementVoice=args[2]; + api.respond(message, "My new voice is "+api.announcementVoice+" from "+api.announcementEngine.longName); + } else { + api.announcementVoice=api.announcementEngine.getDefaultVoice(); + api.respond(message, "Your voice name was invalid, so I switched to the default voice ("+api.announcementVoice+") for "+api.announcementEngine.longName+" instead."); + } + } + }); +} \ No newline at end of file diff --git a/modules/welcomer/index.js b/modules/welcomer/index.js index e3ba7d0..9dba07a 100644 --- a/modules/welcomer/index.js +++ b/modules/welcomer/index.js @@ -5,6 +5,6 @@ module.exports = function(bot, api) { const channel = await bot.channels.fetch(process.env.CHANNEL); await api.joinChannel(channel); - api.speak(channel, `Hi! I'm alive. It is now ${new Date().toLocaleTimeString()} on ${new Date().toLocaleDateString()}`,api.ttsEngines.espeak, "en"); + api.speak(channel, `Hey buddies! How does it feel like to be a buddy? Are you proud of being a buddy? Well that's great!'`); }) } \ No newline at end of file diff --git a/tts/BaseEngine/index.js b/tts/BaseEngine/index.js index 4a9aa73..351feb3 100644 --- a/tts/BaseEngine/index.js +++ b/tts/BaseEngine/index.js @@ -5,7 +5,12 @@ module.exports=class { this.longName=longName; this.fileExtension=fileExtension; } - async getSpeech(text, voice, params) {} + getInternalVoiceName(str) { + return this.voices?this.voices[str]:str; + } + getDefaultVoice() {} + validateVoice(voice) {return this.voices ? this.voices[voice] : true;} + async getSpeech(text, voice=this.getDefaultVoice(), params) {} async getSpeechFile(text, filepath, voice, params) { const data = await this.getSpeech(text, voice, params); const contents = await data.arrayBuffer(); diff --git a/tts/espeak/index.js b/tts/espeak/index.js index 9ff980c..bec0bf6 100644 --- a/tts/espeak/index.js +++ b/tts/espeak/index.js @@ -5,7 +5,10 @@ module.exports=class extends BaseEngine { constructor() { super('ESpeak','wav') } - async getSpeechFile(text, filepath, voice='en', params={}) { + getDefaultVoice() { + return 'en'; + } + async getSpeechFile(text, filepath, voice=this.getDefaultVoice(), params={}) { let proc=await spawn('espeak', ['-v', voice, '-w',filepath, '--stdin']); proc.stdin.end(text); } diff --git a/tts/gtranslate/index.js b/tts/gtranslate/index.js index 5847aba..ab4174e 100644 --- a/tts/gtranslate/index.js +++ b/tts/gtranslate/index.js @@ -6,7 +6,10 @@ module.exports= class extends BaseEngine { constructor() { super("Google Translate TTS","mp3"); } - async getSpeech(text, voice='en-us', params={}) { + getDefaultVoice() { + return 'en-us'; + } + async getSpeech(text, voice=this.getDefaultVoice(), params={}) { const url = tts.getAudioUrl(text, {lang: voice}); return fetch(url); } diff --git a/tts/watson/index.js b/tts/watson/index.js index 8511727..0188876 100644 --- a/tts/watson/index.js +++ b/tts/watson/index.js @@ -5,9 +5,17 @@ const querystring = require('querystring'); module.exports= class extends BaseEngine { constructor() { super("IBM Watson TTS","ogg"); + this.voices={ + 'Michael': 'en-US_MichaelV3Voice', + 'Allison': 'en-US_AllisonV3Voice', + 'Kevin': 'en-US_KevinV3Voice', + }; } - async getSpeech(text, voice='en-us', params={}) { - const url = process.env.watsonURL+"/v1/synthesize"; + getDefaultVoice() { + return 'Michael'; + } + async getSpeech(text, voice=this.getSpeechVoice(), params={}) { + const url = process.env.watsonURL+"/v1/synthesize?voice="+this.getInternalVoiceName(voice); let buff=new Buffer('apikey:'+process.env.watsonAPIKey); let b64auth=buff.toString('base64'); const authorization='Basic '+b64auth;