From 158ed0372faa3219dbb99a59e2a3ca234de60862 Mon Sep 17 00:00:00 2001
From: guilevi <guilevi2000@gmail.com>
Date: Wed, 7 Apr 2021 01:33:47 +0200
Subject: [PATCH] Implement api.output, announcevoice command, a bunch of other
 tts shit, etc etc etc buh

---
 .gitignore                   |   3 ++-
 index.js                     |  19 ++++++++++++++++---
 modules/.DS_Store            | Bin 6148 -> 8196 bytes
 modules/ttsSettings/index.js |  18 ++++++++++++++++++
 modules/welcomer/index.js    |   2 +-
 tts/BaseEngine/index.js      |   7 ++++++-
 tts/espeak/index.js          |   5 ++++-
 tts/gtranslate/index.js      |   5 ++++-
 tts/watson/index.js          |  12 ++++++++++--
 9 files changed, 61 insertions(+), 10 deletions(-)
 create mode 100644 modules/ttsSettings/index.js

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 db591ff990f23d97b63e4775ad9d1ea66c5c4cab..5be33a5d064704a25ec7c7af4a35df2b168ec20f 100644
GIT binary patch
delta 354
zcmZoMXmOBWU|?W$DortDU;r^WfEYvza8E20o2aMAD6}zPH}hr%jz7$c**Q2SHn1=X
zP0nW(+pNSggHfEDp#%tv8G;#7!K_S%Jce|J;>o93uhrv_%Sks3PR`FQ0NMcqI8^55
zySOCf<R<}@aRe=!r`XPS*b&IasX7HkwFiFX1sTLTWAkd(7^aO4woHP|5C=<e18G-K
l5N#IZ_|80;U&M2=KMw~7BP8?~Cdczkn{3T~W@CdD69D(5OT+*G

delta 109
zcmZp1XfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~50$jGxXU^g=(&*XeTvCT>XGZ;75
v3i~oGX6N7#WCkh&0s(Fy;R@2RvG6<dWPTY>kbVXxh*==x88*lB%wYxq?$8lz

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;