Simplified version of EzBot
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
require('dotenv').config() | |
const Discord = require('discord.js') | |
const config = require('./config') | |
const { Transform } = require('stream') | |
const googleSpeech = require('@google-cloud/speech') | |
async function playFile(connection, filePath) { | |
return new Promise((resolve, reject) => { | |
const dispatcher = connection.play(filePath) | |
dispatcher.setVolume(1) | |
dispatcher.on('start', () => { | |
console.log('Playing') | |
}) | |
dispatcher.on('end', () => { | |
resolve() | |
}) | |
dispatcher.on('error', (error) => { | |
console.error(error) | |
reject(error) | |
}) | |
}) | |
} | |
function convertBufferTo1Channel(buffer) { | |
const convertedBuffer = Buffer.alloc(buffer.length / 2) | |
for (let i = 0; i < convertedBuffer.length / 2; i++) { | |
const uint16 = buffer.readUInt16LE(i * 4) | |
convertedBuffer.writeUInt16LE(uint16, i * 2) | |
} | |
return convertedBuffer | |
} | |
class ConvertTo1ChannelStream extends Transform { | |
constructor(source, options) { | |
super(options) | |
} | |
_transform(data, encoding, next) { | |
next(null, convertBufferTo1Channel(data)) | |
} | |
} | |
const discordClient = new Discord.Client() | |
const googleSpeechClient = new googleSpeech.SpeechClient() | |
const GamesAndChannels = { | |
Mines: '[Voice Channel ID]' | |
} | |
discordClient.on('ready', () => { | |
console.log(`Logged in as ${discordClient.user.tag}!`) | |
}) | |
discordClient.on('presenceUpdate', async (oldPresence, newPresence) => { | |
const member = newPresence.member | |
const presence = newPresence | |
const memberVoiceChannel = member.voice.channel | |
if (!presence || !presence.activity || !presence.activity.name || !memberVoiceChannel) { | |
return | |
} | |
const activityName = presence.activity.name | |
const channelId = GamesAndChannels[activityName] | |
if (!channelId) { | |
return | |
} | |
const connection = await memberVoiceChannel.join() | |
const receiver = connection.receiver | |
await playFile(connection, 'audio/wrongChannelEn.mp3') | |
setTimeout(() => { | |
memberVoiceChannel.leave() | |
}, 30000) | |
console.log('I am ready to listen...') | |
connection.on('speaking', (user, speaking) => { | |
if (!speaking) { | |
return | |
} | |
console.log(`I'm listening to ${user.username}`) | |
// this creates a 16-bit signed PCM, stereo 48KHz stream | |
const audioStream = receiver.createStream(user, { mode: 'pcm' }) | |
const requestConfig = { | |
encoding: 'LINEAR16', | |
sampleRateHertz: 48000, | |
languageCode: 'en-US' | |
} | |
const request = { | |
config: requestConfig, | |
interimResults: true | |
} | |
const recognizeStream = googleSpeechClient | |
.streamingRecognize(request) | |
.on('error', console.error) | |
.on('data', response => { | |
const transcription = response.results | |
.map(result => result.alternatives[0].transcript) | |
.join('\n') | |
.toLowerCase() | |
console.log(`Transcription: ${transcription}`) | |
if (transcription.indexOf('yes') > -1) { | |
connection.channel.members.array().forEach(member => { | |
if (member.user.id !== discordClient.user.id) { | |
console.log(`Moving member ${member.displayName} to channel ${channelId}`) | |
member.edit({ channel: channelId }).catch(console.error) | |
memberVoiceChannel.leave() | |
recognizeStream.destroy() | |
} | |
}) | |
} else if (transcription.indexOf('no') > -1) { | |
memberVoiceChannel.leave() | |
recognizeStream.destroy() | |
} | |
}) | |
const convertTo1ChannelStream = new ConvertTo1ChannelStream() | |
audioStream.pipe(convertTo1ChannelStream).pipe(recognizeStream) | |
audioStream.on('end', async () => { | |
console.log('audioStream end') | |
}) | |
}) | |
}) | |
discordClient.login(config.discordApiToken) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment