Skip to content

Instantly share code, notes, and snippets.

@chromakode

chromakode/trekbot.js

Last active Mar 9, 2020
Embed
What would you like to do?
A star trek questions Discord bot using Wavenet TTS
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