Using a variable in more than 1 file - discord.js

TL:DR - I need help using a variable in more than 1 file
Currently I have a bot that counts how many times the word ":p" has been used. It adds that number to the variable "numberofp". On a separate file I want to call the variable on an embed but it says numberofp is undefined. Code is below. If you would like more code just ask!
code for index.js
// variables
var numberofp = 0;
client.on('message', (message) => {
if(message.author.id = 714544589305806868){
if(message.content.includes(':p')){
numberofp = numberofp + 1;
console.log('Porsha_boy said :p, so far it has been sent this many times:', numberofp);
}
}
})
Code for embed
const db = require("quick.db")
const Discord = require('discord.js')
module.exports = {
name: 'rub',
description: 'a command that tells you what your ping is',
execute(message, args, Discord){
// Basic embed
var embed = new Discord.MessageEmbed()
.setAuthor(numberofp)
.setColor("#34BDE1")
console.log('working')
}
}

You need to export the variable to be visible from the module outside:
wordcounter.js
let counter = 0;
function increase(a = 1) {
counter += a;
}
function getCounter() {
return counter;
}
exports.increase = increase;
exports.getCounter = getCounter;
clientone.js
const wc = require('./wordcounter');
wc.increase();
wc.increase(2);
wc.increase(5);
clienttwo.js
const wc = require('./wordcounter');
wc.increase(1);
wc.increase(1);
wc.increase(5);
index.js
const wc = require('./wordcounter');
const c1 = require('./clientone');
const c2 = require('./clienttwo');
console.log(wc.getCounter());

Related

Jest not generating values correctly using crypto

I made a function to generate a complex password using window.crypto lib, this work perfectly and return values like jQzPN%c#tr71ie6Dt^C8.
Here is my function :
const genPwd = (length: number): string => {
const regex = /^(?=.*[A-Z])(?=.*[!##$%^&*])(?=.*[0-9]).{8,}$/;
const charset =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!##$%^&*()_-+={[}]|:;<,>.?/';
let result = '';
let values = new Uint32Array(length);
window.crypto.getRandomValues(values);
for (let i = 0; i < length; i++) {
result += charset[values[i] % charset.length];
}
if (!regex.test(result)) {
console.log('result', result);
return genPwd(length);
} else {
return result;
}
};
But when I try to test this function using Jest, it falls everytime in the last condition because it doesn't match the regex, the console.log shows "AAAAAAAAAAAAAAAAAAAA", like nothing is generating correctly, so it doesn't match the regex and looping.
Here is my test :
it('should generate a x length password', () => {
const mGetRandomValues = jest.fn().mockReturnValueOnce(new Uint32Array(20));
Object.defineProperty(globalThis, 'crypto', {
value: { getRandomValues: mGetRandomValues },
});
const valueToConvert = utils.genPwd(20);
const valueToFind = 20;
expect(valueToConvert).toHaveLength(valueToFind);
expect(mGetRandomValues).toBeCalledWith(new Uint32Array(valueToFind));
});
Does anyone have a solution ?
I have no idea about this issue

Can someone help me find what is wrong with my code?

Im trying to make a stopwatch command that when you say !duty on and then !duty off it will calculate the time took to stop it. It works like a regular stopwatch but it is for discord. I have been trying to fix the err for a week but i cant understand why it doesnt work pls help me. The err is in line 10 id where it says message.guild.id
the code:
const Discord = require('discord.js');
const StopWatch = require("timer-stopwatch-dev");
const moment = require('moment');
module.exports = {
name: 'duty',
description: "This is a stopwatch command",
async execute(client, message, args, CurrentTimers) {
try {
let guildTimers = CurrentTimers.get(message.guild.id);
let guildTimersUser = guildTimers.get(message.author.id);
if(!guildTimersUser){ guildTimers.set(message.author.id, new StopWatch()); guildTimersUser = guildTimers.get(message.author.id); };
if(!args[0] || args[0] === 'on'){
if(guildTimersUser.isRunning()) return message.channel.send('You need to stop your shift first!')
guildTimersUser.start();
message.channel.send('You have started your shift')
} else if(args[0] === 'off'){
if(!guildTimersUser.isRunning()) return message.channel.send('You need to start the Stopwatch first!')
guildTimersUser.stop();
message.channel.send(new Discord.RichEmbed().setTitle('You have stopped the Stopwatch!').setDescription('Total Time: ' + dhm(guildTimersUser.ms)).setTimestamp());
}
}
catch(err) {
console.log(err)
}
function dhm(ms){
days = Math.floor(ms / (24*60*60*1000));
daysms=ms % (24*60*60*1000);
hours = Math.floor((daysms)/(60*60*1000));
hoursms=ms % (60*60*1000);
minutes = Math.floor((hoursms)/(60*1000));
minutesms=ms % (60*1000);
sec = Math.floor((minutesms)/(1000));
return days+" days, "+hours+" hours, "+minutes+" minutes, "+sec+" seconds.";
}
}
}
my main:
require('dotenv').config();
//create cooldowns map
const cooldowns = new Map();
module.exports = (Discord, client, 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));
if(command){
//If cooldowns map doesn't have a command.name key then create one.
if(!cooldowns.has(command.name)){
cooldowns.set(command.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(command.name);
const cooldown_amount = (command.cooldown) * 1000;
//If time_stamps has a key with the author's id then check the expiration time to send a message to a user.
if(time_stamps.has(message.author.id)){
const expiration_time = time_stamps.get(message.author.id) + cooldown_amount;
if(current_time < expiration_time){
const time_left = (expiration_time - current_time) / 1000;
return message.reply(`Please wait ${time_left.toFixed(1)} more seconds before using ${command.name}`);
}
}
//If the author's id is not in time_stamps then add them with the current time.
time_stamps.set(message.author.id, current_time);
//Delete the user's id once the cooldown is over.
setTimeout(() => time_stamps.delete(message.author.id), cooldown_amount);
}
try{
command.execute(message,args, cmd, client, Discord, CurrentTimers);
} catch (err){
message.reply("There was an error trying to execute this command!");
console.log(err);
}
}
You didn’t show the actual error but I suspect that it is something like Cannot read property 'id' of undefined. The way to fix this is to make sure of 2 things:
Make sure the message is not in DM
Make sure your execution parameters are passed in correctly.
command.execute(client, message, args, CurrentTimers)
//these may not be the same variable names, but make sure the values are correct

Command Cooldown discord.js

I have been working on updating my current command cooldown, when upadting my message.js file the cooldown does not show.
This is the current code in the command cooldown file
const botconfig = require("../../botconfig.json");
const fs = require("fs")
const Discord = require('discord.js')
const cooldowns = new Map()
module.exports = async (bot, message) => {
if(message.author.bot || message.channel.type === "dm") return;
let prefixes = JSON.parse(fs.readFileSync("././prefixes.json", "utf8"))
if(!prefixes[message.guild.id]){
prefixes[message.guild.id] = {
prefixes: botconfig.prefix
};
}
let prefix = prefixes[message.guild.id].prefixes;
let args = message.content.slice(prefix.length).trim().split(/ +/g);
let cmd = args.shift().toLowerCase();
if(!message.content.startsWith(prefix)) return;
let commandfile = bot.commands.get(cmd) || bot.commands.get(bot.aliases.get(cmd))
if(commandfile) commandfile.run(bot, message, args)
if(!cooldowns.has(commandfile.name)){
cooldowns.set(commandfile.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(commandfile.name);
const cooldown_amount = (commandfile.cooldown) * 1000;
if(time_stamps.has(message.author.id)){
const experation_time = time_stamps.get(message.author.id) + cooldown_amount;
if (current_time < experation_time){
const time_left = (experation_time - current_time) / 1000;
return message.reply(`Please wait ${time_left.toFixed(1)} more seconds before using this command!`)
}
}
time_stamps.set(message.author.id, current_time);
setTimeout(() => time_stamps.delete(message.author.id), cooldown_amount);
}
In the command file I have
module.exports = {
config:{
name: "beg",
aliases: [],
cooldown: 5, // current cooldown in seconds
category: "currency",
description: "Gets you money",
usage: "[command | alias]",
accessableby: "Members"
},
When I use the command the command will work but the cooldown does not work and lets me use the command again. Am I doing something wrong? I would also like to know if I stop running the bot for an update will the cooldown save for example I use the command "!!daily" then re-set the bot for an update and 24 hours did not pass that when it goes back online the cooldown save's and keeps counting.
Cooldown should be a Discord.Collection
const cooldowns = new Discord.Collection(); //that goes on top of your script
Is first time what I comment here, I hope it helps you.
It is a matter of order:
First you call if(commandfile) commandfile.run(bot, message, args) but then only you check if the Cooldown exists. You need to rearange you code like this, move the .run down.
const botconfig = require("../../botconfig.json");
const fs = require("fs")
const Discord = require('discord.js')
const cooldowns = new Discord.Collection();
// While this does not matter, we make a Collection to for consistentcy
module.exports = async (bot, message) => {
if(message.author.bot || message.channel.type === "dm") return;
let prefixes = JSON.parse(fs.readFileSync("././prefixes.json", "utf8"))
if(!prefixes[message.guild.id]){
prefixes[message.guild.id] = {
prefixes: botconfig.prefix
};
}
let prefix = prefixes[message.guild.id].prefixes;
let args = message.content.slice(prefix.length).trim().split(/ +/g);
let cmd = args.shift().toLowerCase();
if(!message.content.startsWith(prefix)) return;
let commandfile = bot.commands.get(cmd) || bot.commands.get(bot.aliases.get(cmd));
if(!commandfile) return;
// return if no command Found, if one is found, proceed to check for cooldown
if(!cooldowns.has(commandfile.name)){
cooldowns.set(commandfile.name, new Discord.Collection());
}
const current_time = Date.now();
const time_stamps = cooldowns.get(commandfile.name);
const cooldown_amount = (commandfile.cooldown) * 1000;
if(time_stamps.has(message.author.id)){
const experation_time = time_stamps.get(message.author.id) + cooldown_amount;
if (current_time < experation_time){
const time_left = (experation_time - current_time) / 1000;
return message.reply(`Please wait ${time_left.toFixed(1)} more seconds before using this command!`);
}
}
// above here is the return, if the cooldown is still active, if so it returns with the message
time_stamps.set(message.author.id, current_time);
// here we set the time_stamp and now can run the command
commandfile.run(bot, message, args);
}

Automatic Slowmode Discord.js

I've been trying to create a system that automatically sets the slowmode in a channel to a certain amount depending on how many messages have been sent. Lua is my primary language, and not Node.js, therefore I'm having quite a bit of trouble as to how I would go about this. If anyone had any suggestions, please let me know.
Two ways to go about it:
Use discord.js's <TextChannel>.setRateLimitPerUser(number)
https://discord.js.org/#/docs/main/stable/class/TextChannel?scrollTo=setRateLimitPerUser
Not sure if this actually does what you want though, the other option is creating a session storage of the text channels msgCount and compare it to time, i found setRateLimitPerUser in the middle of writing the code so didn't finish it, be here's a start:
const { Client, Collection } = require("discord.js");
const client = new Client();
client.slowdown = new Collection();
client.on("message", msg => {
const id = msg.channel.id;
const attempt = client.slowdown.get(id);
//4 messages at most per second
const ratio = 4;
//look at last how many seconds
const timeSpace = 5;
//TODO: check if channel already has cooldown
if (attempt) {
attempt.msgCount++;
const currentTime = Date.now();
const timePassed = (currentTime - attempt.time) / 1000;
if (attempt.msgCount >= ratio && attempt.msgCount / timePassed >= ratio) {
//setCoolDown
}
if (timePassed >= timeSpace) {
attempt.time = currentTime;
attempt.msgCount = 0;
}
} else {
client.slowdown.set(id, {
time: Date.now(),
msgCount: 1
});
}
});

How to get the specific discord bot channel with channelid?

My bot returns undefined when using bot.channels.get(channelid).
Here's a sample of my code:
//this is executed in a guild with id 416809320513011713
const Discordjs = require("discord.js");
const bot = new Discordjs.Client();
const auth = require('./auth.json');
const FileSys = require("fs");
bot.on('messageDelete', async function (message) {
console.log('message deleted')
let currentguildsettings = JSON.parse(FileSys.readFileSync('./DatStore/GuildDat/' + message.guild.id + '.dat', 'UTF8'));
if (currentguildsettings[0] == 1) {
if (currentguildsettings[1] != 0) {
let channelid = currentguildsettings[1].toString()
let channel = bot.channels.get(channelid);
console.log('settings on true, channelid ' + channelid)
if (channel) {
console.log('channel found')
}
}
}
}
bot.login(auth.token)
file ./DatStore/GuildDat/416809320513011713.dat contains:
[1,424085503361417200,0]
Here's the output:
message deleted
settings on true, channelid 424085503361417200
If the channel was found it should've logged 'channel found' in the output.
What should I change to make it return the channel?
The channel id key is a string, you must enclose it as a string in your array.
let c1 = bot.channels.get(424085503361417200); // Will produce undefined
let c2 = bot.channels.get('424085503361417200'); // Will produce a channel object (if available)
The channel wasn't available since I used the wrong id:
I saved the id's at my server settings command in int format instead of string, parseInt() broke the exact number.
if (logchannelaction == 'set') {
if (currentguildsettings[1] == message.channel.id) return message.reply("logchannel was already set to this channel");
currentguildsettings[1] = parseInt(message.channel.id);
message.reply("logchannel has set to #" + message.channel.name);
if (currentguildsettings[0] == 0) {
currentguildsettings[0] = 1
message.reply("logchannel has automatically enabled");
}
FileSys.writeFileSync(guilddatpath, JSON.stringify(currentguildsettings));
return
}
Thank you for trying to help me.

Resources