Node packages work locally but not when deployed to Heroku - node.js

I've implemented a very simple discord.js music bot which uses the node.js packages ytdl-core and opus-script. The bot is never able to join the voice channels and stream the music using the new packages implemented when deployed to Herkou, however the messages associated with each command such as the embeds still send.
const ytdl = require('ytdl-core');
const streamOptions = { seek: 0, volume: 1}
const Discord = require('discord.js')
require('dotenv-flow').config()
const config = {
token: process.env.TOKEN,
owner: process.env.OWNER,
prefix: process.env.PREFIX
}
const ytdl = require('ytdl-core')
const streamOptions = {
seek: 0,
volume: 1
}
const prefix = config.prefix
const client = new Discord.Client()
client.on('ready', () => {
console.log('ready!')
console.log(prefix)
client.user.setActivity("foo", {
type: "WATCHING"
})
});
client.on("message", async message => {
const args = message.content.slice(prefix.length).trim().split(/ +/g)
const command = args.shift().toLowerCase()
if (message.author.bot) return
if (message.content.indexOf(prefix) !== 0) return
if (command === "play") {
const link = args[0]
if (message.channel.id === musicChannel) {
if (message.member.voiceChannel) {
if (!link) return message.reply("please enter a YouTube url to play!")
if (!ytdl.validateURL(`${link}`)) return message.reply("pleae enter a valid YouTube url!")
message.member.voiceChannel.join().then(connection => {
console.log("Successfully connected.");
const stream = ytdl(`${link}`, {
filter: 'audioonly'
})
const dispatcher = connection.playStream(stream, streamOptions);
})
.catch(e => {
console.error(e);
})
const embed = new Discord.RichEmbed()
.setTitle("__A New Youtube URL Is Playing:__")
.setThumbnail(client.user.avatarURL)
.addField("Current URL:", `${link}`)
.addField("Changed by:", `${message.member.user}`)
.setColor("#32a852")
message.guild.channels.get(musicChannel).send(embed).catch(e => {
console.error(e);
})
} else {
message.reply("you must be in a voice channel!")
}
} else {
message.reply(`please use music commands in: <#${musicChannel.toString()}>`)
}
}
if (command === "stop") {
if (message.channel.id === musicChannel) {
if (message.guild.voiceConnection) {
message.guild.voiceConnection.disconnect()
message.channel.send("successfully disconnected from voice channel!")
} else {
message.reply("There is currently no music playing!")
}
} else {
message.reply(`please use music commands in: <#${musicChannel.toString()}>`)
}
}
}
});
client.login(process.env.TOKEN);

Tried uploading it through github desktop? (no gitignore , upload it with the node-modules folder)

Related

I want my bot to run on several servers with database

so this code below works fine but the problem is I can't run it in all servers that have my bot I used quick.db but It seem to work only in one sever since it takes the last variable or I might did a mistake. Is there any way to change from quick.db to mongoDB so it work for all servers.
I hope I explain the issue successfully.
Code: what I am trying to do in this code is the bot will send a random messages from json file to a specific text channel specified by user which works fine, but I think I have a problem with the database.
discord.js v12
hosting the bot throw Heroku
index.js file
require('events').EventEmitter.prototype._maxListeners = 30;
const Discord = require('discord.js')
const client = new Discord.Client()
const ytdl = require('ytdl-core');
const config = require('./config.json')
const mongo = require('./mongo')
const command = require('./command')
const loadCommands = require('./commands/load-commands')
const commandBase = require('./commands/command-base')
const { permission, permissionError } = require('./commands/command-base')
const cron = require('node-cron')
const zkrList = require('./zkr.json')
const logo =
'URL HERE'
const db = require(`quick.db`)
const prefix = "!"
let cid;
client.on('ready', async () => {
await mongo().then((mongoose) => {
try {
console.log('Connected to mongo!')
} finally {
mongoose.connection.close()
}
})
console.log(`${client.user.tag} is online`);
console.log(`${client.guilds.cache.size} Servers`);
console.log(`Server Names:\n[ ${client.guilds.cache.map(g => g.name).join(", \n ")} ]`);
loadCommands(client)
cid = client.guilds.cache.map(guild => { db.get(`${guild.id}_channel_`) });
cron.schedule('*/10 * * * * *', () => {
const zkrRandom = zkrList[Math.floor(Math.random() * zkrList.length)]
const zkrEmbed = new Discord.MessageEmbed()
.setDescription(zkrRandom)
.setAuthor('XX', logo)
.setColor('#447a88')
client.channels.cache.get(cid).send(zkrEmbed);
})
client.on("message", async message => {
if (message.author.bot) {
return
}
console.log(client.guilds.cache.map(guild => { db.get(`${guild.id}_channel_`) }))
if (!message.member.hasPermission('ADMINISTRATOR') && message.content.startsWith('XX')) return message.reply('YOU DONT HAVE A PERMISSION TO RUN THIS COMMAND.')
if (!message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).trim().split(/ +/g)
const cmd = args[0]
if (cmd === "s") {
let c_id = args[1]
if (!c_id) return message.reply("YOU NEED TO MENTION A TEXT CHANNEL/ID")
c_id = c_id.replace(/[<#>]/g, '')
const channelObject = message.guild.channels.cache.get(c_id);
try { if (channelObject.type === 'voice') return message.reply('YOU CANNOT SEND MESSAGES TO VOICE CHANNEL') } catch (err) { return message.reply('AN ERROR OCCURRED') }
if (client.channels.cache.get(c_id)) {
client.guilds.cache.map(guild => { db.set(`${guild.id}_channel_`, c_id) })
message.reply(`SENDING TO THIS CHANNEL ${message.guild.channels.cache.get(c_id)}`);
cid = db.get(client.guilds.cache.map(guild => { db.get(`${guild.id}_channel_`) }))
const zkrRandom = zkrList[Math.floor(Math.random() * zkrList.length)]
const zkrEmbed = new Discord.MessageEmbed()
.setDescription(zkrRandom)
.setAuthor('XX', logo)
.setColor('#447a88')
client.channels.cache.get(cid).send(zkrEmbed);
} else {
return message.reply("NOT A VALID CHANNEL")
}
}
})
})
client.login(config.token)
zkr.json file
[
"MESSAGE 1",
"MESSAGE 2",
"MESSAGE 3"
]

TypeError: Cannot read property 'user' of undefined discord.js

So I was trying to fix this thing for a few hours now, and I have no idea what I'm doing wrong.
This thing should execute itself when member joins the guild
const { Discord, MessageEmbed } = require("discord.js")
module.exports = {
name: "guildMemberAdd",
run: async ({bot, member}) => {
const welcome = new MessageEmbed()
.setDescription(`
<:nezuko_peek:974066160108732517> — New friend just showed up: <#${member.user.id}>
Welcome fellow adventurer in **Jasmine Dragon**! What brings you in these sides? <:girl_love:973968823449436190> Here, go to <#972618593294512128> to introduce yourself and talk with us in <#971800237507248158>!
`)
.setImage("https://64.media.tumblr.com/01a9f72f062feaafa60cdbf80f9ba729/tumblr_inline_orgoyznIM51sd5e91_500.gif")
.setColor("#F7DF79")
.setFooter({ text: "Thank you for joining and enjoy your stay!" })
member.guild.channels.cache.get("971800237507248158").send({ content: `<#&974343947105206382>`, embeds: [welcome] })
}
}
Here's my event handler
const { getFiles } = require("../util/functions")
module.exports = (bot, reload) => {
const {client} = bot
let events = getFiles("./events/", ".js")
if (events.length === 0){
console.log("No events to load")
}
events.forEach((f, i) => {
if (reload)
delete require.cache[require.resolve(`../events/${f}`)]
const event = require(`../events/${f}`)
client.events.set(event.name, event)
if (!reload)
console.log (`${i + 1}. ${f} loaded`)
})
if (!reload)
initEvents(bot)
}
function triggerEventHandler(bot, event, ...args){
const {client} = bot
try {
if (client.events.has(event))
client.events.get(event).run(bot, ...args)
else
throw new Error(`Event ${event} does not exist`)
}
catch(err){
console.error(err)
}
}
function initEvents(bot) {
const {client} = bot
client.on("ready", () => {
triggerEventHandler(bot, "ready")
})
client.on("messageCreate", (message) => {
triggerEventHandler(bot, "messageCreate", message)
})
client.on("guildMemberAdd", () => {
triggerEventHandler(bot, "guildMemberAdd")
})
}
And here's my index.js
const Discord = require("discord.js")
require("dotenv").config()
const { MessageEmbed, MessageActionRow, MessageSelectMenu } = require("discord.js")
const slashcommands = require("./handlers/slashcommands")
const client = new Discord.Client({
intents: [
"GUILDS",
"GUILD_MESSAGES",
"GUILD_MEMBERS"
]
})
// Bot config
let bot = {
client,
prefix: "i?",
owners: ["511889215672287242"]
}
// Handlers
client.commands = new Discord.Collection()
client.events = new Discord.Collection()
client.slashcommands = new Discord.Collection()
client.loadEvents = (bot, reload) => require("./handlers/events")(bot, reload)
client.loadCommands = (bot, reload) => require("./handlers/commands")(bot, reload)
client.loadSlashCommands = (bot, reload) => require("./handlers/slashcommands")(bot, reload)
client.loadEvents(bot, false)
client.loadCommands(bot, false)
client.loadSlashCommands(bot, false)
// Slash commands handler
client.on("interactionCreate", (interaction) => {
if (!interaction.isCommand()) return
if (!interaction.inGuild()) return interaction.reply("This command can only be used in a server")
const slashcmd = client.slashcommands.get(interaction.commandName)
if (!slashcmd) return interaction.reply("Invalid slash command")
if (slashcmd.perm && !interaction.member.permissions.has(slashcmd.perm))
return interaction.reply("You don not have permission for this command")
slashcmd.run(client, interaction)
})
module.exports = bot
client.login(process.env.TOKEN)
Other events like "ready" and "messageCreate" are working just fine so I'm not sure why it's not working.

Discordjs: How to fix execute is not defined?

I started making a music bot for my discord server when i input command for playing song it returns that execute is not defined i tried to fix but i had no success. That's why I am asking here.
Note: I made event and command handler but that is not the problem since it was also not working before implementing it.
Here is my code from event that happens on message aka starting command:
module.exports = (client, Discord, message)=>{
const prefix = '-';
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split('/ +/');
const cmd = args.shift().toLowerCase();
const command = client.commands.get(cmd) || client.commands.find(a => a.aliases && a.aliases.includes(cmd));
//const ChannelName = message.channel.name;
try{
command.execute(args, cmd, client, Discord, message);
} catch(err){
message.reply("There was an error trying to execute this command!");
console.log(err);
}
}
And here is my code for play command:
const ytdl = require('ytdl-core');
const ytSearch = require('yt-search');
const queue = new Map();
module.exports = {
name: 'play',
aliases: ['skip', 'stop'],
cooldown: 0,
description: 'Advanced music bot',
async execute(args, cmd, client, Discord, message){
const voice_channel = message.member.voice.channel;
if (!voice_channel) return message.channel.send('You need to be in a channel to execute this command!');
const permissions = voice_channel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT')) return message.channel.send('You dont have the correct permissins');
if (!permissions.has('SPEAK')) return message.channel.send('You dont have the correct permissins');
const server_queue = queue.get(message.guild.id);
if (cmd === 'play'){
if (!args.length) return message.channel.send('You need to send the second argument!');
let song = {};
if (ytdl.validateURL(args[0])) {
const song_info = await ytdl.getInfo(args[0]);
song = { title: song_info.videoDetails.title, url: song_info.videoDetails.video_url }
} else {
const video_finder = async (query) =>{
const video_result = await ytSearch(query);
return (video_result.videos.length > 1) ? video_result.videos[0] : null;
}
const video = await video_finder(args.join(' '));
if (video){
song = { title: video.title, url: video.url }
} else {
message.channel.send('Error finding video.');
}
}
if (!server_queue){
const queue_constructor = {
voice_channel: voice_channel,
text_channel: message.channel,
connection: null,
songs: []
}
queue.set(message.guild.id, queue_constructor);
queue_constructor.songs.push(song);
try {
const connection = await voice_channel.join();
queue_constructor.connection = connection;
video_player(message.guild, queue_constructor.songs[0]);
} catch (err) {
queue.delete(message.guild.id);
message.channel.send('There was an error connecting!');
throw err;
}
} else{
server_queue.songs.push(song);
return message.channel.send(`👍 **${song.title}** added to queue!`);
}
}
else if(cmd === 'skip') skip_song(message, server_queue);
else if(cmd === 'stop') stop_song(message, server_queue);
}
}
const video_player = async (guild, song) => {
const song_queue = queue.get(guild.id);
if (!song) {
song_queue.voice_channel.leave();
queue.delete(guild.id);
return;
}
const stream = ytdl(song.url, { filter: 'audioonly' });
song_queue.connection.play(stream, { seek: 0, volume: 0.5 })
.on('finish', () => {
song_queue.songs.shift();
video_player(guild, song_queue.songs[0]);
});
await song_queue.text_channel.send(`🎶 Now playing **${song.title}**`)
}
const skip_song = (message, server_queue) => {
if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
if(!server_queue){
return message.channel.send(`There are no songs in queue 😔`);
}
server_queue.connection.dispatcher.end();
}
const stop_song = (message, server_queue) => {
if (!message.member.voice.channel) return message.channel.send('You need to be in a channel to execute this command!');
server_queue.songs = [];
server_queue.connection.dispatcher.end();
}
I think that problem is in main part of code but I cant seem to find problem.
Here is code for command handling
const fs = require('fs');
module.exports = (client, Discord) =>{
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for (const file of commandFiles){
const command = require(`../commands/${file}`);
if(command.name){
client.commands.set(command.name, command);
} else{
continue;
}
}
}
And here is my main file of the bot with commands collection
const Discord = require('discord.js');
const client = new Discord.Client();
client.once('ready', () => {
client.user.setStatus('online')
console.log('Bot is online!');
client.user.setActivity('Youtube',{
type:"LISTENING"
})
console.log('Servers:')
client.guilds.cache.forEach((guild) => {
console.log('-' + guild.name)
})
});
const fs = require('fs');
const message = require('./events/guild/message');
client.commands = new Discord.Collection();
client.events = new Discord.Collection();
['command_handler', 'event_handler'].forEach(handler =>{
require(`./handlers/${handler}`)(client, Discord);
})

Discord.js - Rewritten version of a code for my music bot doesn't work

I'm having a problem with my music bot. The rewritten one joins and triggers the "Playing song" line, but doesn't play audio. The messy one works just fine. What could be the case-- everything is basically the same except these functions
Messy code
const videoPlayer = async function (message, song, skip, stop) {
const guild = message.guild;
const songQueue = queue.get(guild.id);
if(!song && !skip && !stop) {
songQueue.connection.disconnect();
queue.delete(guild.id);
return;
}
if (skip) {
if (!songQueue) return message.channel.send("There are currently no songs in the queue");
const prev = songQueue.songs[0].title
await songQueue.textChannel.send(`Skipping \`${prev}\`!`)
songQueue.songs.shift();
if (!song && songQueue.songs.length == 0) {
songQueue.connection.disconnect();
queue.delete(guild.id);
return songQueue.textChannel.send("There are currently no songs in the queue");
}
var music = songQueue.songs[0]
var stream = ytdl(music.url, {filter: 'audioonly', highWaterMark: 1<<25})
} else {
var stream = ytdl(song.url, {filter: 'audioonly', highWaterMark: 1<<25})
}
const player = Voice.createAudioPlayer();
const resource = Voice.createAudioResource(stream);
await player.play(resource);
songQueue.connection.subscribe(player);
if (!song && music) {
song = music
}
player.on(Voice.AudioPlayerStatus.Playing, async () => {
await songQueue.textChannel.send(`Playing \`${song.title}\`!`)
});
player.on(Voice.AudioPlayerStatus.Idle, () => {
songQueue.songs.shift();
videoPlayer(message, songQueue.songs[0])
});
}
Rewritten Code
const videoPlayer = async (message, song) => {
const guild = message.guild;
const songQueue = queue.get(guild.id);
if(!song) {
songQueue.connection.disconnect();
queue.delete(guild.id);
return message.channel.send("There are no more songs in queue.");
}
const stream = ytdl(song.url, {filter: 'audioonly', highWaterMark: 1<<25});
const player = Voice.createAudioPlayer();
const resource = Voice.createAudioResource(stream);
await player.play(resource);
songQueue.connection.subscribe(player);
player.on(Voice.AudioPlayerStatus.Playing, async () => {
await songQueue.textChannel.send(`Playing \`${song.title}\``)
});
player.on(Voice.AudioPlayerStatus.Idle, async () => {
songQueue.songs.shift();
videoPlayer(message, songQueue.songs[0]);
})
}
const skipSong = async (message) => {
guild = message.guild;
songQueue = queue.get(guild.id);
if(!songQueue) return message.channel.send("There are currently no songs in queue.");
let song = songQueue.songs[0];
await message.channel.send(`Skipping \`${song.title}\`!`);
songQueue.songs.shift();
song = songQueue.songs[0];
if(!song) return message.channel.send("There are no more songs in queue.");
videoPlayer(message, song);
}
const stop = async (message) => {
songQueue = queue.get(message.guild.id);
await songQueue.textChannel.send('Stopping in just a moment...');
songQueue.connection.disconnect();
queue.delete(guild.id);
return;
}
I don't get what the problem is-- please help!
Edit:
So it turns out, there's no problem with the code but their directory. For some reason, it just works on the original one-- I still don't know what the problem is exactly but it works now '^^

how do i make a setpresence command to trigger it by myself?

Im trying to do a set presence command to being able to change presence without restarting my bot and changing my code but im not able to do it, here's my code:
const Discord = require("discord.js")
const bot = new Discord.Client()
const fetch = require('node-fetch')
const config = require("./config.json")
bot.login(config.token)
bot.on("ready", () => {console.log("Loaded up!")});
bot.on("message", message => {
if (message.author.bot) return;
if (message.content.indexOf(config.prefix) !== 0) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase()
if (command === "set") {
bot.user.setPresence({
status: "online",
game: {
name: "a",
type: "WATCHING" }})}});
Having a look at the documentation for discordjs. I can see an example for setting your clientUsers presence while the bot is running.
working code:
const Discord = require("discord.js");
const config = require("./config.json")
const bot = new Discord.Client();
bot.on("ready", () => {
console.log("Initialized bot, listening...")
});
bot.on("message", message => {
if (message.author.bot || !message.content.startsWith(config.prefix)) return;
let [command, ...args] = message.content.slice(config.prefix.length).split(/ +/g);
if (command === "set") {
bot.user.setPresence({ activity: { name: 'with discord.js' }, status: 'idle' });
return;
}
if (command === "ping") {
message.channel.send("Pong")
return;
}
})
bot.login(config.token)
Documentation Link:
https://discord.js.org/#/docs/main/stable/class/ClientUser?scrollTo=setPresence

Resources