Dynamic help command discord.js - javascript

I'm currently making a discord bot but I have an issue. I'm still quite new to discord.js and node.js. This is my code:
module.exports.run = async (bot, message, args) => {
function getMenu() {
var hpmenu = {};
return new Promise(function(resolve, reject) {
dashboard.readServerBoundValue(
`${message.guild.id}`,
'PREFIX',
async function(output) {
if (output) {
var prefixxx = output;
} else {
var prefixxx = config.botPrefix;
}
//=====================================================================================================
fs.readdir('./src/commands/', (err2, files2) => {
files2.forEach((f2, i2) => {
hpmenu[f2] = new discord.MessageEmbed();
hpmenu[f2].setTitle(`${f2}`);
console.log('Added catagory ' + f2);
//=========================================================================================
fs.readdir(`./src/commands/${f2}`, (err, files) => {
files.forEach((f, i) => {
const cmd = f.replace('.js', '');
hpmenu[f2].addField(cmd, 'test');
console.log('Added command ' + cmd);
//=====================================================================================================
});
resolve(hpmenu);
});
});
});
}
);
});
}
async function main() {
var output = await getMenu();
message.channel.send(output['developer']);
}
main();
};
This code doesnt have any errors but this is the issue I'm having:
The issue is that it runs the main function before it finished the getMenu function.
How to solve this? I have read multiple posts about this. Thanks for reading everyone!

After alot of coding i reached my goal; Making a dynamic help menu with pagination.
This is the code:
https://pastebin.com/QGVfutti
It functions good. The only thing you need is to make a file named config.json in the root directory of the bot where index.js is located and add a key named "embedColor" put your commands in
./src/commands/CATAGORY/COMMAND.js
and this is the result:
sorry for bad english. Do note if you use it you still have to implement the prefix and description yourself this depends per command handler and database engine.
You can change the description code and the command name at line 19 in the pastebin. if you want a image you can add a new line after line 13:
hmu[i].setImage("IMAGE");
Its just a discord embed and it will work fine, add thumbnails, authors, and change however you like. You do not have to credit me if you're using it
Sorry for my bad english and a thank you to Lioness100 for editing the text. English is not my first language :) Have a nice day everyone bye!

Related

How do I #everyone with discord.js?

I want to have a simple command like "!hello" to output "Hello #everyone" and ping everyone. The output text is correct, but it doesn't actually ping. The command just shows the text #everyone without doing the mention.
const Discord = require("discord.js")
module.exports.run = async (bot, message, args) => {
message.channel.send("#everyone Hello!");
}
module.exports.help = {
name: "hello"
}
I would expect it to output this:
Actual Result:
So, turns out I had:
const bot = new Discord.Client({disableEveryone: True});
Once I changed it to:
const bot = new Discord.Client({disableEveryone: False});
everything worked.
Thank you for your help everyone.
Citing discord.js issue #2285:
You mention everyone or here with the literal strings #everyone or #here, not a > regular role mention.
This is not a bug, but a discord thing.
Try this
message.channel.send("<#everyone>" + "Hello!");
There is a guild.defaultRole
You can mention it like this:
client.on('message', (msg) => {
msg.channel.send(msg.guild.defaultRole.toString());
});
You can check if your bot can mention everyone this way:
client.on('message', (msg) => {
let everyone = msg.guild.defaultRole;
if (msg.guild.me.hasPermission(everyone.permissions)) {
msg.channel.send(everyone.toString());
} else {
console.log("I can't mention everyone");
}
});
You can fetch the everyone role from guild.roles.
const everyone = await guild.roles.fetch("#everyone");
channel.send(`Hello ${everyone}`);
I'm not sure why, but I remember having to put the role in its own string literal in the send call:
message.channel.send("#everyone" + " Hello!");
Unable to test for myself atm, see if that works.

Discord x Hastebin command doesn't behave as intended

So I'm trying to make a bot that posts given data to hastebin.
But it doesn't really behave well. I'm using discord.js and hastebin-gen.
This is the code:
const hastebin = require('hastebin-gen');
exports.run = (client, msg, args) => {
let haste = args.slice(0).join(" ")
let type = args.slice(1).join(" ")
if (!args[0]) { return msg.channel.send("Usage: bin.haste yourmsghere.") }
hastebin(haste, type).then(r => {
msg.channel.send(":white_check_mark: Posted text to Hastebin at this URL: " + r);
}).catch(console.error);
}
When ran, for example bin.haste this code is awesome, it returns this:(https://a.pomf.cat/rkjqog.png) (Note: Can't post images yet, sorry.)
If I click on the link, it successfully uploads the text given to Hastebin: (https://a.pomf.cat/ovcpzb.png)
But there's just that annoying fact that it repeats the given text, as seen at the end of the link, and after the link.
What it's adding is the extension you're passing to hastebin-gen. Don't pass one and it will just respond with the link.
Hastebin-gen only adds the extension to the link at this line:
res("https://hastebin.com/" + body.body.key + ((extension) ? "." + extension : ""));
The extension doesn't matter at all, hastebin.com/beqojuzowe.jhffyjbfft will point to the same as hastebin.com/beqojuzowe.
TL;DR use this:
hastebin(haste).then(r => {

javascript array function can't be used

below is a piece of js code.When I run it with "node" command. It displays. "notes.filter" is not a function.If I comment "JSON.parse" line. It works. But video tutorial does have this line. So I am quite confused here. Could any one helps here. Thanks a lot.
var addNote = (title, body) => {
var notes = [];
var note = {
title,
body
}
try {
var notesstring = fs.readFileSync('notes-data.json');
notes = JSON.parse(notesstring);
} catch (e) {
}
console.log(Array.isArray(notes));
var duplicateNote = notes.filter((note) => note.title === title);
if (duplicateNote.length === 0) {
notes.push(note);
fs.writeFileSync('notes-data.json', JSON.stringify(note));
}
};
I had the same problem while going through the course but ended up fixing it.
For some reason, I was getting back bad JSON, and so I had to delete the note-data.json file, and then re-run the app. This fixed it for me!

Twitter bot image posting bug

Ok so I've had a lot of fun setting up a twitterbot through these tutorials and I have had no problems up to image posting. I have been following along these tutorials: https://www.youtube.com/playlist?list=PLRqwX-V7Uu6atTSxoRiVnSuOn6JHnq2yV and was stuck on 15.6 (https://www.youtube.com/watch?v=mUoIPmZ4KwA) where we post images. It's takes kind of a while to watch all of it but you might be able to skip the simple tweeting text and follow response videos. Now, I understand about 80% of what this guy is saying, as I am a little new to JS compared to some of you guys who are much more experienced than me, so some of my code is a little repetitive, but I wanted to make sure everything runs.
var imageTweet = function(txt) {
var tweet = {
status:txt
}
//This is for uploading the image to twitter but not actually tweeting it
//Might want to define the b64_img
var b64_img = 0;
var imageProcessing = function(){
var filename = "dankykang.jpg";
var params_img = {
encoding:'base64'
}
b64_img = fs.readFileSync(filename, params_img)
}
imageProcessing();
var upload_params = {
media_data: b64_img
}
T.post('media/upload', upload_params, tweeted_img);
function upload_img(err, data, response){
//This part does the tweet
var id = data.media_id_string;
var tweet = {
//for text in the image tweet
status:"testing a new way to tweet an image...",
//This calls the image from the imageProcessing function
media_ids:[id]
}
T.post('statuses/update', tweet, imgstatustweeted);
function imgstatustweeted(){
if (err){
console.log("The status didn't work")
} else {
console.log("Status worked")
}
}
imgstatustweeted();
}
upload_img();
function tweeted_img(err, data, response){
if (err){
console.log("Image not posted");
} else {
console.log("Image posted");
}
}
tweeted_img();
}
imageTweet();
I follow most of his steps with some name changes, and I don't think I am missing anything... but when I run bot.js it keeps giving me an error on data.media_id_string; [above var tweet = {...} and below function upload_img(...)]
it says TypeError: Cannot read property 'media_id_string' of undefined. But according to the tutorial I'm following, I think this has to to with the npm which was set up. So I don't know why it runs fine on his end but doesn't run fine on my end. If I'm not mistaken its not a syntax problem.

How to Play Audio File Into Channel?

How do you play an audio file from a Discord bot? Needs to play a local file, be in JS, and upon a certain message being sent it will join the user who typed the message, and will play the file to that channel.
GitHub Project: LINK
In order to do this there are a few things you have to make sure of first.
Have FFMPEG installed & the environment path set for it in Windows [link]
Have Microsoft Visual Studio (VS) installed [link]
Have Node.js installed.[link]
Have Discord.js installed in VS.
From there the steps are quite simple. After making your project index.js you will start typing some code. Here are the steps:
Add the Discord.js dependency to the project;
var Discord = require('discord.js');
Create out client variable called bot;
var bot = new Discord.Client();
3. Create a Boolean variable to make sure that the system doesn't overload of requests;
var isReady = true;
Next make the function to intercept the correct message;
bot.on('message', message =>{ENTER CODE HERE});
Create an if statement to check if the message is correct & if the bot is ready;
if (isReady && message.content === 'MESSAGE'){ENTER CODE HERE}
Set the bot to unready so that it cannot process events until it finishes;
isReady = false;
Create a variable for the channel that the message-sender is currently in;
var voiceChannel = message.member.voice.channel;
Join that channel and keep track of all errors;
voiceChannel.join().then(connection =>{ENTER CODE HERE}).catch(err => console.log(err));
Create a refrence to and play the audio file;
const dispatcher = connection.play('./audiofile.mp3');
Slot to wait until the audio file is done playing;
dispatcher.on("end", end => {ENTER CODE HERE});
Leave channel after audio is done playing;
voiceChannel.leave();
Login to the application;
bot.login('CLIENT TOKEN HERE');
After you are all finished with this, make sure to check for any un-closed brackets or parentheses. i made this because it took my hours until I finally found a good solution so I just wanted to share it with anybody who is out there looking for something like this.
thanks so much!
One thing I will say to help anyone else, is things like where it says ENTER CODE HERE on step 10, you put the code from step 11 IE:
dispatcher.on("end", end => voiceChannel.leave());
As a complete example, this is how I have used it in my message command IF block:
if (command === "COMMAND") {
var VC = message.member.voiceChannel;
if (!VC)
return message.reply("MESSAGE IF NOT IN A VOICE CHANNEL")
VC.join()
.then(connection => {
const dispatcher = connection.playFile('c:/PAtH/TO/MP3/FILE.MP3');
dispatcher.on("end", end => {VC.leave()});
})
.catch(console.error);
};
I went ahead an included Nicholas Johnson's Github bot code here, but I made slight modifications.
He appears to be creating a lock; so I created a LockableClient that extends the Discord Client.
Never include an authorization token in the code
auth.json
{
"token" : "your-token-here"
}
lockable-client.js
const { Client } = require('discord.js')
/**
* A lockable client that can interact with the Discord API.
* #extends {Client}
*/
class LockableClient extends Client {
constructor(options) {
super(options)
this.locked = false
}
lock() {
this.setLocked(true)
}
unlock() {
this.setLocked(false)
}
setLocked(locked) {
return this.locked = locked
}
isLocked {
return this.locked
}
}
module.exports = LockableClient;
index.js
const auth = require('./auth.json')
const { LockableClient } = require('./lockable-client.js')
const bot = new LockableClient()
bot.on('message', message => {
if (!bot.isLocked() && message.content === 'Gotcha Bitch') {
bot.lock()
var voiceChannel = message.member.voiceChannel
voiceChannel.join().then(connection => {
const dispatcher = connection.playFile('./assets/audio/gab.mp3')
dispatcher.on('end', end => voiceChannel.leave());
}).catch(err => console.log(err))
bot.unlock()
}
})
bot.login(auth.token)
This is an semi old thread but I'm going to add code here that will hopefully help someone out and save them time. It took me way too long to figure this out but dispatcher.on('end') didn't work for me. I think in later versions of discord.js they changed it from end to finish
var voiceChannel = msg.member.voice.channel;
voiceChannel.join()
.then(connection => {
const dispatcher = connection.play(fileName);
dispatcher.on("finish", end => {
voiceChannel.leave();
deleteFile(fileName);
});
})
.catch(console.error);
Note that fileName is a string path for example: fileName = "/example.mp3". Hopefully that helps someone out there :)
Update: If you want to detect if the Audio has stopped, you must subscribe to the speaking event.
voiceChannel
.join()
.then((connection) => {
const dispatcher = connection.play("./audio_files/file.mp3");
dispatcher.on("speaking", (speaking) => {
if (!speaking) {
voiceChannel.leave();
}
});
})

Categories

Resources