Node JS Discord Bot | Reading and Writing Config File - javascript

I am having a problem with figuring out how my NodeJS bot can read and write data to a config.json file. Apart from that, I do not know how to detect arguments sent with a Bot Command. Therefore my Questions are as following:
How to Read / Write Data to a config.json?
How to detect args sent with Bot Command?
Thank you in Advance :)
-Luis

I have a NodeJS discord bot as well and for importing settings I use the following. I have not found the need to write to a json file, though hopefully this helps solve the first part of your question.
Code sample
fs.readFile(file, 'utf8', (err, data) => {
var tree = JSON.parse(data);
token = tree.token;
});
config file
{
"token":""
}
For getting arguments from a command, you can do something like this:
client.on("message", async message => {
const param = message.content.split(' ');
const command = param[0].substr('!'.length);
const arguments = param.slice(1);
})
Here is my main discord bot file with such code bits. It is pretty cluttered with other stuff so beware. https://github.com/NicholasLKSharp/DiscordJSMusicBot-SpotifyPuller/blob/master/main.js

Related

Welcome message not sending through Discord.js

So I am coding a discord bot with discord.js and one of the features is that when a new user joins the server the bot sends a message. I am not making it an embed for now, I can do that myself later.
Here is my main welcome.js file specifically made for this feature:
module.exports = (client) => {
const channelId = '868192573011931185' //welcome channel
client.on('guildMemberAdd', (member) => {
console.log(member.name)
const message = `Hello <#${member.id}> and welcome to ${guild.name}!
Please verify through the Server Captcha Bot in your DMs,
then read the rules in <#868192573263605884>
and lastly pick your roles in <#868192573263605880>!`
const channel = member.guild.channels.cache.get(channelId)
channel.send(message)
})
}
And in my index.js file I just imported the file, and added welcome(client).
But for some reason my code is not showing up in the Welcome channel... Any help will be appreciated.
Check your intents are open and check this post for further information:
I don't know the context of your index.js but I suggest reading through this handy guide where they explain how you can handle events in seperate files.
Basically they loop through an events folder(where your welcome.js would be).
Then they dynamically register the events that the client object receives to execute through those event files.
Link: Event handling.
In your code, instead of saying
const channel = member.guild.channels.cache.get(channelId)
try say:
const channel = Client.channels.cache.get(channelId)
Hope it works :)

Reading file attachments (Ex; .txt file) - Discord.JS

Second time posting on StackOverflow so I apologize for any mistakes.
Please bear with me.
Same with the title; How do you read contents of a discord attachment let's say a .txt file and print the contents?
I have tried with fs but unfortunately failed and I have also searched the documentation but failed also.
Ideas?
You can't use the fs module for this as it only deals with local files. When you upload a file to the Discord server, it gets uploaded to a CDN and all you can do is grab the URL of this file from the MessageAttachment using the url property.
If you need to get a file from the web, you can fetch it from a URL using the built-in https module, or you can install one from npm, like the one I used below, node-fetch.
To install node-fetch, run npm i node-fetch in your root folder.
Check out the working code below, it works fine with text files:
const { Client } = require('discord.js');
const fetch = require('node-fetch');
const client = new Client();
client.on('message', async (message) => {
if (message.author.bot) return;
// get the file's URL
const file = message.attachments.first()?.url;
if (!file) return console.log('No attached file found');
try {
message.channel.send('Reading the file! Fetching data...');
// fetch the file from the external URL
const response = await fetch(file);
// if there was an error send a message with the status
if (!response.ok)
return message.channel.send(
'There was an error with fetching the file:',
response.statusText,
);
// take the response stream and read it to completion
const text = await response.text();
if (text) {
message.channel.send(`\`\`\`${text}\`\`\``);
}
} catch (error) {
console.log(error);
}
});
reply to #Andryxa, maybe you can use this with external APIs like a transcription service in case of audio files or to send requests to already created bots from services like dialogflow to replies to the messages

Why wont VS Code track variable types for JavaScript?

I am trying to create a discord bot using JS. I create a .js file for each command I intend to implement and there is a check in the 'main' script that will make calls to the other command scripts. I am going to use pictures to show what I mean when I say that VS code wont tell me the variable type for parameters nor will it tell me any info regarding a method call. Intellisense also seems to not work well in these command .js scripts.
Background Info: I have a lot more experience programming in Java. JS seems to be confusing for me for whatever reason, but I want to learn and understand it better.
I am not going to show all the code, only what is needed for my example.
The main.js script:
require('dotenv').config();
const { Client } = require('discord.js');
const client = new Client();
const prefix = "++";
const fs = require('fs');
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('.src/commands/').filter(file => file.endsWith('.js'));
for(const file of commandFiles){
const command = require(`.src/commands/${file}`);
client.commands.set(command.name, command);
}
client.on('message', (message) => {
if(message.author.bot) return;
console.log(`[${message.author.tag}]: ${message.content}`);
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if(command === 'ping'){
client.commands.get('ping').execute(message, args);
});
The ping.js script:
module.exports = {
name: 'ping',
description: 'This is a ping command.',
execute(message, args){
message.channel.send('Pong!');
}
}
Images:
It just says any, I assume any variable type, I think... But this just seems messy and hard to follow.
main.js
https://gyazo.com/86f7118513df791743def98bcf052f06
ping.js
https://gyazo.com/06bb2e47a3fd39d2e4445591d8537131
Discord.js send() returns a Promise<(Message)> or Promise<(Array<Message>)> (discord.js docs for channel.send()). Promises are great for sequential tasks in any API but don't seem to be a data type recognized by your environment. If VSCode and IntelliJ (as well as many other IDE's) don't recognize the data type of your method's return value or if it isn't predefined (as it more commonly is in Java compared to JS functions or methods), they will highlight the method's return value as any.

Commands that don't require prefixes not working. Discord.js

I've been coding a Discord bot using js for a couple days now and most everything has been working fine. I am trying to get my bot to respond to a code word but the command isn't working unless I use my prefix which is !.
I've tried pretty much every variation of the code, but none is working.
Example of the command:
if(message.content.includes('ping')) {
message.reply('Pong');
}
if your code looks like
const Discord = require('discord.js');
const client = new Discord.Client();
let token = "your token here";
client.on('message', message => {
if(message.content.includes('ping')) {
message.reply('Pong');
}
});
client.login(token)
and nothing happens when you send 'ping', then it looks like some technical issue. Otherwise, you have to send the whole code so people can take a look and tell you what is wrong.

Discord.js(); How to send file (It always sends a 0 byte file?)

I'm having trouble sending a file after downloading using ytdl. I notice it's very strange, it will successfully send the file to the server provided that I name it manually something other than the title... otherwise it only sends a 0 byte file to my server. I tried running all sorts of string methods on my title scheme thinking that could be wrong, but that didn't work. I have a hunch that maybe it's related to:
https://github.com/hydrabolt/discord.js/issues/1907
But man I have no idea I'm clueless. Any help would be greatly appreciated. Below is my source. Function im having issues sending the file is command === 'ytm'
const Discord = require('discord.js'); //need discord.js library of course.
const config = require("./config.json"); //load up the token and prefix from our object configuration file.
const bot = new Discord.Client(); //establishing the bot as the client. "bot" means "client" when looking at the documentation!
bot.on('ready', () => {
console.log('I am ready!');
});
bot.on('message', message => {
if(message.author.bot) return; //prevents the bot from reacting to itself.
if(message.content.indexOf(config.prefix) !== 0) return; //reads out the first character of the message, and if its not our prefix we don't do break away
const args = message.content.slice(config.prefix.length).trim().split(/ +/g); //setting up to split things into arguments for handling commands, and usage of the prefix
const command = args.shift().toLowerCase();
if (command === 'ping') {
message.channel.send('pong');
//console.log(args);
//console.log(command);
}
if (command === 'ytm') {
const fs = require('fs');
const ytdl = require('ytdl-core');
url = args[0];
//console.log(ytdl.getURLVideoID(url));
//tried to actually work with the "title" information outside of the callback. apparently impossible?
ytdl.getInfo(url,function(err, info){
var title = info['title'];
var length = title.length;
title = title.substring(0, (length / 3));
title = title.trim();
title = './' + title + '.mp3'
console.log(title);
//console.log(info['size']);
ytdl(url, {filter:'audioonly', format:'mp3'}).pipe(fs.createWriteStream(title.toString()));
message.channel.send("Here's your mp3, boi.", {files:[(title)]});
//message.channel.sendFile(('./' + title), title, 'Heres your mp3, boi,'); //deprecated?
})
}
});
bot.login(config.token);
The issue is you're attempting to send the title variable as your file which you've explicitly set as a string by doing title = './' + title + '.mp3'. Your issue is that you're attempting to send a video stream instead of a video file. ytdl-core is a module that's made explicity for streaming videos instead of downloading videos. To get and send an MP3 file, you have to use youtube-dl instead (what ytdl-core is based off of). This will emit an event when the file has finished downloading, which you can then send through Discord.js.

Categories

Resources