How can I include a code from another file commands - node.js

I am using this code, and what I want is for the commands to come from another file to make the index.js cleaner
const tmi = require('tmi.js');
const client = new tmi.Client({
options: { debug: true },
channels: [ 'my_name' ]
});
client.connect();
client.on('message', (channel, tags, message, self) => {
// Ignore echoed messages.
if(self) return;
if(message.toLowerCase() === '!hello') {
// "#alca, heya!"
client.say(channel, `#${tags.username}, heya!`);
}
});
In the index include the code
// index.js
// ======
var commands = require('./commands');
const tmi = require('tmi.js');
var commands = require('./commands');
const client = new tmi.Client({
options: { debug: true },
channels: [ 'my_name' ]
});
client.connect();
client.on('message', (channel, tags, message, self) => {
// Ignore echoed messages.
if(self) return;
// I replace the command with the file
commands();
});
I have the commands file structured in this way.
// commands.js
// ========
module.exports = function (channel, tags, message, self) {
if(message.toLowerCase() === '!hello') {
// "#alca, heya!"
client.say(channel, `#${tags.username}, heya!`);
}
}
But it doesn't work for me, I don't know what I'm doing wrong.
I have republished it from a new account, it has not allowed me to access the one with which I made the query. And it does not allow me to vouch for the lack of reputation. How can I include a code from another file
Responding to #jabaa's answer.
The problem you have when typing !hello should give the answer Heya! which would be client.say(channel, #${tags.username}, heya!);
#Dave Newton the intention is only to load the information from commands.js so that the index is cleaner if I use the direct code it works but when I use Commands(); It doesn't make any response.

Assuming you have 2 files in the same directory
/foo/bar/commands.js
/foo/bar/main.js
You can define commands.js like this:
exports = module.exports = {
someFunction,
anotherFunction,
}
function someFunction(text) {
console.log(`in someFunction: ${text}`);
}
function anotherFunction(text) {
console.log(`in anotherFunction(): ${text}`);
}
And then you can pull that into main.js like so:
const cmds = require('./commands');
cmds.someFunction('hello, there!');
cmds.anotherFunctio('and again!');
and get the following written to the console:
in someFunction(): hello, there!
in anotherFunction(): and again!
If you set the default export as the function itself,
exports = modules.exports = someFunction(text) {
console.log(`in someFunction(): ${text}`);
}
Then what's returned from the require() is that function:
const foo = require('./commands.js');
foo('hello, there!'):
and running that you get:
in someFunction(): hello, there!

Related

onValue triggering multiple times

I'm using Node.js v18.12.1 and Discord.js v14. for developing the Discord bot. I need to read some data from Firebase. I'm confused because I'm used to how Java with Hibernate fetches data differently. Here, I need to use onValue() listener.
My onValue() acts strange. Instead of just reading the data from Firebase, it skips entirely, then it triggers multiple times, each time skipping the body block of its code, and then it actually does the code after.
I've read somewhere on this forum that this can happen because there are more onValue() listeners that are subscribed and they are all fired up. Someone mentioned I need to use the off() function somewhere "before" the onValue(). This confuses me because I'm using this listener in many locations. I need it in each command file, in execute(interaction) functions. You know, when you need to execute slash commands in Discord. I have it something like this:
async execute(interaction) {
const infographicRef = ref(db, '/infographics/arena/' + interaction.options.getString("arena-team"));
var imageUrl = null;
var postUrl = null;
onValue(infographicRef, (snapshot) => {
imageUrl = snapshot.child("image-url").val();
interaction.reply(imageUrl);
})
},
And I planned for each command, in each command.js file to have onValue(). I'm not sure exactly what to do.
Also, I tried to work around this with once() method, I see it in Firebase documentation, but I got the error: ref.once() is not a function.
It seems that after first triggering of onValue method when the body is not executed, my code in interactionCreate.js is triggered as well, it points for a command to be executed again:
const { Events } = require('discord.js');
module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {
if (!interaction.isChatInputCommand()) return;
const command = interaction.client.commands.get(interaction.commandName);
if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`);
return;
}
try {
await command.execute(interaction);
} catch (error) {
console.error(`Error executing ${interaction.commandName}`);
console.error(error);
}
},
};
my bot.js (which is in my case an index file)
const fs = require('node:fs');
const path = require('node:path');
const { Client, Collection, Events, GatewayIntentBits } = require('discord.js');
const { token } = require('./config.json');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
const eventsPath = path.join(__dirname, 'events');
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));
for (const file of eventFiles) {
const filePath = path.join(eventsPath, file);
const event = require(filePath);
if (event.once) {
client.once(event.name, (...args) => event.execute(...args));
} else {
client.on(event.name, (...args) => event.execute(...args));
}
}
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);
client.commands.set(command.data.name, command);
}
client.once(Events.ClientReady, () => {
console.log('Ready!');
});
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
}
});
client.login(token);
The onValue function registers a realtime listener, that continues to monitor the value on the database.
If you want to read a value once, that'd be done with get() function in v9 (which is the equivalent of the once method in earlier SDK versions). Have a look at the code sample in the documentation on reading data once.

KuCoin API - TypeError: request.charAt is not a function

I'm trying to make a request to the KuCoin API to query the balance. I'm using the NodeJS API found here but I keep getting the error whenever I execute the code.
And here's the code snippet
data().then(api => {
const apiKey = api.api_key;
const apiSecretKey = api.api_secret;
const contactId = api.contact_id;
const exchange = api.exchange;
const passphrase = 'Passphrase';
/** Init Configure */
const config =
{
key: apiKey, // KC-API-KEY
secret: apiSecretKey, // API-Secret
passphrase: passphrase, // KC-API-PASSPHRASE
environment: "live"
}
API.init(require(config));
if (apiKey && exchange === "KuCoin-Futures") {
console.log("KuCoin Balance")
async function getBalance() {
try {
let r = await API.getAccountOverview()
console.log(r.data)
} catch(err) {
console.log(err)
}
}
return getBalance()
}
});
I the console log I get the following error
TypeError: request.charAt is not a function
at Function.Module._resolveLookupPaths (internal/modules/cjs/loader.js:617:15)
Does anyone know how I can fix this??
There are couple of things which look weird in the code snippet you provided, but the sample code from the kucoin-node-api library you linked should work perfectly fine. In case you are using that one, try this snippet which should show your account info:
const api = require('kucoin-node-api');
const config = {
apiKey: 'YOUR_KUCOIN_API_KEY',
secretKey: 'YOUR_KUCOIN_API_SECRET',
passphrase: 'YOUR_KUCOIN_API_PASSPHRASE',
environment: 'live'
};
api.init(config);
api.getAccounts().then((r) => {
console.log(r.data);
}).catch((e) => {
console.log(e);
});
In case you're using a different library, kucoin-node-sdk maybe (judging by your code snippet), then try to configure it correctly:
config.js file:
module.exports = {
baseUrl: 'https://api.kucoin.com',
apiAuth: {
key: 'YOUR_KUCOIN_API_KEY',
secret: 'YOUR_KUCOIN_API_SECRET',
passphrase: 'YOUR_KUCOIN_API_PASSPHRASE'
},
authVersion: 2
}
and your main.js (or whatever the name is):
const API = require('kucoin-node-sdk');
API.init(require('./config'));
const main = async () => {
const getTimestampRl = await API.rest.Others.getTimestamp();
console.log(getTimestampRl.data);
};
main();
The code above will show you KuCoin server timestamp only, but should be enough to keep going.
Good luck with trading!

Code that worked on Replit doesn’t work in VSC

Basically, my code worked completely fine in replit, but now it doesnt work in a vsc folder. my replit version also suddenly can’t send any messages anymore. it sends all the console.logs but the client.say stuff it just skips without an error.
const tmi = require('tmi.js');
// Define configuration options
const opts = {
identity: {
username: 'BormBot',
password: 'cut out for a reason'
},
channels: [
'Epicurious__'
]
};
// Create a client with our options
const client = new tmi.client(opts);
const jsonFile = require('./link.json');
const fs = require('fs');
const mongoose = require('mongoose');
// Register our event handlers (defined below)
client.on('connected', onConnectedHandler);
// Connect to Twitch:
client.connect();
client.on('message', (channel, tags, msg, self, target) => {
if (self) return;
//start of geoguessr commands
const link = {
"link": ""
};
if (msg.startsWith('!geolink')) {
if (tags.badges.broadcaster == 1) {
const arguments = msg.split(/[ ]+/)
if (arguments[1]) {
let link = arguments[1];
const data = JSON.stringify(link);
fs.writeFile('./link.json', data, (err) => {
if (err) {
throw err;
}
console.log("JSON data is saved.");
});
client.say(channel, link);
} else {
console.log("no args");
}
}
}
if (msg.startsWith('!game')) {
// read JSON object from file
fs.readFile('./link.json', 'utf-8', (err, data) => {
if (err) {
throw err;
}
// parse JSON object
const linkDone = JSON.parse(data.toString());
// print JSON object
client.say(channel, `The link for the current geoguessr game is: ${linkDone}`);
console.log(`${linkDone}`);
});
}
//end of geoguessr commands
});
// Called every time the bot connects to Twitch chat
function onConnectedHandler(addr, port) {
console.log(`* Connected to ${addr}:${port}`);
}
console
Also on twitch developer forum: 2
On twitch developer forum there hasn't been an answer yet, hence why I'm also putting it on here. Hopefully I can find an answer, also, maybe add a tag for tmi.js

Is it possible to use Discord slash commands as module?

First things first, I'm a beginner in node.js and discord.js.
I'm currently working on my own discord bot for fun and I was wondering if it was possible to "store" the data of a slash command. Here is an example of what I mean :
const response = new Discord.MessageEmbed()
.properties()
.properties()
etc...
module.exports = () {
const data = {
data: {
type: 4, // I don't know what type to use for embed message so please correct me if I'm wrong
data: {
content: response
}
}
}
}
Could this be possible to "store" the embed message data in rules.js and use it in main.js like so :
const rules = require('rules.js') //the file would be in a "commands" folder but I'm keeping this simple
client.ws.on('INTERACTION_CREATE', async (interaction) => {
const command = interaction.data.name.toLowerCase()
if (command === 'rules') {
client.api.interactions(interaction.id, interaction.token).callback.post(data) // or post(rules.data) ??? again, I'm a beginner
}
})
You should try to create a function instead of save and export module because is dangerous to use instance class like a module because it's causing a memory issue, so write a factory for this
Here is something you can try:
//file name: slashCmd.js
const Discord = require('discord.js')
module.exports = async function(client, cmdObj) {
client.api.applications(client.user.id).commands.post(cmdObj)
}
You can customize the function as much as you want but you can do this in your index.js
const slashCmd = require('./slashCmd.js');
const client = new Discord.Client()
client.on('ready', () => {
slashCmd(client, {
name: 'cmdName',
description: 'cmdDesc'
})
})

How can I make my Discord bot ignore the set prefix for certain commands only? (Discord.js)

I'm very new to Java and trying to code a simple bot. When I first coded this, it did not have a command handler with multiple files, and everything worked. However, while some commands like sending random images still work, I can't figure out a way to make my bot ignore prefixes for certain commands: For example, before my bot could respond to "Where are you?" with "I am here" without having the prefix "!" in front. When I include this command in the index.js file with an if statement it still works, but trying to put it in another file doesn't. I'd really appreciate if anyone could help me with this.
Here is my code:
index.js
const discord = require('discord.js');
const client = new discord.Client({ disableMentions: 'everyone' });
client.config = require('./config/bot');
client.commands = new discord.Collection();
fs.readdirSync('./commands').forEach(dirs => {
const commands = fs.readdirSync(`./commands/${dirs}`).filter(files => files.endsWith('.js'));
for (const file of commands) {
const command = require(`./commands/${dirs}/${file}`);
console.log(`Loading command ${file}`);
client.commands.set(command.name.toLowerCase(), command);
};
});
const events = fs.readdirSync('./events').filter(file => file.endsWith('.js'));
for (const file of events) {
console.log(`Loading discord.js event ${file}`);
const event = require(`./events/${file}`);
client.on(file.split(".")[0], event.bind(null, client));
};
client.login(client.config.discord.token);
Some of my commands files:
sendrand.js (This one works)
module.exports = {
name: 'sendrand',
category: 'sendpic',
execute(client, message, args) {
var num = 33;
var imgNum = Math.floor(Math.random() * (num - 1 + 1) + 1);
message.channel.send({files: ["./randpics/" + imgNum + ".png"]});
}
};
where.js(This one doesn't)
module.exports = {
name: 'where',
category: 'core',
execute(client, message, args) {
if(message.startsWith('where are you){
message.channel.reply('I am here!)
}
};
I know I could make it so that the bot would respond to "!where are you", but I'd like to have it without the prefix if possible
You could do:
module.exports = {
name: "respond",
category: "general",
execute(client, message) {
if (message.content.toLowerCase().startsWith("where are you")) {
message.reply("I am here!");
}
},
};

Resources