I made a whatsapp bot using Baileys and made a werewolf game feature, I want the time to change every 5 minutes from morning to night then morning again like a loop until the winner is determined. I use setInterval but it causes spam
I also used Node Corn and the result is the same
the all_room json db
[
{
"code":"FJ32Q",
"group_id":"6288742689173-1610938001#g.us",
"time":"morning",
"night":0,
"status":"starting",
"vote":false
}
]
getTime (function to get time from db)
const getTime = (group) => {
let alldb = JSON.parse(fs.readFileSync('./database/ww/all_room.json'))
satu = alldb.find((obj => obj.group_id == `${group}`));
return satu.time
}
set_time (functon to change value)
const set_time = (times, group) => {
let alldb = JSON.parse(fs.readFileSync('./database/ww/all_room.json'))
satu = alldb.findIndex((obj => obj.group_id == `${group}`));
alldb[satu].time = times
fs.writeFileSync('./database/ww/all_room.json', JSON.stringify(alldb))
}
if(isWS(group.id)){ // true
setInterval(() => {
if(getTime() === "morning") {
set_time("night")
reply("the sun is setting be careful because the werewolves are starting to roam")
} else if(getTime() === "night") {
set_time("morning")
reply("the sun has risen")
}
}, 300000);
}
Result
this is even spam
Related
I've been working on this command (that I have a problem with) where when the user says u?hi, the bot replies before putting you in a set. You are then put in a timeout for 20 seconds, and while you are in the timeout, if you type u?hi, the bot replies gotta wait x seconds. When the timeout ends, they can type u?hi and the cycle keeps going.
However, I've encountered a problem. In my code, after doing u?hi, I get put in a timeout (just like how I planned). However, while in the timeout, if I type u?hi while lets say 1 seconds into the timeout, instead of the bot saying gotta wait 19 more seconds, the bot says gotta wait 19 more seconds and then starts counting down all the way to 0. Here's what I mean (Screenshot):
Here's my code:
const intervalSet = new Set();
bot.on("message", msg => {
let args = msg.content.substring(prefix.length).split(" ");
switch (args[0]) {
case "hi":
var interval = 20;
var intervalID;
if (intervalSet.has(msg.author.id)) {
intervalID = setInterval(() => {
interval -= 1;
if (interval !== 0 && args[0] === 'hi') {
msg.channel.send(`gotta wait ${interval} more seconds`);
}
if (interval === 0) {
clearInterval(intervalID);
msg.channel.send(`Ended`);
intervalSet.delete(msg.author.id);
}
}, 1000);
} else {
intervalSet.add(msg.author.id);
msg.channel.send("heyy");
}
}
});
I've tried moving the
if (interval !== 0 && args[0] === 'hi') {
msg.channel.send(`gotta wait ${interval} more seconds`);
}
part to other places of the code and changing it up but nothing seems to work. What can I do about this?
Yes that's normal with your code. What you need to do is to create a map, named cooldown. User IDs will be linked with times, so you'll be able to calculate for how long the user is in cooldown.
Here is an update of your code:
const cooldown = new Map();
bot.on("message", msg => {
let args = msg.content.substring(prefix.length).split(" ");
switch (args[0]) {
case "hi":
var interval = 20000; // use milliseconds instead of seconds
var intervalID;
if (cooldown.has(msg.author.id)) {
let cooldownTime = Date.now() - cooldown.get(msg.author.id);
let timeToWait = (interval-cooldownTime)/1000;
if(cooldownTime < interval) {
return message.channel.send(`gotta wait ${timeToWait} more seconds`);
}
}
cooldown.set(msg.author.id, Date.now());
msg.channel.send("heyy");
}
});
If you have any questions, don't hesitate to post a comment!
I am doing a time-to-click score table but first I have to localstorage each time I get in a game but I dont know how I have been trying everything but it still not working, I need to finish this fast, and I need help... otherwise I would try everyday to resolve this alone because I know that's the way to learn.. When I press the finished button It says that times.push() is not a function.
let times = Array.from(
{ length: 3 }
)
let interval2;
// Timer CountUp
const timerCountUp = () => {
let times = 0;
let current = times;
interval2 = setInterval(() => {
times = current++
saveTimes(times)
return times
},1000);
}
// Saves the times to localStorage
const saveTimes = (times) => {
localStorage.setItem('times', JSON.stringify(times))
}
// Read existing notes from localStorage
const getSavedNotes = () => {
const timesJSON = localStorage.getItem('times')
try {
return timesJSON ? JSON.parse(timesJSON) : []
} catch (e) {
return []
}
}
//Button which starts the countUp
start.addEventListener('click', () => {
timerCountUp();
})
// Button which stops the countUp
document.querySelector('#start_button').addEventListener('click', (e) => {
console.log('click');
times = getSavedNotes()
times.push({
score: interval2
})
if (interval) {
clearInterval(interval);
clearInterval(interval2);
}
})
You probably need to change the line times = JSON.parse(localStorage.times || []) to times = JSON.parse(localStorage.times) || [] this makes sure that if the parsing fails it will still be an array.
Even better is wrap them with try-catch just in case if your JSON string is corrupted and check if the time is an array in the finally if not set it to empty array.
I want to build a "timer". User can define a duration and the interval. So it will start with a warnsignat, then there will be a warnsignal, which peeps every interval and at the end there should be one.
The problem is: it doesn't work.
The audio just plays all the time.
Possible errorsources:
peep.loop = false does not work
it does not block.
const peepUrl = require('./../../../Assets/peep.mp3');
const peep = new Audio(peepUrl);
peep.loop = false;
_peep = () => {
peep.play();
if(this.state.myInterval > 0) {
setTimeout(() => {
peep.play();
}, 60000*this.state.myInterval);
}
clearInterval(this.state.myDuration)
peep.play();
}
So basically I want my bot to have a dynamic status that changes every 5 seconds and displays how many users my bot is currently helping. The changing status part is not the issue, the problem is the users helped count does not change without restarting my bot, which is not ideal considering it is hosted and on many servers, no point restarting all the time just for the user count to be accurate.
What I have tried is by including a interval timer that will update the userCount variable in an attempt to make it accurate to how many users it is helping. What seems to be happening is when a user joins the server, the variable will update accordingly and display +1 in relation to the previous number of users helped. But, when a user leaves, it does not subtract one from the count, instead, it just leaves it at the previous count. I included console.log(userCount) just to make it easier to see the number every 10 seconds in the console, instead of having to wait for the bot's status to change to the proper one.
bot.on('ready', function() {
let userCount = bot.users.size
setInterval(() => {
userCount = bot.users.size
console.log(userCount)
}, 10000);
setInterval(async () => {
let statuslist = [
'blah',
"blah'",
'blah ' + ` ${userCount} Users`
];
const random = Math.floor(Math.random() * statuslist.length);
try {
await bot.user.setPresence({
game: {
name: `${statuslist[random]}`,
type: "Playing"
},
status: "online"
});
} catch (error) {
console.error(error);
}
}, 5000);
console.log("Logged in as " + bot.user.username);
});
I feel as though this isn't a library issue, because I am not very confident in my ability to create code that checks for changes. Ideally, it will display the accurate number based on users joining/leaving servers the bot is on, as well as guilds inviting/removing the bot from the guild. I am not sure if I should use events for this, and even if I was to, I do not know how I could.
But, when a user leaves, it does not subtract one from the count, instead, it just leaves it at the previous count.
This is expected of client.users. It's a collection of all the users the client has cached at some point, so it shouldn't remove any. I think what you're looking for is this...
bot.on('ready', () => {
setInterval(async () => {
let users = 0;
for (let g of bot.guilds.array()) users += (g.members.size - 1));
await bot.user.setActivity(`${users} user${users !== 1 ? 's' : ''}`, {type: 'WATCHING'})
.catch(err => console.error());
}, 15000);
});
Note that this will count users over again if they're in 2 guilds. If you'd rather have a precise count, at the cost of memory, you could use...
bot.on('ready', () => {
setInterval(() => {
let guilds = bot.guilds.array();
let users = [];
for (var i = 0; i < guilds.length; i++) {
let members = guilds[i].members.array();
for (var i = 0; i < members.length; i++) {
if (members[i].user.id !== bot.user.id && users.indexOf(members[i].user.id) === -1) users.push(members[i].user.id);
}
}
bot.user.setActivity(`${users.length} user${users.length !== 1 ? 's' : ''}`, {type: 'WATCHING'})
.catch(err => console.error());
});
});
You have 2 setIntervals, combine them!
That should solve your issue.
You could also use the guildMemberAdd / guildMemberRemove event.
bot.on('ready', function() {
setInterval(async () => {
const statuslist = [
'blah',
'blah_1',
` ${bot.users.size} Users`,
];
console.log(statuslist);
const random = Math.floor(Math.random() * statuslist.length);
try {
await bot.user.setPresence({
game: {
name: `${statuslist[random]}`,
type: 'Playing',
},
status: 'online',
});
}
catch (error) {
console.error(error);
}
}, 15000);
console.log('Logged in as ' + bot.user.username);
});
I am coding a multipurpose Discord bot to replace some of the more minor ones, and I am looking for a piece of code for a feature that recognizes repeated messages or messages sent in a very short time period (let's say 5000ms).
Here is what could be used to implement this idea.
client.on("message", (message) => {
//let's use something like a spam variable for 10 or more messages sent within 5000ms
if(message.content === spam) {
message.reply("Warning: Spamming in this channel is forbidden.");
console.log(message.author.username + " (" + message.author.id + ") has sent 10 messages or more in 5 seconds in " + message.channel.name + ".");
}
});
For reference, I also made a feature that deletes messages, using a ~delete [n] command. It looks like this:
//this will only delete one message in the channel, the most recent one.
message.delete(1000);
//1000 represents the timeout duration. it will only delete one message, regardless of the value.
//we can delete multiple messages with this, but note it has to come before the reply message.
message.channel.bulkDelete(11);
I was thinking of somehow combining the delete command with recognizing spam messages. If you have any ideas, that would be perfect.
Try This:
const usersMap = new Map();
const LIMIT = 7;
const DIFF = 5000;
client.on('message', async(message) => {
if(message.author.bot) return;
if(usersMap.has(message.author.id)) {
const userData = usersMap.get(message.author.id);
const { lastMessage, timer } = userData;
const difference = message.createdTimestamp - lastMessage.createdTimestamp;
let msgCount = userData.msgCount;
console.log(difference);
if(difference > DIFF) {
clearTimeout(timer);
console.log('Cleared Timeout');
userData.msgCount = 1;
userData.lastMessage = message;
userData.timer = setTimeout(() => {
usersMap.delete(message.author.id);
console.log('Removed from map.')
}, TIME);
usersMap.set(message.author.id, userData)
}
else {
++msgCount;
if(parseInt(msgCount) === LIMIT) {
message.reply("Warning: Spamming in this channel is forbidden.");
message.channel.bulkDelete(LIMIT);
} else {
userData.msgCount = msgCount;
usersMap.set(message.author.id, userData);
}
}
}
else {
let fn = setTimeout(() => {
usersMap.delete(message.author.id);
console.log('Removed from map.')
}, TIME);
usersMap.set(message.author.id, {
msgCount: 1,
lastMessage : message,
timer : fn
});
}
})