receive audio form a user with discord bot - javascript

I'm working on a discord project and in that project i need to record a user voice, i'm following this document.
so far this is what i wrote:
const fs = require('fs');
const Discord = require('discord.js');
const client = new Discord.Client();
client.once('ready', () => {
console.log('Ready!');
});
client.on('message', async message => {
if (message.content === 'a' && message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
const audio = connection.receiver.createStream('user_id?', { mode: 'pcm' });
audio.pipe(fs.createWriteStream('user_audio'));
}
});
client.login('token');
but the problem is that always the user_audio file is empty!

This is a bug in discord.js, to solve this problem we need to play an audio...
const fs = require('fs');
const Discord = require('discord.js');
const client = new Discord.Client();
const { Readable } = require('stream');
const SILENCE_FRAME = Buffer.from([0xF8, 0xFF, 0xFE]);
class Silence extends Readable {
_read() {
this.push(SILENCE_FRAME);
this.destroy();
}
}
client.once('ready', () => {
console.log('Ready!');
});
client.on('message', async message => {
if (message.content === 's' && message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
const audio = connection.receiver.createStream(message, { mode: 'pcm', end: 'manual' });
audio.pipe(fs.createWriteStream('user_audio'));
connection.play(new Silence(), { type: 'opus' });
console.log(message.member.user.id);
}
});
client.login('token');

Related

Cannot read properties of undefined (reading '______')

Anything that I change to make this code work just changes said undefined thing.
I have tried to fix using multiple different answers, but no luck.
// Require the necessary discord.js classes
const { Client, GatewayIntentBits, message } = require('discord.js');
const { token } = require('./config.json');
const guildId = '1009548907015057460';
const channelId = '1009548907702915245';
// Create a new client instance
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
// When the client is ready, run this code (only once)
client.once('ready', () => {
console.log('Ready!');
});
client.on('interactionCreate', async interaction => {
if (!interaction.isChatInputCommand()) return;
const { commandName } = interaction;
if (commandName === 'invite') {
const guild = await client.guilds.fetch(guildId);
console.log(guild);
const channel = await guild.channels.cache.get(channelId);
let invite = await guild.channel.createInvite(
{
maxAge: 300000,
maxUses: 1,
},
'${message.author.tag} requested a invite',
).catch(console.log);
await interaction.deferReply({ ephemeral: true });
await interaction.editReply(invite ? 'Join: ${invite}' : 'Error');
}
}
Anything can help.
You don't need to fetch the guild, you can get the channel from the client
There's no need for await when you're getting information from cache
guild.channel.createInvite should be channel.createInvite
You're using single quotes for variables, they'll end up being strings
There's no need for invite to use let when the value doesn't change
Defer the reply at the beginning rather than right before replying
message.author.tag would return undefined, message doesn't exist. Use interaction.user.tag instead
Add await to channel.createInvite as it returns a promise
Replace ${invite} with ${invite.url}
Also it's best to store the token in a .env file rather than a JSON one.
// Require the necessary discord.js classes
const { Client, GatewayIntentBits, message } = require('discord.js');
const { token } = require('./config.json');
const channelId = '1009548907702915245';
// Create a new client instance
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
// When the client is ready, run this code (only once)
client.once('ready', () => {
console.log('Ready!');
});
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
await interaction.deferReply({ ephemeral: true });
const { commandName } = interaction;
if (commandName === 'invite') {
const channel = client.channels.cache.get(channelId);
const invite = await channel.createInvite({
maxAge: 604800, // 1 week
maxUses: 1,
reason: `${interaction.user.tag} requested an invite`
}).catch(console.log);
interaction.editReply(invite ? `Join: ${invite.url}` : 'Error');
}
}
Resolving the promise works. This is the code after:
// Require the necessary discord.js classes
const { Client, GatewayIntentBits, message } = require('discord.js');
const { token } = require('./config.json');
const channelId = '1009548907702915245';
// Create a new client instance
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
// When the client is ready, run this code (only once)
client.once('ready', () => {
console.log('Ready!');
});
client.on('interactionCreate', async (interaction) => {
if (!interaction.isChatInputCommand()) return;
await interaction.deferReply({ ephemeral: true });
const { commandName } = interaction;
if (commandName === 'invite') {
const channel = client.channels.cache.get(channelId);
const invite = channel.createInvite({
maxAge: 604800, // 1 week
maxUses: 1,
reason: `${interaction.user.tag} requested an invite`
})
.catch(console.log);
const promise = Promise.resolve(invite);
promise.then((value) => {
interaction.editReply(`Join: ${value}`);
});
}
}

I cant get access to the client in my command file discord.js

My reaction role file:
module.exports = {
name: "rr",
desc: "make a reaction role --> <",
async run(message, client) {
const jsEmoji = "🍏";
const pythonEmoji = "🍍";
let embedMessage = await message.channel.send("react for a role");
embedMessage.react(jsEmoji);
embedMessage.react(pythonEmoji);
client.on("messageReactionAdd", (user, reaction) => {
console.log("he reacted");
});
},
};
my bot file:
const intents = new Discord.Intents(32767);
I initialized my client here
const client = new Discord.Client({ intents: intents });
const fs = require("fs");
const commandFolders = fs.readdirSync("./Commands");
client.commands = new Discord.Collection();
commandFolders.forEach((folder) => {
const commandFiles = fs
.readdirSync(`./Commands/${folder}`)
.filter((file) => file.endsWith(".js"));
commandFiles.forEach((file) => {
const command = require(`./Commands/${folder}/${file}`);
client.commands.set(command.name, command);
});
});
client.on("messageCreate", (message) => {
if (message.author.bot || !message.content.startsWith(config.prefix)) return;
const [command, ...args] = message.content
.substring(config.prefix.length)
.split(/\s+/);
I tried getting access to the client here and passing it into the run function but that didnt work.
client.commands.forEach((cmd) =>
command === cmd.name
? client.commands.get(cmd.name).run(message, args, client)
: null
);
});
client.login(config.token);
My Error:
client.on("messageReactionAdd", (user, reaction) => {
^
TypeError: client.on is not a function
Is there another way to get access to my client?
your arguments are wrong on command file.
You should use async run(client, message, args)
Here's a full code for you:
module.exports = {
name: "rr",
desc: "make a reaction role --> <",
async run(client, message, args) {
const jsEmoji = "🍏";
const pythonEmoji = "🍍";
let embedMessage = await message.channel.send("react for a role");
embedMessage.react(jsEmoji);
embedMessage.react(pythonEmoji);
client.on("messageReactionAdd", (user, reaction) => {
console.log("he reacted");
});
},
};

Cannot read property 'commands' of undefiened (discord.js)

I am trying to code in / commands into my discord bot. But I keep on getting this error:
Cannot read property 'commands' of undefined
Below I have attached my main.js file, as well as the part that just keeps giving me the error:
Part that gives me the error
const getApp = (guildID) => {
const app = client.api.applications(client.user.id)
if (guildID) {
app.guilds(guildID)
}
}
client.once('ready', async() => {
client.user.setActivity('FALLBACK BOT, USE THE MAIN CHECKPOINT BOT INSTEAD. THIS IS FOR DEVELOPMENT PURPOSES')
const commands = await getApp(guildID).commands.get()
console.log(commands)
await getApp(guildID).commands.post({
data: {
name: 'ping',
description: 'Shows your current ping.',
},
})
});
Here is the full script
// Just grabbing some librarys
const Discord = require('discord.js');
require('dotenv').config();
const client = new Discord.Client({ partials: ["MESSAGE", "CHANNEL", "REACTION" ]});
const mongoose = require('mongoose');
// Defining the guildID
const guildID = (process.env.guildID);
// Filtering the command folder so it only includes .js files
const { join } = require('path');
const fs = require('fs');
require('./dashboard/server');
client.commands = new Discord.Collection();
client.events = new Discord.Collection();
const getApp = (guildID) => {
const app = client.api.applications(client.user.id)
if (guildID) {
app.guilds(guildID)
}
}
client.once('ready', async() => {
client.user.setActivity('FALLBACK BOT, USE THE MAIN CHECKPOINT BOT INSTEAD. THIS IS FOR DEVELOPMENT PURPOSES')
const commands = await getApp(guildID).commands.get()
console.log(commands)
await getApp(guildID).commands.post({
data: {
name: 'ping',
description: 'Shows your current ping.',
},
})
});
['command_handler', 'event_handler'].forEach(handler =>{
require(`./handlers/${handler}`)(client, Discord);
})
mongoose.connect(process.env.MONGODB_SRV, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false
}).then(()=> {
console.log('Connected to Database')
}).catch((err) =>{
console.log(err);
})
// Logging into the bot (THIS INCLUDES THE TOKEN SO DONT INCLUDE IT WHEN SENDING MESSAGES)
client.login(process.env.DISCORD_TOKEN);
Note: I am quite new to JS so. keep that in mind
Your getApp() function doesn't return anything so you are trying to read commands property from undefined value.
You have to return you app.guilds(guildId) so you can read property from it.
const getApp = (guildID) => {
const app = client.api.applications(client.user.id)
if (guildID) {
app.guilds(guildID)
}
return app;
}
client.once('ready', async() => {
client.user.setActivity('FALLBACK BOT, USE THE MAIN CHECKPOINT BOT INSTEAD. THIS IS FOR DEVELOPMENT PURPOSES')
const app = getApp(guildID);
if (app === null) {
console.error('error');
return;
}
const commands = await app.commands.get()
console.log(commands)
await app.commands.post({
data: {
name: 'ping',
description: 'Shows your current ping.',
},
})
});

Post mentioned user's avatar embedded using Discord.js

I'm using Discord.js for a discord bot and I'm trying to make it so that when you do the command !avatar #user
It will reply back with an embedded image of the mentioned user's avatar. I keep getting:
(node:3168) UnhandledPromiseRejectionWarning: DiscordAPIError: Invalid Form Body embed.image.url: Not a well formed URL.
This is the code I have so far, however I'm unaware of how else to grab the user's avatar?
const Discord = require('discord.js');
const config = require('./config.json');
const client = new Discord.Client();
function getUserFromMention(mention) {
if (!mention) return;
if (mention.startsWith('<#') && mention.endsWith('>')) {
mention = mention.slice(2, -1);
if (mention.startsWith('!')) {
mention = mention.slice(1);
}
return client.users.get(mention);
}
}
function getUserFromMentionRegEx(mention) {
const matches = mention.match(/^<#!?(\d+)>$/);
const id = matches[1];
return client.users.get(id);
}
client.once('ready', () => {
console.log('Ready!');
});
const prefix = "!";
client.on('message', message => {
if (!message.content.startsWith(prefix)) return;
const withoutPrefix = message.content.slice(prefix.length);
const split = withoutPrefix.split(/ +/);
const command = split[0];
const args = split.slice(1);
if (command === 'avatar') {
if (args[0]) {
const user = getUserFromMention(args[0]);
const userAvatar = user.displayAvatarURL;
if (!user) {
return message.reply('Please use a proper mention if you want to see someone else\'s avatar.');
}
const avatarEmbed = new Discord.RichEmbed()
.setColor('#275BF0')
.setImage('userAvatar');
message.channel.send(avatarEmbed);
}
return message.channel.send(`${message.author.username}, your avatar: ${message.author.displayAvatarURL}`);
}
});
client.login(config.token);
you dont need parse mentions with another function, discord have method for this. You can use message.mentions.members.first()
And you try to set image a string, with text userAvatar so sure you got error.
You can get mention member avatar and send it with this code.
const Discord = require('discord.js');
const config = require('./config.json');
const client = new Discord.Client();
client.once('ready', () => {
console.log('Ready!');
});
const prefix = "!";
client.on('message', message => {
if (!message.content.startsWith(prefix)) return;
const withoutPrefix = message.content.slice(prefix.length);
const split = withoutPrefix.split(/ +/);
const command = split[0];
const args = split.slice(1);
if (command === 'avatar') {
let targetMember;
if(!message.mentions.members.first()) {
targetMember = message.guild.members.get(message.author.id);
} else {
targetMember = message.mentions.members.first()
}
let avatarEmbed = new Discord.RichEmbed()
.setImage(targetMember.user.displayAvatarURL)
.setColor(targetMember.displayHexColor);
message.channel.send(avatarEmbed);
}
});

How do I send a random Image from a google search?

I'm VERY new to JavaScript (Started last week), and I couldn't find a working answer.
How does one exactly send a random image with a keyword from Google Images to a Discord Channel?
Here's my code so far:
const GoogleImages = require('google-images');
const Discord = require('discord.js');
const client = new Discord.Client();
const client2 = new GoogleImages('', '');
client.on('ready', () => {
console.log('I am ready!');
});
client2.search('Riolu Pokemon')
.then(images => {});
client.on('message', message => {
if (message.content === 'more riolu') {
return message.channel.send(images);
}
});
client.login('');
Solved with:
const GoogleImages = require("google-images");
const { Client, Attachment } = require("discord.js");
const client = new Client;
const googleImages = new GoogleImages("", "");
async function onMessage(message) {
if (message.content !== "more riolu") return;
try {
const results = await googleImages.search("Riolu Pokemon");
const reply = !results.length ?
"No results" :
new Attachment(results[Math.floor(Math.random() * results.length)].url);
message.channel.send(reply);
}
catch (e) {
console.error(e);
message.channel.send("Error happened, see the console");
}
}
client
.on("ready", () => console.log("I am ready!"))
.on("message", onMessage)
.login("");

Categories