Last active
March 9, 2020 19:29
-
-
Save chromakode/7e18e4623b4f1c5e7db071b0a17f1d7e to your computer and use it in GitHub Desktop.
A star trek questions Discord bot using Wavenet TTS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs').promises | |
const sample = require('lodash/sample') | |
const intoStream = require('into-stream') | |
const Discord = require('discord.js') | |
const textToSpeech = require('@google-cloud/text-to-speech') | |
const tts = new textToSpeech.TextToSpeechClient() | |
function waitFor(emitter, event) { | |
return new Promise(resolve => emitter.once(event, resolve)) | |
} | |
function sleep(ms) { | |
return new Promise(resolve => setTimeout(resolve, ms)) | |
} | |
async function speechStream(args) { | |
const response = await tts.synthesizeSpeech(args) | |
return intoStream(response[0].audioContent) | |
} | |
async function main() { | |
const questionsText = await fs.readFile('./qs.json') | |
const questions = JSON.parse(questionsText) | |
const client = new Discord.Client() | |
client.login(process.env.DISCORD_TOKEN) | |
await waitFor(client, 'ready') | |
console.log('ready') | |
const guild = client.guilds.get(process.env.DISCORD_GUILD) | |
const gen = guild.channels.find(c => c.type === 'text' && c.name === 'General') | |
const vc = guild.channels.find(c => c.type === 'voice' && c.name === 'General') | |
const withVoice = async cb => { | |
const voiceConn = await vc.join() | |
const play = path => waitFor(voiceConn.playFile(path), 'end') | |
const say = async text => { | |
const stream = await speechStream({ | |
input: {text}, | |
voice: {languageCode: 'en-US', name: 'en-AU-Wavenet-C'}, | |
audioConfig: {audioEncoding: 'OGG_OPUS'}, | |
}) | |
return waitFor(voiceConn.playStream(stream), 'end') | |
} | |
await cb({play, say}) | |
voiceConn.disconnect() | |
} | |
const trekQuestion = () => withVoice(async ({play, say}) => { | |
const {q, as} = sample(questions) | |
await play('incoming_hail3.mp3') | |
await say(` | |
it\'s time to answer a star trek question. | |
${q} | |
is the answer... ${as[0].t}, ${as[1].t}, ${as[2].t}, or ${as[3].t}? | |
again, ${q} | |
is the answer... ${as[0].t}, ${as[1].t}, ${as[2].t}, or ${as[3].t}? | |
`) | |
await play('scrsearch.mp3') | |
await say('time\'s up! the answer is: ' + as.find(a => a.c).t) | |
await play('processing3.mp3') | |
}) | |
client.on('message', async msg => { | |
if (msg.content == '!drink') { | |
const online = msg.channel.members.filter(member => member.presence.status === 'online') | |
const selected = online.random() | |
msg.channel.send(`<@${selected.id}> drinks`) | |
await withVoice(async ({play, say}) => { | |
await play('alert16.mp3') | |
await say(`${selected.user.username} drinks`) | |
}) | |
} else if (msg.content == '!trek') { | |
await trekQuestion() | |
} | |
}) | |
setInterval(trekQuestion, 20 * 60 * 1000) | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment